用 buildroot 构建 raspberrypi 4B 使用 uboot 启动的 image

buildroot 可以直接编译出树莓派简单的 image。但并没有使用 uboot,而且 GPU 初始化官方并不对外公开。不利于我自己瞎折腾。而 buildroot 不依赖与环境所以选择用 buildroot 来瞎搞。

我并不想破坏 buildroot 正常编译 raspberrypi 4b 的环境,保留 raspberrypi 4b 的原有编译环境可以在我自己调试出问题时做对比测试,所以我在 buildroot 环境上加了一个新的的配置。

添加新板卡

每个板卡 image 里的内容,分区信息都不一样,所以这里新建一个 raspberrypi4-64-magic 板卡。在 board 目录下 添加 raspberrypi4-64-magic 的软连接连接到 raspberrypi 目录。在 raspberrypi 添加相应的 image 配置。先用和原 64 bit image 同样的配置,所以拷贝 genimage-raspberrypi4-64.cfg 到 genimage-raspberrypi4-64-magic.cfg。这样就添加了一块 raspberrypi4-64-magic 的板卡和对应的 image 配置。

添加默认配置文件

在 config 目录下是各板卡设备的默认配置,添加 raspberrypi4_64_magic 的配置,这里拷贝原有树莓派 64 bit 的配置 raspberrypi4_64_defconfig 到 raspberrypi4_64_magic_defconfig。 修改下 文件里的板卡配置信息。

BR2_ROOTFS_POST_BUILD_SCRIPT=”board/raspberrypi4-64-magic/post-build.sh”
BR2_ROOTFS_POST_IMAGE_SCRIPT=”board/raspberrypi4-64-magic/post-image.sh”

添加 uboot 编译

把编译 uboot 添加到 config 文件中。在 raspberrypi4_64_magic_defconfig 文件中添加下面配置。

在 image 打包 uboot。

在生成 image 的配置文件中添加 uboot。在 genimage-raspberrypi4-64-magic.cfg 中把 u-boot.bin 添加到 boot 分区中。

修改树莓派启动配置文件

默认 buildroot 启动是由 gpu 直接启动 kernel。这里要加载 uboot 就要修改树莓派 boot 分区中的配置文件。之前没有仔细看打包的脚本,所以在这踩了个坑,这个后面再提。config.txt 文件的启动配置是由 post-image.sh,为了不影响原有的我在这里 copy 了份 post-image-magic.sh 来使用。所以之前的配置文件中的 post image 脚本配置要改掉。

BR2_ROOTFS_POST_IMAGE_SCRIPT=”board/raspberrypi4-64-magic/post-image-magic.sh”

修改 post-image-magic.sh 脚本,把 Kernel 配置改成 u-boot.bin 同时使能串口。

原来启动 Image 的配置

直接配置我们新加的默认配置编译就可以编译出启动 uboot 的 image 文件。

make raspberrypi4_64_magic_defconfig
make

生成的 image 在 output/images/ 下,烧录 sdcard.img 到 SD 卡即可。

接下来是我踩的坑。

谁动了 config.txt

没看 post-image.sh 以为 config.txt 是 rpi-firmware 包中自带的,为了不影响原来的编译。我复制了 package 下的 rpi-firmware 到 rpi-firmware-magic 同时把里面的所有 RPI_FIRMWARE 改成了 RPI_FIRMWARE_MAGIC。(这里不小心改漏了还坑了我好久。)文件名也改掉,然后修改里面的 config.txt,还改了 genimage-raspberrypi4-64-magic.cfg。本以为完事具备结构发现还是直接引导了内核。查看配置文件确实是错的。单独编译 rpi-firmware-magic package 是对的,一打包 config.txt 就被改掉了,研究了老半天才发现是 post-image.sh 干的,那我直接改 post-image.sh 脚本就好了,干嘛动 rpi-firmware 包,还因为改漏给自己挖了个大坑。既然改了就不能浪费。顺便把 rpi-firmware-magic 换成了 git 上最新的正式版。

把 version 换成 git 上最新发布的版本。我取得时候的最新版是下面的 commit id。

 RPI_FIRMWARE_MAGIC_VERSION = 934252b0b5258a6f1caedc6708393d44e6710cbc

rpi-firmware-magic.hash 校验文件也一并改掉。

# Locally computed
sha256  1922ee9089f923ab9aa08c34af39b52d706d741915556b9d3faa40a5aa9f3833  rpi-firmware-magic-934252b0b5258a6f1caedc6708393d44e6710cbc.tar.gz
sha256  c7283ff51f863d93a275c66e3b4cb08021a5dd4d8c1e7acc47d872fbe52d3d6b  boot/LICENCE.broadcom

start4db.elf 到底有啥用

信了官方的邪,想看看 start4db.elf 的 debug 功能,就又在配置文件里把打包 start4db.elf 和 fixup4db.dat 加了进去。

https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md

要不是 Firmware 打印出来的时间差了几秒,我还以为我没替换成功呢。果然 debug 功能不是给我这种凡人来玩的。

添加方式 rpi-firmware-magic 包中 Config.in 做如下修改。编译加上 BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DB 配置。

config BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DB
        bool "debug ('db', more debug information)"
        help
          The debug firmware, for output debug information, with default
          firmware.

endchoice

config BR2_PACKAGE_RPI_FIRMWARE_MAGIC_BOOT
        string
        default ""      if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DEFAULT && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI
        default "4"     if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DEFAULT && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI4
        default "_x"    if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_X && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI
        default "4x"    if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_X && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI4
        default "_cd"   if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_CD && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI
        default "4cd"   if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_CD && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI4
        default "_db"   if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DB && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI
        default "4db"   if BR2_PACKAGE_RPI_FIRMWARE_MAGIC_DB && BR2_PACKAGE_RPI_FIRMWARE_MAGIC_VARIANT_PI4