移植最新uboot的總結(jié)
1、從下面的官網(wǎng)下載最新的U-boot。用google英文版搜索最新的u-boot源碼
2、建立sourceinsight工程
3、編譯
嘗試編譯
編譯不成功,因?yàn)榘姹咎?br />
4、下載剛編譯成功的u-boot.bin,發(fā)現(xiàn)重新啟動(dòng),串口沒(méi)有任何信息
二、分析u-boot: 通過(guò)鏈接命令分析組成文件、閱讀代碼分析啟動(dòng)過(guò)程
重新編譯,只關(guān)心最后一條鏈接命令:
里面有這句arm-linux-ld
通過(guò)鏈接腳本知道: . = 0x00000000;同時(shí)-Ttext 0x0,由此我們知道是從NOR flash開(kāi)始運(yùn)行,通過(guò)鏈接腳本還知道第一個(gè)運(yùn)行的是arch/arm/cpu/arm920t/start.s
自己寫(xiě)bootload的總結(jié)的過(guò)程:
a. 初始化硬件:關(guān)看門(mén)狗、設(shè)置時(shí)鐘、設(shè)置SDRAM、初始化NAND FLASH
b. 如果bootloader比較大,要把它重定位到SDRAM
c. 把內(nèi)核從NAND FLASH讀到SDRAM
d. 設(shè)置"要傳給內(nèi)核的參數(shù)"
e. 跳轉(zhuǎn)執(zhí)行內(nèi)核
反匯編:
新uboot的過(guò)程:
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 設(shè)置時(shí)鐘比例
2.5 設(shè)置內(nèi)存控制器
2.6 設(shè)置棧,調(diào)用C函數(shù)board_init_f
2.7 調(diào)用函數(shù)數(shù)組init_sequence里的各個(gè)函數(shù)
2.7.1 board_early_init_f : 設(shè)置系統(tǒng)時(shí)鐘、設(shè)置GPIO
......
2.8 重定位代碼:
2.8.1 從NOR FLASH把代碼復(fù)制到SDRAM
2.8.2 程序的鏈接地址是0,訪問(wèn)全局變量、靜態(tài)變量、調(diào)用函數(shù)時(shí)是使"基于0地址編譯得到的地址"
2.8.3 程序里有些地址在鏈接時(shí)不能確定,要到運(yùn)行前才能確定:fixabs
2.9 clear_bss
2.10 調(diào)用C函數(shù)board_init_r:第2階段的代碼
book@book-desktop:/work/system/u-boot-2012.04.01$
可以修改配置定義CONFIG_S3C2440
3. 修改U-BOOT代碼
3.1 建一個(gè)單板(修改3個(gè)文件)
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01/board/samsung$
book@book-desktop:/work/system/u-boot-2012.04.01/board/samsung$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01/include/configs$
看看是否能編譯通過(guò):
book@book-desktop:/work/system/u-boot-2012.04.01/include/configs$
book@book-desktop:/work/system/u-boot-2012.04.01$
make: *** No rule to make target `smdk2440_config.
make: *** [smdk2440_config] Error 1
編譯通不過(guò).懷疑是makefile的問(wèn)題,搜索一下:
book@book-desktop:/work/system/u-boot-2012.04.01$
arch/arm/include/asm/mach-types.h:1644:# define machine_is_smdk2410()
arch/arm/include/asm/mach-types.h:1646:# define machine_is_smdk2410()
board/samsung/smdk2410/Makefile:28:COBJS
board/samsung/smdk2440/Makefile:28:COBJS
boards.cfg:65:smdk2410
MAINTAINERS:750:
book@book-desktop:/work/system/u-boot-2012.04.01$
在boards.cfg文件下復(fù)制65行,修改boards.cfg:
仿照
smdk2410
添加:
smdk2440
然后重新配置一下
book@book-desktop:/work/system/u-boot-2012.04.01$
然后重新編譯一下
book@book-desktop:/work/system/u-boot-2012.04.01$
3.2 燒寫(xiě)看結(jié)果無(wú)法執(zhí)行,下面按照第2節(jié)里面的分析啟動(dòng)過(guò)程
3.3 調(diào)試:
a. 閱讀代碼發(fā)現(xiàn)不足:UBOOT里先以60MHZ的時(shí)鐘計(jì)算參數(shù)來(lái)設(shè)置內(nèi)存控制器,但是MPLL還未設(shè)置
#define S3C2440_MPLL_400MHZ
#endif
完成上面3步之后,編譯生成新的uboot.bin,我們先用openjtag燒寫(xiě)原來(lái)的uboot,然后通過(guò)原來(lái)的uboot來(lái)下載新生成的uboot.bin
3.4 亂碼,查看串口波特率的設(shè)置,發(fā)現(xiàn)在get_HCLK里沒(méi)有定義CONFIG_S3C2440
①更改get_HCLK里沒(méi)有定義CONFIG_S3C2440
board_init_f
②做完第一步后我們編譯一下,發(fā)現(xiàn)錯(cuò)誤,由于第一步的更改導(dǎo)致了第二步出現(xiàn)問(wèn)題:
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
查看代碼后解決:
book@book-desktop:/work/system/u-boot-2012.04.01$
那我們就去掉這個(gè)宏:在smdk2440.h
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
解決辦法:暫時(shí)去掉如下行
③驗(yàn)證:先燒寫(xiě)1.1.6的uboot,然后重啟開(kāi)發(fā)板,燒寫(xiě)開(kāi)發(fā)板
下面是uboot輸出:
U-Boot 2012.04.01 (Jul 29 2013 - 20:26:01)
CPUID: 32440001
FCLK:
HCLK:
PCLK:
DRAM:
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
3.5 修改UBOOT支持NAND啟動(dòng)
3.5.1 去掉 "-pie"選項(xiàng)
book@book-desktop:/work/system/u-boot-2012.04.01$
3.5.2 參考"畢業(yè)班第1課"的start.S, init.c來(lái)修改代碼
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改鏈接腳本: 把start.S, init.c, lowlevel.S等文件放在最前面
book@book-desktop:/work/system/u-boot-2012.04.01$
生成反匯編文件檢查
book@book-desktop:/work/system/u-boot-2012.04.01$
燒寫(xiě):
OpenJTAG> usb 1 30000000
OpenJTAG> nand erase 0 80000
OpenJTAG> nand write 30000000 0 80000
把開(kāi)關(guān)撥到nand重啟有輸出,說(shuō)明現(xiàn)在支持了nand啟動(dòng):
U-Boot 2012.04.01 (Jul 29 2013 - 22:08:35)
CPUID: 32440001
FCLK:
HCLK:
PCLK:
DRAM:
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
在源碼里面搜索“Flash:”,可以發(fā)現(xiàn)出現(xiàn)錯(cuò)誤的原因,是由于board_init_r函數(shù)里面,
如果你的程序是從nand啟動(dòng),那么會(huì)卡死,做如下修改:
# endif
3.6 修改UBOOT支持NOR FLASH
3.7 修改UBOOT支持NAND FLASH
分析過(guò)程:
nand_init
燒寫(xiě)實(shí)驗(yàn):
①燒寫(xiě)到NOR Flash
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000
②燒寫(xiě)到NAND Flash
SMDK2410 # nand erase 0 80000
SMDK2410 # nand write 0 0 80000 把norflash 0地址里面的程序燒寫(xiě)到nand flash 0地址里面去,燒寫(xiě)80000
比較
SMDK2410 # nand read 30000000 0 80000
NAND read: device 0 offset 0x0, size 0x80000
SMDK2410 # cmp.b 0 30000000 80000
Total of 524288 bytes were the same
3.8 修改UBOOT支持DM9000網(wǎng)卡
①修改smdk2440.h使它支持網(wǎng)卡DM9000
#if 0
#define CONFIG_CS8900
#define CONFIG_CS8900_BASE
#define CONFIG_CS8900_BUS16
#else
#define CONFIG_DRIVER_DM9000
#endif
然后編譯出錯(cuò):dm9000x.c:156: error: DM9000_DATA undeclared (first use in this function)
查找原因:
book@book-desktop:/work/system/u-boot-2012.04.01$
參考別人的代碼:更改smdk2440.h和lowlevel_init.S里面的時(shí)序
還是有錯(cuò)誤:看一下調(diào)用過(guò)程
*** ERROR: `ethaddr not set
現(xiàn)在可以用tftp下載代碼了:
SMDK2410 # set ipaddr 192.168.1.17
SMDK2410 # set ethaddr 00:0c:29:4d:e4:f4
到這里先要在xp打開(kāi)tptp服務(wù)器,服務(wù)器ip為192.168.1.50
SMDK2410 # set serverip 192.168.1.50
SMDK2410 # tftp 30000000 uImage
SMDK2410 # bootm 30000000
移植網(wǎng)卡搞定。
4. 易用性修裁剪及制作補(bǔ)丁
沒(méi)有tftp時(shí)colin 下載uboot
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000
tftp可ping通時(shí)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
①環(huán)境變量的保存
重啟uboot后,會(huì)打?。?** Warning - bad CRC, using default environment,這說(shuō)明沒(méi)有找到環(huán)境變量,需要使用默認(rèn)的環(huán)境變量
在si中搜索,可以發(fā)現(xiàn)默認(rèn)的參數(shù)修改
②裁剪
③以前在設(shè)置好了環(huán)境變量的時(shí)候一直不敢用save命令
內(nèi)核打印出來(lái)的分區(qū)信息
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
以前是這么燒寫(xiě):
nand erase 60000 200000
nand write 30000000 60000 200000
現(xiàn)在可以用分區(qū)名字代替:
tftp 30000000 uImage
nand erase.part kernel
nand write 30000000 kernel
set bootcmd nand read 30000000 kernel;bootm 30000000
最后看看能不能燒寫(xiě)文件系統(tǒng):
一:
燒寫(xiě)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
二:
燒寫(xiě)YAFFS
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000
更新UBOOT:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
colin 查看數(shù)據(jù):
SMDK2410 # nand dump 260000
制作補(bǔ)?。?br />book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system$
book@book-desktop:/work/system$
book@book-desktop:/work/system$
book@book-desktop:/work/system$
diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch
怎么用這個(gè)補(bǔ)?。?br />book@book-desktop:/work/system$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01$
book@book-desktop:/work/system/u-boot-2012.04.01$
最重要的一點(diǎn):
修改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: #################################################################
分析"重定位之修改代碼為新地址":
#ifndef CONFIG_SPL_BUILD
fixloop:
fixabs:
fixrel:
fixnext:
#endif
=====================================================================================
1、下載、建立source insight工程、編譯、燒寫(xiě)、如果無(wú)運(yùn)行分析原因
tar xjf u-boot-2012.04.01.tar.bz2
cd u-boot-2012.04.01
make smdk2410_config
make
由于arm-linux-gcc版本太低,編譯出錯(cuò)
arm-linux-gcc -v
下面來(lái)更換arm-linux-gcc到最新版本,以arm-linux-gcc-4.3.2.tar.bz2為例:
a、到服務(wù)器上安裝工具鏈:
PATH=/usr/local/arm/4.3.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/g
ames
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.
2/bin"
b、設(shè)置好最新的編譯器以后,先回到u-boot-2012.04.01目錄下,執(zhí)行:make distclean命令刪除之前編譯出
的文件,重新make smdk2410_config,再make
2. 分析u-boot: 通過(guò)鏈接命令分析組成文件、閱讀代碼分析啟動(dòng)過(guò)程
a. 初始化硬件:關(guān)看門(mén)狗、設(shè)置時(shí)鐘、設(shè)置SDRAM、初始化NAND FLASH
b. 如果bootloader比較大,要把它重定位到SDRAM
c. 把內(nèi)核從NAND FLASH讀到SDRAM
d. 設(shè)置"要傳給內(nèi)核的參數(shù)"
e. 跳轉(zhuǎn)執(zhí)行內(nèi)核
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 設(shè)置時(shí)鐘比例
2.5 設(shè)置內(nèi)存控制器
2.6 設(shè)置棧,調(diào)用C函數(shù)board_init_f
2.7 調(diào)用函數(shù)數(shù)組init_sequence里的各個(gè)函數(shù)
2.7.1 board_early_init_f : 設(shè)置系統(tǒng)時(shí)鐘、設(shè)置GPIO
......
2.8 重定位代碼:
2.8.1 從NOR FLASH把代碼復(fù)制到SDRAM
2.8.2 程序的鏈接地址是0,訪問(wèn)全局變量、靜態(tài)變量、調(diào)用函數(shù)時(shí)是使"基于0地址編譯得到的地址"
2.8.3 程序里有些地址在鏈接時(shí)不能確定,要到運(yùn)行前才能確定:fixabs
2.9 clear_bss
2.10 調(diào)用C函數(shù)board_init_r:第2階段的代碼
可以修改配置定義CONFIG_S3C2440
3. 修改U-BOOT代碼
3.1 建一個(gè)單板
cd board/samsung/
cp smdk2410 smdk2440 -rf
cd ../../include/configs/
cp smdk2410.h smdk2440.h
修改boards.cfg:
仿照
smdk2410
添加:
smdk2440
3.2 燒寫(xiě)看結(jié)果
3.3 調(diào)試:
a. 閱讀代碼發(fā)現(xiàn)不足:UBOOT里先以60MHZ的時(shí)鐘計(jì)算參數(shù)來(lái)設(shè)置內(nèi)存控制器,但是MPLL還未設(shè)置
3.4 亂碼,查看串口波特率的設(shè)置,發(fā)現(xiàn)在get_HCLK里沒(méi)有定義CONFIG_S3C2440
3.5 修改UBOOT支持NAND啟動(dòng)
3.5.1 去掉 "-pie"選項(xiàng)
3.5.2 參考"畢業(yè)班第1課"的start.S, init.c來(lái)修改代碼
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改鏈接腳本: 把start.S, init.c, lowlevel.S等文件放在最前面
3.6 修改UBOOT支持NOR FLASH
3.7 修改UBOOT支持NAND FLASH
分析過(guò)程:
nand_init
nand_init_chip
board_nand_init
設(shè)置nand_chip結(jié)構(gòu)體, 提供底層的操作函數(shù)
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()
以用來(lái)發(fā)列地址(頁(yè)內(nèi)地址)、行地址(哪一頁(yè))
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);
3.8 修改UBOOT支持DM9000網(wǎng)卡
eth_initialize
board_eth_init
cs8900_initialize
*** ERROR: `ethaddr not set
set ipaddr 192.168.1.17
set ethaddr 00:0c:29:4d:e4:f4
set serverip 192.168.1.3
4. 易用性修裁剪及制作補(bǔ)丁
內(nèi)核打印出來(lái)的分區(qū)信息
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
燒寫(xiě)JFFS2
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 0x00260000 5b89a8
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
燒寫(xiě)YAFFS
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000
更新UBOOT:
tftp 30000000 u-boot_new.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
制作補(bǔ)?。?/p>
diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch
分析"重定位之修改代碼為新地址":
#ifndef CONFIG_SPL_BUILD
ldr r0, _TEXT_BASE
// r0=0, 代碼基地址
sub r9, r6, r0
// r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000
ldr r10, _dynsym_start_ofs
// r10 = 00073608
add r10, r10, r0
// r10 = 00073608 + 0 = 00073608
ldr r2, _rel_dyn_start_ofs
// r2=0006b568
add r2, r2, r0
// r2=r2+r0=0006b568
ldr r3, _rel_dyn_end_ofs
// r3=00073608
add r3, r3, r0
// r3=r3+r0=00073608
fixloop:
ldr r0, [r2]
1. r0=[0006b568]=00000020
add r0, r0, r9
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
1. r7 == 23(0x17)
beq fixrel
cmp r7, #2
beq fixabs
b fixnext
fixabs:
mov r1, r1, LSR #4
add r1, r10, r1
ldr r1, [r1, #4]
add r1, r1, r9
b fixnext
fixrel:
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
1. r2=r2+8=0006b568+8=6B570
cmp r2, r3
1.
blo fixloop
#endif
評(píng)論