1. 程式人生 > >韋東山老師講解移植uboot-2012.04.01的筆記總結

韋東山老師講解移植uboot-2012.04.01的筆記總結

一:準備移植
1、從下面的官網下載最新的U-boot。用google英文版搜尋最新的u-boot原始碼
 ftp://ftp.denx.de/pub/u-boot/
2、建立sourceinsight工程
 a、解壓並在E:\colin weidongshan\transplant_u-boot-2012.04.01\u-boot-2012.04.01建立SI
 b、新增檔案到SI工程
  1、點選"Add All",選中“Include top level sub-directories”和“Recursively add lower sub-directories”點選“OK”
  2、選中“Board”目錄,點選“Remove Tree”,去掉總個目錄
   進入“Board\Samsung\Smdk2410\”,點選"Add All"
  3、選中“Arch”目錄,點選“Remove Tree”,去掉總個目錄
   進入“Arch\Arm\Cpu\Arm920t\”,雙擊選中“Cpu.c”“Interrupts.c”“start.S”。
   進入“Arch\Arm\Cpu\Arm920t\S3c24x0\”,點選"Add All"
   進入“Arch\Arm\”,選中"Dts"目錄,點選"Add Tree"
   進入“Arch\Arm\Include\Asm\Arch_s3c24x0”,點選"Add All"
   進入“Arch\Arm\Include\Asm\”,點選"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加頂層目錄的檔案
   進入“Arch\Arm\Include\Asm\”,單擊選中"Proc-armv",點選"Add Tree"
   進入“Arch\Arm\Lib\”,點選"Add All"
  4、選中“Include”目錄,點選“Remove Tree”,去掉總個目錄
   進入“Include\”,點選"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加頂層目錄的檔案
   進入“Include\”,單擊選中"Andestech",點選"Add Tree"
   進入“Include\”,單擊選中"Asm-generic",點選"Add Tree"
   進入“Include\”,同上選中除"Configs"目錄外的所有目錄,點選"Add Tree"。"Configs"目錄先不加,下面再議
   進入“Include\Configs\”,雙擊選中“Smdk2410.h”
  5、同步檔案,完成

3、編譯
嘗試編譯
   解壓: [email protected]:/work/system$ tar xjf u-boot-2012.04.01.tar.bz2
     [email protected]:/work/system$ cd u-boot-2012.04.01/ 
   配置: [email protected]:/work/system/u-boot-2012.04.01$ make smdk2410_config
   編譯: [email protected]

:/work/system/u-boot-2012.04.01$ make
  
編譯不成功,因為版本太老
   檢視版本: [email protected]:/work/system/u-boot-2012.04.01$ arm-linux-gcc -v
   拷貝解壓: [email protected]:/work/system/u-boot-2012.04.01$ cd /work/tools/
  [email protected]:/work/tools$ mkdir tmp
  
[email protected]:/work/tools$
tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C tmp/
  [email protected]:/work/tools$ cd tmp/
  [email protected]:/work/tools/tmp$ ls
  usr
  [email protected]:/work/tools/tmp$ cd usr/local/arm/4.3.2/
  [email protected]:/work/tools/tmp/usr/local/arm/4.3.2$ ls
  arm-none-linux-gnueabi  bin  lib  libexec  share
  [email protected]:/work/tools/tmp/usr/local/arm/4.3.2$ ls bin/
  
  解壓到根目錄:[email protected]:/work/tools$ sudo tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /
  檢視環境變數: [email protected]:/work/tools$ echo $PATH
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/other_board/gcc-3.4.5-glibc-2.3.6/bin
  設定環境變數:[email protected]:/work/tools$ export PATH=/usr/local/arm/4.3.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
  檢視環境變數:[email protected]:/work/tools$ arm-linux-gcc  -v
 如果不想手動設定,你可以按如下方式修改:
   [email protected]-desktop:/work/tools$ sudo vi /etc/environment
   
  重新編譯: [email protected]:/work/tools$ cd /work/system/u-boot-2012.04.01/
  [email protected]:/work/system/u-boot-2012.04.01$ make distclean
  [email protected]:/work/system/u-boot-2012.04.01$ make smdk2410_config
  Configuring for smdk2410 board...
  [email protected]:/work/system/u-boot-2012.04.01$ make
4、下載剛編譯成功的u-boot.bin,發現重新啟動,串列埠沒有任何資訊

二、分析u-boot: 通過連結命令分析組成檔案、閱讀程式碼分析啟動過程

重新編譯,只關心最後一條連結命令:
 [email protected]:/work/system/u-boot-2012.04.01$ rm u-boot
 [email protected]:/work/system/u-boot-2012.04.01$ make
裡面有這句arm-linux-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_SYM arch/arm/cpu/arm920t/start.o
 [email protected]:/work/system/u-boot-2012.04.01$ vi u-boot.lds
通過連結指令碼知道: . = 0x00000000;同時-Ttext 0x0,由此我們知道是從NOR flash開始執行,通過連結指令碼還知道第一個執行的是arch/arm/cpu/arm920t/start.s

自己寫bootload的總結的過程:
a. 初始化硬體:關看門狗、設定時鐘、設定SDRAM、初始化NAND FLASH
b. 如果bootloader比較大,要把它重定位到SDRAM
c. 把核心從NAND FLASH讀到SDRAM
d. 設定"要傳給核心的引數"
e. 跳轉執行核心

反彙編: [email protected]:/work/system/u-boot-2012.04.01$ arm-linux-objdump -D u-boot > u-boot.dis
 
新uboot的過程:  
2.1 set the cpu to SVC32 mode
2.2 turn off the watchdog
2.3 mask all IRQs by setting all bits in the INTMR
2.4 設定時鐘比例
2.5 設定記憶體控制器
2.6 設定棧,呼叫C函式board_init_f
2.7 呼叫函式陣列init_sequence裡的各個函式
2.7.1 board_early_init_f : 設定系統時鐘、設定GPIO
......
2.8 重定位程式碼:
2.8.1 從NOR FLASH把程式碼複製到SDRAM
2.8.2 程式的連結地址是0,訪問全域性變數、靜態變數、呼叫函式時是使"基於0地址編譯得到的地址"
      現在把程式複製到了SDRAM
      需要修改程式碼,把"基於0地址編譯得到的地址"改為新地址
2.8.3 程式裡有些地址在連結時不能確定,要到執行前才能確定:fixabs
2.9 clear_bss
2.10 呼叫C函式board_init_r:第2階段的程式碼
  
 
[email protected]:/work/system/u-boot-2012.04.01$ arm-linux-ld --help | grep pie
  -pie, --pic-executable      Create a position independent executable
可以修改配置定義CONFIG_S3C2440


3. 修改U-BOOT程式碼

3.1 建一個單板(修改3個檔案)

[email protected]:/work/system/u-boot-2012.04.01$ make distclean
[email protected]:/work/system/u-boot-2012.04.01$ cd board/samsung/
[email protected]:/work/system/u-boot-2012.04.01/board/samsung$ cp smdk2410 smdk2440 -rf
[email protected]:/work/system/u-boot-2012.04.01/board/samsung$ cd ../..
[email protected]:/work/system/u-boot-2012.04.01$ cd include/configs/
[email protected]:/work/system/u-boot-2012.04.01/include/configs$ cp smdk2410.h smdk2440.h
看看是否能編譯通過:
[email protected]:/work/system/u-boot-2012.04.01/include/configs$ cd ../..
[email protected]:/work/system/u-boot-2012.04.01$ make smdk2440_config
make: *** No rule to make target `smdk2440_config'.  Stop.
make: *** [smdk2440_config] Error 1
編譯通不過.懷疑是makefile的問題,搜尋一下:
[email protected]:/work/system/u-boot-2012.04.01$ grep "smdk2410" * -nR
arch/arm/include/asm/mach-types.h:1644:# define machine_is_smdk2410()   (machine_arch_type == MACH_TYPE_SMDK2410)
arch/arm/include/asm/mach-types.h:1646:# define machine_is_smdk2410()   (0)
board/samsung/smdk2410/Makefile:28:COBJS        := smdk2410.o
board/samsung/smdk2440/Makefile:28:COBJS        := smdk2410.o
boards.cfg:65:smdk2410                     arm         arm920t     -                   samsung        s3c24x0
MAINTAINERS:750:        smdk2410        ARM920T

[email protected]:/work/system/u-boot-2012.04.01$ vi boards.cfg
在boards.cfg檔案下複製65行,修改boards.cfg:
仿照
smdk2410                     arm         arm920t     -                   samsung        s3c24x0
新增:
smdk2440                     arm         arm920t     -                   samsung        s3c24x0
然後重新配置一下
[email protected]:/work/system/u-boot-2012.04.01$ make smdk2440_config
然後重新編譯一下
[email protected]:/work/system/u-boot-2012.04.01$ make

3.2 燒寫看結果無法執行,下面按照第2節裡面的分析啟動過程

3.3 除錯:
a. 閱讀程式碼發現不足:UBOOT裡先以60MHZ的時鐘計算引數來設定記憶體控制器,但是MPLL還未設定
   ①處理措施: 把MPLL的設定放到start.S裡,取消board_early_init_f裡對MPLL的設定,如下面註釋掉下面兩行
   //writel(0xFFFFFF, &clk_power->locktime);

 /* configure MPLL */
 //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
 //       &clk_power->mpllcon);
  
   編譯出來的uboot非常大,可以先燒寫主光盤裡的u-boot.bin到nor,然後用這個uboot來燒寫新的uboot
 先檢視一下是不是剛下的燒寫結果是不是有問題
   等待usb下載完:   OpenJTAG> usb 1 30000000   //1表示一直等待
   把flash的防寫去掉:  OpenJTAG> protect off all  //解除norflash防寫
   把flash擦除:開始和結束地址 OpenJTAG> erase 0 7FFFF    //擦除從0到0x7FFFF共0x80000個位元組
   下載進flash:  OpenJTAG> cp.b 30000000 0 80000  //從記憶體0x30000000開始燒寫程式到norflash的0地址去,燒寫0X80000個位元組
   反彙編:  [email protected]:/work/system/u-boot-2012.04.01$ arm-linux-objdump -D u-boot > u-boot.dis
 上面反彙編的目的是:檢視call_board_init_f所在的彙編地址,開始執行這個函式的時候,說明cpu_init_crit已經執行完了,SDRAM已經初始化完了,我們現在就是想驗證一下SDRAM是否初始化成功
 
    ②修改start.S裡的程式碼
    # endif

 

 /* 2. 設定時鐘 */
 ldr r0, =0x4c000014
 // mov r1, #0x03;     // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
 mov r1, #0x05;     // FCLK:HCLK:PCLK=1:4:8
 str r1, [r0]

 /* 如果HDIVN非0,CPU的匯流排模式應該從“fast bus mode”變為“asynchronous bus mode” */
 mrc p15, 0, r1, c1, c0, 0  /* 讀出控制暫存器 */
 orr r1, r1, #0xc0000000   /* 設定為“asynchronous bus mode” */
 mcr p15, 0, r1, c1, c0, 0  /* 寫入控制暫存器 */

#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))

 /* MPLLCON = S3C2440_MPLL_200MHZ */
 ldr r0, =0x4c000004
 ldr r1, =S3C2440_MPLL_400MHZ
 str r1, [r0]

 /* 啟動ICACHE */
 mrc p15, 0, r0, c1, c0, 0 @ read control reg
 orr r0, r0, #(1<<12)
 mcr p15, 0, r0, c1, c0, 0   @ write it back

 

#endif /* CONFIG_S3C24X0 */

     ③把lowlevel_init.S裡面的lowlevel_init函式裡面
     SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30
 替換為:
 SMRDATA:
     .long 0x22011110  //BWSCON
 .long 0x00000700  //BANKCON0
 .long 0x00000700  //BANKCON1
 .long 0x00000700  //BANKCON2
 .long 0x00000700  //BANKCON3 
 .long 0x00000700  //BANKCON4
 .long 0x00000700  //BANKCON5
 .long 0x00018005  //BANKCON6
 .long 0x00018005  //BANKCON7
 .long 0x008C04F4  // REFRESH
 .long 0x000000B1  //BANKSIZE
 .long 0x00000030  //MRSRB6
 .long 0x00000030  //MRSRB7

完成上面3步之後,編譯生成新的uboot.bin,我們先用openjtag燒寫原來的uboot,然後通過原來的uboot來下載新生成的uboot.bin
   等待usb下載完:   OpenJTAG> usb 1 30000000   //1表示一直等待
   把flash的防寫去掉:  OpenJTAG> protect off all  //解除norflash防寫
   把flash擦除:開始和結束地址 OpenJTAG> erase 0 7FFFF    //擦除從0到0x7FFFF共0x80000個位元組
   下載進flash:  OpenJTAG> cp.b 30000000 0 80000  //從記憶體0x30000000開始燒寫程式到norflash的0地址去,燒寫0X80000個位元組
  
   到這裡可以用openjtag去驗證一下記憶體設定有沒有成功
 
3.4 亂碼,檢視串列埠波特率的設定,發現在get_HCLK裡沒有定義CONFIG_S3C2440
①更改get_HCLK裡沒有定義CONFIG_S3C2440
board_init_f
   init_sequence
      serial_init
         serial_init_dev
            _serial_setbrg
               get_PCLK
                  get_HCLK
    處理措施:include/configs/smdk2440.h: 去掉CONFIG_S3C2410
                                          #define CONFIG_S3C2440
②做完第一步後我們編譯一下,發現錯誤,由於第一步的更改導致了第二步出現問題:
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
檢視程式碼後解決:
[email protected]:/work/system/u-boot-2012.04.01$ vi drivers/mtd/nand/Makefile
那我們就去掉這個巨集:在smdk2440.h
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
解決辦法:暫時去掉如下行
                                          //#define CONFIG_CMD_NAND
③驗證:先燒寫1.1.6的uboot,然後重啟開發板,燒寫開發板
   等待usb下載完:   OpenJTAG> usb 1 30000000   //1表示一直等待
   把flash的防寫去掉:  OpenJTAG> protect off all  //解除norflash防寫
   把flash擦除:開始和結束地址 OpenJTAG> erase 0 7FFFF    //擦除從0到0x7FFFF共0x80000個位元組
   下載進flash:  OpenJTAG> cp.b 30000000 0 80000  //從記憶體0x30000000開始燒寫程式到norflash的0地址去,燒寫0X80000個位元組
下面是uboot輸出:
U-Boot 2012.04.01 (Jul 29 2013 - 20:26:01)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###

3.5 修改UBOOT支援NAND啟動
    原來的程式碼在連結時加了"-pie"選項, 使得u-boot.bin裡多了"*(.rel*)", "*(.dynsym)"
    使得程式非常大,不利於從NAND啟動(重定位之前的啟動程式碼應該少於4K)
3.5.1 去掉 "-pie"選項
[email protected]:/work/system/u-boot-2012.04.01$ grep "\-pie" * -nR
      arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉這行
     
3.5.2 參考"畢業班第1課"的start.S, init.c來修改程式碼
      把init.c放入board/samsung/smdk2440目錄,修改init.c檔案主要是加上static , 修改Makefile
      修改CONFIG_SYS_TEXT_BASE為0x33f80000
      修改start.S
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改連結指令碼: 把start.S, init.c, lowlevel.S等檔案放在最前面
[email protected]:/work/system/u-boot-2012.04.01$ find -name "u-boot.lds"
      ./arch/arm/cpu/u-boot.lds:
     
      board/samsung/smdk2440/libsmdk2440.o
生成反彙編檔案檢查     
[email protected]:/work/system/u-boot-2012.04.01$ arm-linux-objdump -D u-boot > u-boot.dis
燒寫:
OpenJTAG> usb 1 30000000
OpenJTAG> nand erase 0 80000
OpenJTAG> nand write 30000000 0 80000
把開關撥到nand重啟有輸出,說明現在支援了nand啟動:
U-Boot 2012.04.01 (Jul 29 2013 - 22:08:35)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###

在原始碼裡面搜尋“Flash:”,可以發現出現錯誤的原因,是由於board_init_r函式裡面,
如果你的程式是從nand啟動,那麼會卡死,做如下修改:
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
 } else {
  puts("0 KB\n\r");
  //puts(failed);
  //hang();
 }

3.6 修改UBOOT支援NOR FLASH
  drivers\mtd\jedec_flash.c 加上新的型號
  #define CONFIG_SYS_MAX_FLASH_SECT (128)

  修復了重定時留下來的BUG:SP要重新設定
 
  SMDK2410 # loady 32000000
  SMDK2410 # protec off all
  SMDK2410 # erase 0 7ffff
  SMDK2410 # cp.b 32000000 0 80000


3.7 修改UBOOT支援NAND FLASH
    修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND
    把drivers\mtd\nand\s3c2410_nand.c複製為s3c2440_nand.c
                                         

分析過程:
nand_init
 nand_init_chip
  board_nand_init
   設定nand_chip結構體, 提供底層的操作函式
  nand_scan
   nand_scan_ident
    nand_set_defaults
     chip->select_chip = nand_select_chip;
     chip->cmdfunc = nand_command;
     chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
     
    nand_get_flash_type
     chip->select_chip
     chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
       nand_command()  // 即可以用來發命令,也可以用來發列地址(頁內地址)、行地址(哪一頁)
        chip->cmd_ctrl
          s3c2440_hwcontrol
        
     chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
     *maf_id = chip->read_byte(mtd);
     *dev_id = chip->read_byte(mtd);

燒寫實驗:
①燒寫到NOR Flash
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000
②燒寫到NAND Flash
SMDK2410 # nand erase 0 80000
SMDK2410 # nand write 0 0 80000 把norflash 0地址裡面的程式燒寫到nand flash 0地址裡面去,燒寫80000
比較
SMDK2410 # nand read 30000000 0 80000

NAND read: device 0 offset 0x0, size 0x80000
 524288 bytes read: OK
SMDK2410 # cmp.b 0 30000000 80000
Total of 524288 bytes were the same


3.8 修改UBOOT支援DM9000網絡卡
①修改smdk2440.h使它支援網絡卡DM9000
#if 0
#define CONFIG_CS8900  /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
#else
#define CONFIG_DRIVER_DM9000
#endif
然後編譯出錯:dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)
查詢原因:
[email protected]:/work/system/u-boot-2012.04.01$ grep "DM9000_DATA" * -nR
參考別人的程式碼:更改smdk2440.h和lowlevel_init.S裡面的時序
還是有錯誤:看一下呼叫過程
 eth_initialize
  board_eth_init
   cs8900_initialize

*** ERROR: `ethaddr' not set
現在可以用tftp下載程式碼了:
SMDK2410 # set ipaddr 192.168.1.17
SMDK2410 # set ethaddr 00:0c:29:4d:e4:f4
到這裡先要在xp開啟tptp伺服器,伺服器ip為192.168.1.50
SMDK2410 # set serverip 192.168.1.50
SMDK2410 # tftp 30000000 uImage
SMDK2410 # bootm 30000000
移植網絡卡搞定。

4. 易用性修裁剪及製作補丁

沒有tftp時colin 下載uboot
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000


tftp可ping通時colin 下載uboot:
SMDK2410 # tftp 30000000 u-boot_new.bin
SMDK2410 # protect off all
SMDK2410 # erase 0 3ffff
SMDK2410 # cp.b 30000000 0 40000
SMDK2410 # reset                       //重啟

①環境變數的儲存
重啟uboot後,會列印:*** Warning - bad CRC, using default environment,這說明沒有找到環境變數,需要使用預設的環境變數
在si中搜索,可以發現預設的引數修改
②裁剪

③以前在設定好了環境變數的時候一直不敢用save命令     
核心打印出來的分割槽資訊
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
以前是這麼燒寫:
nand erase 60000 200000
nand write 30000000 60000 200000
現在可以用分割槽名字代替:
tftp 30000000 uImage
nand erase.part kernel
nand write 30000000 kernel

set bootcmd 'nand read 30000000 kernel;bootm 30000000'

 

最後看看能不能燒寫檔案系統:
一:
燒寫JFFS2
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 0x00260000 5b89a8

set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

二:
燒寫YAFFS
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000  889bc0

更新UBOOT:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

 

colin 檢視資料:
SMDK2410 # nand dump 260000

製作補丁:
[email protected]:/work/system/u-boot-2012.04.01$ make distclean
[email protected]:/work/system/u-boot-2012.04.01$ rm u-boot.dis
[email protected]:/work/system/u-boot-2012.04.01$ cd ..
[email protected]:/work/system$ mv u-boot-2012.04.01 u-boot-2012.04.01_100ask
[email protected]:/work/system$ tar xjf u-boot-2012.04.01.tar.bz2
[email protected]:/work/system$ diff --help
[email protected]:/work/system$ diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask_colin.patch
diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch

怎麼用這個補丁:
[email protected]:/work/system$ cd u-boot-2012.04.01
[email protected]:/work/system/u-boot-2012.04.01$ patch -p1 < ../u-boot-2012.04.01_100ask_colin.patch
[email protected]:/work/system/u-boot-2012.04.01$ make smdk2440_config
[email protected]:/work/system/u-boot-2012.04.01$ make


最重要的一點:
修改NFS.C裡面的#define NFS_TIMEOUT (10*2000UL)
這樣可以解決
SMDK2410 # nfs 32000000 192.168.1.51:/work/nfs_root/uImage_new
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
could not establish link
Using dm9000 device
File transfer via NFS from server 192.168.1.51; our IP address is 192.168.1.17
Filename '/work/nfs_root/uImage_new'.
Load address: 0x32000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##############T T *** ERROR: Cannot umount


/*--------------------------視訊熱身---”重定位之修改程式碼為新地址“--------------------------------------------------------------------*/

注意:以下為uboot-2012.04.01的連結說明

指令碼uboot.lds,該版本的連結指令碼可以把uboot放到記憶體的任何位置,而不需要指定連結地址,會自動計算並改為記憶體中的連結地址

但是會造成程式碼複雜龐大。分析"重定位之修改程式碼為新地址":就是在分析自動計算連結地址的過程,僅供閱讀,但本文采用的是指定

記憶體連結地址的方法,大大優化了uboot的程式碼結構。


分析"重定位之修改程式碼為新地址":
#ifndef CONFIG_SPL_BUILD
 /*
  * fix .rel.dyn relocations
  */
 ldr r0, _TEXT_BASE  /* r0 <- Text base */
 // r0=0, 程式碼基地址
 
 sub r9, r6, r0  /* r9 <- relocation offset */
 // r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000
 
 ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
 // r10 = 00073608
 
 add r10, r10, r0  /* r10 <- sym table in FLASH */
 // r10 = 00073608 + 0 = 00073608
 
 ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
 // r2=0006b568
 
 add r2, r2, r0  /* r2 <- rel dyn start in FLASH */
 // r2=r2+r0=0006b568
 
 ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
 // r3=00073608
 
 add r3, r3, r0  /* r3 <- rel dyn end in FLASH */
 // r3=r3+r0=00073608
 
fixloop:
 ldr r0, [r2]  /* r0 <- location to fix up, IN FLASH! */
 1. r0=[0006b568]=00000020
 
 add r0, r0, r9  /* r0 <- location to fix up in RAM */
 1. r0=r0+r9=00000020 + 0x33f41000 = 0x33f41020
 
 ldr r1, [r2, #4]
 1. r1=[0006b568+4]=00000017
 
 and r7, r1, #0xff
 1. r7=r1&0xff=00000017
 
 cmp r7, #23   /* relative fixup? */
 1. r7 == 23(0x17)
 
 beq fixrel
 cmp r7, #2   /* absolute fixup? */
 
 beq fixabs
 /* ignore unknown type of fixup */
 b fixnext
fixabs:
 /* absolute fix: set location to (offset) symbol value */
 mov r1, r1, LSR #4  /* r1 <- symbol index in .dynsym */
 
 add r1, r10, r1  /* r1 <- address of symbol in table */
 
 ldr r1, [r1, #4]  /* r1 <- symbol value */
 
 add r1, r1, r9  /* r1 <- relocated sym addr */
 
 b fixnext
fixrel:
 /* relative fix: increase location by offset */
 ldr r1, [r0]
 1. r1=[00000020]=000001e0
 
 add r1, r1, r9
 1. r1=r1+r9=000001e0 + 0x33f41000 = 33F411E0
 
fixnext:
 str r1, [r0]
 1. [0x33f41020] = 33F411E0
 
 add r2, r2, #8  /* each rel.dyn entry is 8 bytes */
 1. r2=r2+8=0006b568+8=6B570
 
 cmp r2, r3
 1.
 
 blo fixloop
#endif