Raspbian のイメージを焼いた SD カードを直接 PC Linux (Ubuntu) 上へマウントし中身の Raspbian 環境をセットアップする方法を紹介する。基本的には Debian Wiki にある記事の内容 (→Raspberry Pi Emulation Using qemu-user-static) の通りだが、途中にいくつかの落とし穴があったので解決方法を補充した。
這篇跟大家分享直接把已有燒入 Raspbian 的 SD 卡掛載到 PC 的 Linux (Ubuntu) 上面,而在 PC Linux 系統上調整 Raspbian 的環境的實際步驟。基本上跟 Debian Wiki 的內容 (-> Raspberry Pi Emulation Using qemu-user-static) 相同,但是我補充中間遇過的有些陷阱與其解決做法。
なおこの文書では以降 /dev/sdd を USB カードリーダーに繋がった SD カードのデバイスエントリとしている。
在此以後 /dev/sdd 用來表示插到讀卡器的 SD 卡片。
Step 1. Install QEMU and sydtemd containers.
$ sudo apt-get install qemu qemu-user-static binfmt-support systemd-container
Step 2. dd
/dev/sdd に含まれるパーティションがどこかへマウントされていないことを確かめてから dd する。
做 dd 之前稍微注意一下都不會被掛載 /dev/sdd 的分區。
$ sudo umount /dev/sdd?
$ sudo dd if=2017-04-10-raspbian-jessie-lite.img of=/dev/sdd bs=512M
Step 3. Resize partition
/dev/sdd2 の領域を SD カードの空き一杯まで広げる。 parted の中で mkpart へ与える引数は各々実際の状況に合わせて変えてほしい。また、この操作により SD カードのそれぞれのパーティションに割り当てられていた PARTUUID の値が変わってしまうので cmdline.txt と fstab を修正する。
分區 /dev/sdd2 放大到 SD 卡後面的整個空間。在 parted 操作中檔使用 mkpart 時指定的參數的部分,請改成跟自己環境適合的數值。另外,因爲這操作會引起各 SD 卡分區的 PARTUID 的改變 (參考後述的「 Step 4-1. Change PARTUUID 」章節 ) ,所以要修改 cmdline.txt 與 fstab 。
$ sudo parted /dev/sdd
GNU Parted 3.2
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: MXT-USB Storage Device (scsi)
Disk /dev/sdd: 4351MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 4194kB 62.9MB 58.7MB primary fat16 lba
2 62.9MB 3277MB 3214MB primary ext4
(parted) rm 2
(parted) mkpart primary 62.9 4351
(parted) print
Model: MXT-USB Storage Device (scsi)
Disk /dev/sdd: 4351MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 4194kB 62.9MB 58.7MB primary fat16 lba
2 62.9MB 4351MB 4288MB primary lba
(parted) quit
$ sudo e2fsck -f /dev/sdd2
e2fsck 1.42.13 (17-May-2015)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdd2: 86233/261632 files (0.1% non-contiguous), 634636/1046784 blocks
$ sudo resize2fs /dev/sdd2
resize2fs 1.42.12 (29-Aug-2014)
Resizing the filesystem on /dev/sdd2 to 1046784 (4k) blocks.
The filesystem on /dev/sdd2 is now 1046784 (4k) blocks long.
$ sudo blkid
:
/dev/sdd1: LABEL="boot" UUID="70CE-EB76" TYPE="vfat" PARTUUID="4bd62493-01"
/dev/sdd2: UUID="f2100b2f-ed84-4647-b5ae-089280112716" TYPE="ext4" PARTUUID="4bd62493-02"
$ mkdir /tmp/raspbian_mnt
$ sudo mount /dev/sdd2 -o rw /tmp/raspbian_mnt
$ sudo mount /dev/sdd1 -o rw /tmp/raspbian_mnt/boot
$ sudo vi /tmp/raspbian_mnt/etc/fstab
:
: (modify PARTUUID, e.g. 4bd62493-02, 4bd62493-02)
:
$ vi /tmp/raspbian_mnt/boot/cmdline.txt
:
: (modify PARTUUID, e.g. 4bd62493-02)
:
$ sudo umount /dev/sdd?
$ rmdir /tmp/raspbian_mnt
Step 4. Modify files in the Raspbian rootfs
Preparation
SD カードの各パーティションをマウント、 Raspbian の rootfs にある /etc/ld.so.preload の中身を全てコメントアウトし、 PC の qemu-arm-static コマンドを Raspbian の rootfs 内へコピー。最後に QEMU user emulation を起動。
首先掛載 SD 卡的各分區,再來注解掉在 Raspbian rootfs 內 /etc/ld.so.preload 裡面的所有的內容,然後從 PC 把 qemu-arm-static 指令檔複製到 Raspbian 的 rootfs 內。這些做完,就可以啓動 QEMU user emulaiton 。
$ mkdir /tmp/raspbian_mnt
$ sudo mount /dev/sdd2 -o rw /tmp/raspbian_mnt
$ sudo mount /dev/sdd1 -o rw /tmp/raspbian_mnt/boot
$ sudo vi /tmp/raspbian_mnt/etc/ld.so.preload
:
: (comment out everything)
:
$ sudo cp /usr/bin/qemu-arm-static /tmp/raspbian_mnt/usr/bin
$ sudo systemd-nspawn --directory='/tmp/raspbian_mnt' 'bin/bash'
Spawning container mnt on /tmp/raspbian_mnt.
Press ^] three times within 1s to kill container.
Failed to create directory /tmp/raspbian_mnt/sys/fs/selinux: Read-only file system
Failed to create directory /tmp/raspbian_mnt/sys/fs/selinux: Read-only file system
/etc/localtime is not a symlink, not updating container timezone.
root@raspbian_mnt:/#
以降、 PC の上で ARM の環境として Raspbian のユーザーランドの操作が可能。
以後在 PC 上實現虛擬 ARM 環境而可以做任何的 Raspbian 的 user land 的操作。
Step 4-1. Change hostname
root@raspbian_mnt:/# vi /etc/hostname
:
: (edit, "raspberry" -> name as you want)
:
root@raspbian_mnt:/# vi /etc/hosts
:
: (edit, "raspberry" -> name as you want)
:
Step 4-2. Remove calling of init_resize.sh
「 Step 3. Resize partition 」でパーティションの拡張は実施済みなので、 /boot/cmdline.txt から「 init=init_resize.sh 」の部分を削除する。
因爲在「 Step 3. Resize partition 」已經做完放大分區的步驟,所以從 /boot/cmdline.txt 檔刪除掉「 init=init_resize.sh 」的指定。
root@raspbian_mnt:/# vi /boot/cmdline.txt
:
: (remove "init=init_resize.sh")
:
Step 4-3. Setup Wi-Fi (OPTION)
必要ならばこの時点で Wi-Fi のセットアップを実施。
如果需要的話,在這裡預先可以做 Wi-Fi 的設定。
root@raspbian_mnt:/# wpa_passphrase <SSID> <PASSWORD>
network={
ssid="<SSID>"
#psk="<PASSWORD>"
psk=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
root@raspbian_mnt:/# vi /etc/wpa_supplicant/wpa_supplicant.conf
:
: (change ``country=GB`` -> ``country=TW``)
: (paste your network information -- as generated above -- at tail)
:
Step 4-4. Enable SSH daemon (OPTION)
Raspbian ブート後に sshd が走ってたい場合には、空の /boot/ssh ファイルを作っておく。
啓動 Raspbian 後想要開始跑 sshd ,產生 /boot/ssh 檔 (空檔就好) 。
root@raspbian_mnt:/# touch /boot/ssh
Step 4-5. etc..
その他、 apt-get などがしたければどうぞ。
其他想要做,就可以做,例如, apt-get 等等。
root@raspbian_mnt:/# apt-get update
root@raspbian_mnt:/# apt-get dist-upgrade
root@raspbian_mnt:/# apt-get install (...as you want)
:
root@raspbian_mnt:/# apt-get autoremove
root@raspbian_mnt:/# apt-get autoclean
root@raspbian_mnt:/# apt-get clean
Cleanup
QEMU usermode emulation から抜け、作業開始時にコメントアウトした Raspbian の /etc/ld.so.preload の中身を全て元に戻す。最後に SD カードの各パーティションをアンマウント。
跳出 QEMU usermode emulation ,而要回復剛才注解掉的,在 Raspbian rootfs 內 /etc/ld.so.preload 裡面的所有的內容。最後卸載 Raspbian 的各分區。
root@raspbian_mnt:/# exit
$ sudo vi /tmp/raspbian_mnt/etc/ld.so.preload
:
: (restore everything that commented out before)
:
$ sudo umount /dev/sdd?
$ rmdir /tmp/raspbian_mnt
Step 5. Launch Raspbian!
SD カードを Raspberry Pi へ挿して電源 ON!
把 SD 卡插到 Raspberry Pi 而上電!
Appendix A. QEMU launching script for loopback
イメージファイルを直接ループバックマウントして前述と同様の QEMU usermode emulation 環境を起動するスクリプトの例。
這腳本是個範例,是直接把 Raspbian 的 image 檔用 loopback 的方式掛載起來,而啓動跟上述似的 QEMU usermode emulation 環境。
#!/bin/bash
## apt-get install qemu qemu-user-static binfmt-support systemd-container
set -eu
readonly raspbiandir_="`pwd`/mnt"
readonly uid_="`/usr/bin/id | /bin/sed 's/uid=\([0-9]*\)(.*/\1/'`"
if [ 0 -ne "$uid_" ] ; then
cat << EOT__ >&2
Need as root.
EOT__
exit 1
fi
gotdev_="`/sbin/losetup --find --show --partscan 2017-04-10-raspbian-jessie-lite.img`"
ret_="$?"
if [ 0 -ne "$ret_" -o 'x' = x"$gotdev_" ] ; then
cat << EOT__ >&2
Failure creation loopback device.
EOT__
exit 1
fi
readonly loopdev_="$gotdev_"
/bin/mkdir -p "$raspbiandir_"
on_exit_() {
/bin/umount "${raspbiandir_}/boot"
/bin/umount "${raspbiandir_}"
/sbin/losetup --detach "$loopdev_"
}
trap 'on_exit_' EXIT
#
# Note that we need to comment out all lines in the
# "${raspbiandir_}/etc/ld.so.preload" before launch
# systemd-nspawn.
#
/bin/mount "${loopdev_}p2" -o rw "$raspbiandir_"
/bin/mount "${loopdev_}p1" -o rw "${raspbiandir_}/boot"
/bin/cp -f /usr/bin/qemu-arm-static "${raspbiandir_}/usr/bin"
/usr/bin/systemd-nspawn --directory="$raspbiandir_" 'bin/bash'
exit 0
参考サイト