Odroid-C2

来自 Alpine Linux

简介

Odroid-C2 单板计算机对 Alpine/Linux 的支持不是很好。但是,“通用 ARM (aarch64)” 构建包含了几乎所有我们需要的东西!

我们需要什么?

  • 内核:Alpine 团队提供的内核无法启动
  • u-boot:提供的 u-boot 在没有串口连接的情况下无法自动启动
  • 系统文件:一切正常

硬件方面

  • Odroid-C2
  • 官方 PSU 或仅需 micro-SD 电缆(注意:建议使用圆柱插头(内径(正极)0.8mm,外径(负极)2.5mm),无需 J1 跳线器)
  • micro-SD (或 eMMC)
  • USB to TTL (官方CP2102 芯片组 或旧的 rpi)


所需环境和工具链

推荐使用 GNU/Linux,本指南列出了所需的依赖项,以 Debian 为例:

apt install bc bison flex make gcc gcc-aarch64-linux-gnu libssl-dev libncurses-dev git squashfs-tools

如果未使用 arm64 机器,则需要设置特定的环境变量。通常,您应该在 x64 架构(Intel 或 AMD)上运行,因此您可能需要交叉编译。

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu


从源代码构建 u-boot

我们需要从源代码构建 uboot,因为提供的 u-boot 在没有 UART 连接的情况下无法自动启动。

git clone --depth 1 https://source.denx.de/u-boot/u-boot.git -b v2022.01 u-boot-denx.de
cd u-boot-denx.de
export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu-
make mrproper && make odroid-c2_defconfig

我们使用了 Odroid-C2 的特定默认配置,但正如之前提到的:我们希望在有或没有 UART 连接的情况下都能自动启动。您仍然可以在两秒倒计时结束前按两次“Enter”键来访问 SPL 提示符。

sed -i -e 's/.*CONFIG_SD_BOOT.*/CONFIG_SD_BOOT=y/' .config
sed -i -e 's/.*CONFIG_AUTOBOOT_KEYED .*/CONFIG_AUTOBOOT_KEYED=y/' .config
echo "CONFIG_AUTOBOOT_FLUSH_STDIN=y" >> .config
echo "CONFIG_AUTOBOOT_PROMPT="Press quickly 'Enter' twice to stop autoboot: %d\n"" >> .config
echo "# CONFIG_AUTOBOOT_ENCRYPTION is not set" >> .config
echo "CONFIG_AUTOBOOT_DELAY_STR=""" >> .config
echo "CONFIG_AUTOBOOT_STOP_STR="\xd\xd"" >> .config
echo "CONFIG_AUTOBOOT_KEYED_CTRLC=y" >> .config

然后,是构建的时候了

export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu-
make odroidc2_defconfig
time make -j$(nproc)

晶晨半导体 (Amlogic) 没有提供固件和创建引导加载程序映像所需工具的源代码,因此有必要从板卡供应商发布的 git 树中获取它们。

因此,您需要获取晶晨半导体 (Amlogic) u-boot 的分支来组装 u-boot 二进制文件

cd ..
git clone --depth 1 https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 u-boot
cd u-boot

将 "u-boot.bin" 从之前的 git 仓库 (source.denx.de) 复制到 晶晨半导体 (amlogic) u-boot 仓库

cp ../u-boot-denx.de/u-boot.bin .

然后,使用 晶晨半导体 (amlogic) fip 工具生成 u-boot

./fip/fip_create --bl30  ./fip/gxb/bl30.bin --bl301 ./fip/gxb/bl301.bin --bl31 ./fip/gxb/bl31.bin --bl33  u-boot.bin ./fip.bin
./fip/fip_create --dump ./fip.bin
cat ./fip/gxb/bl2.package ./fip.bin > ./boot_new.bin
./fip/gxb/aml_encrypt_gxb --bootsig --input ./boot_new.bin --output ./u-boot.img
dd if=./u-boot.img of=./u-boot.gxbb bs=512 skip=96


从源代码构建最新的 LTS 内核

git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-5.15.y linux-stable
cd linux-stable
export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu-
make mrproper && make defconfig

我们需要调整 defconfig 生成的默认 arm64 配置。此配置是 Alpine/Linux 所必需的,并且默认情况下未启用。

sed -i -e 's/.*CONFIG_SQUASHFS_XZ.*/CONFIG_SQUASHFS_XZ=y/' .config
sed -i -e 's/.*CONFIG_UEVENT_HELPER.*/CONFIG_UEVENT_HELPER=y/' .config
sed -i -e 's/.*CONFIG_BLK_DEV_RAM.*/CONFIG_BLK_DEV_RAM=y/' .config
echo CONFIG_UEVENT_HELPER_PATH=\"/sbin/hotplug\" >> .config
echo CONFIG_BLK_DEV_RAM_COUNT=16 >> .config
echo CONFIG_BLK_DEV_RAM_SIZE=4096 >> .config

我们还可以禁用不需要的 DRM 模块。因此,您将获得更少的模块,vmlinux 将更小,并且内核构建将更快。请注意,您还可以禁用更多模块或功能,例如删除所有 DRM 驱动程序或禁用声音(如果需要)。这将非常适合无头机器。

sed -i -e 's/CONFIG_DRM_\(.*\)=.*/# CONFIG_DRM_\1 is not set/' .config
sed -i -e 's/.*CONFIG_DRM_LIMA.*/CONFIG_DRM_LIMA=m/' .config
sed -i -e 's/.*CONFIG_DRM_PANFROST.*/CONFIG_DRM_PANFROST=m/' .config

如果您想为 s905 晶晨半导体 (amlogic) cpu 启用 DVFS

git apply --ignore-space-change --ignore-whitespace - << EOF
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 201596247..027df3756 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -348,7 +348,8 @@ &saradc {
 };

 &scpi_clocks {
-       status = "disabled";
+       /* Works only with new blobs that have limited DVFS table */
+       status = "okay";
 };

 /* SD */
EOF

然后,从源代码构建您的内核、关联模块和 DTB (设备树 Blob)

time make -j$(nproc) Image dtbs modules

创建 modloop

rm -rf installed-modules && mkdir installed-modules
INSTALL_MOD_PATH=installed-modules make modules_install
find installed-modules -type l -delete
rm -f modloop
mksquashfs installed-modules/lib/ modloop -b 1048576 -comp xz -Xdict-size 100% -all-root
rm -rf installed-modules


组装

内核部分

DST="/mnt/mmcblk0p1"
gzip -c arch/arm64/boot/Image > ${DST}/vmlinuz
cp .config ${DST}/config
cp modloop ${DST}/modloop
cp System.map ${DST}/System.map

复制 dtb

mkdir ${DST}/boot/dtbs
cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ${DST}/boot/dtbs
cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dtb ${DST}/boot/dtbs

系统部分

tar -C $DST -xzf alpine-uboot-3.15.4-aarch64.tar.gz ./.alpine-release ./alpine.apkovl.tar.gz ./apks ./boot/initramfs-lts 2>/dev/null


U-Boot 脚本

创建 boot.cmd 文件到 /dev/mmcblk0

DST="/mnt/mmcblk0p1"
cat << EoF > boot.cmd
#------------------------------------------------------------------------------------------------------
#
# HELP:
# boot.cmd = source file for humans
# boot.scr = destination file needed for the board
# recompile-me with:
# mkimage -C none -A arm -T script -d boot.cmd boot.scr
#
#------------------------------------------------------------------------------------------------------

# init.
setenv modloop "/boot/modloop"
setenv console "tty1"
setenv condev "console=ttyAML0,115200n8"
setenv verbosity "7"
setenv display_autodetect "true"

# console arguments configuration
setenv consoleargs "modules=loop,squashfs,sd-mod,usb-storage modloop=\${modloop} \${condev} console=\${console} panic=10"
setenv bootargs "\${consoleargs} loglevel=\${verbosity}"

# load files
setenv devtype "mmc"
setenv devnum "0:1"
load \${devtype} \${devnum} \${kernel_addr_r} /boot/vmlinuz
load \${devtype} \${devnum} \${ramdisk_addr_r} /boot/initramfs-lts
load \${devtype} \${devnum} \${fdt_addr_r} /boot/dtbs/meson-gxbb-odroidc2.dtb

# boot
booti \$kernel_addr_r \$ramdisk_addr_r:3200000 \$fdt_addr_r
EoF

然后,为 u-boot 构建此文件。mkimage 二进制文件在 source.denx.de 仓库的 ./tools/ 目录中可用(请参阅“从源代码构建 u-boot”部分)。

mkimage -C none -A arm -T script -d boot.cmd boot.scr

请注意,这两个文件必须放在 /boot/ 目录中。


启动

将您的 USB to TTL 转换器连接到您的板子上:我注意到您不需要连接所有导线,引脚 1 似乎不是强制性的。

_____UART____
|Pin 4 - GND|
|Pin 3 - RXD|
|Pin 2 - TXD|
|Pin 1 - VCC|
\___________|

所有详细信息都可以在 odroid wiki 上找到:https://wiki.odroid.com/accessory/development/usb_uart_kit