【树莓派4b的uboot编译移植】

2023-12-26 23:28:55

树莓派4b的uboot编译移植

引言

0.1、什么是uboot

  1. OS跑起来前,需要的一段引导程序
  2. 负责部署整个计算机系统,引导操作系统内核启动并给内核传参
  3. 提供一个命令行界面供人操作
  4. 是一个开源项目,uboot就是universal bootloader(通用的启动代码)
  5. 命令行用的行缓存,linux终端设计有3种缓冲机制:无缓冲、行缓冲、全缓冲

0.2、uboot命令

  1. printenv/print 打印出系统中所有的环境变量
  2. setenv/set 设置环境变量
    set 环境变量 值
  3. saveenv/save 保存环境变量到flash
  4. ping 网络测试指令

一、原理图

1.1、树莓派4b引脚图

树莓派4B Raspberry Pi 4B 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

  1. .gitignore:git工具的文件
  2. config.mk:是一个Makefile文件
  3. MAINTAINERS:维护者
  4. Makefile:uboot源代码的主Makefile
  5. README:所有的软件都有README,简单的使用说明书。

  1. api:?硬件无关的功能函数的API
  2. board:文件夹下每一个文件都代表一个开发板
  3. common:放的是一些与具体硬件无关的普遍适用的一些代码
  4. disk:磁盘有关的
  5. doc:文档目录,里面存放了很多uboot相关文档
  6. drivers:驱动,这里面放的就是从linux源代码中的linux设备驱动,如网卡驱动、Inand/SD卡、NandFlash等的驱动
  7. examples:示例代码
  8. fs:filesystem,文件系统
  9. include:头文件目录
  10. lib:(典型的lib_arm和lib_generic)架构相关的库文件
  11. net:网络相关的代码
  12. tools:里面是一些工具类的代码
  13. arch:这个目录是SoC相关的,里面存放的代码都是SoC相关初始化和控制代码(譬如CPU的、中断的、串口等SoC内部外设的,包括起始代码start.S也在这里)

2.2、主Makefile

2.2.1、Makefile配置编译

  1. u-boot.lds,就是uboot的链接脚本
  2. configs文件夹,uboot 配置文件,xxx_defconfig

安装依赖项

  1. sudo?apt-get?install libssl-dev
  2. sudo apt-get install bison
  3. sudo apt-get install flex

编译生成u-boot.bin

  1. export CROSS_COMPILE=aarch64-linux-gnu- #export 设置环境变量
  2. cd u-boot
  1. make distclean ?# 清除上次的make命令所产生文件以及配置文件
  2. make?rpi_4_defconfig # 使用树莓派4的配置文件,执行完这步会生成.config文件
  3. 生成.config文件
  4. make ?# 编译uboot

三、启动uboot

3.1、格式化SD卡

Windows上直接格式化FAT32

Linux上:删除分区、新建分区、挂载、格式化、挂载分区

  1. sudo fdisk /dev/sdb 根据提示进行即可
  2. sudo mkfs.vfat /dev/sdb1 格式化FAT32
  3. sudo mount /dev/sdb1 /mnt 挂载分区

3.2、树莓派4b的启动流程

rpi4的启动分区依旧是使用FAT32文件系统,并采用如下三阶段启动方式

  1. 树莓派复位上电时,CPU处于复位状态,由GPU来负责启动系统。
  1. 第一阶段引导程序(ROM程序): GPU首先启动固化在rpi4中的BootRom程序。这一阶段非常简单,BootRom主要支持读取SD中FAT32文件系统中的第二阶段引导程序bootcode.bin;注意:树莓派4B已经把bootcode.bin引导程序固化到SPI Boot EEPROM里。
  2. 第二阶段引导程序(bootcode.bin): GPU加载并执行启动分区中的bootcode.bin。bootcode.bin主要功能是解析elf格式文件,并加载并解析同样位于分区中的start4.elf文件;
  3. 第三阶段引导程序(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

?????? 设置 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博客

树莓派U-Boot编译教程-鸿蒙开发者社区-51CTO.COM

树莓派简单操作系统制作之一:树莓派4B U-boot移植并加载裸机程序_树莓派uboot-CSDN博客

文章来源:https://blog.csdn.net/qq_41204553/article/details/135232684
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。