U-Boot源码结构
在顶层目录下有18个子目录,分别存放和管理不同的源程序。这些目录中所要存放的文件有其规则,可以分为3类。
第1类目录与处理器体系结构或者开发板硬件直接相关;
第2类目录是一些通用的函数或者驱动程序;
第3类目录是U-Boot的应用程序、工具或者文档。
平台依赖
board: 存放电路板相关的目录文件,例如:RPXlite(mpc8xx)、smdk2410(arm920t)、sc520_cdp(x86) 等目录
cpu: 存放CPU相关的目录文件,例如:mpc8xx、ppc4xx、arm720t、arm920t、 xscale、i386等目录
lib_ppc: 存放对PowerPC体系结构通用的文件,主要用于实现PowerPC平台通用的函数
lib_arm: 存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数
lib_i386: 存放对X86体系结构通用的文件,主要用于实现X86平台通用的函数
通用:
include: 头文件和开发板配置文件,所有开发板的配置文件都在configs目录下
common: 通用的多功能函数实现
lib_generic: 通用库函数的实现
Net: 存放网络的程序
Fs: 存放文件系统的程序
Post: 存放上电自检程序
drivers: 通用的设备驱动程序,主要有以太网接口的驱动
Disk: 硬盘接口程序
Rtc: RTC的驱动程序
Dtt: 数字温度测量器或者传感器的驱动
应用例程
examples: 一些独立运行的应用程序的例子,例如helloworld
工具
tools: 存放制作S-Record 或者 U-Boot格式的映像等工具,例如mkimage
文档
Doc: 开发使用文档
U-Boot编译
由顶层目录的Makefile递归调用各级子目录下的Makefile来完成编译,最终将程序链接成U-Boot映像。
Makefile中有对开发板的定义:
xxx_config: unconfig
@./mkconfg $(@:_config) ... ...
执行 make xxx_config命令,利用./mkconfig脚本生成config.mk配置文件,在include目录下。config.mk文件定义了ARCH, CPU,BOARD,SOC变量,以便平台依赖的目录文件使用
Makefile的编译选项和规则在顶层目录的config.mk中定义。各种体系的通用规则也在改文件中定义。而不同体系结构的规则 分别包含在ppc_config.mk、arm_config.mk、
Makefile缺省的编译目标是all,包括u-boot.srec、u-boot.bin、System.map。u-boot.srec
通过 make xxx_config以及make命令得到:
System.map: U-Boot 映像的符号表
u-boot: U-Boot 映像的 ELF 格式
u-boot.bin: U-Boot 映像原始的二进制格式
u-boot.srec: U-Boot 映像的 S-Record 格式
U-Boot的移植
移植 U-Boot 工作就是添加开发板硬件相关的文件、配置选项,然后配置编译。
移植之前要分析U-Boot已经支持的开发板,并选择最相近的开发板。选择的原则是:首先处理器相同,其次处理器体系结构相 同,然后是以太网接口等外围接口。
U-boot移植步骤:
1. 在顶层Makefile中添加开发板配置:
xxx_config : unconfig
@./mkconfig $(@:_config=) <arch> <cpu> <board> NULL <soc>
2. 创建新目录存放开发板相关代码,并添加文件
board/<board_name>/config.mk
board/<board_name>/flash.c
board/<board_name>/fs2410.c
board/<board_name>/Makefile
board/<board_name>/memsetup.S
board/<board_name>/u-boot.lds
3. 为开发板添加新的配置文件
include/configs/<board_name>.h
4. 配置开发板
$make <board_name>_config
5. 编译U-Boot
$make
6. 添加驱动或者功能选项
实现U-Boot的以太网接口、Flash擦写功能等。
7. 调试U-Boot源代码,直到U-Boot可以在开发板上正常启动
U-Boot启动过程
reset -> cup_init_crit -> memsetup -> relocate -> stack_setup -> start_armboot() -> init_sequence[], ... , getenv() -> main_loop()
程序入口点:从board/<board_name>/u-boot.lds中可以看到,u-boot的程序入口点是_start
_start在cpu/<cpu_name>/start.S中,由汇编语言实现。start.S主要完成的工作有:
定义Image的入口点,通常放在ROM(Flash)的0x0地址;
设置异常向量
设置CPU的速度、始终频率及中断控制寄存器
初始化内存控制器
将ROM中的程序复制到RAM中
初始化堆栈
转到RAM中执行( ldr pc)
start_armboot()在lib_arm/board.c中,是C语言开始的函数,也是整个启动代码中C语言的主函数。主要完成的工作有:
调用一系列的初始化函数
初始化flash设备
初始化系统内存分配函数
如果目标系统拥有NAND设备,则初始化NAND设备
如果目标系统有显示设备,则初始化该类设备
初始化相关网络设备,填写IP、MAC地址等
进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
另外,init_sequence[]数组保存基本的初始化函数指针
init_fnc_t *init_sequence[] = {
cpu_init, /* 基本的处理器相关配置 -- cpu/arm920t/cpu.c */
board_init, /* 基本的板级相关配置 -- board/smdk2410/smdk2410.c */
interrupt_init, /* 初始化例外处理 -- cpu/arm920t/s3c24x0/interrupt.c */
env_init, /* 初始化环境变量 -- common/cmd_flash.c */
init_baudrate, /* 初始化波特率设置 -- lib_arm/board.c */
serial_init, /* 串口通讯设置 -- cpu/arm920t/s3c24x0/serial.c */
console_init_f, /* 控制台初始化阶段 1 -- common/console.c */
display_banner, /* 打印 u-boot 信息 -- lib_arm/board.c */
dram_init, /* 配置可用的 RAM -- board/smdk2410/smdk2410.c */
display_dram_config, /* 显示 RAM 的配置大小 -- lib_arm/board.c */
NULL,
};
U-Boot与内核的关系
通常,U-Boot使用go和bootm直接引导内核映像启动。U-Boot 与内核的关系主要是内核启动过程中参数的传递。
go 命令调用 do_go()函数,跳转到某个地址执行的。如果在这个地址准备好了自引导的内核映像,就可以启动了。尽管 go 命令可以带变参,实际使用时一般不用来传递参数。
/* common/cmd_boot.c */
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
bootm 命令调用 do_bootm 函数。这个函数专门用来引导各种操作系统映像,可以支持引导 Linux、vxWorks、QNX 等操作系统。 /* common/cmd_bootm.c */
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
do_bootm_linux()函数是专门引导 Linux 映像的函数,它还可以处理 ramdisk 文件系统的映像。这里引导的内核映像和 ramdisk 映像,必须是 U-Boot 格式的。U-Boot 格式的映像可以通过 mkimage 工具来转换,其中包含了 U-Boot 可以识别的符号。
/* lib_arm/armlinux.c */
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],ulong addr, ulong *len_ptr, int verify)
烧写U-Boot到Flash
对于可以取下来的EPROM或Flash,可通过编程器直接烧写
对于不能取下来的贴片Flash,可通过处理器的调试接口,直接对板上的Flash编程:
标准的处理器调试接口有BDM,JTAG和EJTAG 3种。
BDM(Background Debug Mode)主要支持PowerPC8xx系列处理器
JTAG(Joint Test Action Group)支持大多数比较复杂的器件,如ARM,DSP,FPGA等
EJTAG(Extended JTAG)主要支持MIPS处理器
U-Boot常用命令
autoscr - run script from memory
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
dhcp - invoke DHCP client to obtain IP/boot params
echo - echo args to console
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print online help
iminfo - print header information for application image
imls - list all images found in flash
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing)
mtest - simple RAM test
mw - memory write (fill)
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
printenv - print environment variables
protect - enable or disable FLASH write protection
rarpboot - boot image via network using RARP/TFTP protocol
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
sleep - delay execution for some time
tftpboot - boot image via network using TFTP protocol
version - print monitor version
U-Boot环境变量
可以通过pringenv命令打印环境变量:
bootdelay: 定义执行自动启动的等候秒数
baudrate: 定义串口控制台的波特率
netmask: 定义以太网接口的掩码
ethaddr: 定义以太网接口的 MAC 地址
bootfile: 定义缺省的下载文件
bootargs: 定义传递给 Linux 内核的命令行参数
bootcmd: 定义自动启动时执行的几条命令
serverip: 定义 tftp 服务器端的 IP 地址
ipaddr: 定义本地的 IP 地址
stdin: 定义标准输入设备,一般是串口
stdout: 定义标准输出设备,一般是串口
stderr: 定义标准出错信息输出设备,一般是串口
U-Boot usage
最新推荐文章于 2024-09-09 09:21:26 发布