当前位置:   article > 正文

u-boot-2012.04.01移植(六)提供nand flash启动支持_make 命令 -pie

make 命令 -pie

重新编译烧写,串口输出错误信息:

Flash:*** failed ***

### ERROR ### Please RESET the board

 

这个错误下一节再解决,这一节先为u-boot提供nand flash启动的支持

前面分析uboot时提到链接时加上-pie选项会生成位置无关码,将变量、函数的地址保存起来,以便于在uboot重定位代码时使用,这样虽然可以不指定程序的链接地址,但会导致程序增大,超过4k,不易使用nand启动,并且重定位代码复杂

修改办法:

1、修改Makefile去掉链接命令中的-pie选项

通过下面命令找到-pie的位置在arch/arm/config.mk的75行

grep “\-pie” * -nR

注释掉arch/arm/config.mk的75行

#LDFLAGS_u-boot += -pie

 

2、添加nand支持

①、修改board/samsung/smdk2440/Makefile

  1. //COBJS := smdk2410.o
  2. COBJS := smdk2410.o init.o

 

②、在board/samsung/smdk2440中新增一个文件init.c,提供nand flash的操作函数、启动flash类型的判断、代码重定位函数等等

  1. /* NAND FLASH */
  2. #define NFCONF (*((volatile unsigned long *)0x4E000000))
  3. #define NFCONT (*((volatile unsigned long *)0x4E000004))
  4. #define NFCMMD (*((volatile unsigned char *)0x4E000008))
  5. #define NFADDR (*((volatile unsigned char *)0x4E00000C))
  6. #define NFDATA (*((volatile unsigned char *)0x4E000010))
  7. #define NFSTAT (*((volatile unsigned char *)0x4E000020))
  8. //void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);
  9. static int isBootFromNorFlash(void)
  10. {
  11. volatile int *p = (volatile int *)0;
  12. int val;
  13. val = *p;
  14. *p = 0x12345678;
  15. if (*p == 0x12345678)
  16. {
  17. *p = val;
  18. return 0;
  19. }
  20. return 1;
  21. }
  22. void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
  23. {
  24. int i = 0;
  25. if (isBootFromNorFlash())
  26. {
  27. while (i < len)
  28. {
  29. dest[i] = src[i];
  30. i++;
  31. }
  32. }
  33. else
  34. {
  35. nand_read((unsigned int)src, dest, len);
  36. }
  37. }
  38. void clear_bss(void)
  39. {
  40. extern int __bss_start, __bss_end;
  41. int *p = &__bss_start;
  42. for (; p < &__bss_end; p++)
  43. *p = 0;
  44. }
  45. void nand_init_ll(void)
  46. {
  47. #define TACLS 0
  48. #define TWRPH0 1
  49. #define TWRPH1 0
  50. NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
  51. NFCONT = (1<<4)|(1<<1)|(1<<0);
  52. }
  53. static void nand_select(void)
  54. {
  55. NFCONT &= ~(1<<1);
  56. }
  57. static void nand_deselect(void)
  58. {
  59. NFCONT |= (1<<1);
  60. }
  61. static void nand_cmd(unsigned char cmd)
  62. {
  63. volatile int i;
  64. NFCMMD = cmd;
  65. for (i = 0; i < 10; i++);
  66. }
  67. static void nand_addr(unsigned int addr)
  68. {
  69. unsigned int col = addr % 2048;
  70. unsigned int page = addr / 2048;
  71. volatile int i;
  72. NFADDR = col & 0xff;
  73. for (i = 0; i < 10; i++);
  74. NFADDR = (col >> 8) & 0xff;
  75. for (i = 0; i < 10; i++);
  76. NFADDR = page & 0xff;
  77. for (i = 0; i < 10; i++);
  78. NFADDR = (page >> 8) & 0xff;
  79. for (i = 0; i < 10; i++);
  80. NFADDR = (page >> 16) & 0xff;
  81. for (i = 0; i < 10; i++);
  82. }
  83. static void nand_wait_ready(void)
  84. {
  85. while (!(NFSTAT & 1));
  86. }
  87. static unsigned char nand_data(void)
  88. {
  89. return NFDATA;
  90. }
  91. void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
  92. {
  93. int col = addr % 2048;
  94. int i = 0;
  95. nand_select();
  96. while (i < len)
  97. {
  98. nand_cmd(0x00);
  99. nand_addr(addr);
  100. nand_cmd(0x30);
  101. nand_wait_ready();
  102. for (; (col < 2048) && (i < len); col++)
  103. {
  104. buf[i] = nand_data();
  105. i++;
  106. addr++;
  107. }
  108. col = 0;
  109. }
  110. nand_deselect();
  111. }

 

③、修改arch/arm/lib/board.c

修改board_init_f的返回值类型为unsigned int,并且对应修改其声明的返回值,注意要去掉__attribute__ ((noreturn)),声明位于include/common.h

 

在board_init_f函数中

Ⅰ、将

  1. addr -= gd->mon_len;
  2. addr &= ~(4096 - 1);

替换为

	addr = _TEXT_BASE;

指定一个固定的链接地址(u-boot在SDRAM上的起始地址)

Ⅱ、在函数头部添加一行,引用外部变量,变量等下会定义在start.S中,用于存放栈指针

extern ulong base_sp;

Ⅲ、在函数末尾

 relocate_code(addr_sp, id, addr);

替换为

  1. base_sp = addr_sp;
  2. return id;

保存栈指针,返回参数地址

 

④、修改arch/arm/cpu/arm920t/start.S,使用新的重定位、清除bss段代码,栈也需要重新设置

Ⅰ、

源代码:

  1. call_board_init_f:
  2. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  3. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  4. ldr r0,=0x00000000
  5. bl board_init_f

 

修改后:

  1. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  2. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  3. bl nand_init_ll
  4. mov r0, #0
  5. ldr r1, _TEXT_BASE
  6. ldr r2, _bss_start_ofs
  7. bl copy_code_to_sdram
  8. bl clear_bss
  9. ldr pc, =call_board_init_f
  10. call_board_init_f:
  11. ldr r0,=0x00000000
  12. bl board_init_f
  13. /*board_init_f返回值存于r0,用于传入board_init_r*/
  14. ldr r1, _TEXT_BASE
  15. ldr sp, base_sp
  16. bl board_init_r
  17. .globl base_sp
  18. base_sp:
  19. .long 0

为了让代码跳转到重定位后的位置,需要用绝对跳转指令ldr pc, =call_board_init_f(如果使用相对跳转指令bl,无法跳到SDRAM),跳转到SDRAM后即可使用相对跳转指令bl调用子程序

 

Ⅱ、删除这段重定位相关代码

  1. .globl relocate_code
  2. relocate_code:
  3. mov r4, r0 /* save addr_sp */
  4. mov r5, r1 /* save addr of gd */
  5. mov r6, r2 /* save addr of destination */
  6. /* Set up the stack */
  7. stack_setup:
  8. mov sp, r4
  9. adr r0, _start
  10. cmp r0, r6
  11. beq clear_bss /* skip relocation */
  12. mov r1, r6 /* r1 <- scratch for copy_loop */
  13. ldr r3, _bss_start_ofs
  14. add r2, r0, r3 /* r2 <- source end address */
  15. copy_loop:
  16. ldmia r0!, {r9-r10} /* copy from source address [r0] */
  17. stmia r1!, {r9-r10} /* copy to target address [r1] */
  18. cmp r0, r2 /* until source end address [r2] */
  19. blo copy_loop
  20. #ifndef CONFIG_SPL_BUILD
  21. /*
  22. * fix .rel.dyn relocations
  23. */
  24. ldr r0, _TEXT_BASE /* r0 <- Text base */
  25. sub r9, r6, r0 /* r9 <- relocation offset */
  26. ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
  27. add r10, r10, r0 /* r10 <- sym table in FLASH */
  28. ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
  29. add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
  30. ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
  31. add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
  32. fixloop:
  33. ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
  34. add r0, r0, r9 /* r0 <- location to fix up in RAM */
  35. ldr r1, [r2, #4]
  36. and r7, r1, #0xff
  37. cmp r7, #23 /* relative fixup? */
  38. beq fixrel
  39. cmp r7, #2 /* absolute fixup? */
  40. beq fixabs
  41. /* ignore unknown type of fixup */
  42. b fixnext
  43. fixabs:
  44. /* absolute fix: set location to (offset) symbol value */
  45. mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
  46. add r1, r10, r1 /* r1 <- address of symbol in table */
  47. ldr r1, [r1, #4] /* r1 <- symbol value */
  48. add r1, r1, r9 /* r1 <- relocated sym addr */
  49. b fixnext
  50. fixrel:
  51. /* relative fix: increase location by offset */
  52. ldr r1, [r0]
  53. add r1, r1, r9
  54. fixnext:
  55. str r1, [r0]
  56. add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
  57. cmp r2, r3
  58. blo fixloop
  59. #endif
  60. clear_bss:
  61. #ifndef CONFIG_SPL_BUILD
  62. ldr r0, _bss_start_ofs
  63. ldr r1, _bss_end_ofs
  64. mov r4, r6 /* reloc addr */
  65. add r0, r0, r4
  66. add r1, r1, r4
  67. mov r2, #0x00000000 /* clear */
  68. clbss_l:str r2, [r0] /* clear loop... */
  69. add r0, r0, #4
  70. cmp r0, r1
  71. bne clbss_l
  72. bl coloured_LED_init
  73. bl red_led_on
  74. #endif

 

3、修改链接地址

修改include/configs/smdk2440.h

  1. //#define CONFIG_SYS_TEXT_BASE 0
  2. #define CONFIG_SYS_TEXT_BASE 0x33F00000

 

4、修改链接脚本,将重定位前所用到的文件放在最前面

通过下面命令找到链接脚本位置arch/arm/cpu

find -name *.lds | grep arm

修改链接脚本

源代码

  1. .text :
  2. {
  3. __image_copy_start = .;
  4. CPUDIR/start.o (.text)
  5. *(.text)
  6. }

修改后

  1. .text :
  2. {
  3. __image_copy_start = .;
  4. CPUDIR/start.o (.text)
  5. board/samsung/smdk2440/libsmdk2440.o (.text)
  6. *(.text)
  7. }

 

重新编译烧写后即支持nand flash启动

 

 

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/899239
推荐阅读
相关标签
  

闽ICP备14008679号