Bootloader概述
Bootloader的含义
PC机上windows、linux引导过程简介
嵌入式Bootloader介绍与分析
嵌入式bootloader介绍
Bootloader的操作模式
Bootloader的安装及启动媒介
Bootloader的启动过程
Bootloader的通信设备及协议
Bootloader:中文解释为启动引导程序
可以工作在无操作系统的环境下,也可以工作在有操作系统的环境下
在无操作系统环境下:
通常表现为:与应用程序编译在一起,在应用程序之前运行的一段代码,一般由汇编编写
完成节基本硬件及对战的初始化,为应用程序做准备
人们通常说的bootloader一般特指在操作系统下:
在操作系统运行之前运行的一段或多段程序
初始化硬件设备、建立系统的内存空间映射图,将系统的软件硬件环境带到一个合适的状态,为调用操作系统内核准备好正确的环境
把操作系统内核映像加载到RAM中,并将系统控制权交给它
Bootloader的种类非常的繁多
针对不同的cpu架构对bootloader的要求不同
针对X86上有LILO、GRUB、ntloader等
针对ARM架构的有u-boot、vivi、armboot等
针对ppc架构的有ppcboot等
针对不同的操作系统也有所不同:
比如专门用来启动linux的vivi
启动Wince的eboot、启动eCose的reboot,可以启动多种操作系统的u-boot等
下表将一些常用bootloader做简单对比介绍
Bootloader Monitor 描述 X86 ARM
LILO 否 Linux磁盘引导程序 是 否
GRUB 否 GNU的LILO替代程序 是 否
Loadlin 否 从DOS引导Linux 是 否
ntldr 否 从x86上引导windowsNT系列 是 否
armboot 是 专门为arm架构设计的boot 否 是
ppcboot 是 专门设计用来引导基于ppc架构操作系统的loader,u-boot前身 否 是
U-Boot 是 通用引导程序,支持多种CPU架构、多种操作系统引导 是 是
RedBoot 是 基于eCos的引导程序 是 是
vivi 是 Mizi公司针对SAMSUNG的ARM CPU设计的引导程序 否 是
下面我们以ntldr和grub为例讲解一下在PC机上windowsXP和linux是如何引导起来的
无论windows还是linux都是采用多阶段引导方式从大的角度分为:硬件+软件
硬件部分由固化在PC主板上的BIOS完成
windows与linux完全一致
软件部分由安装在硬盘的bootloader完成
linux常用LILO、GRUB
windows有引导2000\XP\2003系列的ntloader
引导vista、win7系列的Bootmgr等
首先介绍一下BIOS的相关知识:
BIOS是固化在计算机主板上一个芯片,里面固化着我们常说的bios程序
bios在cpu开机启动时首先被启动
bios读取CMOS中的配置参数,完成硬件检测(内存、CPU、显卡、鼠标等)、中断初始化等工作
cmos也是主板上的一块芯片,保存了bios的一些配置及硬件检测信息,采用ram结构,掉电丢失需要电池供电
最终bios根据启动选项读取硬盘MBR分区(0柱面0磁头1扇区)上的引导程序,完成第二阶段引导过程
Bios程序一般固化在EEROM或FLASH中,掉电不丢失数据,可以使用特定的软件进行升级、更新
系统开机时可以通过特定按键(del、F2等)启动“系统设置程序”(我们常见的蓝色屏幕)进行基本功能设置
设置完成后结果会保存在cmos中,cmos采用ram电路构成,由主板上的一个电池供电,保证信息不丢失
目前市面上较流行的主板BIOS主要有 Award BIOS、AMI BIOS、Phoenix BIOS三种类型
绝大多数台式机都采用的Award BIOS,笔记本上一半采用Phoenix BIOS较多
Bios最后一阶段会读取硬盘0柱面0磁头1扇区上程序完成后续初始化,此分区称为MBR分区,由三部分组成:共512字节
主引导程序:446个字节
负责从活动分区中装载、运行系统引导程序
硬盘分区表(DPT):64个字节
记录了硬盘中分区的数量以及每一分区的大小
每个分区占16个字节,最多只能有4个主分区
第三部分是magic number,占2个字节,固定为55AA
MBR主引导代码扫描硬盘分区表,找到一个可引导分区
(活动分区)
将该分区的第一个扇区读到内存,并将控制转移给它
此分区被称为“引导分区”,引导分区的第一个扇区称为“引导扇区”,引导扇区上运行着软件引导的第二部分(OBR)
以windowsNT系列为例,假如我们在C盘下安装了windows xp,系统安装时会自动在MBR分区、引导分区安装相应的软件程序
MBR主引导程序找到了活动分区C盘
然后执行C盘(0柱面1磁头1扇区)上的引导程序OBR(操作系统引导扇区)
OBR找到c盘目录下的NTLDR引导程序并加载,NTLDR读取BOOT.ini文件显示引导项
最后加载系统内核
Linux下常见的引导程序有两种,LILO、GRUB
LILO是历史比较悠久、功能比较强大的一款bootloader,在linux刚开始时就已经出现
GNU GRUB(简称“GRUB”)是一个来自GNU项目的多操作系统启动程序,逐渐已经代替了的LILO的地位
GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统
不但可以引导linux还可以windows
GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数
GRUB引导linux与windows的引导过程有些类似
在MBR分区安装主引导程序(grub第一阶段代码)
(会覆盖windows分区写入的信息)
在引导分区安装grub第二阶段代码
此阶段代码会寻找配置文件(menu.lst),根据menu.lst的列表启动操作系统
(windows、linux均可以引导)
如果menu.lst损坏或按下了特定按键,可以进入一个命令行接口,由用户手动操作引导操作系统
在专用的嵌入式系统上运行GNU/Linux系统已经变得越来越流行
一个嵌入式Linux系统从软件的角度看通常可以分为四个层次:
引导加载程序:
BootLoader(一般仅由软件部分组成)
Linux内核:
特定于嵌入式系统的定制内核以及内核启动参数
文件系统:
根文件系统和建立于Flash内存设备之上文件系统
用户应用程序:
特定于用户的应用程序
嵌入式领域通常Bootloader对硬件的依赖性非常强,建立一个通用的Bootloader几乎是不可能的
Bootloader依赖于CPU体系结构,不同的CPU架构,如arm、x86、mips等要求的启动配置不同
基于同一架构的不同芯片,例如同样基于ARM920T的S3C2410、S3C2440,要求配置不同
基于同一芯片设计的不同开发板,由于外设资源的不同,同样需要修改配置
Bootloader还依赖于内核的具体格式与类型:
如压缩、非压缩内核,nand或nor启动的内核等
因此bootloader的移植与修改工作就是围绕以上几点进行的
从最终用户的角度看,Bootloader的作用就是加载操作系统
对于开发人员来说,Bootloader包含两种不同的操作模式:启动加载模式和下载模式
启动加载(Boot loading)模式:
BootLoader从目标机上某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入
在嵌入式产品发布时,BootLoader工作在此模式
下载(Down loading)模式:
开发人员可以使用各种命令,通过串口连接或网络连接等通信手段从主机下载文件。比如:下载应用程序、数据文件、内核映像等
BootLoader的这种模式通常在系统更新时使用
Bootloader的安装地址
嵌入式系统一般采用统一编址方式管理数据/程序区,同时使用三总线进行寻址
系统加电复位后,所有的CPU通常都从某个CPU制造商预先安排的地址上取指令,如基于ARM核的CPU通常从0x00000000取它的第一条指令
嵌入式系统通常都有某种类型的固态存储设备(如ROM或FLASH)被映射到这个预先安排的地址上
Bootloader被烧写到其中,所以在系统加电后,CPU将首先执行Bootloader程序
Bootloader启动方式:
基于以上原理,bootloader提供了多种启动方式:NOR启动、nand启动、SD卡启动、网络启动、DRAM启动等
NOR FLASH启动:
NOR FLASH是intel公司推出的一款总线型FLASH存储器
NOR FLASH一般安装在总线0x000000―0xXX地址范围内,并且将bootloader烧写在NOR的0x00000000地址上
当系统复位时就可以执行NORFLASH上的bootloader、内核、根文件
有些芯片有内置的FLASH芯片,如atmel系列
有些芯片需要外置FLASH芯片,如三星系列等
NOR FLASH可以片上执行应用程序,但是速度、大小都受到限制,一般在一些简单系统中比较多
很多bootloader采用NOR FLASH中存储、ram中运行的方式引导系统,即将bootloader烧写在NOR FLASH中,最终还要读入ram中运行
NAND FLASH启动:
NAND是由东芝率先推出,得到各大厂商广泛支持的一种大容量FLASH,在U盘、SD卡等数据存储中大量应用
NAND FLASH与NOR FLASH不同,采用的非总线接口,不能通过总线寻址,不支持片上执行,因此需要进行一步中转读入SDRAM才可以运行
SD卡启动
FLASH必须固化在板子上,烧写、编程需要专门的工具,因此在一些最新的CPU中,如三星的6410提供了一种新型的启动方式,将bootloader烧入SD中,进行设备的引导与启动
同NAND启动类似,SD卡也不是采用总线结构,也需要进行过渡启动
我们以S3C2440及s3c6410为例讲解以上启动过程
S3C2440采用总线结构管理片上外设及内存,存储器管理器提供访问外部存储器的所有控制信号
27位地址信号、32位数据信号、8个片选信号、以及读/写控制信号等
总共有8个存储器bank(bank0―bank7)共1GB
s3c2440支持两种启动方式:
NOR FLASH启动
代码直接写入NOR FLASH,运行时直接在NOR上运行
NAND FLASH启动方式
代码烧到NAND FLASH中,借助片内4K的sram,将代码由NAND FLASH烤到SDRAM中,在SDRAM中运行
Bootloader的启动过程启动过程可以分为单阶段(Single Stage)、多阶段(Multi-Stage)两种:
通常多阶段的Bootloader能提供更为复杂的功能,以及更好的可移植性
从固态存储设备上启动的Bootloader大多都是两阶段的启动过程
第一阶段使用汇编来实现,它完成一些依赖于 CPU体系结构的初始化,并调用第二阶段的代码
第二阶段则通常使用C语言来实现,完成与体系结构无关的功能,这样可以实现更复杂的功能,而且代码会有更好的可读性和可移植性
Bootloader第一阶段的功能:
硬件设备初始化
屏蔽所有的中断
设置 CPU 的速度和时钟频率
mem初始化:
包括正确地设置系统的内存控制器的功能寄存器以及各内存库控制寄存器等
初始化LED或串口:
通过GPIO来驱动LED或串口,用来做调试信息输出
拷贝Bootloader的第二阶段代码到RAM空间中
简单NAND FLASH读取驱动
设置好栈,为第二阶段
跳转到第二阶段代码的C入口点
Bootloader第二阶段的功能:
初始化本阶段要使用到的硬件设备
MTD设备驱动初始化
uart、电源、时钟初始化
网卡、USB设备、SD卡等设备初始化
初始化软件环境:
堆空间的初始化
Bootloader私有数据初始化,例如vivi的mtd分区表信息、串口传输协议,u-boot环境变量等
提供一个命令行模式:进行下载更新等工作
将内核映像从Flash上读到RAM空间中
调用内核
压缩内核、非压缩内核
在开发过程中Bootloader各功能的实现通常需要人的介入,因此bootloader需要提供一定的通信方式进行信息与数据的交换
Bootloader与主机进行信息交互:
通常会通过串口来进行信息的交互,例如:输出打印信息到串口,从串口读取用户控制字符等
Bootloader与主机进行数据交互
最基本会通过串口连接,文件传输协议通常是xmodem/ymodem/zmodem/kermit协议中的一种
很多bootloader会提供网络、usb、sd发等硬件设备进行大量数据的传输
网络一般基于dhcp、tftp、nfs等协议,sd卡一般基于fat文件系统等