bootloader的目标——从Nand中读出内核、启动内核
一、uboot
如何获得一个uboot文件
【注意,uboot文件与patch不要在共享路径下进行解压和打补丁,否则可能会有问题】
【如果出错的话,可以加上“sudo”试一试】
步骤一:先在liunx环境下解压uboot开源源代码
tar xjf u-boot-1.1.6.tar.bz2
步骤二:然后打开发板的补丁
patch -p1 < ../u-boot-1.1.6_jz2440.patch
-
-p1 —— 含义是忽略第一个【/】之前的内容,在这里就是忽略【u-boot-1.1.6/】
-
步骤三:配置
make 100ask24x0_config
配置这里一般有三种途径
-
make menuconfig,然后一个一个配置;
-
使用默认配置 (arch/arm/configs),然后再改;
-
使用板子厂家提供的配置文件
步骤四:编译
make
uboot的源码分析
uboot 的内存分配(分区表)
从代码上看,uboot在Nand上的存放位置是固定的:
-
BootLoader从0开始,256K
-
params是接下去的128K
-
kernel是接下去的2M
-
剩下的作为root
各个地址如下:
kernel在SDRAM上的入口地址——0x30007FC0
nand read.jffs2 0x30007EC0 kernel
bootm 0x30007FC0
uboot怎么传递参数给kernel——通过tag
-
setup_start_tag
-
setup_memory_tags
-
setup_commandline_tag
-
setup_end_tag
内核启动流程
二、自己做一个bootloader
【默认是将内核、文件系统放置在Nand中,需要用到是复制到SDRAM中运行】
最简单的bootloader所需要的功能
-
初始化硬件:关看门狗,设置时钟,设置SDRAM,配置NAND;
-
将内核程序从Nand Flash读到SDRAM;
-
设置“要传给内核的参数”;
-
跳转并执行内核;
设置栈
将栈顶指针设置在SDRAM中;由于SDRAM的起始地址是0x3000000,SDRAM共有64K大小,所以
ldr sp, =0x30000000 + 64*1024*1024
ldr sp, =0x34000000
复制boot代码到SDRAM
-
起始地址:0(NOR启动0地址在NOR、Nand启动0地址在内部的SRAM)
-
目标地址: 从链接脚本中获取,一般为text段的开始,到bss段之前(SDRAM地址范围为0x3000000~0x34000000,前边预留作为内核、文件系统,bootloader512K足够用,所以0x3400 0000-512K = 0x33F80000 )
-
复制长度:从链接脚本中获取
重定位
如果是从NOR启动
-
上电后CPU从Nor的0地址开始运行;
-
由于NorFlash【只读不能写】的特征,需要重定位;在重定位时,把代码都复制到链接地址的SDRAM上去。
如果是Nand启动
-
芯片上电后,硬件会自动将Nand的前4K代码复制到芯片内部的SRAM中;并开始运行;
-
由于程序有时可能超过4K等原因,所以从Nand启动时,需要在前4K代码中,将整个程序从Nand复制到链接地址的SDRAM去。
一些地址你需要知道
- SDRAM的地址范围——0x30000000 ~ 0x34000000
- 内核在Nand中存放的地址——0x60000(前64K是uImage的一些头部)
- 内核在SDRAM中的入口地址——0x30008000
- 内核参数的存放地址——0x30000100
- uboot的重定位地址——0x33f80000(0x34000000 - 512K)