切腹のイラスト

uConsole CM4でGentoo Linux

{
  date: "",
  category: "/unix-like",
  tags: ["夏休みの宿題"]
}

夏休みの自由研究(適当)

方針

前準備

まずカーネルをクロスコンパイルするためのツールチェーンをホストにインストールする必要がある。 I use Gentoo btw なので今回もcrossdevを使って構築する。 LLVMベースなやつはGNUなやつと違ってtripleごとにツールチェーンをコンパイルしないのでお得(な気がする)。

ところで現状(2025-08-30),crossdevのLLVMサポートは未だexperimentalでかつ微妙に壊れているので,コマンドを若干工夫する必要がある。 (なんかstable指定してんのに~arm64なcompiler-rtをインストールしやがり,ツールチェーンがcompiler-rtを見つけられずmuslのリンクに失敗する。)

doas crossdev -S -P -v -s0 aarch64-unknown-linux-musl
ACCEPT_KEYWORDS=-~arm64 doas crossdev -L -S -P -v aarch64-unknown-linux-musl
doas sed -i 's/ ~arm64//' /etc/portage/package.accept_keywords/cross_llvm-aarch64-unknown-linux-musl

カーネルのコンパイル

素のlinux-rpiだと画面やらキーボードやらインターフェースのドライバが足りないので,uConsole対応のLinuxを用意する必要がある。

ClockworkPi本家のリポジトリ(clockworkpi/uConsole)にlinux-rpi-5.10.17向けのパッチセットが置いてあるが,これらのパッチを適用しながらlinux-rpiのアプストに追従してくれているフォーク(ak-rex/ClockworkPi-linux)があるので,今回はそっちを使う。

具体的には以下を見ていい感じ™にやっていく。 今回はLLVMを使うのでexport LLVM=1としておく。

クリックして展開
export LLVM=1 #
export KERNEL=kernel8
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

make bcm2711_defconfig

make -j4

mkdir -p ../modules
rm -rf ../modules/*

INSTALL_MOD_PATH=../modules make modules_install

mkdir -p ../firmware
rm -rf ../firmware/*
mkdir -p ../firmware/overlays

cp arch/arm64/boot/Image ../firmware/$KERNEL.img
cp arch/arm64/boot/dts/broadcom/*.dtb ../firmware
cp arch/arm64/boot/dts/overlays/*.dtb* ../firmware/overlays/
cp arch/arm64/boot/dts/overlays/README ../firmware/overlays/

KERNEL_VER=$(make kernelrelease)
cp arch/arm64/boot/Image.gz ../vmlinuz-${KERNEL_VER}

cp System.map  ../System.map-${KERNEL_VER}
cp .config  ../config-${KERNEL_VER}

mkdir -p ../linux-headers-${KERNEL_VER}

make headers_install INSTALL_HDR_PATH=../linux-headers-${KERNEL_VER}

コンパイルが終わり,firmware/modules/が生えたらOK。

SDカードの準備

パーティションはbootとrootfsの2つでOK。 GPTはなんか大袈裟な気がしたのでMBRでやった。

ここで,さっき紹介したカーネルは最初からCONFIG_F2FS_FS=yだったので,安心してrootfsをF2FSで作る。

doas fdisk /dev/sdx # パーティションをええ感じに切る
doas mkfs.vfat -nboot /dev/sdx1
doas mkfs.f2fs -lrootfs /dev/sdx2

uConsole公式イメージのループバックマウント

作業時になにかと参照するので。

以下の怪レいところからダウンロードしてくる。 まあそれっぽいソースは公開されてるし,ぱっと見中身も大丈夫そう。

ループバックマウントする。

doas losetup --partscan /dev/loop0 /path/to/uConsole_CM4_v2.0_64bit.img
doas mkdir -p /mnt/lo/{boot,rootfs}
doas mount -o ro /dev/loop0p1 /mnt/lo/boot
doas mount -o ro /dev/loop0p2 /mnt/lo/rootfs
# 終了するときは: doas umount /mnt/lo/{boot,rootfs} && doas losetup -d /dev/loop0

boot partition

カーネルやファームウェアを入れる場所。

Gentoo WikiではRPi公式ファームウェアraspberrypi/firmwareboot/をベチャっと展開してそのまま使っているが,今回は自炊のカーネルで一部を置き換える。

doas cp -r /path/to/rpi-firmware/boot/* /mnt/boot/
doas cp -r /path/to/built-firmware/* /mnt/boot/

また,わざわざ消す必要はないかもしれないが,uConsole公式イメージがそうなっているのと,どのみちドライバが無くて使い物にならないという理由から,使わないカーネル等を削除する。

cd /mnt/boot
doas rm kernel{,7,7l,8_rt,_2712}.img bcm2708*.dtb bcm2709*.dtb
cd -

次に,さっきマウントしたuConsole公式イメージからconfig.txtをパクってくる。 このファイルのソースコードもといリポジトリを探すのは怠かったのでサボった。TDN設定ファイルだし別に良いよね……。

そして,またuConsole公式イメージを参考にcmdline.txtを書く。 今回はとりあえずこんな感じにした。

console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=f2fs fsck.repair=yes rootwait

rootfsの指定について,root=LABEL=rootfsのようなlabelによる指定はできなかった。 シリアル端子が無くてカーネルパニックなどの断末魔が見れないので原因は不明。

rootfs partition

Gentoo arm64 stage3をぶちまける。 kernel moduleもぶちまける。 swapfileを生やす。 fstabを書く。

doas tar xpvf /path/to/stage3-arm64-musl.tar.xz -C /mnt/rootfs --xattrs-include='*.*' --numeric-owner
doas cp -a /path/to/built-modules /mnt/rootfs/lib/modules
doas fallocate -l4G /mnt/rootfs/swapfile
doas mkswap -Lswap /mnt/rootfs/swapfile
doas vim /mnt/rootfs/etc/fstab

fstabはこんな感じ。 dump・passの列は適当。

LABEL=boot		/boot		vfat		noatime		1 2
LABEL=rootfs		/		f2fs		noatime		0 0
tmpfs			/tmp		tmpfs		noatime		0 0
/swapfile		none		swap		sw		0 0

引き続きGentoo Wikiに従い,仕上げをしていく。

echo uconsole | doas tee /mnt/rootfs/etc/hostname
doas vim /mnt/rootfs/etc/shadow

shadowの各フィールドの意味はman 5 shadowを参考にすると良い。

起動

すんなり起動。

uConsole Gentoo boot screen ↑ログイン画面のファンシーなAAは/etc/issue.logoにある。

総括

夏休みが終わってしまいそうなので今回は一旦ここまでとする。 以下はToDoリスト。