切腹のイラスト

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としておく。

firmware/modules/が生えたらOK。

SDカードの準備

パーティションはファームウェアを入れるやつと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では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による指定はできなかった。 シリアル端子が無くてカーネルパニックなどの断末魔が見れないので原因は不明。 今思い出したけどMicro HDMI端子はあるな……。

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リスト。