1. u-boot 介绍
u-boot 是一个 open source 的 bootloader ,目前版本是 0.4.0 。 u-boot 是在 ppcboot 以及 armboot 的基础上发展而来,虽然宣称是 0.4.0 版本,却相当的成熟和稳定,已经在许多嵌入式系统开发过程中被采用。由于其开发源代码,其支持的开发板众多。唯一遗憾的是并不支持我们现在学习所用 samsung 44B0X 的开发板。
为什么我们需要 u-boot ?显然可以将 ucLinux 直接烧入 flash ,从而不需要额外的引导装载程序( bootloader )。但是从软件升级的角度以及程序修补的来说,软件的自动更新非常重要。事实上,引导装载程序( bootloader )的用途不仅如此,但仅从软件的自动更新的需要就说明我们的开发是必要的。同时, u-boot 移植的过程也是一个对嵌入式系统包括软硬件以及操作系统加深理解的一个过程。
2. u-boot 移植的框架
移植 u-boot 到新的开发板上仅需要修改和硬件相关的部分。在代码结构上:
在 board 目录下创建 ev44b0ii 目录,创建 ev44b0ii.c 以及 flash.c,memsetup.S,u-boot.lds 等。不需要从零开始,可选择一个相似的目录,直接复制过来,修改文件名以及内容。我在移植 u-boot 过程中,选择的是 ep7312 目录。由于 u-boot 已经包含基于 s3c24b0 的开发板目录,作为参考,也可以复制相应的目录。
在 cpu 目录下创建 arm7tdmi 目录 , 主要包含 start.S , interrupts.c 以及 cpu.c,serial.c 几个文件。同样不需要从零开始建立文件,直接从 arm720t 复制,然后修改相应内容。
在 include/configs 目录下添加 ev44b0ii.h ,在这里放上全局的宏定义等。
找到 u-boot 根目录下 Makefile 修改加入
ev44b0ii_config : unconfig
@./mkconfig $(@:_config=) arm arm7tdmi ev44b0ii
运行 make ev44bii_config, 如果没有错误就可以开始硬件相关代码移植的工作 3. u-boot 的体系结构
1) 总体结构
u-boot 是一个层次式结构。从上图也可以看出,做移植工作的软件人员应当提供串口驱动( UART Driver ) , 以太网驱动 (Ethernet Driver),Flash 驱动( Flash 驱动) ,USB 驱动( USB Driver )。目前,通过 USB 口下载程序显得不是十分必要,所以暂时没有移植 USB 驱动。驱动层之上是 u-boot 的应用, command 通过串口提供人机界面。我们可以使用一些命令做一些常用的工作,比如内存查看命令 md 。 Kermit 应用主要用来支持使用串口通过超级终端下载应用程序。 TFTP 则是通过网络方式来下载应用程序,例如 uclinux 操作系统。
2) 内存分布
在 flash rom 中内存分布图
ev44b0ii 的 flash 大小 2M (8bits), 现在将 0-40000 共 256k 作为 u-boot 的存储空间。由于 u-boot 中有一些环境变量,例如 ip 地址,引导文件名等,可在命令行通过 setenv 配置好 , 通过 saveenv 保存在 40000-50000 (共 64k )这段空间里。如果存在保存好的环境变量, u-boot 引导将直接使用这些环境变量。正如从代码分析中可以看到,我们会把 flash 引导代码搬移到 DRAM 中运行。下图给出 u-boot 的代码在 DRAM 中的位置。引导代码 u-boot 将从 0x0000 0000 处搬移到 0x 0C 700000 处。特别注意的由于 ev44b0ii uclinux 中断向量程序地址在 0x 0c 00 0000 处,所以不能将程序下载到 0x 0c 00 0000 出,通常下载到 0x 0c 08 0000 处。
start.S 代码结构
1) 定义入口
一个可执行的 Image 必须有一个入口点并且只能有一个唯一的全局入口,通常这个入口放在 Rom(flash) 的 0x0 地址。例如 start.S 中的
.globl _start
_start:
值得注意的是你必须告诉编译器知道这个入口,这个工作主要是修改连接器脚本文件( lds )。
2) 设置异常向量 (Exception Vector)
异常向量表,也可称为中断向量表,必须是从 0 地址开始,连续的存放。如下面的就包括了复位 (reset), 未定义处理( undef ) , 软件中断 (SWI), 预去指令错误 (Pabort), 数据错误 (Dabort), 保留,以及 IRQ,FIQ 等。注意这里的值必须与 uclinux 的 vector_base 一致。这就是说如果 uclinux 中 vector_base( 在 include/armnommu/proc-armv/system.h) 定义为 0x0c00 0000, 则 HandleUndef 应该在 0x0c00 0004 。
b reset //for debug
ldr pc,=HandleUndef
1 2 3 4 5 6 7