树莓派3B+移植uboot

一、前言

最近入手得一块树莓派3B+开发板,试着移植Uboot到其中作启动内核,练练手。

树莓派3B+

二、大致过程

1、准备一张8G以上microSD卡或U盘(树莓派3B+默认支持USB启动),在Windows环境,下载官方烧写程序Raspberry Pi Imager,烧写安装官方树莓派32位操作系统,

启动流程:
1、First stage bootloader
树莓派上电后,SoC 中的 bootloader 首先被执行,其作用是挂载 SD 卡上的 FAT32 分区,从而加载下一阶段的 bootloader。这部分程序被固化在 SoC 的 ROM 中,用户无法修改。
2、Second stage bootloader (bootcode.bin)
这个阶段的 bootloader 会从 SD 卡上检索 GPU 固件,将固件写入 GPU,随后启动 GPU。
3、GPU firmware (start.elf)
本阶段中,GPU 启动后会检索附加配置文件(config.txt、fixup.dat),根据其内容设置 CPU 运行参数及内存分配情况,随后将用户代码加载至内存,启动 CPU。
4、User code (kernel8.img)
通常情况下,CPU 启动后便开始执行 kernel8.img 中的指令,初始化操作系统内核,在某些情况下,也可以被 U-BOOT 代替,由 U-BOOT 来加载内核。在树莓派 1 代中,User code 部分被保存在 kernel.img 文件中,2 代中,该文件更名为 kernel7.img,3 代中,该文件更名为 kernel8.img
官方的启动流程介绍链接

SD卡里的boot包含如下文件(官方链接):
overlays:存放设备树,不可少
bcm2710-rpi-3-b-plus.dtb: 设备树文件
bootcode.bin:bootloader文件
fixup.dat :GPU固件Videocore
start.elf :GPU内存
kernel.img :系统会先后搜寻config.txt中参数kernel=xxx指定的文件作为接下来接受系统控制权的对象,树莓派默认该文件是linux内核,我们可以替换为用uboot作为新一个bootloader然后再去启动linux内核。如果config.txt里没指定kernel参数,则默认是先后搜寻kernel8.img、kernel8-32.img、kernel7.img、kernel.img,分别对应ARMv8-aarch64、ARMv8-aarch32、ARMv7和之前版本的。
config.txt :如上面所说,该文件是启动过程第三阶段用来读取参数的。https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md
cmdline.txt :是树莓派原生系统启动时传给内核的参数,我们用uboot其实用不着这个

2、准备交叉编译工具(在unbutun20.10系统环境)

64位:

https://snapshots.linaro.org/gnu-toolchain/10.2-2021.04-1/aarch64-linux-gnu/gcc-linaro-10.2.1-2021.04-x86_64_aarch64-linux-gnu.tar.xz

在主目录下新建目录:~/gcc_cros2021/aarch64

解压:tar -xvJf gcc-linaro-10.2.1-2021.04-x86_64_arm-linux-gnueabihf.tar.xz 

32位:

https://snapshots.linaro.org/gnu-toolchain/10.2-2021.04-1/arm-linux-gnueabihf/gcc-linaro-10.2.1-2021.04-x86_64_arm-linux-gnueabihf.tar.xz

在主目录下新建目录:~/gcc_cros2021/arm

解压:tar -xvJf gcc-linaro-10.2.1-2021.04-x86_64_arm-linux-gnueabihf.tar.xz 

环境变量设置 :

sudo vi ~/.bashrc

# 交叉编译器aarch64
export PATH=~/gcc_cros2021/aarch64/bin:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

## 交叉编译器arm32
#export PATH=~/gcc_cros2021/arm/bin:$PATH
#export CROSS_COMPILE=arm-linux-gnueabihf-

3、编译U-Boot

下载Uboot,用git工具,(git clone https://source.denx.de/u-boot/u-boot.git)

针对树莓派有如下配置可选(产生u-boot/.config文件):

lrg@lrg-virtual-machine:~/u-boot$ ls ./configs/ | grep rpi
rpi_0_w_defconfig
rpi_2_defconfig
rpi_3_32b_defconfig
rpi_3_b_plus_defconfig
rpi_3_defconfig
rpi_4_32b_defconfig
rpi_4_defconfig
rpi_arm64_defconfig
rpi_defconfig

编译aarch64版本u-boot(设置如上相应aarch64交叉编译器环境变量):

lrg@lrg-virtual-machine:~/u-boot$ make rpi_3_b_plus_defconfig
#
# configuration written to .config
#
lrg@lrg-virtual-machine:~/u-boot$ make -j4

编译arm32版本u-boot(设置如上相应arm32交叉编译器环境变量):

lrg@lrg-virtual-machine:~/u-boot$ make rpi_3_32b_defconfig
#
# configuration written to .config
#
lrg@lrg-virtual-machine:~/u-boot$ make -j4
scripts/kconfig/conf  --syncconfig Kconfig
  CHK     include/config.h
  CFG     u-boot.cfg
......

  LD      u-boot
  OBJCOPY u-boot.srec
  OBJCOPY u-boot-nodtb.bin
  SYM     u-boot.sym
  COPY    u-boot.bin
===================== WARNING ======================
CONFIG_OF_EMBED is enabled. This option should only
be used for debugging purposes. Please use
CONFIG_OF_SEPARATE for boards in mainline.
See doc/README.fdt-control for more info.
====================================================
  CFGCHK  u-boot.cfg
lrg@lrg-virtual-machine:~/u-boot$ 

u-boot.bin为编译产生的u-boot启动内核二进制文件,将其拷入SD卡的boot分区根目录下,

sd卡的boot分区中config.txt设置(类似PC机的BIOS设置):

······
##64位
# arm_64bit=1
# kernel=u-boot64.bin
#32位
kernel=u-boot32.bin
······

其中u-boot64.bin、u-boot32.bin,就是前面编译生成相应aarch64版本及arm版本的u-boot.bin改名而来。

启动界面:

aarch64版本:

Uboot启动

arm版本:

arm版本启动界面

 

至此,移植U-boot操作告一段落。为测试一下是否通过U-boot启动引导原安装的树莓派系统,继续折腾。。。。。。


设置sd卡读取系统镜像(在32位arm版本U-boot环境):

方法一,开发板上电启动后进入U-boot,命令行设置启动命令与参数并保存(这种方法不便修改):

U-Boot> setenv bootcmd "fatload mmc 0:1 0x80000 kernel7.img;fatload mmc 0:1 0x2600000 bcm2710-rpi-3-b-plus.dtb;bootm 0x80000 - 0x2600000"
U-Boot> setenv bootargs "console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait noinitrd"
U-Boot> saveenv
U-Boot> boot

方法二,进入编译U-boot的Unbutun系统中编写U-boot启动脚本,利用U-boot工具mkimage生成脚本镜像boot.scr。

在用户目录下或者新一个目录,新建文件script_uboot,内容:

lrg@lrg-virtual-machine:~$ vi script_uboot

setenv fdtfile bcm2710-rpi-3-b-plus.dtb
setenv bootargs "earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait noinitrd"
fatload mmc 0:1 ${kernel_addr_r} kernel7.img
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
bootz ${kernel_addr_r} - ${fdt_addr_r}

再新建文件make_scr,内容:

mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n "RPi3b+ Boot Script" -d script_uboot boot.scr

在终端下source出boot.scr

lrg@lrg-virtual-machine:~$ source make_scr

最后把boot.scr拷入SD卡的boot分区根目录下,重启,成功了!

启动界面:

启动后,声音及蓝牙没有被驱动,其他正常,小激动后有些遗憾。

经试验,换成kernel8.img内核不能启动,提示内核文件格式不对;

尝试用aarch64版本U-boot、kernel8.img内核,提示没有bootz命令,重新编译aarch64版本U-boot时在.config配置文件中打开bootz选项,编译出支持bootz的64位U-boot内核,还是提示内核格式不对,换成bootm命令也不能启动,kernel8.img换成kernel7.img,无限重启,反正在aarch64版本U-boot下,就是死活不启动原生树莓派系统。不折腾了...

 

参考引用:

树莓派3B+的uboot启动内核

 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值