於 x86 環境下建立 Debian rootfs for armhf

假設我們工作於 debian based distro 中.

首先, 裝上需要用的工具

$ sudo apt-get install debootstrap qemu-user-static

因為我們會在 x86 環境下執行 armhf binary, 所以需要用到 qemu-user. 並且因為我們會做 chroot/systemd-nspawn, process 的 root 會指向 armhf 的, 因此 qemu 必須使用 static 版本, 以免外部 shared library 相依.

接著, 用 debootstrap 產生 rootfs

$ sudo debootstrap --foreign --arch=armhf jessie debian-armhf/ http://httpredir.debian.org/debian
$ sudo cp /usr/bin/qemu-arm-static debian-armhf/usr/bin
$ sudo chroot debian-armhf /debootstrap/debootstrap --second-stage

以上指令會在目錄目前下的 debian-armhf 中準備好 first stage rootfs, distro 版本為 jessie (Debian 8.0), package 從指定的 mirror (http://httpredir.debian.org/debian) 下載, 供後續 chroot 進去完成 second stage 的 package 安裝.

注意到命令中加了 --foreign 告訴 debootstrap 這個 rootfs 不是 native 的, 不要直接進行 chroot 完成 stage 2 (因為一定不會成功, rootfs 中的 binary 都是供 armhf 而不是 x86 使用的).

接著, 我們將 qemu-arm-static 放入 debian-armhf/usr/bin 中做為 chroot 後 elf 的 interpreter, 配合 binfmt_misc 在 x86 下執行 armhf 用的 binary, 最後, chrootdebian-armhf 目錄完成 debootstrap 的 stage 2 工作.

為了方便使用, 可再做以下小修改. 首先, 加上更多 package 來源, 修改 debian-armhf/etc/apt/sources.list

deb http://httpredir.debian.org/debian jessie main non-free contrib
deb-src http://httpredir.debian.org/debian jessie main non-free contrib
deb http://httpredir.debian.org/debian jessie-backports main non-free contrib
deb-src http://httpredir.debian.org/debian jessie-backports main non-free contrib
deb http://httpredir.debian.org/debian jessie-proposed-updates main non-free contrib
deb-src http://httpredir.debian.org/debian jessie-proposed-updates main non-free contrib
deb http://security.debian.org/ jessie/updates main non-free contrib
deb-src http://security.debian.org/ jessie/updates main non-free contrib

更新 package 資訊

$ sudo chroot debian-armhf apt-get update

裝上 bash-completion 及 command-not-found, 方便命令行的使用, 裝上 locales 以支持不同的編碼, 這樣一些如 perl 命令就不會印出一堆 warning messages 了

$ sudo chroot debian-armhf apt-get install locales bash-completion command-not-found
$ for locale in en_US zh_TW zh_CN; do sudo sed -e "[email protected]^# [email protected][email protected]" -i debian-armhf/etc/locale.gen; done
$ sudo chroot debian-armhf locale-gen
$ sudo chroot debian-armhf update-command-not-found
$ sudo bash -c 'echo en_US.UTF-8 >debian-armhf/etc/locale.conf'
$ sudo chroot debian-armhf apt-get clean

第 1 個命令裝上 package. 第二個命令修改 debian-armhf/etc/locale.gen 去掉 en_US.UTF-8, zh_TW.UTF-8, zh_CN.UTF-8 三個 locale 前的 #, 接著第 4 個命令用 locale-gen 命令產生 locale 資料, 第 5 個命令更新 command-not-found 資訊. 第 6 個命令設定 default locale. 最後一個命令清掉 download 下來的 .deb 檔.

這樣基本 rootfs 準備完成, 可用以下命令進到新建立的 rootfs 中

$ sudo chroot debian-armhf

或者, 可配合 systemd-nspawn 產生 container (但可能是因為 qemu 沒有實現完整的 syscall, `--boot` 模式不可用)

$ sudo systemd-nspawn -D debian-armhf