u-boot工程与编译系统
1.BootLoader介绍
- 对于计算机系统来说,从开机上电到操作系统启动需要一个引导过程。嵌入式Linux系统同样离不开引导程序,这个引导程序就叫作启动加载程序(Bootloader)。
- Bootloader是在操作系统运行之前执行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。对于嵌入式系统,Bootloader是基于特定硬件平台实现的。因此,几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader。Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。对于两块不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般都需要修改Bootloader的源程序。
从上述描述,我们可以知道:
- 在设备上电运行系统之前,需要先运行BootLoader。BootLoader为系统的运行准备好软硬件环境(软硬件初始化)。
- CPU架构、板载硬件资源任意一个不同,BootLoader程序代码都不同。
- 虽然是这样,BootLoader仍然可以通过类似穷举一样,将各个CPU架构源代码都加入进来,使得整个源代码能支持更多的硬件,uboot就是其中做得比较好的,u-boot就同时支持PowerPC、ARM、MIPS和X86等体系结构,支持的板子有上百种。
- uboot源码实质就是一个工程,使用Makefile管理,最早是德国的DENX软件公司的CEO:Wolfgang Denk创建,慢慢完善之后,现在u-boot已经支持PowerPC、ARM、X86、MIPS体系结构的上百种开发板,已经成为功能最多、灵活性最强,并且开发最积极的开源Bootloader。目前仍然由DENX的Wolfgang Denk维护。
2.获取uboot源码方式
- u-boot的源码包可以从其官方网站下载:DENX的u-boot主页:http://www.denx.de/wiki/u-boot。
- git源码库:git://www.denx.de/git/u-boot.git 。
3.u-boot源码结构
从网站上下载得到u-boot源码包,如本书中使用的u-boot-2009.11.tar.bz2,将其解压就可以得到全部u-boot源程序。在顶层目录下有30多个子目录,分别存放和管理不同的源程序。这些目录中存放的文件有其规则,可以分为3类。
- 第1类目录与处理器体系结构或开发板硬件直接相关。
- 第2类目录是一些通用的函数或驱动程序。
- 第3类目录是u-boot的应用程序、工具或文档。
4.u-boot源码配置
- u-boot的源码是通过GNU Makefile Makefile完成对开发板的整体配置,然后递归调用各级子目录下的 Makefile,最后把所有编译过的程序链接成u-boot映像。下面将以S3C2410处理器公板smdk2410为例,介绍u-boot的配置编译方法,并简单分析其原理。
(1)基本的配置编译方法
- 配置编译u-boot的方法十分简单,只需在解压并进入源码包后,在 u-boot顶层目录中执行如下两个命令:
- make <board_name> config
- make
- 第一个命令用来配置u-boot,其中<board_name>要用具体的开发板名称代替。例如,用smdk2410替代后就是“make smdk2410_config”。执行第二个命令后即开始编译过程。
(2)顶层目录下的Makefile
- 每一种开发板在顶层 Makefile中都需要有自己的配置规制。例如,用smdk2410开发板的规制定义如下:
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0
- 执行配置u-boot的命令:make smdk2410_config,将通过u-boot顶层目录下的mkconfig脚本生成配置文件 include/config.mk,内容如下。这些内容正是根据 Makefile对开发板的配置生成的。
ARCH = arm
CPU = arm920t
BOARD = smdk2410
VENDOR = samsung
SOC = s3c24x0
- 上面的include/config.mk文件定义了ARCH、CPU、 BOARD、 VENDOR、SOC等变量这样硬件平台依赖的目录文件可以根据这些定义来确定。SMDK2410平台相关目录如下:
board/samsung/smdk2410/
cpu/arm920t/
cpu/arm920t/s3c24x0/
lib_arm/
include/asm-arm/
include/configs/smdk2410.h
- 再回到顶层目录的Makefile文件开始的部分,其中下列几行包含了对前面所述变量的定义。
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
- Makefile的编译选项和规则在顶层目录的config.mk文件中定义。各种体系结构通用的规则直接在该文件中定义。通过ARCH、CPU、BOARD、SOC等变量为不同硬件平台定义不同选项。不同体系结构的规则分别包含在各自的lib_xxx(xxx表示体系架构,如lib_arm)目录下的config.mk文件中。
(3)开发板配置头文件
- 除了编译顶层Makefile以外,还要在移植时为开发板定义配置选项或参数。这个头文件是include/configs/<board_name>.h。<board_name>用相应的BOARD定义代替。
- 这些头文件中定义的选项或参数宏以CONFIG_为前缀,用来选择处理器、设备接口、命令、属性等。例如:
#define CONFIG_ARM920T 1
#define CONFIG_DRIVER_CS8900 1
(4)编译结果
- 编译完成后,可以得到u-boot各种格式的映像文件和符号表:
- u-boot的3种映像格式都可以烧写到Flash中,但需要看加载器能否识别这些格式。一般u-boot.bin最为常用,直接按照二进制格式下载,并且按照绝对地址烧写到Flash中即可。
5.U-Boot命令详解
- 帮助命令:help
- 查看环境变量:printenv
- 修改环境变量:setenv 添加、修改、删除环境变量
- 保存环境变量:saveenv 保存环境变量将当前定义的所有变量及其值存入flash中
- 执行程序:bootm {addr} {arg},执行固定格式的2进制程序 范例:#bootm 0xc0008000
查看、修改内存内容
- md采用十六进制和ASCII码两种形式来显示存储单元的内容。这条命令还可以采用长度标识符 .l, .w和.b :
- md [.b, .w, .l] address
范例:
- md.w 100000
- 00100000: 2705 1956 5050 4342 6f6f 7420 312e 312e
- 00100010: 3520 284d 6172 2032 3120 3230 3032 202d
mm 修改内存,地址自动递增
- mm [.b, .w, .l] address
- mm 提供了一种互动修改存储器内容的方法。它会显示地址和当前值,然后提示用户输入。如果你输入了一个合法的十六进制数,这个新的值将会被写入该地址。然后提示下一个地址。如果你没有输入任何值,只是按了一下回车,那么该地址的内容保持不变。如果想结束输入,则输入空格,然后回车。
- => mm 100000
- 00100000: 27051956 ? 0
- 00100004: 50504342 ? AABBCCDD
擦除nand flash
- nand erase 起始地址start 长度len
- 擦除start处开始的,长度为len的区域
范例:
- #nand erase 0x400000 0x500000
写/读nand flash
- nand write 内存起始地址 flash起始地址 长度len
- 将内存起始地址处,长度为len的数据,写入flash起始地址处。
- nand read 内存起始地址 flash起始地址 长度len