为拆机板移植 Armbian
之前买了一块拆机板,pico3399,卖家提供了 Ubuntu 系统,是 3 年前的版本了,每次更新都会更出一点小毛病,而且配置也会随着版本采用不同的配置工具而导致失效,所以一气之下就打算换成 Armbian Debian 版。
因为不是正规开发板,所以没有 ttl 等可以调试的方式,只能摸黑前进,不知道到底那里出问题,底板进不了 Maskrom 模式就得短接,而且没有半点资料可以查,其实蛮折腾的。
硬件
- 板子
- 短接线
- Micro USB OTG
系统正常,通电按住 Power 和 Recovery,然后先放开 Power 再放开 Recovery。
红色是短接点,底板和核心是分开的。
Boot
不同板子,不同系统都是不一样的,我的板子是 RK3399 的,需要的是 Rockchip 的:
- loader bin
- miniloader
- ddr blob
可以参考 Rockchip 的 github,这里我使用 rk3399_miniloader_v1.26.bin
和 rk3399_miniloader_v1.26.bin
生成的是 loader bin 是 rk3399_loader_v1.24.126.bin
。
Armbian
现在是 23.08,但是这里我以三年前的 20.08 来弄,因为老版本的坑比较多,所以更有意义。
DTB 和 DTS
提取板子的 DTB 文件,然后反编译为 DTS:
dtc -I dtb -O dts em3399-pico3399.dtb -o rk3399-pico3399.dts
在 DTS 里加上对应的头文件:
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/pwm/pwm.h>
#include "rk3399.dtsi"
#include "rk3399-opp.dtsi"
脚本
移植之前要保证 Armbian 的脚本能否正常运行,像我的主机是 Gentoo,然后是在 chroot
下模拟出 Armbian 需要的 Ubuntu 环境,我的环境不支持 rysnc
的 xattr
,会报出 rsync_xal_set 的 lsetxattr failed Operation not supported
,所以需要在 lib/functions/image/rootfs-to-image.sh
中将 declare rsync_ea=" -X "
改为 declare rsync_ea=""
。
配置
创建 config/boards/pico3399.conf
文件:
BOARD_NAME="PICO3399"
BOARDFAMILY="rockchip64"
BOOTCONFIG="pico3399-rk3399_defconfig"
KERNEL_TARGET="current"
BUILD_DESKTOP="no"
我们也可以加上 BOOT_FDT_FILE="rockchip/rk3399-pico3399.dtb"
自定义 dtb 的位置,位置以 /boot/dtb
为当前目录。
在 config/sources/families/include/rockchip64_common.inc
增加我们板子用的 loader:
elif [[ $BOARD == pico3399 ]]; then
BOOT_USE_BLOBS=yes
DDR_BLOB='rk33/rk3399_ddr_800MHz_v1.24.bin'
MINILOADER_BLOB='rk33/rk3399_miniloader_v1.26.bin'
BL31_BLOB='rk33/rk3399_bl31_v1.30.elf'
当然最新版的不是在该文件加上 $BOARD
判断,反正就是修改让 Armbian 知道选择哪些 Rockchip 需要的东西就可以。
同样是该文件,将 KERNELBRANCH="branch:linux-5.10.y"
改为 KERNELBRANCH="tag:v5.10.60"
,折算是一个大坑吧,本来以为 Linux-Stable 的东西应该很 stable,结果拉下来一堆内核代码问题,首先是 fbcon 在 4.4 的时候去掉的 softback 很多都回来,你需要在 $ARMBIAN_KERNEL/drivers/video/fbdev/core/fbcon.c
加上:
/* Software scrollback */
static int fbcon_softback_size = 32768;
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long softback_top, softback_end;
后面还有一大堆 Rockchip 的代码问题,如 ret = -EINVAL
得改成 return -EINVAL
等,最好的办法就是像上面说的,自己指定内核版本。
补丁
需要注意的是,在执行 ./compile.sh
时候,下载的东西会耗费你半天或者一天时间,你挂代理或者指定国内镜像都会遇见各种问题,如指定国内镜像,他不是所有都走国内,有些还是会走国外。
创建补丁执行 ./compile.sh CREATE_PATCHES=yes
,然后在 cache
文件夹修改 u-boot
和 kernel
的代码,然后生成 patch
给以后构建使用,这里我们可以使用国内镜像,虽然效果不一定好:
./compile.sh REGIONAL_MIRROR=china
也可以指定某些:
./compile.sh DOWNLOAD_MIRROR=china MAINLINE_MIRROR=tuna UBOOT_MIRROR=gitee GITHUB_MIRROR=fastgit
,为了避免 Ubuntu 的 APT NG 会在生成镜像时产生 localhost 的错误,我们还需要 NO_APT_CACHER=yes
,而且不想一直在线下载还得加上 OFFLINE_WORK=yes
。最终创建补丁如下:
./compile.sh CREATE_PATCHES=yes DOWNLOAD_MIRROR=china MAINLINE_MIRROR=tuna UBOOT_MIRROR=gitee GITHUB_MIRROR=fastgit OFFLINE_WORK=yes NO_APT_CACHER=yes
然后根据 u-boot
和 kernel
对应提示在 cache/sources
里对代码进行改动,如果是 23.08 的构建版本,那么创建补丁的脚本被拆为:
./compile.sh BOARD=pico3399 BRANCH=current uboot-patch
./compile.sh BOARD=pico3399 BRANCH=current kernel-patch
根据提示,先对 u-boot
更改,复制 DTS 文件:
cp rk3399-pico3399.dts cache/sources/u-boot/v2020.10/arch/arm/dts/
在 cache/sources/u-boot/v2020.10/arch/arm/dts/Makefile
的 dtb-$(CONFIG_ROCKCHIP_RK3399) += \
下面加上:
rk3399-pico3399.dtb \
创建在配置 config/boards/pico3399.conf
时我们指定的 pico3399-rk3399_defconfig
,位置是 cache/sources/u-boot/v2020.10/configs/pico3399-rk3399_defconfig
,内容:
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_TEXT_BASE=0x00200000
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_OFFSET=0x3F8000
CONFIG_DEFAULT_DEVICE_TREE="rk3399-pico3399"
CONFIG_ROCKCHIP_RK3399=y
CONFIG_TARGET_EVB_RK3399=y
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART=y
CONFIG_SYS_LOAD_ADDR=0x800800
# CONFIG_ANDROID_BOOT_IMAGE is not set
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-pico3399.dtb"
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_R=y
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
CONFIG_TPL=y
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
CONFIG_ROCKCHIP_EFUSE=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_NVME_PCI=y
CONFIG_PCI=y
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM_RK3399_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_MCS7830=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_USB_GADGET=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y
CONFIG_DISPLAY_ROCKCHIP_HDMI=y
CONFIG_SPL_TINY_MEMSET=y
CONFIG_ERRNO_STR=y
之后对运行 ./compile.sh
创建补丁的那个终端回车会得到 output/patch/u-boot-rockchip64-current.patch
。
接下来是 kernel
的,同样先复制 DTS 文件:
cp rk3399-pico3399.dts cache/sources/linux-mainline/v5.10.60/arch/arm64/boot/dts/rockchip/
在 cache/sources/linux-mainline/v5.10.60/arch/arm64/boot/dts/rockchip/Makefile
里加上:
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pico3399.dtb
最后同样在执行 ./compile.sh
的交互终端回车会生成 output/patch/kernel-rockchip64-current.patch
。
20.08 生成的 patch 需要放到 userpatches
对应的目录里,才能在之后的构建生效,23.08 则不需要:
cp output/patch/kernel-rockchip64-current.patch userpatches/kernel/rockchip64-current/
cp output/patch/u-boot-rockchip64-current.patch userpatches/u-boot/u-boot-rockchip64-mainline/
生成镜像
执行 ./compile.sh
后,依照需求选择,然后会自动打补丁,在 output/images
生成如 Armbian_21.08.1_Pico3399_bullseye_current_5.10.60.img
的镜像。