http://blog.chinaunix.net/uid-11909535-id-2801654.html
分类: LINUX
1. 引导加载程序。包括固化在固件firmware中的boot代码和boot loader两大部分。
2. linux内核。特定于嵌入式板子定制的内核以及内核的启动参数。
3. 文件系统。 包括文件系统和建立于flash内存设备之上的文件系统。通常用ramdisk来作为rootfs。
4. 用户应用程序。特定于用户的应用程序。有时在用户程序和内核层之间可能会包括一个嵌入式图形界面。
回忆下X86体系结构:pc机中的引导加载程序是有BIOS和位于硬盘MBR中的OS boot loader(如GRUB、LILO)共同构成的,BIOS完成上电自检和资源分配后,便将MBR中的boot loader加载到系统的RAM中,然后将控制权交给了boot loader。boot loader的主要任务就是将操作系统的内核映像读入到RAM中,然后跳转到内核的入口点去,即开始启动操作系统。在嵌入式系统中,通常没有像BIOS那样的固件程序(主要是针对特定任务的,短小精悍),因此整个加载系统的任务都是有boot loader来完成的。系统在上电或者复位通常都是从地址0x0000000处开始执行,而在这个地址处安排的通常就是系统 的bootloader程序。简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
bootloader的启动
linux启动过程是通过bootloader引导启动的。一上电就要执行bootloader来初始化系统。
系统加电或者复位后,所有cpu都会从某个地址开始执行,这是由处理器设计决定的。比如X86的复位向量是在高地址端,ARM处理器复位是从地址0x00000000开始取第一条指令的。因此嵌入式系统开发板都需要把板子的ROM或Flash映射到这个地址。由于第一步便是执行uboot,所以必须把bootloader程序存储在相应的Flash位置,好使系统加电后首先执行它。
主机和目标机之间一般有串口可以连接,Bootloader软件通常会通过串口来输入输出。例如:输出出错或者执行结果信息到串口终端,从串口终端读取用户控制命令等。
Bootloader启动过程通常是多阶段的,这样既能提供复杂的功能,又有很好的可移植性。例如:从Flash启动的Bootloader多数是两阶段的启动过程。
大多数Bootloader都包含2种不同的操作模式:本地加载模式和远程下载模式。这2种操作模式的区别仅对于开发人员才有意义,也就是不同启动方式的使用。从最终用户的角度看,Bootloader的作用就是用来加载操作系统,而并不存在所谓的本地加载模式与远程下载模式的区别。
Bootloader的主要功能是引导操作系统启动,它的启动方式一般有三种
1. 网络启动
这种方式开发板不需要配置较大的存储介质,跟无盘工作站有点类似。但是使用这种启动方式之前,需要把Bootloader安装到板上的EPROM或者Flash中。Bootloader通过以太网接口远程下载Linux内核映像或者文件系统。第4章介绍的交叉开发环境就是以网络启动方式建立的。这种方式对于嵌入式系统开发来说非常重要。
使用这种方式也有前提条件,就是目标板有串口、以太网接口或者其他连接方式。串口一般可以作为控制台,同时可以用来下载内核影像和RAMDISK文件系统。串口通信传输速率过低,不适合用来挂接NFS文件系统。所以以太网接口成为通用的互连设备,一般的开发板都可以配置10M以太网接口。
对于PDA等手持设备来说,以太网的RJ-45接口显得大了些,而USB接口,特别是USB的迷你接口,尺寸非常小。对于开发的嵌入式系统,可以把USB接口虚拟成以太网接口来通讯。这种方式在开发主机和开发板两端都需要驱动程序。
另外,还要在服务器上配置启动相关网络服务。Bootloader下载文件一般都使用TFTP网络协议,还可以通过DHCP的方式动态配置IP地址。
DHCP/BOOTP服务为Bootloader分配IP地址,配置网络参数,然后才能够支持网络传输功能。如果Bootloader可以直接设置网络参数,就可以不使用DHCP。
TFTP服务为Bootloader客户端提供文件下载功能,把内核映像和其他文件放在/tftpboot目录下。这样Bootloader可以通过简单的TFTP协议远程下载内核映像到内存。如图所示
大部分引导程序都能够支持网络启动方式。例如:BIOS的PXE(Preboot Execution Environment)功能就是网络启动方式;U-Boot也支持网络启动功能。
2.磁盘启动方式
传统的Linux系统运行在台式机或者服务器上,这些计算机一般都使用BIOS引导,并且使用磁盘作为存储介质。如果进入BIOS设置菜单,可以探测处理器
![](http://blogimg.chinaunix.net/blog/upfile2/081207194638.png)
Linux传统上是通过LILO(LInux LOader)引导的,后来又出现了GNU的软件GRUB(GRand Unified Bootloader)。这2种Bootloader广泛应用在X86的Linux系统上。你的开发主机可能就使用了其中一种,熟悉它们有助于配置多种系统引导功能。
LILO软件工程是由Werner Almesberger创建,专门为引导Linux开发的。现在LILO的维护者是John Coffman,最新版本下载站点:http://lilo.go.dyndns.org。LILO有详细的文档,例如LILO套件中附带使用手册和参考手册。此外,还可以在LDP的“LILO mini-HOWTO”中找到LILO的使用指南。
GRUB是GNU计划的主要bootloader。GRUB最初是由Erich Boleyn为GNU Mach操作系统撰写的引导程序。后来有Gordon Matzigkeit和Okuji Yoshinori接替Erich的工作,继续维护和开发GRUB。GRUB的网站http://www.gnu.org/software/grub/上有对套件使用的说明文件,叫作《GRUB manual》。GRUB能够使用TFTP和BOOTP或者DHCP通过网络启动,这种功能对于系统开发过程很有用。
除了传统的Linux系统上的引导程序以外,还有其他一些引导程序,也可以支持磁盘引导启动。例如:LoadLin可以从DOS下启动Linux;还有ROLO、LinuxBIOS,U-Boot也支持这种功能。
3 Flash启动方式
大多数Flash使用Flash存储介质,Flash存储介质有很多类型,包括NOR flash、NAND flash 等。其中NOR fash(也就是线性fash)使用最为普遍。
因为NOR flash可以支持随机访问,所以代码可以直接在fash上执行。bootloader一般是存储在flash芯片上的,通常linux内核映像和RAMDISk也是存储在flash上的。通常需要把flash分区使用,每个区的大小应该是flash擦除大小的整数倍。如下图是bootloader和内核映像以及文件系统的分区表。
![](http://blogimg.chinaunix.net/blog/upfile2/081207194910.png)
bootloader一般放在flash的低端或者顶端,这是根据处理器的复位向量置的。要使bootloader的入口位于处理器上电执行第一条指令的位置。
接下来分配参数区,这里可以作为Bootloader的参数保存区域。
再下来内核映像区。Bootloader引导Linux内核,就是要从这个地方把内核映像解压到RAM中去,然后跳转到内核映像入口执行。
然后是文件系统区。如果使用Ramdisk文件系统,则需要Bootloader把它解压到RAM中。如果使用JFFS2文件系统,将直接挂接为根文件系统。这两种文件系统将在第12章详细讲解。
最后还可以分出一些数据区,这要根据实际需要和Flash大小来考虑了。
这些分区是开发者定义的,Bootloader一般直接读写对应的偏移地址。到了Linux内核空间,可以配置成MTD设备来访问Flash分区。但是,有的Bootloader也支持分区的功能,例如:Redboot可以创建Flash分区表,并且内核MTD驱动可以解析出redboot的分区表。
除了NOR Flash,还有NAND Flash、Compact Flash、DiskOnChip等。这些Flash具有芯片价格低,存储容量大的特点。但是这些芯片一般通过专用控制器的I/O方式来访问,不能随机访问,因此引导方式跟NOR Flash也不同。在这些芯片上,需要配置专用的引导程序。通常,这种引导程序起始的一段代码就把整个引导程序复制到RAM中运行,从而实现自举启动,这跟从磁盘上启动有些相似。
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 | 文档 | 开发使用文档 |