Bootloader
Bootloader中文解释为:启动引导程序
1、Bootloader的种类归纳:
分类标准 | 说明 |
---|---|
针对不同 CPU架构 | 1、针对X86架构的有LILO、GRUB、ntldr等 2、针对ARM架构的有vivi、armboot等 3、针对PPC架构的有ppcboot等 4、可以支持多种架构的u-boot等 |
针对不同 操作系统 | 1、专门用来启动Linux系统的vivi 2、专门用来启动WinCE系统的eboot 3、基于eCos系统的引导程序redboot 4、可以启动多种操作系统的u-boot等 |
一些常用Bootloader做简单对比:
Bootloader | Monitor | 描述 | X86 | ARM |
---|---|---|---|---|
LILO | 否 | Linux磁盘引导程序 | 是 | 否 |
GRUB | 否 | GNU的LILO替代程序 | 是 | 否 |
ntldr | 否 | x86上引导windowsNT系列 | 是 | 否 |
armboot | 是 | 专门为arm架构设计的boot | 否 | 是 |
ppcboot | 是 | 引导ppc架构操作系统 | 否 | 是 |
vivi | 是 | 韩国Mizi公司针对三星ARM架构CPU设计引导程序 | 否 | 是 |
redboot | 是 | 基于eCos的引导程序 | 是 | 是 |
u-boot | 是 | 通用引导程序,支持多种CPU架构、多种 操作系统 | 是 | 是 |
2、arm系统的启动流程
以s5p6818开发板为例
- 芯片选择启动iROM设备
- iROM选择启动下一阶段引导程序所在设备(p95)
- iROM启动UBOOT第一阶段BL1
- UBOOT第一阶段启动UBOOT第二阶段BL2
- UBOOT第二阶段启动内核
s5p6818支持多种启动方式,但常见的BL0一般 都来至固化在片内的Internal ROM,以SD卡为例:
- 从上图可以看出,我们的user bootcode是从SD卡等外部设备 上加载的,这样iROM就会先找到能够启动的外部设备 SD卡,并从核心板上的EMMC上搬运user bootcode,而 搬运的这段代码就是我们常说的Bootloader。
- ubootpak.bin主要就是一个包含了2ndboot和 uboot.bin的完整Bootloader。
- 嵌入式Bootloader的启动过程可以分为以下两种: 单阶段(Single-Stage)、多阶段(Multi-Stage)
- 通常多阶段的Bootloader能够提供更复杂的功能,及 更好的可读性和移植性。从外部存储设备上启动的 Bootloader大多是两阶段的启动过程,其功能如下:
阶段 | 功能特点 |
---|---|
第一阶段 | 通常用汇编实现,完成一些依赖于CPU体系结构的初 始化,并调用 |
第二阶段 | 代码 第二阶段 通常用C语言实现,完成体系结构之外的功能 |
- 以下是s5p6818启动流程:
和上图一样此图更详细
内核传参过程:
引导程序(Bootloader)将要传递给系统的信息给内核后就可以释放了,系统启动后就不需要Bootloader了。
- 传递给内核的参数由多个结构体组成
- 各结构体放在一段连续的内存空间,起始地址为0x4000_0100(uboot中bi_boot_params成员记录)
- 每一个结构体代表一条信息,并首尾相连
- 内核引导起来以后,将从指定内存按照同样的数据结构将数据取出
参数数据结构及存储结构如下:
参数数据结构:
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_videotext videotext;
struct tag_ramdisk ramdisk;
struct tag_initrd initrd;
struct tag_serialnr serialnr;
struct tag_revision revision;
struct tag_videolfb videolfb;
struct tag_cmdline cmdline;
struct tag_acorn acorn;
struct tag_memclk memclk;
} u;
};
struct tag_header {
u32 size;
u32 tag;
};
struct tag_mem32 {
u32 size;
u32 start;
/*physical start address*/
};
参数存储结构:
3、u-boot的介绍
- u-boot最初是由PPCBoot发展而来的,
- 目前已成为Armboot和PPCboot的替代品
特点
- 主要支持操作系统:Linux、NetBSD、 VxWorks、QNX、RTEMS、ARTOS、LynxOS等
- 主要支持处理器架构:PowerPC、MIPS、x86、ARM、NIOS、XScale等
u-boot目前最新版本是:https://gitlab.denx.de/u-boot/u-boot
u-boot 是不能下载下来直接编译使用的,要经过厂家适配,或者你就是做这种工作的
我有一个关于u-boot移植的文档 已经上传到csdn 需要的可以下载下来看一下。
u-boot文件介绍:
- arch: 体系结构相关,按架构进行分类,如当前架构arch\arm\cpu\slsiap,第一阶段启动代码start.S就在这里,官方源码会包含多种架构和cpu,我们裁剪掉了(整个uboot的C语言起始函数board_init_r也在arch\arm\lib\board.c中)
- board: 开发板相关,根据厂商进行分类,本平台裁剪成board\s5p6818\x6818,有的版本会包含初级初始化内容:lowlevel_init.S
- common: 各种命令的实现,通常一个命令就是一个C文件
- include: 各种头文件和开发板配置文件,如include\configs\x6818.h
- api:用于演示测试用的代码,通常不参与工程编译
- disk:硬盘接口程序,disk驱动分区处理代码,嵌入式不常用
- doc:开发使用文档,主要介绍不同平台的配置编译方法
- drivers: 设备驱动,如:网卡、SD卡、USB等
- examples:一些独立运行的实例,通常不参与工程编译
- fs: 所能支持的文件系统,如fat、ubifs等,用于访问带文件系统的存储设备
- lib: 用于存放库和其他主要支持文件程序,中断处理、启动相关等
- net: 独立于网卡驱动的网络协议,如于下载传输的TFTP协议,网络文件系统中的NFS协议等
- post: 上电自检程序,与旧的PPC相关,当前平台下未被编译到工程
- prototype:参与6818开发的三星协作厂商的一些code在这里
- scripts用于生成指定的config.mk配置文件,以及一些检查工具
- tools: 工具软件,如mkimage用于制作内核镜像,scripts用于生成指定的config.mk配置文件,mk6818用于生成6818专用uboot镜像,还有支持GDB的调试工具等
4、u-boot的编译
- 清除编译结果
make distclean
- 配置对应平台 如X6818
make x6818_config
Makefile 会构建编译结构,如:架构、cpu、开发板、厂商、芯片、目录等,为下一步真正编译链接做准备。
- 编译
make
- 生成ubootpak.bin 在uboot根目录 就可以食用了
- 使用方法开袋即食、蒸泡煮炸也可以 :fastboot刷入,通过网络(TFTP+DHCP_Server/tftpd32.exe)也行等等
编译内核时需要一下操作:
编译完成uboot在tools下面会生成一个mkimage的工具,请将该工具拷贝到/bin目录下,这样才能使用编译Linux内核时可以生成uboot可以识别的内核镜像
5、u-boot的启动过程
u-boot阶段入口代码位置为:
arch/arm/cpu/slsiap/start.S
arch/arm/lib/board.c
boot为标准的两阶段启动bootloader
第一阶段为汇编代码(2ndboot),主要为初始化cpu硬件体系结构
1、禁用看门狗、初始化系统时钟
2、设置异常向量表(用到中断的情况下设置)
3、动态内存控制器初始化配置
4、初始化调试指示灯(可选)
5、初始化UART,用于开发调试(可选)
6、从NAND、NOR或SD卡中复制代码到DRAM
7、跳转并进入Bootloader第二阶段
第二阶段为c程序代码(u-boot.bin),主要提供多种复杂命令并引导操作系统
1、汇编阶段核心初始化
2、初始化GPIO
3、初始化MMC等存储设备
4、MMU初始化
5、各类通信设备相关驱动初始化
6、环境变量和参数的加载及初始化
7、倒计时监听串口(进入命令模式或启动内核)
8、启动内核(拷贝内核镜像并跳转到内核入口)