您的位置:首页 > 其它

移植u-boot

2017-12-22 10:09 495 查看

移植U-boot

(一)初试

在官网上下载最新的uboot(u-boot-2012.04.01)压缩包,并将其拖到服务器上;

1.1 在SecureCRT上第一次尝试编译



1.2 出错



出错原因:编译工具链版本低。


1.3 查看当前交叉编译工具链版本



安装新的编译工具链(arm-linux-gcc-4.3.2);

2.1 解压到根目录



2.2 修改环境变量(进入根目录/usr/local/arm/4.3.2/bin)



另一种方法(如下图):sudo vi /etc/environment




再次编译u-boot,进入之前u-boot-2012.04.01文件夹

3.1 清除之前编译的:make distclean

3.2 配置:make smdk2410_config

3.3 编译:make

3.4 编译成功–生成u-boot.bin文件

将生成u-boot.bin文件用eop下载到NOR Flash,启动,但串口上并没有什么显示。(这是正常的,因为还没有做修改)

(二)源码分析启动过程

创建si工程;

添加代码时:board文件夹只需添加的Samaung中的smdk2410,arch文件夹下的Arm->cpu->arm920t->s3c24x0、include->Asm->arch-s3c24x0是我们关注的,其他文件夹可以均添加上。

第一阶段代码分析(文件:start.S (arch\arm\cpu\arm920t),lowlevel_init.S (board\samsung\smdk2410))

2.1 将CPU的工作模式设为管理模式(svc):/* set the cpu to SVC32 mode */

2.2 关闭看门狗:/* turn off the watchdog */

2.3 /* mask all IRQs by setting all bits in the INTMR - default */

2.4 设置FCLK、HCLK、PCLK的比例(设置CLKDIVN寄存器):/* FCLK:HCLK:PCLK = 1:2:4 */

2.5 设置内存控制器: cpu_init_crit

a. /* flush v4 I/D caches */

b. 关闭MMU、CACHE:/* disable MMU stuff and caches */

c. 跳转至lowlevel_init:bl  lowlevel_init

为加载BootLoader的第二阶段代码准备RAM空间(lowlevel_init.S)--开发板相关

即:初始化内存芯片,对于S3C2440,使得外接的SDRAM可用。

lowlevel_init函数,并不复杂,只是这时的代码、数据只保存在NOR FLASH中,内存中还没有,所以读取数据时要变换地址。






第137-139行:进行地址变换,因为这时候内存中还没有数据,不能使用链接程序时确定的地址来读取数据。

第137行:SMRDATA表示这13个寄存器的值存放的开始地址(连接地址),为0x33F8xxxx,处于内存中。

第138行:获得代码段的起始地址,即“_TEXT_BASE”,在board\smdk2410\config.mk中定义"TEXT_BASE = 0x33F80000"

第139行:将0x33F8xxxx与0x33F80000相减,就是13个寄存器值在NOR Flash上存放的地址。


2.6 设置栈,调用C函数board _ init _ f:/* Set stackpointer in internal RAM to call board_init_f */

a. 调用函数数组init_sequence里的各个函数:(例)board_early_init_f : 设置系统时钟、设置GPIO

b. board _ init _ f最后调用的重定位函数:relocate_code(addr_sp, id, addr);

addr:把NOR Flash中的程序拷贝到哪里去;

addr_sp:设置的栈;

id:一些变量的地址

1. addr

addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;

/* CONFIG_SYS_SDRAM_BASE=0x30000000, gd->ram_size=64MB, 所以addr=0x34000000 */

addr -= (4096 * 4);  /* addr = 33FFC000 */

addr &= ~(0x10000 - 1); /* addr = 33FF0000 */

addr -= gd->mon_len; /* gd->mon_len = _bss_end_ofs;--uboot程序的大小:AE4E0(反汇编文件中),所以addr= 33F41B20 */

addr &= ~(4096 - 1);  /* addr=33F41000 */

2. addr_sp

addr_sp = addr - TOTAL_MALLOC_LEN;

addr_sp -= sizeof (bd_t);

addr_sp -= sizeof (gd_t);

addr_sp -= 12;

3. id

id = (gd_t *) addr_sp; /* 指向一个结构体gd_t */


2.7 重定位代码

分析重定位代码(start.S文件):relocate_code(addr _ sp, id, addr)–C语言调用汇编(其中addr _ sp存储到r0,id存储到r1,addr存储到r2)

分析重定位代码

2.8 clear_bss

2.9 调用C函数board_init_r:第2阶段的代码

(三)修改代码

移植u-boot之修改代码

(I)修改代码— 建新板 _ 时钟 _ SDRAM _ UART

(II)修改代码—支持NAND启动

(III)修改代码—支持Nor Flash(读写)

(IV)修改代码—支持Nand Flash(读写)

(V)修改代码—支持DM9000网卡

(四)裁剪和修改默认参数

易用性裁剪uboot(修改配置文件smdk2440.h)







—重新编译后的uboot大小



修改默认参数

2.1 修改默认参数

—启动后,从串口提示信息找到文件







—设置配置文件中的参数





2.2 参考内核中的分区

set ipaddr 192.168.0.4

set ethaddr 00:0c:29:07:33:a6

set serverip 192.168.0.2

tftp 30000000 uImage_4.3

bootm 30000000


—设置参数



—内核启动后,查看分区



2.3 设置关于存储环境变量分区的参数

—由sav命令的帮助信息(saveenv),找到所需文件





—根据目录,查看其文件夹下的Makefile,找到该文件编译进uboot所需的宏,并在配置文件中定义该宏





—在Env_nand.c文件的saveenv函数中,找到我们还需要定义的宏



—在配置文件中,参照2.2中内核的分区,设置宏



上传配置文件,重新编译uboot后,在串口设置环境变量后用tftp烧写新的uboot到sdram,然后再用命令将其拷贝到NOR Flash中





—重启后,打印变量



—消除之前的警告







—uboot移植到这里也基本上完整了。

设置分区–以便我们使用(仅仅是方便的功能)

4.1 添加mtdparts命令所需的宏:所需要编进uboot的文件为cmd_mtdparts.c,在所在目录下的Makefile中找到所依赖的宏,并在配置文件中定义该宏





4.2 在uboot源码下执行命令搜索:grep “mtdparts” * -nR,找出参考文件来仿照设置分区

—参考文件



—配置文件中定义



4.3 根据老师试验,还需在Board.c文件中加入一行代码



4.4 将修改的两文件上传,重新编译失败并解决该问题





4.4 将修改的两文件上传,重新编译成功后,现在可以直接下载到sdram(不用设置环境变量),再复制到NOR Flash中重启开发板,执行mtdparts命令,出现如图打印





4.5 试验–把下载到sdram中的拷贝到Nand Flash

—下载uImage_4.3到sdram



—擦除(原:nand erase 60000 200000)



—nand写(原:nand write 30000000 60000 200000)



最后,我们在将之前的bootcmd修改一下,重新编译



—此时,我们可以不用再烧写uboot,直接在串口上设置bootcmd,保存,重启



—打印查看



—此时我们再次reset,uboot启动后,倒数5秒后就会直接启动内核



(五)支持yaffs映像及制作补丁

试验1–烧写JFFS文件系统

1.1 tftp烧写文件(嵌入式–第二期\资料光盘\bin\文件系统)fs_mini_mdev.jffs2

tftp 30000000 fs_mini_mdev.jffs2


1.2 拷贝到Nand中文件系统分区

nand erase.part rootfs
nand write.jffs2 30000000 260000 5b89a8
注:这里260000就是文件系统分区的偏移地址,5b89a8就是fs_mini_mdev.jffs2的文件大小(tftp烧写完即可得到)


1.3 设置bootargs

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


1.4 boot后,启动内核,成功挂载jffs2文件系统



试验2–烧写yaffs文件系统

1.1 重启开发板,tftp烧写文件(嵌入式–第二期\资料光盘\bin\文件系统)fs_mini_mdev.yaffs2

tftp 30000000 fs_mini_mdev.yaffs2


1.2 拷贝到Nand中文件系统分区

nand erase.part rootfs
nand write.yaffs 30000000 260000 889bc0
注:这里260000就是文件系统分区的偏移地址,889bc0就是fs_mini_mdev.yaffs2的文件大小(tftp烧写完即可得到)


执行完上条命令会出现如下图错误提示,需在配置文件中配置相应的宏,重启编译并烧写新的uboot后,重新烧写文件系统



—找到根源文件



—配置宏



1.3 bootargs不用修改,选择默认即可

1.4 boot后,启动内核,串口出现如下图错误指示



解决试验2的问题

3.1 比较源文件fs_mini_mdev.yaffs2(用UE打开)和烧写到Nand中的文件(nand dump命令),发现Nand中的第一页的oob与源文件不符并且其余页均为数据均不符

补充:现开发板使用的Nand:一页大小为2M(包含oob)


—源文件(第一页oob)



—nand(第一页oob)





—源文件(第二页数据)



—nand(第二页数据)



3.2 修改相关文件



—适用nand有坏块的情况



3.3 重新编译、烧写uboot

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




3.4 重复试验2烧写yaffs文件系统的步骤



到这里,我们已经完整的移植了2012版的uboot了!!!

<补充:制作uboot的补丁文件>

制作补丁文件(使用diff命令)

—制作步骤



—查看补丁文件



打补丁(进入之前源码解压后的文件夹)

patch -p1 <../u-boot-2012.04.01_tp.patch

注:../表示补丁文件在该文件夹的上层目录下,即/work/system




最后,配置编译,生成新的uboot.bin文件,用tftp烧写到NOR Flash中,并将yaffs文件系统烧到NAND分区中,boot后成功挂载(与之前一步一步修改的效果是一样的)。

2017.11.25
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: