摘要
这篇博客讲述了作者在Orangepi R1 Plus LTS上安装Arch Linux的过程。尽管该板卡原本计划用于软路由,但由于缺少Wi-Fi蓝牙模块,作者放弃了软路由方案,转而尝试安装Arch Linux。作者详细描述了U-Boot配置、ARM Trusted Firmware编译以及U-Boot和设备树的编译和安装过程。最终,作者成功在Orangepi R1 Plus LTS上安装并启动了Arch Linux系统。作者还提到了官方推荐的Debian脚本编译U-Boot的方法,但由于使用Arch Linux,未进一步测试。
前情提要
最近突然想起来手头有一个之前白嫖的Orangepi R1 Plus LTS(后称R1+LTS)已经吃灰好久。本来打算弄软路由,但是这个板子本身并不内置Wi-Fi蓝牙模块导致如果想变成路由器我得再买一个USB网卡,否则就只能当旁路由。这么看性价比其实并不是很高,想了想软路由不是刚需就没折腾了。
既然不用来装Openwrt,总觉得应该装点什么东西。然而目前这个开发板被官方或者非官方支持发行版却只有寥寥无几(Ubuntu,Debian,Openwrt,Android和Armbian)。不过也正常,这个板子除了当软路由之外毫无性价比可言,能有这么多发行版我觉得已经超出我的想象了。不过思来想去还是想装个Arch Linux玩玩。
Arch Linux Arm (后称Alarm)官方并没有支持特别多的开发板(反而隔壁Manjaro Arm支持的更好),但好像大部分芯片至少都能找到一个对应的开发板被支持。R1+LTS的芯片是Rockchip 3328,Alarm对这个芯片仅支持了Rock64开发板。看了一下官方安装说明,使用的是Generic镜像配合上Rock64的U-Boot的安装方式。这看起来很有戏,技术思路就是重新编译一下R1+LTS的U-Boot固件,然后仿照官方说明安装即可。同时还惊喜的发现在两周前官方新增了对R1+LTS的支持。
安装过程
这里快速的过一下正确安装过程,踩的雷放在下一章讲。
不想手动编译的可以直接移动到安装Arch Linux,本文提供以编译好的文件。
配置 U-Boot
以下内容可配合U-Boot官方文档阅读。
- 找到一个可以编译U-Boot的环境,我这里选用的是一个装有Arch Linux的amd64设备。
- 从官网获取U-Boot。
- 安装交叉编译依赖,文档中并没给Arch系的依赖,所以我只装了
gcc-aarch64-linux-
开头的几个必要的编译工具,剩下的等make
的时候报错再递归的安装。 - 找到需要的开发板的配置文件,对于R1+LTS而言,配置文件在
configs/orangepi-r1-plus-lts-rk3328_defconfig
。运行配置:
make orangepi-r1-plus-lts-rk3328_defconfig
此处先不进行U-Boot的编译,编译了会报错:
Image 'simple-bin' is missing external blobs and is non-functional: atf-bl31
/binman/simple-bin/fit/images/@atf-SEQ/atf-bl31 (bl31.elf):
See the documentation for your board. You may need to build ARM Trusted
Firmware and build with BL31=/path/to/bl31.bin
表示需要ARM Trusted Firmware,所以还需要去编译一个ATF。
编译 ARM Trusted Firmware
以下内容可配合ATF官方文档阅读。
- 使用与上节一样的编译环境。
- 获取ATF仓库,这里我直接去GitHub镜像下载了。
- 在路径
docs/plat/rockchip.rst
中找到了型号和教程。我这里运行的编译命令如下:
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3328
- 编译完之后路径
build/rk3328/release/bl31/bl31.elf
下可以找到所需要的文件。复制到U-Boot的目录下:
cp build/rk3328/release/bl31/bl31.elf ../u-boot/
编译 U-Boot
回到 u-boot
目录。
- 按照错误提示进行编译
CROSS_COMPILE=aarch64-linux-gnu- BL31=bl31.elf make
- 编译后当前目录下有两个文件是我们需要的:
idbloader.img
和u-boot.itb
。同时我们还需要找到一个文件,后面会用arch/arm/dts/rk3328-orangepi-r1-plus-lts.dtb
,这是R1+LTS的设备树。
安装 Arch Linux
刚刚我们获取了三个文件idbloader.img
、u-boot.itb
和rk3328-orangepi-r1-plus-lts.dtb
。下文还将生成一个boot.scr
,点击链接可以直接下载编译好的文件。
请同步参照Alarm官方文档。 这里只讲差异点。
- 这里需要一个U-Boot的boot.scr脚本,对于Rock64有现成的,这里我们需要自制一个。
touch boot.cmd # 创建boot.cmd文件
vim boot.cmd # 写入boot.cmd文件,具体内容在下方
mkimage -A arm64 -O linux -T script -C none -a 0 -e 0 -d boot.cmd boot.scr # 创建U-Boot引导脚本的二进制文件
cp boot.scr root/boot/ # 放入boot文件夹内
下面是 boot.cmd
的内容
part uuid ${devtype} ${devnum}:${bootpart} uuid
setenv bootargs console=${console} root=PARTUUID=${uuid} rw rootwait
setenv fdtfile rockchip/rk3328-orangepi-r1-plus-lts.dtb
if load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} /boot/Image; then
if load ${devtype} ${devnum}:${bootpart} ${fdt_addr_r} /boot/dtbs/${fdtfile}; then
fdt addr ${fdt_addr_r}
fdt resize
if load ${devtype} ${devnum}:${bootpart} ${ramdisk_addr_r} /boot/initramfs-linux.img; then
booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r};
else
booti ${kernel_addr_r} - ${fdt_addr_r};
fi;
fi;
fi
- 在
umount
之前,我们需要将之前的存的设备树放于root/boot/dtbs/rk3328-orangepi-r1-plus-lts.dtb
,因为Arch所提供的镜像中并没有R1+LTS的设备树。然后再Unmount:
umount root
- 这里使用我们之前编译好的两个文件
idbloader.img
和u-boot.itb
。假设都已经放入u-boot
目录下。
dd if=idbloader.img of=/dev/sdX seek=64 conv=notrunc
dd if=u-boot.itb of=/dev/sdX seek=16384 conv=notrunc
[P.S.]最后不需要进行 Install the U-Boot package
操作,因为官方源并没有提供R1+LTS的U-Boot包,贸然删了 boot.scr
可能就启动不了了。
Arch 启动!
-` leachim@alarm
.o+` -------------
`ooo/ OS: Arch Linux ARM aarch64
`+oooo: Host: Xunlong Orange Pi R1 Plus LTS
`+oooooo: Kernel: 6.2.1-1-aarch64-ARCH
-+oooooo+: Uptime: 2 hours, 14 mins
`/:-:++oooo+: Packages: 156 (pacman)
`/++++/+++++++: Shell: bash 5.1.16
`/++++++++++++++: Terminal: /dev/pts/0
`/+++ooooooooooooo/` CPU: (4) @ 1.296GHz
./ooosssso++osssssso+` Memory: 75MiB / 967MiB
.oossssso-````/ossssss+`
-osssssso. :ssssssso.
:osssssss/ osssso+++.
/ossssssss/ +ssssooo/-
`/ossssso+/:- -:/+osssso+-
`+sso+:-` `.-/+oso:
`++:. `-/+/
.` `/
写在最后
其实Orangepi是提供了R1+LTS的U-Boot适配代码的。在Branch v2020.10-rockchip64
里提供了R1+LTS的配置。但不知道为啥我编译不出来:
drivers/ram/rockchip/sdram_rk3328.c: In function 'rk3328_dmc_init':
drivers/ram/rockchip/sdram_rk3328.c:526:55: error: 'struct dtd_rockchip_rk3328_dmc' has no member named 'rockchip_sdram_params'
526 | (void *)dtplat->rockchip_sdram_params;
| ^~
make[4]: *** [scripts/Makefile.build:265: tpl/drivers/ram/rockchip/sdram_rk3328.o] Error 1
make[3]: *** [scripts/Makefile.build:419: tpl/drivers/ram/rockchip] Error 2
make[2]: *** [scripts/Makefile.build:419: tpl/drivers/ram] Error 2
官方其实推荐的是在Debian系下使用官方脚本来编译U-Boot,奈何手头上是Arch Linux就没有进行进一步测试了。