uboot移植之支援板子nand啟動
之前介紹的uboot原始碼中smdk2410開發板的重定位方式只支援板子從nand啟動,可以從重定位的copy_loop看出:
重定位時cpu直接從flash中讀資料,寫入目的地址(位於SDRAM),這樣的方式只能用在norflash中啟動的程式碼上,nandflash中的內容不能像這樣簡單地通過指令讀寫。
smdk2410的重定位方式支援把程式碼重定位到任何地址上,但這種方式有兩個缺點:
1、重定位程式碼複雜
2、會增加需要移植的uboot的體積,因為需要增加rel.dyn段,記錄 儲存著全域性變數地址的LABEL的地址
現在採用直接指定uboot連結地址的方法,重寫重定位程式碼,使板子能從nandflash啟動。
需要做如下工作:
1、去掉 "-pie"選項,連結時不生成rel.dyn段
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 註釋掉這行
2、board/samsung/smdk2440目錄中增加init.c檔案,裡面加入對nandflash讀寫的程式碼:
並在makefile中新增init.o目標檔案:
3、修改連結指令碼: 把start.S, init.c, lowlevel.S等檔案放在最前面
./arch/arm/cpu/u-boot.lds:
這是因為s3c2440如果設定為nand啟動,上電後會nandflash中的前4k內容讀到cpu內部ram執行,要保證我們自己實現的nand的讀寫、初始化函式、重定位等程式碼位於前4k才能被正確執行。
4、修改start.S
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) /*sp = 30000f80*/ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ //由於nandflash是c函式,在呼叫c函式之前要先設定棧 bl nand_init_ll //呼叫nand初始化函式 mov r0, #0 //設定r0,r1,r2,傳參給copy_code_to_sdram //ldr r1, =_start ldr r1, _TEXT_BASE ldr r2, _bss_start_ofs bl copy_code_to_sdram //重定位程式碼c函式 bl clear_bss //清除bss段 ldr pc, =call_board_init_f /* Set stackpointerin internal RAM to call board_init_f */ call_board_init_f: ldr r0,=0x00000000 bl board_init_f /*board_init_f 的返回值(unsigned int)id的值存在r0裡,傳參給board_init_r用*/ ldr r1, _TEXT_BASE /*呼叫第二階段程式碼*/ bl board_init_r
5、在board.c檔案中,在board_init_f函式末尾把relocate_code(addr_sp,id,addr)註釋掉
因為之前在start.S中呼叫了重定位函式,這邊就不需要再重定位了。
6、之前smdk2410在SDRAM中給uboot留了一段空間用於儲存重定位之後的uboot程式碼,現在儲存uboot的地址由自己定義,為0x33f000000,需要把borad.c中的
board_init_f函式裡addr變數賦值為0x33f000000。重新編譯uboot,從nandflash啟動會打印出uboot資訊,說明nandflash啟動成功: