1、Bootloader介绍
Boot 概念
- 启动引导,自举程序

- 由于boot设计比较偏底层,所以根据cpu架构和OS类型可能有所不同
- uboot是对cpu架构和os类型支持比较多的一种开源引导程序
Bootloader中文解释为:启动引导程序
Bootloader的种类繁多,归纳如下:


2、s5p6818启动过程

S5P6818的启动过程
- 芯片选择启动irom设备
- iROM选择启动下一阶段引导程序所在设备(p5)
- iROM启动UBOOT第一阶段BL1
- UBOOT第一阶段启动UBOOT第二阶段BL2
- UBOOT第二阶段启动内核
s5p6818启动流程
- 芯片最先是从iRom启动,叫BL0
- iROM选择启动下一阶段引导程序BL1
- 单阶段启动:如果BL1可以完成内核加载,这就是单阶段启动
- 多阶段启动:启动加载内核的工作由BL2之后的程序完成,这就是多阶段启动。
TPS: BL1的内存不能超过56K,因为UBOOT有的达到400K, 所以会分两个阶段启动BL2。增加DRAM的内存,DRAM可达1G.

问:为什么BL1不直接加载到DRAM里面?
- SRAM比DDR更快
- DDR需要初始化,而SRAM不需要
BL1启动Bootloader第二阶段BL2,BL2启动内核,内核加载根文件系统。
引导传参:引导程序最终没有了,达成一个共识,引导程序怎么给内存传参。

- 所传数据结构必须约定一致,不一致即便传过去,内核解析不出来。
- 引导程序与内核之间必须约定一个参数存放的地址base+0x100(一般可以修改)
- 数据格式约定一致,比如用户传递给内核的参数:


3、u-boot介绍
3.1、u-boot介绍及配置
u-boot介绍
- 源码获取:
- 官网下载
- 从芯片原厂获取配套的BSP
- 拷贝"资料/sourcecode/u-boot.xxxx.tar.bz2"到虚拟机
- 解压源码:tar xvf xxxxx
- 拷贝内核镜像生成工具(编译uImage时用到):sudo cp tools/mkImage /bin/
- u-boot最初是由PPCBoot发展而来
- 已经成为当前主流引导程序
- 官方引导程序由于与硬件平台差异,所以并不能下载直接运行(需要经过调试和修改及移植)
- 编译uboot
API:只是一些接口不一定用到
arch:非常重要,每个目录代表一个架构
board:代表芯片,平台,基于arm的芯片和平台特别多
commom:绝大部分cmd开头,每个cmd代表一个命令,例如:loadb
disk:磁盘
doc:针对u-boot开源软件的介绍
drivers:驱动,这些驱动绝大部分第二阶段的代码,第一阶段不需要那么多驱动,只是完成DDR的初始化和拷贝。
dts:设备树,现在内核把设备树直接跟内核放在和镜像打成一个包,下载直接下载到指定的地址。
fs:文件系统,uboot支持很多文件系统,ext4ls 直接通过命令查看很多文件内容 例如:ext4ls mmc 0:1
include:头文件的集中营,绝大部分头文件汇总到这里
lib:很多的库,不能使用带有系统调用的C库,因为很多人写习惯可以自己实现跟C类似的库。
licenses:走到GPL,BSD,LGPI开源公共协议
net:不是网卡驱动,走的协议相关的,除了支持串口USB,也支持网络下载
post:自检,检查系统是否正常的相关代码
prototype: 兼容性相关的 s5p4418 和 s5p6818能否引导程序在这上面跑起来。
scripts:脚本,完成系统的配置,编译引导程序之前,需要配置,生成目标平台。
tools:处理制作镜像用到的工具,内核生成制作镜像也会用到,例如:mkimage。



配置编译uboot
- 进入uboot源码目录:cd u-boot-2014.07
- 清除编译痕迹(只是第一次做):make distclean,不需要每次都做,每次要好几分钟
- 编译器配置成目标平台:make x6818_config
- 编译源码:make
- 在源码根目录下会生成镜像:ubootpak.bin


镜像烧写
- 找到官方提供的标准镜像
- 开发板开机 进uboot命令行模式

- 执行下载命令:fastboot
- 插入miniUSB下载线
- 如果打开了虚拟机,要确认USB链接到的是物理主机
- 未安装驱动效果,和安装驱动效果如下图右边。


- 安装驱动,双击打开fastboot 驱动。

- 安装完驱动后重新插拔USB线
- 下载:通过fastboot.exe
- 修改下载脚本文件:REM表示注释一行
- 下载uboot:fastboot flash ubootpark ../linux_image/ubootpak.bin
- 下载内核:fastboot flah boot ../linux_image/boot.img
- 下载根文件系统:flash gtkfs ../linux_image/gtkfa.img

- 双击:"sp_linux_image_down.bat",下载完成,开发板提示:FLASH:ubootpark - DONE
- 下载完成后,Ctrl+C退回命令行,或直接重启开发板即可


配置编译原理分析

- 用户执行make x6818_config,其实是调用了一个脚本:
bash
/u-boot-2014.07/mkconfig -A x6818 #$(MKCONFIG) -A $(@:_config=)

- mkconfig脚本从u-boot-2014.07/boards.cfg中找到x6818所在行,并将该所有信息设置成mkconfig脚本的新的命令行参数:


- mkconfig将定义的变量值修改成命令行获取到的参数,存入include/config.mk文件中:


- mkconfig创建include/config.h 并写入一个定制的头文件及目标平台相关信息


- include/config.h默认是被所有源码所包含的不变的头文件
- 所以只要包含了include/config.h文件的源码,就会间接包含x6818.h
- 包含方法:#include <configs/${CONFIG_NAME}.h>
- x6818.h中的裁剪配置宏均以CONFIG_开头
- 这个宏会被脚本解析成变量定义在include/autoconf.mk
- include/autoconf.mk最后又会被Makefile所包含,并决定哪些文件需要编译。
uboot镜像产生
- 链接脚本:arch/arm/cpu/slsiap/u-boot.lds
- 查看更加详细的编译过程: make V=1
bash
arm-linux-ld -pie --gc-sections -Bstatic -Ttext 0x43C0000 ......
- 如果命令行和链接脚本同时指定了同一个段的链接地址,命令行的优先有效。
- 裁剪镜像去格式处理:

- uboot源码生成的可执行程序是:u-boot.bin
- 镜像打包:镜像组成:nsih+2ndboot+u-boot.bin=ubootpak.bin


3.2、控制命令



设置启动命令行参数:setenv bootargs

boot启动系统时,自动加载的环境变量;setenv bootcmd ext4load mmc ..


下载镜像命令,至少三种:
- loadb 0x48000000 (通过串口下载文件到内存中)
- fastboot (通过usb下载文件到磁盘中)
- tftp 0x48000000(通过网络下载文件到内中)
启动命令:
- boot(从外存启动)
- bootm 0x48000000(从指定内存启动系统)
- 从上位机启动(主要用于调试内核)
- fastboot flash app uImage(先从PC端下载镜像到内存0x48000000)
- bootm ox48000000(从指定内存启动系统)

3.3、命令实现

uboot添加一条自定义命令:
- 在common/文件夹下建立cmd_helloworld.c
- 还可以在include/configs/行818.h中增加一项宏定义:
cpp
#define CONFIG_CMD_HELLOWORLD 1
- 包含必备头文件
cpp
#include <common.h>
#include <command.h>
- 调用命令定义宏:

- 完成命令回调函数

- 在common/Makefile中增加一项


3.4、启动过程


-
通过ext4load或fastboot下载一个内核uImage到内存0x48000000
-
通过bootm 0x48000000启动内核
-
先找到cmd_bootm.c文件
-
找到bootm命令回调函数
-
具体调用关系如下:
cppdo_bootm() -> do_bootm_states() -> bootm_os_get_boot_func() -> boot_os[] -> do_bootm_linux() -> boot_jump_linux() -> kernel_entry(0,machid,r2);//启动内核

