U-BOOT 全线移植分析系列之一
――――BOOTLOADER 介绍
Sailor_forever sailing_9806@163.com 转载请注明
http://blog.csdn.net/sailor_8318/archive/2008/08/04/2768049.aspx
【摘要】本节介绍了 bootloader 的基本概念。首先分析了为什么要针对特定的 CPU 和开发
板移植 bootloader 的必要性。然后介绍了两种如何在裸板中烧写 bootloader 的方法以及如何
确定烧写地址。其次介绍了产品发布的启动加载模式和开发使用的下载模式(更新内核文件
系统及 bootloader 自身)。最后介绍了 bootloader 的两个通用启动阶段的流程及代码特性和
运行位置。
【关键词】bootloader,烧写,复位地址,固化 loader,启动加载,stage1,位置无关
一 bootloader 介绍
1.1 Bootloader 移植的必要性 Bootloader 是与系统硬件环境高度相关的初始化软件,它担负
着初始化硬件和引导操作系统的双重责任。一些 ARM 平台可以共用同一种 Bootloader,但
是总的说来,每一个特定系统的 Bootloader 都会有所不同。Bootloader 广泛用于有操作系统
的手持终端设备、智能家电及机顶盒等嵌入式设备上,它负责完成硬件初始化、操作系统引
导和系统配制等。Bootloader 移植是在特定硬件平台上操作系统移植至关重要的一步。
1.2 BootLoader 所支持的 CPU 和嵌入式系统板每种不同的 CPU 体系结构都有不同的
BootLoader。有些 BootLoader 也支持多种体系结构的 CPU,比如 U-BOOT 就同时支持 ARM、
MIPS、POWERPC 等体系结构。除了依赖于 CPU 的体系结构外,BootLoader 实际上也依赖
于具体的嵌入式板级设备的配置。也就是说,对于两块不同的嵌入式板而言,即使它们是基
于同一种 CPU 而构建的,要想让运行在一块板子上的 BootLoader 程序也能运行在另一块板
子上,通常也都需要修改 BootLoader 的源程序。
1.3. Boot Loader 的烧录和存储系统加电或复位后,所有的 CPU 通常都从某个由 CPU 制造商
预先安排的地址上取指令。比如,at91rm9200 的 CPU 在复位时通常都从地址 0x00000000
取它的第一条指令。而 MPC8260 高端启动则时从 0xfff00000 开始取指。这个地址依据特定
的 CPU 而定。通常片外启动时,基于 CPU 构建的嵌入式系统通常都有某种类型的固态存储
设备(EEPROM 或 FLASH 等,at91rm9200 是 0x10000000)被映射到这个预先安排的地址上。
因此在系统加电后,CPU 将首先执行 Boot Loader 程序。
那么 bootloader 最初是怎么烧写到 flash 中的呢?对于一个裸板怎么让它跑起来呢?有两种方
式:
通过片内固化的 loader 加载 bootloader:通常某些 CPU 内部 ROM 中固化了一段程
序可以用于最初的程序下载,如 AT91RM9200。这时下载的程序是在内部 RAM 中运行的,
大小有一定限制,然后由这段程序继续交互下载真正要烧写到 flash 中的程序,将其保存在
外部 RAM 中,最终烧写到 flash 中。
通过 JTAG 或者仿真器下载:通常这些烧录工具可以直接操作 flash,对其进行编程
烧录。需要专门的工具。这种情况多用于那些没有固化 loader 的 CPU,如三星系列。
上图是一个同时装有 Boot Loader、内核的启动参数、内核映像和根文件系统映像的固态存
储设备的典型空间分配结构图。上述顺序是可变的,但 bootloader 首地址一定要在 CPU 复
位取指的地址上。
1.4 Boot Loader 的操作模式(Operation Mode)主机和目标机之间一般通过串口建立连接,
BootLoader 软件在执行时通常会通过串口来进行数据传输,如输出打印信息到串口,从串口
读取用户控制字符。
大多数 Boot Loader 都包含两种不同的操作模式:启动加载模式和下载模式,这种区别仅对
于开发人员才有意义。从最终用户的角度看,BootLoader 的作用就是用来加载操作系统,而
并不存在所谓的启动加载模式与下载工作模式的区别。
启动加载(Boot loading)模式:这种模式也称为自主模式 bootstrap。也即 Boot Loader
将存储在目标板 Flash 中的内核和文件系统的镜像装载到 SDRAM 中,整个过程无需用户的
介入。这种模式是 BootLoader 的正常工作模式,因此在嵌入式产品发布的时候,BootLoader
显然必须工作在这种模式下。
下载 Downloading 模式:在这种模式下,目标机上的 BootLoader 将通过串口连接或
网络连接等通信手段从宿主机 Host 下载文件,比如下载内核映像和根文件系统映像等。从
主机下载的文件通常首先被 BootLoader 保存到目标机的 RAM 中,然后再被 BootLoader 写
到目标机上的 FLASH 类固态存储设备中。BootLoader 的这种模式通常在第一次安装内核与
根文件系统时被使用;此外,以后的系统更新(bootloader 自身也可以这样更新)也会使用
Boot Loader 的这种工作模式。工作于这种模式下的 BootLoader 通常都会向它的终端用户提
供一些简单的命令行接口。
像 U-BOOT 等这样功能强大的 BootLoader 通常同时支持这两种工作模式,而且允许用户在
这两种工作模式之间进行切换。比如,U-BOOT 在启动时处于正常的启动加载模式,但是它
会延时几秒(在配置文件中可以设定)等待终端用户按下任意键而将其切换到下载模式(相当
于 bios 下按 del 键可进入系统配置界面一样,设置从光盘启动可进行重装),如果在给定时
间内没有用户按键,则 U-BOOT 继续启动,进行正常的启动加载。
1.5 Bootloader 与主机之间进行文件传输所用的通信设备及协议最常见的情况就是,目标机
上的 BootLoader 通过串口与主机之间进行文件传输,传输协议通常是 kermit / xmodem /
ymodem 协议中的一种。但是,串口传输的速度是有限的,因此如果该 Bootloader 对目标板
的网卡支持良好,还可以通过以太网连接并借助 TFTP (Trivial File Transfer Protocol)协议来
下载文件是个更好的选择。此时,主机方所用的软件也要考虑,比如,在通过以太网连接和
TFTP 协议来下载文件时,主机方必须有一个软件用来提供 TFTP 服务,如 Windows 平台上
的 tftpd.exe 等或 Linux 下面的 tftp 服务器。
1.6 Bootloader 的通用执行流程
从操作系统的角度看,Bootloader 的总目标就是正确地调用内核来执行。另外,由于
Bootloader 的实现依赖于 CPU 的体系结构,因此大多数 Bootloader 都分为 stagel 和 stage2
两大部分。依赖于 CPU 体系结构的代码,比如设备初始化代码等,通常都放在 stagel 中,
而且通常都用汇编语言来实现,以达到短小精悍和高效的目的。而 stage2 则通常用 C 语言
来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。
Bootloader 的 stagel 为位置无关代码,通常在 FLASH 中运行。所有的指令为相对寻址,可
以在任何位置运行。通常包括以下步骤(以执行的先后顺序):
Ø 硬件设备初始化(配置 SDRAM 存储控制器及 IO),中断初始化;
Ø 为加载 Bootloader 的 stage2 准备 RAM 空间(这个地址由链接脚本指定,为运行域
地址,通常为 RAM 的高端地址),测试内存空间是否有效;
Ø 拷贝 Bootloader 的 stage2 到 RAM 空间中;
Ø 设置好堆栈;
Ø 跳转到 stage2 的 C 入口点。
Bootloader 的 stage2 通常被拷贝到 RAM 中运行,这样可以提高运行速度。通常包括以下步
骤(以执行的先后顺序):
Ø 初始化本阶段要使用到的硬件设备;
Ø 检测系统内存映射(memory map);
Ø 没有用户干预时将 kernel 映像和根文件系统映像从 flash 读到 RAM 空间中;
Ø 为内核设置启动参数;
Ø 调用内核。
本 文 来 自 CSDN 博 客 , 转 载 请 标 明 出 处 :
http://blog.csdn.net/sailor_8318/archive/2008/08/04/2768049.aspx
U-BOOT 全线移植分析系列之二
――U-boot 基础
Sailor_forever sailing_9806@163.com 转载请注明
http://blog.csdn.net/sailor_8318/archive/2008/08/04/2768049.aspx
【摘要】本节介绍了 U-boot 的基本概念。首先介绍了 U-boot 源代码的目录结构,并给出了
一个实例。接着简单介绍了 U-boot 支持的基本功能、常见命令和环境变量。最后详细分析
了 U-boot 启动的两个阶段,重点介绍了加载拷贝代码至 RAM 中的过程。
【关键词】bootloader,U-boot,环境变量, stage1,位置无关,代码搬移
二 U-boot 基础
现在为 Linux 开放源代码 Bootloader 有很多,blob、 redboot 及 U-BOOT 等,其中 U-BOOT
是目前用来开发嵌入式系统引导代码使用最为广泛的 Bootloader。它支持 POWERPC、ARM、
MIPS 和 X86 等处理器,支持嵌入式操作系统有 Linux、Vxworks 及 NetBSD 等。
2.1 U-boot 源代码目录结构|-- board 平台依赖,存放电路板相关的目录文件
|-- common 通用多功能函数的实现
|-- cpu 平台依赖,存放 cpu 相关的目录文件
|-- disk 通用。硬盘接口程序
|-- doc 文档
|-- drivers 通用的设备驱动程序,如以太网接口驱动
|-- dtt
|-- examples 应用例子
|-- fs 通用存放文件系统的程序
|-- include 头文件和开发板配置文件,所有开发板配置文件放在其 configs 里
|-- lib_arm 平台依赖,存放 arm 架构通用文件
|-- lib_generic 通用的库函数
|-- lib_i386 平台依赖,存放 x86 架构通用文件
|-- lib_m68k 平台依赖
|-- lib_microblaze 平台依赖
|-- lib_mips 平台依赖
|-- lib_nios 平台依赖
|-- lib_ppc 平台依赖,存放 ppc 架构通用文件
|-- net 存放网络的程序
|-- post 存放上电自检程序
|-- rtc rtc 的驱动程序
`-- tools 工具
详细实例:
board:开发板相关的源码,不同的板子对应一个子目录,内部放着主板相关代码。
Board/at91rm9200dk/at91rm9200.c, config.mk, Makefile, flash.c ,u-boot.lds 等都和具体开发板
的硬件和地址分配有关。
common:与体系结构无关的代码文件,实现了 u-boot 所有命令,其中内置了一个
shell 脚本解释器(hush.c, a prototype Bourne shell grammar parser), busybox 中也使用了它。
cpu:与 cpu 相关代码文件,其中的所有子目录都是以 u-boot 所支持的 cpu 命名。
cpu/at91rm9200/at45.c, at91rm9200_ether.c, cpu.c, interrupts.c serial.c, start.S, config.mk,
Makefile 等。其中:
cpu.c 负责初始化 CPU、设置指令 Cache 和数据 Cache 等;
interrupt.c 负责设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中
断、预取中止和未定义指令等;
start.S 负责 u-boot 启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为跳转到
C 程序入口点做准备;
at91rm9200_ether.c 和 serial.c 很重要,这是系统能够下载资源的前提。
disk:设备分区处理代码。
doc:u-boot 相关文档。
drivers:u-boot 所支持的设备驱动代码, 网卡、支持 CFI 的 Flash、串口和 USB 总线
等。
fs: u-boot 所支持文件系统访问存取代码, 如 jffs2。
include : u-boot head 文 件 , 主 要 是 与 各 种 硬 件 平 台 相 关 的 头 文 件 , 如
include/asm-arm/arch-at91rm9200/AT91RM9200.h(硬件寄存器名称及地址的定义), hardware.h
(内存及 flash 地址以及 IO 物理地址和虚拟地址的定义),include/asm-arm/proc-armv(与具
体的 CPU 无关,无需移植)。
net:与网络有关的代码,BOOTP 协议、TFTP 协议、RARP 协议代码实现. 无需移
植。
lib_arm:与 arm 体系相关的代码。
tools:编译后会生成 mkimage 工具,用来对生成的 raw bin 文件加入 u-boot 特定的
image_header.
2.2 U-Boot 支持的主要功能主要功能如下:
系统引导,支持 NFS 挂载、RAMDISK(压缩或非压缩)形式的根文件系统;
支持 NFS 挂载、从 FLASH 中引导压缩或非压缩系统内核;
基本辅助功能,强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作
系统,适合系统在不同开发阶段的调试要求与产品发布,尤对 Linux 支持最为强劲;
支持目标板环境参数多种存储方式,如 FLASH、NVRAM、EEPROM;
CRC32 校验,可校验 FLASH 中内核、RAMDISK 镜像文件是否完好;
设备驱动,串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、
USB、PCMCIA、PCI、RTC 等驱动支持;
上电自检功能 SDRAM、FLASH 大小自动检测;SDRAM 故障检测;CPU 型号;
特殊功能,XIP 内核引导。
2.3 U-boot 命令介绍及环境变量 ?得到所有命令列表
Help:help usb, 列出 USB 功能的使用说明
ping:注意只能开发板 PING 别的机器(AT91RM9200 不支持,需要进行配置)
setenv: 设置环境变量
Ø setenv serverip 192.168.0.1
Ø setenv ipaddr 192.168.0.56
Ø setenv bootcmd ‘tftp 32000000 vmlinux; kgo 32000000’
saveenv:保存环境变量。在设置好环境变量以后, 保存变量值
tftp:tftp 32000000 vmlinux, 把 server(IP=环境变量中设置的 serverip)中/tftpboot/
下的 vmlinux 通过 TFTP 读入到物理内存 32000000 处
bootp- 通过网络用 BootP/TFTP 协议来启动映象
tftpboot- 通过网络用 TFTP 协议、设置服务器和客户机的 IP 地址进行映象文件传
送
kgo: 起动没有压缩的 linux 内核,kgo 32000000(AT91RM9200 不支持)
bootm:起动 UBOOT TOOLS 制作的压缩 LINUX 内核, bootm 3200000
protect: 对 FLASH 进行写保护或取消写保护,protect on 1:0-3(就是对第一块 FLASH
的 0-3 扇区进行保护),protect off 1:0-3 取消写保护
erase:删除 FLASH 的扇区, erase 1:0-2(就是对每一块 FLASH 的 0-2 扇区进行删除)
cp: 在内存中复制内容, cp 32000000 0 40000(把内存中 0x32000000 开始的 0x40000
字节复制到 0x0 处)
mw: 对 RAM 中的内容写操作, mw 32000000 ff 10000(把内存 0x32000000 开始的
0x10000 字节设为 0xFF)
md: 修改 RAM 中的内容, md 32000000(内存的起始地址)
flinfo: 列出 flash 的信息
loadb: 准备用 KERMIT 协议接收来自 kermit 或超级终端传送的文件。
nfs: nfs 32000000 192.168.0.12:aa.txt,把 192.168.0.12(LINUX 的 NFS 文件系统)
中的 NFS 文件系统中的 aa.txt 读入内存 0x32000000 处。
最常用的几个命令如下:
go- 在地址 'addr' 处开始程序执行
run- 运行一个环境变量所定义的命令
bootm- 从内存中进行运行经过 mkimage 加工的程序映象
loadb- 通过串口线(kermit mode) 来装载二进制文件
printenv- 打印环境变量
setenv- 设置环境变量
saveenv 保存环境变量到内存
tftp-通过网络下载文件
protect,erase,flash 读写
下面是 U-BOOT 中的简单环境变量
baudrate 波特率
bootdelay boot 延迟
bootcmd Boot 命令
bootargs Boot 参数,传递给内核
bootfile 默认下载启动的内核映象
ipaddr 客户机 IP 地址
serverip 服务器地址
loadaddr 装载地址
ethaddr 网卡 MAC 地址