BootLoader第5章本章结构BootLoader简介BootLoaderU-Boot分析BootLoader的概念常用BootLoader介绍BootLoader的结构和启动过程5-1BootLoader的概念BootLoader就是在操作系统内核运行之前运行的一段小程序目的:为最终调用操作系统内核准备好正确的环境初始化硬件设备建立内存空间的映射图特点:BootLoader是严重地依赖于硬件而实现的因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。5-1-1BootLoader操作模式大多数BootLoader都包含两种不同的操作模式:启动加载(Bootloading)模式:这种模式也称为自主(Autonomous)模式。也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时侯,BootLoader显然必须工作在这种模式下下载(Downloading)模式:在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用BootLoader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。5-1-1BootLoader的位置系统启动代码包括固化在固件(firmware)中的boot代码(可选),和BootLoader两大部分。引导加载程序是系统加电后运行的第一段软件代码。回忆一下PC的体系结构,PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OSBootLoader(比如,LILO和GRUB等)一起组成BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OSBootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,也即开始启动操作系统。5-1-1BootLoader的位置而在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。比如在一个基于ARM的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。嵌入式Linux系统从软件的角度看通常可以分为4个层次:引导加载程序。Linux内核。根文件系统。用户应用程序。5-1-2嵌入式Linux系统典型分区结构每种不同的CPU体系结构都有不同的BootLoader。有些BootLoader也支持多种体系结构的CPU,比如U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体系结构外,BootLoader实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种CPU而构建的,要想让运行在一块板子上的BootLoader程序也能运行在另一块板子上,通常也都需要修改BootLoader的源程序。系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。比如,基于ARM的CPU在复位时通常都从地址0x00000000取它的第一条指令。而基于CPU构建的嵌入式系统通常都有某种类型的固态存储设备(比如:ROM、EEPROM或FLASH等)被映射到这个预先安排的地址上。因此在系统加电后,CPU将首先执行BootLoader程序。5-1-2BootLoader的两个阶段BootLoader第一阶段的功能硬件设备初始化。为加载Bootloader的第二阶段代码准备RAM空间。-复制Bootloader的第二阶段代码到RAM空间中。设置好栈。跳转到第二阶段代码的C入口点。5-1-2BootLoader的两个阶段BootLoader第二阶段的功能初始化本阶段要使用到的硬件设备。检测系统内存映射(memorymap)。将内核映象和根文件系统映象从Flash上读到RAM空间中。为内核设置启动参数。调用内核。5-1-2BootLoader与内核的交互Bootloader与内核的交互是单向的,Bootloader将各类参数传给内核。由于它们不能同时运行,传递办法只有一个:Bootloader将参数放在某个约定的地方之后,再启动内核,内核启动后从这个地方获得参数。标记列表标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。标记的数据结构为tag,它由一个tag_header结构和一个联合(union)组成。structtag_header{u32size;u32tag;};structtag{structtag_headerhdr;union{structtag_corecore;structtag_mem32mem;5-1-2标志列表设置标记ATAG_COREparams=(structtag*)0x30000100;params-hdr.tag=ATAG_CORE;params-hdr.size=tag_size(tag_core);params-u.core.flags=0;params-u.core.pagesize=0;params-u.core.rootdev=0;params=tag_next(params);5-1-2标志列表设置内存标记设置标记ATAG_NONEparams-hdr.tag=ATAG_MEM;params-hdr.size=tag_size(tag_mem32);params-u.mem.start=0x30000000;params-u.mem.size=0x40000000params=tag.next(params);params-hdr.tag=ATAG_NONE;params-hdr.size=0;5-1-3常用BootLoader介绍BootLoaderMonitor描述x86ARMPowerPCLILO否Linux磁盘引导程序是否否GRUB否GNU的LILO替代程序是否否Loadlin否从DOS引导Linux是否否ROLO否从ROM引导Linux而不需要BIOS是否否Etherboot否通过以太网启动Linux系统的固件是否否LinuxBIOS否完全替代BUIS的Linux引导程序是否否BLOB否LART等硬件平台的引导程序否是否U-boot是通用引导程序是是是RedBoot是基于eCos的引导程序是是是5-2-1U-Boot工程简介U-Boot,全称为UniversalBootLoader,即通用Bootloader,是遵循GPL条款的开放代码项目。“通用”有两层含义:可以引导多种操作系统支持多种架构的CPU。它支持如下操作系统:Linux、NetBSD、VxWorks、QNX、RTEMS、ARTOS、LynxOS等支持如下架构的CPU:PowerPC、MIPS、x86、ARM、NIOS、XScale等。获取U-Boot源码源码结构U-Boot-1.1.6根目录下共有26个子目录,可以分为4类。(1)平台相关的或开发板相关的。(2)通用的函数。(3)通用的设备驱动程序。(4)U-Boot工具、示例程序、文档。配置生成U-bootmakeboard_name_configmakeallU-Boot.bin:二进制可执行文件,它就是可以直接烧入ROM、NORFlash的文件。U-Boot:ELF格式的可执行文件。U-Boot.srec:MotorolaS-Record格式的可执行文件。5-2-2U-Boot源码结构5-2-3U-Boot的常用命令帮助命令help下载命令tftpboot命令使用TFTP协议从服务器下载文件nfs命令使用NFS协议下载文件help命令名,比如:helpbootmtftpboot[loadAddress][bootfilename]nfs[1oadAddress][hostipaddr:bootfilename]5-2-3U-Boot的常用命令NandFlash操作命令环境变量命令“nandinfo”查看NANDFlash信息“nanderase[clean][offsize]”擦除NANDFlash“nandread[.jffs2]addroffsize”“nandwrite.yaffsaddroffsize”“nandread.yaffsaddroffsize”“nandwrite.yaffsaddroffsize”“printenv”命令打印全部环境变量“setenvnamevalue”设置名字为name的环境变量的值为value。“setenvname”删除名字为name的环境变量“saveenv”将更改后的所有环境变量写入NandFlash中5-2-3U-Boot的常用命令启动命令“bootm[addr[arg…]]”命令启动存放在地址adds处的U-Boot格式的映象文件“goaddr[arg…]”启动存放在地址addr处的二进制文件“nboot[[[loadAddr]dev]offset]”命令将NANDFlash设备dev上偏移地址off处的映象文件复制到内存loadAddr处,然后,如果环境变量autostart的值为“yes”,就启动这个映象5-2-3U-Boot命令使用实例制作内核镜像文件烧写内核镜像文件uImagearm-linux-objcopy–obinary–R.note–R.comment–Svmlinuxlinux.bingzip-9linux.binmkimage–Aarm–Olinux–Tkernel–Cgzip–a0x30008000–e0x30008000–n“LinuxKernelImage”–dlinux.bin.gzuImagetftp0x30000000uImage或nfs0x30000000192.168.1.201:/work/nfs_root/uImagenanderase0x00x00200000nandwrite.jffs20x300000000x0$(filesize)5-2-3U-Boot命令使用实例烧写yaffs文件系统镜像烧写jffs2文件系统镜像tftp0x30000000yaffs.img或nfs0x30000000192.168.1.201:/work/nfs_root/yaffs.imgnanderase0xA000000x3600000nandwrite.yaffs0x300000000xA00000$(filesize)tftp0x30000000jffs2.img或nfs0x30000000192.168.1.201:/work/nfs_root/jffs2.imgnanderase0x2000000x800000nandwrite.jffs20x300000000x200000$(filesize)5-2-4使用U-Boot来执行程序烧写二进制文件到SDRAM并执行tftp0x30000000test.bin或nfs0x30000000192.168.1.201:/work/nfs_root/test.bingo0x30000000本章结构BootLoade