![a37d145368b21f25dfdbdde5c6bdc3e9.png](https://img-blog.csdnimg.cn/img_convert/a37d145368b21f25dfdbdde5c6bdc3e9.png)
树莓派在今年更新到Raspberry Pi 4 B(rpi4),性能增加了不少的同时,在系统启动方面比之前也变化了不少。在拿到手之后,我也花了不少的时间,才成功将64位的u-boot启动起来。 虽然现在只成功启动u-boot,但是考虑到其他系统在硬件支持层面和u-boot有诸多相通之处,因此对后续操作系统的开发有一定的借鉴意义,因此在这里记录并和大家分享一下整个流程。
编译最新版本u-boot
首先安装64位arm的交叉编译工具链(aarch64-linux-gnu-)。在Ubuntu 18.04下运行:
sudo apt install gcc-aarch64-linux-gnu
最新的u-boot中已经添加了对rpi4的支持,因此,最需要下载最新版本的u-boot,进行配置和编译即可。其中我们选择的64位u-boot配置文件为rpi_4_defconfig
:
git clone https://github.com/u-boot/u-boot
cd u-boot
# 使用刚才下载的交叉工具链
export CROSS_COMPILE=aarch64-linux-gnu-
make distclean
make rpi_4_defconfig
make -j
如果运行不报错,那么会生成二进制文件u-boot.bin
。
将启动文件复制到SD卡中
rpi4的启动分区依旧是使用FAT32文件系统,并采用如下三阶段启动方式:
- 板载的VideoCore GPU启动固化在rpi4中的ROM,这一阶段非常简单,主要支持读取SD中FAT32文件系统的第二阶段启动程序;
- VideoCore GPU加载并执行启动分区中的
bootcode.bin
,该文件主要功能是解析elf格式文件,并加载并解析同样位于分区中的start4.elf
; - 运行
start4.elf
,读取并解析config.txt
配置文件,并加载执行真正的u-boot程序。
和之前版本的树莓派不同的是,这里的启动elf文件由start.elf
变成了start4.elf
。
同时,由于u-boot中没有预置rpi4的dts文件(device tree source),因此采用了在u-boot运行时动态传入硬件描述dtb(device tree blob)文件的方式,用于u-boot启动时枚举硬件。这里对于rpi来说就是bcm2711-rpi-4-b.dtb文件。
另外,在rpi3上运行过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
:其他版本的树莓派。
在SD卡上新建一个分区(空间不用太大,100M就足够了),具体方式可以链接。
格式化为vfat格式,并挂载,这里以/dev/sdc1
为例:
sudo mkfs.vfat /dev/sdc1
sudo mount /dev/sdc1 /mnt
将相应的文件都复制到SD卡中(其中bootcode.bin、start4.elf和bcm2711-rpi-4-b.dtb直接通过官方链接下载即可):
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bcm2711-rpi-4-b.dtb -o /mnt/bcm2711-rpi-4-b.dtb
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start4.elf -o /mnt/start4.elf
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bootcode.bin -o /mnt/bootcode.bin
sudo cat > /mnt/config.txt << EOF
enable_uart=1
arm_64bit=1
EOF
sudo cp u-boot.bin /mnt/kernel8.img
卸载SD卡,并插到rpi4中:
sudo umount /mnt
然后,将如下的文件复制到SD卡中
运行u-boot
将micro hdmi视频线连接到rpi4上,或者使用串口的方式与上位机终端进行连接。这里我采用的是Ubuntu上位机串口(PL2303串口转USB线)的方式:
sudo screen /dev/ttyUSB0 115200
rpi4连接电源,启动结果显示为如下:
![b4fe19a3827f0488a5ea49edb5f27c27.png](https://img-blog.csdnimg.cn/img_convert/b4fe19a3827f0488a5ea49edb5f27c27.png)
至此,U-boot已在树莓派4上成功启动。
附:32位和64位u-boot的启动的不同之处
虽然RPI4已经有4G内存版本,但考虑到相当部分的系统还是采用的32位字长,因此这里也分享一下32位u-boot制作和启动的不同。
arm32位工具链
sudo apt install gcc-arm-linux-gnueabihf
编译配置
export CROSS_COMPILE=arm-linux-gnueabihf-
make rpi_4_32b_defconfig
config.txt和镜像文件
镜像的名字不再是kernel8.img
,而应该是kernel7l.img
。
另外,config.txt
文件的内容需要相应的调整:
enable_uart=1
# arm64_bit=1 32位的版本这里就不需要了