5. Uboot的编译与修改¶
5.1. 下载安装编译镜像系统¶
推荐使用平台:Ubuntu 18.04.5 LTS 版本和Ubuntu 20.04 LTS 版本
可以使用我们提供的虚拟机镜像 https://doc.embedfire.com/products/link/zh/latest/linux/ebf_i.mx6ull.html#id4
也可以自己下载ubuntu 18.04.5 LTS官方镜像搭建
https://mirrors.aliyun.com/ubuntu-releases/bionic/ubuntu-18.04.5-desktop-amd64.iso
5.2. 安装编译工具和依赖¶
使用apt工具能快速安装好我们需要的工具和依赖
1 | sudo apt install make git gcc-arm-none-eabi gcc bison flex libssl-dev dpkg-dev lzop libncurses5-dev
|
5.3. 获取U-boot¶
5.3.1. 下载源代码¶
uboot的源代码有多种方式可下载,但各自又有不同,野火uboot是根据NXP官方提供的uboot进行板卡的修改与功能的添加,NXP官方的uboot是以uboot官方版本进行芯片的适配。
官方uboot GitHub:
https://github.com/u-boot/u-boot
野火提供的uboot下载链接:
https://gitee.com/Embedfire/ebf_linux_uboot
或者
https://github.com/Embedfire/ebf_linux_uboot
或者
SDK中包含Uboot,可以使用SDK中的Uboot
注意:本教程以野火提供的uboot为分析样本
以下介绍如何单独获取野火uboot。
5.3.2. 查看切换分支¶
通常一个uboot仓库往往维护着不同分支的uboot,进入仓库目录下可通过命令查看及切换uboot分支, 例如在2023-07-23的镜像中使用的uboot分支为 ebf_v2018.11_star 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 git clone https://gitee.com/Embedfire/ebf_linux_uboot.git #查看uboot分支 git branch -a #打印消息如下,默认为master主分支。 * master remotes/origin/HEAD -> origin/master remotes/origin/ebf_v2017_09_rk3328 remotes/origin/ebf_v2018.11_star remotes/origin/ebf_v2020_10_imx remotes/origin/imx_v2019.04_ls1043ardb remotes/origin/imx_v2020.04_5.4.47_2.2.0 remotes/origin/master #切换ebf_v2018.11_star分支 git checkout ebf_v2018.11_star #打印消息如下 分支 'ebf_v2018.11_star' 设置为跟踪来自 'origin' 的远程分支 'ebf_v2018.11_star'。 切换到一个新分支 'ebf_v2018.11_star' #重新查看当前分支 qinghui@ebf-dev:~/embedfire/ebf_linux_uboot$ git branch * ebf_v2018.11_star master
也可以在下载时指定分支,如下所示
1 2 3 4 5 #使用-b参数指定ebf_v2018.11_star分支 git clone -b ebf_v2018.11_star https://gitee.com/Embedfire/ebf_linux_uboot #或者 git clone -b ebf_v2018.11_star https://github.com/Embedfire/ebf_linux_uboot
5.4. U-boot工程结构分析¶
学习一个软件,尤其是开源软件,首先应该从分析软件的工程结构开始。一个好的软件有良好的工程结构,对于读者学习和理解软件的架构以及工作流程都有很好的帮助。
uboot的源代码布局和我们后面讲的Linux类似,使用了按照模块划分的结构,并且充分考虑了体系结构和跨平台问题,其源代码树结构请参考下图
目录/文件 |
说明 |
目录/文件 |
说明 |
---|---|---|---|
api |
通用的API函数相关目录 |
arch |
与芯片架构相关目录 |
board |
板级相关信息目录 |
cmd |
uboot命令相关目录 |
common |
通用代码目录 |
configs |
boot配置文件目录 |
disk |
磁盘相关内容目录 |
doc |
说明文档 |
drivers |
驱动代码相关目录 |
dtoverlay |
|
dts |
设备树相关目录 |
env |
uboot环境相关 |
examples |
示例代码目录 |
fs |
文件系统相关目录 |
include |
头文件相关目录 |
lib |
lib库文件目录 |
Licenses |
许可证相关目录 |
net |
网络相关代码目录 |
post |
上电自检相关目录 |
scripts |
相关脚本目录 |
test |
测试代码目录 |
tools |
uboot构建工具相关目录 |
Kconfig |
图形配置界面相关文件 |
Makefile |
Makefile文件 |
5.5. U-boot编译¶
在uboot源码顶层目录执行以下命令:
1 2 3 4 5 6 | #清除配置和编译产物
make distclean
#加载板级配置文件,具体的板级配置文件在uboot根目录下的configs目录下
make ARCH=arm CROSS_COMPILE=arm-none-eabi- stm32mp15_trusted_defconfig
#设置编译架构为arm 编译工具链为arm-none-eabi-,使用8线程,指定使用的设备树,然后开始编译
make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j8 DEVICE_TREE=stm32mp157a-star
|
如果使用SDK,可以在SDK顶层目录执行以下命令:
1 2 | #使用SDK单独编译uboot
make uboot
|
5.6. 编译产物分析¶
编译成功后,将打印以下信息。
u-boot:初步链接后得到的uboot文件
u-boot-nodtb.bin:是在u-boot的基础上,经过objcopy去除符号表信息之后的可执行程序
u-boot.dtb:uboot的设备树,是由arm-none-eabi-gcc和dtc编译出来的
u-boot.bin:是在u-boot-nodtb.bin后追加了u-boot.dtb形成的
u-boot.stm32:是u-boot.bin 添加了3KB头部信息和尾部信息(结尾添加了1298字节的00,00实际没什么作用)组成的镜像
编译生成的u-boot.stm32文件就是我们想要文件。
5.7. U-boot烧录¶
如果是SD镜像,请编译完整镜像然后烧录到SD卡进行启动。
如果是usb镜像,替换usb烧录包stm32mp157_release_xxx/stm32mp157-cubeprogrammer/目录下的u-boot.stm32,然后烧录到emmc中进行启动。
5.8. U-boot修改¶
一般来说,要适配一块新的板卡,在U-boot中主要设计三部分的修改和添加,分别是board目录下涉及板卡初始化的部分、 configs目录下对应板卡的配置文件、arch目录下与板级外设相关的文件。
野火仅在U-boot中添加了设备树插件功能的实现。并使用boot_scripts方式进行启动引导,用于实现extboot分区的启动,前面介绍“U-boot启动内核过程”章节中,已经讲解过了。
5.8.1. U-boot配置文件¶
在野火mp157板卡上使用的具体文件是ebf_linux_uboot/configs/stm32mp15_trusted_defconfig, 在SDK中ebf-image-builder/configs/boards/ebf_stm_mp157_star.conf文件中UBOOT_MMC_DEFCONFIG变量也定义了使用该配置文件。
5.8.2. U-boot配置修改¶
首先我们要来到U-boot源码顶层目录下,然后执行以下操作:
1 2 3 4 5 | #应用配置文件
make stm32mp15_trusted_defconfig
#使用menuconfig来管理修改配置文件
make menuconfig
|
修改完成之后按ESC按键退出,并保存,然后执行以下代码覆盖原来的配置文件。
1 2 3 4 5 | # 保存defconfig文件
make savedefconfig
# 覆盖原来的配置文件
cp defconfig configs/stm32mp15_trusted_defconfig
|
5.9. U-boot设备树文件¶
设备树文件是板级设备的描述文件,系统通过设备树文件得知板卡上有哪些外设,从而加载相应的驱动使外设正常工作。
原生的U-Boot只支持使用U-Boot自己的DTB,与内核的设备树不同,主要目的是为了兼容外设板级差异,如:power、clock、display 等,差别如下:
U-Boot DTB:负责初始化存储、打印串口等设备的描述
Kernel DTB:负责初始化存储、打印串口以及驱动其他外设的描述
U-Boot初始化时先用U-Boot DTB完成存储、打印串口初始化, 然后从存储上加载Kernel DTB并转而使用这份DTB继续初始化其余外设。
开发者一般不需要修改 U-Boot DTB(除非更换打印串口),mp157使用的defconfig都已启用kernel DTB机制。 所以通常对于外设的DTS修改,用户应该修改kernel DTB。
此处仅说明使用的u-boot-dtb文件,不做过多说明。
野火mp157板卡uboot使用的dtb为:ebf_linux_uboot/arch/arm/dts/stm32mp157a-star.dts
5.10. 参考资料¶
ST原厂U-boot添加了很多自定义的功能,但其主体还是基于官方U-boot的,所以关于U-boot的操作都是基本相同的,我们可以参考以下wiki。
官方uboot下载链接: http://www.denx.de/wiki/uboot/WebHome
官方uboot GitHub: https://github.com/uboot/uboot
uboot wiki: http://www.denx.de/wiki/uboot/WebHome