移植最新uboot的总结
1、从下面的官网下载最新的U-boot。用google英文版搜索最新的u-boot源码
2、建立sourceinsight工程
3、编译
尝试编译
编译不成功,因为版本太老
4、下载刚编译成功的u-boot.bin,发现重新启动,串口没有任何信息
二、分析u-boot: 通过链接命令分析组成文件、阅读代码分析启动过程
重新编译,只关心最后一条链接命令:
里面有这句arm-linux-ld
通过链接脚本知道: . = 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. 跳转执行内核
反汇编:
新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地址编译得到的地址"
2.8.3 程序里有些地址在链接时不能确定,要到运行前才能确定:fixabs
2.9 clear_bss
2.10 调用C函数board_init_r:第2阶段的代码
book@book-desktop:/work/system/u-boot-2012.04.01$
可以修改配置定义CONFIG_S3C2440
3. 修改U-BOOT代码
3.1 建一个单板(修改3个文件)
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$
看看是否能编译通过:
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
编译通不过.怀疑是makefile的问题,搜索一下:
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文件下复制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 烧写看结果无法执行,下面按照第2节里面的分析启动过程
3.3 调试:
a. 阅读代码发现不足:UBOOT里先以60MHZ的时钟计算参数来设置内存控制器,但是MPLL还未设置
#define S3C2440_MPLL_400MHZ
#endif
完成上面3步之后,编译生成新的uboot.bin,我们先用openjtag烧写原来的uboot,然后通过原来的uboot来下载新生成的uboot.bin
3.4 乱码,查看串口波特率的设置,发现在get_HCLK里没有定义CONFIG_S3C2440
①更改get_HCLK里没有定义CONFIG_S3C2440
board_init_f
②做完第一步后我们编译一下,发现错误,由于第一步的更改导致了第二步出现问题:
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
查看代码后解决:
book@book-desktop:/work/system/u-boot-2012.04.01$
那我们就去掉这个宏:在smdk2440.h
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
解决办法:暂时去掉如下行
③验证:先烧写1.1.6的uboot,然后重启开发板,烧写开发板
下面是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启动
3.5.1 去掉 "-pie"选项
book@book-desktop:/work/system/u-boot-2012.04.01$
3.5.2 参考"毕业班第1课"的start.S, init.c来修改代码
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$
烧写:
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:
HCLK:
PCLK:
DRAM:
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
在源码里面搜索“Flash:”,可以发现出现错误的原因,是由于board_init_r函数里面,
如果你的程序是从nand启动,那么会卡死,做如下修改:
# endif
3.6 修改UBOOT支持NOR FLASH
3.7 修改UBOOT支持NAND FLASH
分析过程:
nand_init
烧写实验:
①烧写到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
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
#define CONFIG_CS8900_BASE
#define CONFIG_CS8900_BUS16
#else
#define CONFIG_DRIVER_DM9000
#endif
然后编译出错: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里面的时序
还是有错误:看一下调用过程
*** 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
更新UBOOT:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
colin 查看数据:
SMDK2410 # nand dump 260000
制作补丁:
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
怎么用这个补丁:
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$
最重要的一点:
修改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工程、编译、烧写、如果无运行分析原因
tar xjf u-boot-2012.04.01.tar.bz2
cd u-boot-2012.04.01
make smdk2410_config
make
由于arm-linux-gcc版本太低,编译出错
arm-linux-gcc -v
下面来更换arm-linux-gcc到最新版本,以arm-linux-gcc-4.3.2.tar.bz2为例:
a、到服务器上安装工具链:
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、设置好最新的编译器以后,先回到u-boot-2012.04.01目录下,执行:make distclean命令删除之前编译出
的文件,重新make smdk2410_config,再make
2. 分析u-boot: 通过链接命令分析组成文件、阅读代码分析启动过程
a. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
b. 如果bootloader比较大,要把它重定位到SDRAM
c. 把内核从NAND FLASH读到SDRAM
d. 设置"要传给内核的参数"
e. 跳转执行内核
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地址编译得到的地址"
2.8.3 程序里有些地址在链接时不能确定,要到运行前才能确定:fixabs
2.9 clear_bss
2.10 调用C函数board_init_r:第2阶段的代码
可以修改配置定义CONFIG_S3C2440
3. 修改U-BOOT代码
3.1 建一个单板
cd board/samsung/
cp smdk2410 smdk2440 -rf
cd ../../include/configs/
cp smdk2410.h smdk2440.h
修改boards.cfg:
仿照
smdk2410
添加:
smdk2440
3.2 烧写看结果
3.3 调试:
a. 阅读代码发现不足:UBOOT里先以60MHZ的时钟计算参数来设置内存控制器,但是MPLL还未设置
3.4 乱码,查看串口波特率的设置,发现在get_HCLK里没有定义CONFIG_S3C2440
3.5 修改UBOOT支持NAND启动
3.5.1 去掉 "-pie"选项
3.5.2 参考"毕业班第1课"的start.S, init.c来修改代码
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
分析过程:
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);
3.8 修改UBOOT支持DM9000网卡
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. 易用性修裁剪及制作补丁
内核打印出来的分区信息
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
烧写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
烧写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
制作补丁:
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
评论