树莓派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启动内核

 

### 移植 U-Boot 到 Raspberry Pi 3B #### 准备工作 为了在Raspberry Pi 3B上成功移植U-Boot,需要准备适合的开发环境。这通常是在一台Linux主机上完成,因为大多数嵌入式系统的工具链都是基于Linux构建的。 对于树莓派来说,由于其部分组件特别是GPU的相关代码并未开源,在此情况下移植过来的u-boot并不能完全发挥作为引导加载程序的作用[^1]。不过出于学习目的或是特定需求下的应用,这样的操作仍然是有意义且可行的。 #### 下载源码 获取最新的U-Boot源代码可以通过Git仓库来实现。通过终端输入如下指令可以克隆官方GitHub上的最新版本: ```bash git clone https://github.com/u-boot/u-boot.git ``` 该命令会把整个项目复制到本地机器以便后续处理[^4]。 #### 配置编译选项 进入解压后的文件夹之后,针对不同型号的树莓派有不同的配置方法;对于Raspberry Pi 3B而言,则需指定相应的架构和支持特性。具体做法是利用`make`命令加上对应的参数来进行初始化设置: ```bash cd u-boot/ make rpi_3_defconfig ``` 这里使用的是预定义好的默认配置文件,它包含了启动Raspberry Pi 3所需的基础设定[^5]。 #### 编译过程 有了正确的配置后就可以开始实际编译流程了。考虑到目标平台与当前使用的计算机可能属于不同的CPU体系结构,因此要指明交叉编译器的位置以及名称前缀。例如如果已经安装好了ARM架构的支持包并且路径位于 `/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/`,那么完整的编译语句应该是这样子的: ```bash export CROSS_COMPILE=/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- make -j$(nproc) ``` 上述脚本中的`CROSS_COMPILE`变量用来告知Makefile应该调用哪个系列的GCC编译器去生成适用于ARM设备的目标二进制文件;而后面的`-j$(nproc)`则是让编译任务能够充分利用多核处理器的优势加快速度。 #### 安装部署 当编译顺利完成以后就会得到名为`u-boot.bin`或者其他形式(取决于所选板级支持包)的固件映像。接下来就是将其写入SD卡或其他存储介质内供树莓派读取执行。常见的手段有借助于专门软件如Etcher或者直接采用dd命令从命令行界面操作: ```bash sudo dd if=u-boot.bin of=/dev/sdX bs=1M conv=fsync; sync ``` 注意这里的`sdX`应当替换成为真实的磁盘节点名,并且务必确认无误以免造成数据丢失风险[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值