1. U-Boot简介
Das U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括 PPC、ARM、AVR32、MIPS、x86、68k、NIOS 与 MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。具有十大黄金法则:小巧、快速、简单、可移植、可配置、可调试、易用、可维护、优雅、开源。
所以本文试图从其设计的角度进行分析这些黄金法则,以期自己在软件工程思想的角度能有所获,同时也将自己笔记分享(Keep it open),方便与人交流,以期获得更为深入的理解与体悟。
废话说了蛮多,Let‘s go:
2. U-Boot 文件夹拓扑结构
基于 u-boot-u-boot-2016.09.y 的文件夹结构如下:
arch 体系架构依赖
api 机器架构独立 API,外部调用接口
实现 I/O,如标准化输入输出,显示,网络 API、存储 API 等,为 cmd 提供支持
board 板级依赖实现。
cmd shell 命令实现
common 与架构无关的杂项独立功能
configs 板级配置文件
disk 磁盘分区实现
doc 文档
drivers 通用设备驱动程序
examples 应用示例代码
fs 文件系统实现(cramfs,ext2,jffs 等)
include 头文件
lib 通用库
license
net 网络通讯实现
post 上电自检是实现
scripts 构建脚本以及 Makefile
tests 各种单元测试
tools 生成 S-Record 或 U-Boot 映像的工具等。
3. 项目管理
U-Boot 采用 Kconfig 进行项目管理,实现可裁剪可配置,新版 U-Boot 已支持 make menuconfig 功能,实现了易用的设计目标。其配置界面与内核一样。
4. 模块层次架构分析
arch 实现了不同体系结构的 CPU,指令集、设备树底层抽象,利用链接绑定实现了符号入口相对位置保持不变,故才能实现将内核镜像拷贝到内存然后进行引导的功能。lib 实现了初始化 C 运行时环境(栈 / 堆指针等的初始化),dts 实现了设备树的底层体系架构依赖的具体抽象剥离。
machine ,由于同样的内核相同,各家芯片外设都不尽相同,所以将各自个性实现剥离实现于此,这主要体系在 ARM 体系的芯片,由于 ARM 公司售卖 IP,各家芯片厂商在内核的基础上延伸出各自不同的芯片,所以需要将差异性剥离实现。
board, 实现了产业链下游,设备厂商的差异性,对于产品设计而言,需要将各自在 boot 阶段需要严格初始化的实现放在这里,比如 IO 口的初始化,产品中大部分 IO 口必须显式设置其初始状态。
driver 这里实现了 boot 阶段必要的设备驱动,如网口、显示等。
dts 实现了设备树
api 实现了基本的 IO,如标准化输入输出,显示,网络 API、存储 API 等,为 cmd 提供支持。
disk 实现了轻量级磁盘管理
fs 文件系统实现(cramfs,ext2,jffs 等)
lib 通用库,比如 CRC 算法,加密算法,压缩算法,字符串操作等
cmd 实现了 U-Boot 命令集。
net 实现网络协议层
cmd shell 命令集,调用下层实现用户接口功能,如下载,引导,存储环境变量,打印信息等。
common 是 U-Boot 主体,如系统停留在 U-Boot 阶段,CPU 始终在执行一个死循环,run_main_loop。
5. 基于 armv8 无 SPL 的启动流程分析
5.1 汇编程序执行阶段
5.2 C 执行阶段
board_init_r 的调用,进入 C 执行阶段,如下:
至此,粗浅的将 U-Boot 的架构设计分析了一下。还有很多设计细节有待深挖。文中仅代表个人理解观点。