新聞中心

移植最新uboot的總結(jié)

作者: 時(shí)間:2016-11-21 來(lái)源:網(wǎng)絡(luò) 收藏
一:準(zhǔn)備移植

1、從下面的官網(wǎng)下載最新的U-boot。用google英文版搜索最新的u-boot源碼
ftp://ftp.denx.de/pub/u-boot/
2、建立sourceinsight工程
a、解壓并在E:colin weidongshantransplant_u-boot-2012.04.01u-boot-2012.04.01建立SI
b、添加文件到SI工程
1、點(diǎn)擊"Add All",選中“Include top level sub-directories”和“Recursively add lower sub-directories”點(diǎn)擊“OK”
2、選中“Board”目錄,點(diǎn)擊“Remove Tree”,去掉總個(gè)目錄
進(jìn)入“BoardSamsungSmdk2410”,點(diǎn)擊"Add All"
3、選中“Arch”目錄,點(diǎn)擊“Remove Tree”,去掉總個(gè)目錄
進(jìn)入“ArchArmCpuArm920t”,雙擊選中“Cpu.c”“Interrupts.c”“start.S”。
進(jìn)入“ArchArmCpuArm920tS3c24x0”,點(diǎn)擊"Add All"
進(jìn)入“ArchArm”,選中"Dts"目錄,點(diǎn)擊"Add Tree"
進(jìn)入“ArchArmIncludeAsmArch_s3c24x0”,點(diǎn)擊"Add All"
進(jìn)入“ArchArmIncludeAsm”,點(diǎn)擊"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加頂層目錄的文件
進(jìn)入“ArchArmIncludeAsm”,單擊選中"Proc-armv",點(diǎn)擊"Add Tree"
進(jìn)入“ArchArmLib”,點(diǎn)擊"Add All"
4、選中“Include”目錄,點(diǎn)擊“Remove Tree”,去掉總個(gè)目錄
進(jìn)入“Include”,點(diǎn)擊"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加頂層目錄的文件
進(jìn)入“Include”,單擊選中"Andestech",點(diǎn)擊"Add Tree"
進(jìn)入“Include”,單擊選中"Asm-generic",點(diǎn)擊"Add Tree"
進(jìn)入“Include”,同上選中除"Configs"目錄外的所有目錄,點(diǎn)擊"Add Tree"。"Configs"目錄先不加,下面再議
進(jìn)入“IncludeConfigs”,雙擊選中“Smdk2410.h”
5、同步文件,完成

本文引用地址:http://butianyuan.cn/article/201611/319498.htm

3、編譯
嘗試編譯
解壓:book@book-desktop:/work/system$tar xjf u-boot-2012.04.01.tar.bz2
book@book-desktop:/work/system$cd u-boot-2012.04.01/
配置:book@book-desktop:/work/system/u-boot-2012.04.01$make smdk2410_config
編譯:book@book-desktop:/work/system/u-boot-2012.04.01$make

編譯不成功,因?yàn)榘姹咎?br /> 查看版本:book@book-desktop:/work/system/u-boot-2012.04.01$arm-linux-gcc -v
拷貝解壓:book@book-desktop:/work/system/u-boot-2012.04.01$cd /work/tools/
book@book-desktop:/work/tools$mkdir tmp
book@book-desktop:/work/tools$tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C tmp/
book@book-desktop:/work/tools$cd tmp/
book@book-desktop:/work/tools/tmp$ls
usr
book@book-desktop:/work/tools/tmp$cd usr/local/arm/4.3.2/
book@book-desktop:/work/tools/tmp/usr/local/arm/4.3.2$ls
arm-none-linux-gnueabi bin lib libexec share
book@book-desktop:/work/tools/tmp/usr/local/arm/4.3.2$ls bin/

解壓到根目錄:book@book-desktop:/work/tools$sudo tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /
查看環(huán)境變量:book@book-desktop:/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
設(shè)置環(huán)境變量:book@book-desktop:/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
查看環(huán)境變量:book@book-desktop:/work/tools$arm-linux-gcc -v
如果不想手動(dòng)設(shè)置,你可以按如下方式修改:
book@book-desktop:/work/tools$sudo vi /etc/environment

重新編譯:book@book-desktop:/work/tools$cd /work/system/u-boot-2012.04.01/
book@book-desktop:/work/system/u-boot-2012.04.01$make distclean
book@book-desktop:/work/system/u-boot-2012.04.01$make smdk2410_config
Configuring for smdk2410 board...
book@book-desktop:/work/system/u-boot-2012.04.01$make
4、下載剛編譯成功的u-boot.bin,發(fā)現(xiàn)重新啟動(dòng),串口沒(méi)有任何信息

二、分析u-boot: 通過(guò)鏈接命令分析組成文件、閱讀代碼分析啟動(dòng)過(guò)程

重新編譯,只關(guān)心最后一條鏈接命令:
book@book-desktop:/work/system/u-boot-2012.04.01$rm u-boot
book@book-desktop:/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
book@book-desktop:/work/system/u-boot-2012.04.01$vi u-boot.lds
通過(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)核

反匯編:book@book-desktop:/work/system/u-boot-2012.04.01$arm-linux-objdump -D u-boot > u-boot.dis

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地址編譯得到的地址"
現(xiàn)在把程序復(fù)制到了SDRAM
需要修改代碼,把"基于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$arm-linux-ld --help | grep pie
-pie, --pic-executable Create a position independent executable


可以修改配置定義CONFIG_S3C2440


3. 修改U-BOOT代碼
3.1 建一個(gè)單板(修改3個(gè)文件)

book@book-desktop:/work/system/u-boot-2012.04.01$make distclean
book@book-desktop:/work/system/u-boot-2012.04.01$cd board/samsung/
book@book-desktop:/work/system/u-boot-2012.04.01/board/samsung$cp smdk2410 smdk2440 -rf
book@book-desktop:/work/system/u-boot-2012.04.01/board/samsung$cd ../..
book@book-desktop:/work/system/u-boot-2012.04.01$cd include/configs/
book@book-desktop:/work/system/u-boot-2012.04.01/include/configs$cp smdk2410.h smdk2440.h
看看是否能編譯通過(guò):
book@book-desktop:/work/system/u-boot-2012.04.01/include/configs$cd ../..
book@book-desktop:/work/system/u-boot-2012.04.01$make smdk2440_config
make: *** No rule to make target `smdk2440_config. Stop.
make: *** [smdk2440_config] Error 1
編譯通不過(guò).懷疑是makefile的問(wèn)題,搜索一下:
book@book-desktop:/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

book@book-desktop:/work/system/u-boot-2012.04.01$vi boards.cfg
在boards.cfg文件下復(fù)制65行,修改boards.cfg:
仿照
smdk2410 arm arm920t - samsung s3c24x0
添加:
smdk2440 arm arm920t - samsung s3c24x0
然后重新配置一下
book@book-desktop:/work/system/u-boot-2012.04.01$make smdk2440_config
然后重新編譯一下
book@book-desktop:/work/system/u-boot-2012.04.01$make

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è)置
①處理措施: 把MPLL的設(shè)置放到start.S里,取消board_early_init_f里對(duì)MPLL的設(shè)置,如下面注釋掉下面兩行
//writel(0xFFFFFF, &clk_power->locktime);


//writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
// &clk_power->mpllcon);

編譯出來(lái)的uboot非常大,可以先燒寫(xiě)主光盤(pán)里的u-boot.bin到nor,然后用這個(gè)uboot來(lái)燒寫(xiě)新的uboot
先查看一下是不是剛下的燒寫(xiě)結(jié)果是不是有問(wèn)題
等待usb下載完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的寫(xiě)保護(hù)去掉: OpenJTAG> protect off all //解除norflash寫(xiě)保護(hù)
把flash擦除:開(kāi)始和結(jié)束地址OpenJTAG> erase 0 7FFFF //擦除從0到0x7FFFF共0x80000個(gè)字節(jié)
下載進(jìn)flash:OpenJTAG> cp.b 30000000 0 80000 //從內(nèi)存0x30000000開(kāi)始燒寫(xiě)程序到norflash的0地址去,燒寫(xiě)0X80000個(gè)字節(jié)
反匯編:book@book-desktop:/work/system/u-boot-2012.04.01$arm-linux-objdump -D u-boot > u-boot.dis
上面反匯編的目的是:查看call_board_init_f所在的匯編地址,開(kāi)始執(zhí)行這個(gè)函數(shù)的時(shí)候,說(shuō)明cpu_init_crit已經(jīng)執(zhí)行完了,SDRAM已經(jīng)初始化完了,我們現(xiàn)在就是想驗(yàn)證一下SDRAM是否初始化成功

②修改start.S里的代碼
# endif


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]


mrcp15, 0, r1, c1, c0, 0
orrr1, r1, #0xc0000000
mcrp15, 0, r1, c1, c0, 0

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


ldr r0, =0x4c000004
ldr r1, =S3C2440_MPLL_400MHZ
str r1, [r0]


mrc p15, 0, r0, c1, c0, 0@ read control reg
orr r0, r0, #(1<<12)
mcrp15, 0, r0, c1, c0, 0 @ write it back

#endif

③把lowlevel_init.S里面的lowlevel_init函數(shù)里面
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燒寫(xiě)原來(lái)的uboot,然后通過(guò)原來(lái)的uboot來(lái)下載新生成的uboot.bin
等待usb下載完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的寫(xiě)保護(hù)去掉: OpenJTAG> protect off all //解除norflash寫(xiě)保護(hù)
把flash擦除:開(kāi)始和結(jié)束地址OpenJTAG> erase 0 7FFFF //擦除從0到0x7FFFF共0x80000個(gè)字節(jié)
下載進(jìn)flash:OpenJTAG> cp.b 30000000 0 80000 //從內(nèi)存0x30000000開(kāi)始燒寫(xiě)程序到norflash的0地址去,燒寫(xiě)0X80000個(gè)字節(jié)

到這里可以用openjtag去驗(yàn)證一下內(nèi)存設(shè)置有沒(méi)有成功

3.4 亂碼,查看串口波特率的設(shè)置,發(fā)現(xiàn)在get_HCLK里沒(méi)有定義CONFIG_S3C2440
①更改get_HCLK里沒(méi)有定義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
②做完第一步后我們編譯一下,發(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$vi drivers/mtd/nand/Makefile
那我們就去掉這個(gè)宏:在smdk2440.h
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
解決辦法:暫時(shí)去掉如下行
//#define CONFIG_CMD_NAND
③驗(yàn)證:先燒寫(xiě)1.1.6的uboot,然后重啟開(kāi)發(fā)板,燒寫(xiě)開(kāi)發(fā)板
等待usb下載完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的寫(xiě)保護(hù)去掉: OpenJTAG> protect off all //解除norflash寫(xiě)保護(hù)
把flash擦除:開(kāi)始和結(jié)束地址OpenJTAG> erase 0 7FFFF //擦除從0到0x7FFFF共0x80000個(gè)字節(jié)
下載進(jìn)flash:OpenJTAG> cp.b 30000000 0 80000 //從內(nèi)存0x30000000開(kāi)始燒寫(xiě)程序到norflash的0地址去,燒寫(xiě)0X80000個(gè)字節(jié)
下面是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啟動(dòng)
原來(lái)的代碼在鏈接時(shí)加了"-pie"選項(xiàng), 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)"
使得程序非常大,不利于從NAND啟動(dòng)(重定位之前的啟動(dòng)代碼應(yīng)該少于4K)
3.5.1 去掉 "-pie"選項(xiàng)
book@book-desktop:/work/system/u-boot-2012.04.01$grep "-pie" * -nR
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉這行

3.5.2 參考"畢業(yè)班第1課"的start.S, init.c來(lái)修改代碼
把init.c放入board/samsung/smdk2440目錄,修改init.c文件主要是加上static , 修改Makefile
修改CONFIG_SYS_TEXT_BASE為0x33f00000,u-boot.bin文件太大,0x33f80000不夠放
修改start.S
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$find -name "u-boot.lds"
./arch/arm/cpu/u-boot.lds:

board/samsung/smdk2440/libsmdk2440.o
生成反匯編文件檢查
book@book-desktop:/work/system/u-boot-2012.04.01$arm-linux-objdump -D u-boot > u-boot.dis
燒寫(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: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
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
} else {
puts("0 KBnr");
//puts(failed);
//hang();
}

3.6 修改UBOOT支持NOR FLASH
driversmtdjedec_flash.c 加上新的型號(hào)
#define CONFIG_SYS_MAX_FLASH_SECT(128)

修復(fù)了重定時(shí)留下來(lái)的BUG:SP要重新設(shè)置

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

把driversmtdnands3c2410_nand.c復(fù)制為s3c2440_nand.c

分析過(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ā)命令,也可以用來(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);

燒寫(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
524288 bytes read: OK
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_BASE0x19000300
#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$grep "DM9000_DATA" * -nR
參考別人的代碼:更改smdk2440.h和lowlevel_init.S里面的時(shí)序
還是有錯(cuò)誤:看一下調(diào)用過(guò)程
eth_initialize
board_eth_init
cs8900_initialize

*** 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 889bc0

更新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$make distclean
book@book-desktop:/work/system/u-boot-2012.04.01$rm u-boot.dis
book@book-desktop:/work/system/u-boot-2012.04.01$cd ..
book@book-desktop:/work/system$mv u-boot-2012.04.01 u-boot-2012.04.01_100ask
book@book-desktop:/work/system$tar xjf u-boot-2012.04.01.tar.bz2
book@book-desktop:/work/system$diff --help
book@book-desktop:/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

怎么用這個(gè)補(bǔ)丁:
book@book-desktop:/work/system$cd u-boot-2012.04.01
book@book-desktop:/work/system/u-boot-2012.04.01$patch -p1 < ../u-boot-2012.04.01_100ask_colin.patch
book@book-desktop:/work/system/u-boot-2012.04.01$make smdk2440_config
book@book-desktop:/work/system/u-boot-2012.04.01$make


最重要的一點(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: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##############T T *** ERROR: Cannot umount

分析"重定位之修改代碼為新地址":
#ifndef CONFIG_SPL_BUILD

ldrr0, _TEXT_BASE
// r0=0, 代碼基地址

subr9, r6, r0
// r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000

ldrr10, _dynsym_start_ofs
// r10 = 00073608

addr10, r10, r0
// r10 = 00073608 + 0 = 00073608

ldrr2, _rel_dyn_start_ofs
// r2=0006b568

addr2, r2, r0
// r2=r2+r0=0006b568

ldrr3, _rel_dyn_end_ofs
// r3=00073608

addr3, r3, r0
// r3=r3+r0=00073608

fixloop:
ldrr0, [r2]
1. r0=[0006b568]=00000020

addr0, r0, r9
1. r0=r0+r9=00000020 + 0x33f41000 = 0x33f41020

ldrr1, [r2, #4]
1. r1=[0006b568+4]=00000017

andr7, r1, #0xff
1. r7=r1&0xff=00000017

cmpr7, #23
1. r7 == 23(0x17)

beqfixrel
cmpr7, #2

beqfixabs

bfixnext
fixabs:

movr1, r1, LSR #4

addr1, r10, r1

ldrr1, [r1, #4]

addr1, r1, r9

bfixnext
fixrel:

ldrr1, [r0]
1. r1=[00000020]=000001e0

addr1, r1, r9
1. r1=r1+r9=000001e0 + 0x33f41000 = 33F411E0

fixnext:
strr1, [r0]
1. [0x33f41020] = 33F411E0

addr2, r2, #8
1. r2=r2+8=0006b568+8=6B570

cmpr2, r3
1.

blofixloop
#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ù)器上安裝工具鏈:

先創(chuàng)建臨時(shí)目錄查看有什么內(nèi)容:

mkdir tmp

tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C tmp/

再到bin/目錄下可以看到各種工具鏈,到此時(shí)說(shuō)明該文件(arm-linux-gcc-4.3.2.tar.bz2)可以使用

再回到根目錄下,即和tmp文件夾在同一個(gè)目錄下用以下命令解壓到根目錄下:

sudu tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /

最后設(shè)置環(huán)境變量,當(dāng)執(zhí)行該命令時(shí)系統(tǒng)會(huì)到該目錄下找到該指令執(zhí)行:

查看環(huán)境變量指令,這個(gè)環(huán)境變量指定了去哪里找命令:echo $PATH

重新設(shè)置環(huán)境變量(該指令重啟系統(tǒng)后失效,需要重新設(shè)置):

export

PATH=/usr/local/arm/4.3.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/g

ames

可用以下指令修改文件,重啟系統(tǒng)后永久有效:

sudo vi /etc/environment

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地址編譯得到的地址"

現(xiàn)在把程序復(fù)制到了SDRAM

需要修改代碼,把"基于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 arm arm920t - samsung s3c24x0

添加:

smdk2440 arm arm920t - samsung s3c24x0

3.2 燒寫(xiě)看結(jié)果

3.3 調(diào)試:

a. 閱讀代碼發(fā)現(xiàn)不足:UBOOT里先以60MHZ的時(shí)鐘計(jì)算參數(shù)來(lái)設(shè)置內(nèi)存控制器,但是MPLL還未設(shè)置

處理措施: 把MPLL的設(shè)置放到start.S里,取消board_early_init_f里對(duì)MPLL的設(shè)置

編譯出來(lái)的uboot非常大,可以先燒寫(xiě)主光盤(pán)里的u-boot.bin到nor,然后用這個(gè)uboot來(lái)燒寫(xiě)新的uboot

3.4 亂碼,查看串口波特率的設(shè)置,發(fā)現(xiàn)在get_HCLK里沒(méi)有定義CONFIG_S3C2440

處理措施:include/configs/smdk2440.h: 去掉CONFIG_S3C2410

#define CONFIG_S3C2440

//#define CONFIG_CMD_NAND

3.5 修改UBOOT支持NAND啟動(dòng)

原來(lái)的代碼在鏈接時(shí)加了"-pie"選項(xiàng), 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)"

使得程序非常大,不利于從NAND啟動(dòng)(重定位之前的啟動(dòng)代碼應(yīng)該少于4K)

3.5.1 去掉 "-pie"選項(xiàng)

arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉這行

3.5.2 參考"畢業(yè)班第1課"的start.S, init.c來(lái)修改代碼

把init.c放入board/samsung/smdk2440目錄, 修改Makefile

修改CONFIG_SYS_TEXT_BASE為0x33f00000,u-boot.bin文件太大,0x33f80000不夠放

修改start.S

3.5.3 修改board_init_f, 把relocate_code去掉

3.5.4 修改鏈接腳本: 把start.S, init.c, lowlevel.S等文件放在最前面

./arch/arm/cpu/u-boot.lds:

board/samsung/smdk2440/libsmdk2440.o

3.6 修改UBOOT支持NOR FLASH

driversmtdjedec_flash.c 加上新的型號(hào)

#define CONFIG_SYS_MAX_FLASH_SECT (128)

修復(fù)了重定時(shí)留下來(lái)的BUG:SP要重新設(shè)置

3.7 修改UBOOT支持NAND FLASH

修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND

把driversmtdnands3c2410_nand.c復(fù)制為s3c2440_nand.c

分析過(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ā)命令,也可

以用來(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 889bc0

更新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



關(guān)鍵詞: 移植uboo

評(píng)論


技術(shù)專區(qū)

關(guān)閉