【树莓派4b的uboot编译移植】
树莓派4b的uboot编译移植
引言
0.1、什么是uboot
- OS跑起来前,需要的一段引导程序
- 负责部署整个计算机系统,引导操作系统内核启动并给内核传参
- 提供一个命令行界面供人操作
- 是一个开源项目,uboot就是universal bootloader(通用的启动代码)
- 命令行用的行缓存,linux终端设计有3种缓冲机制:无缓冲、行缓冲、全缓冲
0.2、uboot命令
- printenv/print 打印出系统中所有的环境变量
- setenv/set 设置环境变量
set 环境变量 值 - saveenv/save 保存环境变量到flash
- ping 网络测试指令
一、原理图
1.1、树莓派4b引脚图
树莓派4B Raspberry Pi 4代B 8G开发板
1.2、串口接线
USB转串口接在TXD和RXD,交叉接线,也就是GPIO14和GPIO15
二、uboot 编译
2.1、uboot源码下载
官网下载地址:
GitHub - u-boot/u-boot: "Das U-Boot" Source Tree 国外
u-boot: UBoot 是由开源项目PPCBoot发展起来的,ARMboot并入了PPCBoot,和其他一些arch的Loader合称U-Boot 国内
安装下载:
版本使用2022.01版本:
Release v2022.01 · u-boot/u-boot · GitHub
- .gitignore:git工具的文件
- config.mk:是一个Makefile文件
- MAINTAINERS:维护者
- Makefile:uboot源代码的主Makefile
- README:所有的软件都有README,简单的使用说明书。
- api:?硬件无关的功能函数的API
- board:文件夹下每一个文件都代表一个开发板
- common:放的是一些与具体硬件无关的普遍适用的一些代码
- disk:磁盘有关的
- doc:文档目录,里面存放了很多uboot相关文档
- drivers:驱动,这里面放的就是从linux源代码中的linux设备驱动,如网卡驱动、Inand/SD卡、NandFlash等的驱动
- examples:示例代码
- fs:filesystem,文件系统
- include:头文件目录
- lib:(典型的lib_arm和lib_generic)架构相关的库文件
- net:网络相关的代码
- tools:里面是一些工具类的代码
- arch:这个目录是SoC相关的,里面存放的代码都是SoC相关初始化和控制代码(譬如CPU的、中断的、串口等SoC内部外设的,包括起始代码start.S也在这里)
2.2、主Makefile
2.2.1、Makefile配置编译
- u-boot.lds,就是uboot的链接脚本
- configs文件夹,uboot 配置文件,xxx_defconfig
安装依赖项
- sudo?apt-get?install libssl-dev
- sudo apt-get install bison
- sudo apt-get install flex
编译生成u-boot.bin
- export CROSS_COMPILE=aarch64-linux-gnu- #export 设置环境变量
- cd u-boot
- make distclean ?# 清除上次的make命令所产生文件以及配置文件
- make?rpi_4_defconfig # 使用树莓派4的配置文件,执行完这步会生成.config文件
- 生成.config文件
- make ?# 编译uboot
三、启动uboot
3.1、格式化SD卡
Windows上直接格式化FAT32
Linux上:删除分区、新建分区、挂载、格式化、挂载分区
- sudo fdisk /dev/sdb 根据提示进行即可
- sudo mkfs.vfat /dev/sdb1 格式化FAT32
- sudo mount /dev/sdb1 /mnt 挂载分区
3.2、树莓派4b的启动流程
rpi4的启动分区依旧是使用FAT32文件系统,并采用如下三阶段启动方式:
- 树莓派复位上电时,CPU处于复位状态,由GPU来负责启动系统。
- 第一阶段引导程序(ROM程序): GPU首先启动固化在rpi4中的BootRom程序。这一阶段非常简单,BootRom主要支持读取SD中FAT32文件系统中的第二阶段引导程序bootcode.bin;注意:树莓派4B已经把bootcode.bin引导程序固化到SPI Boot EEPROM里。
- 第二阶段引导程序(bootcode.bin): GPU加载并执行启动分区中的bootcode.bin。bootcode.bin主要功能是解析elf格式文件,并加载并解析同样位于分区中的start4.elf文件;
- 第三阶段引导程序(start4.elf):运行start4.elf,读取并解析config.txt配置文件,并加载执行真正的u-boot程序。start4.elf这是一个包含VideoCore(视频/HDMI模式、内存、控制台帧缓冲区等)和Linux内核(加载地址、设备树、UART/控制台波特率等)的配置参数的文本文件。一旦解析了config.txt文件,第三阶段引导程序将加载cmdline.txt【一个包含要传递给内核的内核命令行参数的文件】和kernel.img【 Linux内核】。两者都加载到分配给ARM处理器的共享内存中。完成后,第三阶段引导程序将释放ARM处理器的复位。您的内核现在应该开始启动。
因此,Linux内核可以在不需要U-Boot的情况下启动。然而,正如所示,U-Boot提供了许多有用的工具,用于开发和调试嵌入式系统,例如通过网络上的TFTP加载新编译的内核进行测试。这消除了在每次微调和编译之间将内核复制到SD卡的缓慢和痛苦的过程。
同时,由于u-boot中没有预置rpi4的dts文件(device tree source),因此采用了在u-boot运行时动态传入硬件描述dtb(device tree blob)文件的方式,用于u-boot启动时枚举硬件。这里对于rpi来说就是bcm2711-rpi-4-b.dtb文件。
注意:
1、rpi4这里的启动elf文件由start.elf变成了start4.elf,和之前版本的树莓派不同。
2、rpi4b已经把bootcode.bin引导程序固化到板载SPI Boot EEPROM里,没用外部文件。
3、在rpi4上运行过64位u-boot的都知道,如果在config.txt中没有特别指明kernel的位置,那么start.elf(或start4.elf)默认需要并启动的文件是kernel8.img:
kernel8.img:64位的Raspberry Pi 4和Raspberry Pi 4;
kernel7l.img:32位的Raspberry Pi 4(使用LPAE);
kernel7.img:32位的Raspberry Pi 4、Raspberry Pi 3和Raspberry Pi 2(未使用LPAE);
kernel.img:其他版本的树莓派。
3.3、启动文件复制到SD卡
?????? bootcode.bin:引导程序。树莓派复位上电时,CPU处于复位状态,由GPU来负责启动系统。GPU首先会启动固化在芯片内部的固件(BootROM代码),读取MicroSD卡中的bootcode.bin文件,并装载和运行bootcode.bin中的引导程序。(树莓派4B已经把bootcode.bin引导程序固化到SPI Boot EEPROM里)。
?????? start4.elf:树莓派4上的GPU固件。bootcode.bin引导程序检索MicroSD卡中的GPU固件,加载固件并启动GPU。
?????? start.elf:树莓派3上的GPU固件。
?????? config.txt:配置文件。GPU启动后读取config.txt配置文件,读取Linux内核映像(比如kernel8.img等)以及内核运行参数等,然后把内核映像加载到共享内存中并启动CPU,CPU结束复位状态开始运行Linux内核。如果在config.txt中没有特别指明kernel的位置,那么start.elf(或start4.elf)默认需要并启动的文件是kernel8.img。
?????? bcm2711-rpi-4-b.dtb: 设备树。由于u-boot中没有预置rpi4的dts文件(device tree source),因此采用了在u-boot运行时动态传入硬件描述dtb(device tree blob)文件的方式,用于u-boot启动时枚举硬件。这里对于rpi4来说就是bcm2711-rpi-4-b.dtb文件。
?????? fixup4.dat:这些是链接器文件,与 start*.elf 列出的文件配对。
3个文件在线下载地址
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bcm2711-rpi-4-b.dtb
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start4.elf
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/fixup4.dat
1个文件u-boot是前面生成复制过来即可。
1个文件config.txt创建写入如下内容即可。
?????? 设置 uart _2ndstage = 1会导致第二阶段加载程序(树莓派 4之前的设备上的 bootcode .bin或树莓派 4设备的 EEPROM 中的启动代码)和主固件(start * .elf) `)将诊断信息输出到 UART0 。
enable_gic(仅适用于 Pi 4B)
?????? 在树莓派 4B上,如果将此值设置为 0 ,则中断将使用旧版中断控制器而不是通过 GIC -400路由到 ARM 内核。默认值为" 1"。
四、遗留
4.1、感觉uart_2ndstage和enable_gic,设置1或0,或者注释掉打印上没啥区别。
4.2、EEPROM里的固件坏了怎么办?
4.3、裁剪uboot尝试,难道仅通过xxxdeconfig配置宏开关就行了?
4.4、从uboot启动内核尝试?
4.5、从uboot启动网络内核尝试?
4.6、修改自写一份嵌入式驱动,例如:uart串口驱动?
4.7、移植很火的鸿蒙系统到树莓派?
五、参考链接
config.txt中的启动选项 - 树莓派中文文档 (hackpi.fun)
<第2章>树莓派4B上运行 uboot_rpi_4_deconfig和rpi_arm4_deconfig-CSDN博客
如何让树莓派4上固件的debug日志输出到串口? - 知乎 (zhihu.com)
树莓派uboot配置编译-云社区-华为云 (huaweicloud.com)
Linux交叉编译——树莓派工具链安装_gcc-linaro-arm-linux-gnueabihf-raspbian-CSDN博客
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!