QEMUのRaspberry Pi 3モデルでLinuxを起動してみました。
QEMU 2.12で追加されたraspi3でLinuxを起動してみました。
Linuxが起動してrootでloginできました。
Debian起動手順
SDイメージをダウンロード
$ wget https://people.debian.org/~stapelberg/raspberrypi3/2018-01-08/2018-01-08-raspberry-pi-3-buster-PREVIEW.img.xz
$ xz -d 2018-01-08-raspberry-pi-3-buster-PREVIEW.img.xz
イメージファイルからブートに必要なファイルを3つ取り出す。
$ sudo virt-filesystems -a 2018-01-08-raspberry-pi-3-buster-PREVIEW.img
/dev/sda1
/dev/sda2
$ sudo guestfish --ro -a 2018-01-08-raspberry-pi-3-buster-PREVIEW.img -m /dev/sda1
Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.
Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell
><fs> ls /
bcm2837-rpi-3-b.dtb
bootcode.bin
cmdline.txt
config.txt
fixup.dat
fixup_cd.dat
fixup_db.dat
fixup_x.dat
initrd.img-4.14.0-3-arm64
start.elf
start_cd.elf
start_db.elf
start_x.elf
vmlinuz-4.14.0-3-arm64
><fs> copy-out /bcm2837-rpi-3-b.dtb .
><fs> copy-out /vmlinuz-4.14.0-3-arm64 .
><fs> copy-out /initrd.img-4.14.0-3-arm64 .
><fs> quit
qemu を起動
qemu-system-aarch64 -M raspi3 -serial mon:stdio \
-kernel vmlinuz-4.14.0-3-arm64 \
-initrd initrd.img-4.14.0-3-arm64 \
-dtb bcm2837-rpi-3-b.dtb \
-append "rw earlycon=pl011,0x3f201000 console=ttyAMA0 loglevel=8 root=/dev/mmcblk0p2 fsck.repair=yes net.ifnames=0 rootwait memtest=1" \
-drive file=2018-01-08-raspberry-pi-3-buster-PREVIEW.img,format=raw,if=sd
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.14.0-3-arm64 (debian-kernel@lists.debian.org) (gcc version 7.2.0 (Debian 7.2.0-18)) #1 SMP Debian 4.14.12-2 (2018-01-06)
[ 0.000000] Boot CPU: AArch64 Processor [410fd034]
[ 0.000000] Machine model: Raspberry Pi 3 Model B
[ 0.000000] earlycon: pl11 at MMIO 0x000000003f201000 (options '')
[ 0.000000] bootconsole [pl11] enabled
[ 0.000000] efi: Getting EFI parameters from FDT:
[ 0.000000] efi: UEFI not found.
[ 0.000000] cma: Reserved 64 MiB at 0x0000000038000000
[ 0.000000] NUMA: No NUMA configuration found
[ 0.000000] NUMA: Faking a node at [mem 0x0000000000000000-0x000000003bffffff]
[ 0.000000] NUMA: NODE_DATA [mem 0x37fdf280-0x37fe0d7f]
[ 0.000000] Zone ranges:
[ 0.000000] DMA [mem 0x0000000000000000-0x000000003bffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
中略
rpi3 login:
rootでログインする. パスワードは raspberry
rpi3 login: root
Password:
Linux rpi3 4.14.0-3-arm64 #1 SMP Debian 4.14.12-2 (2018-01-06) aarch64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Please change the root password by running passwd
root@rpi3:~#
メモ
-
earlycon=pl011,0x3f201000
を設定すると、シリアルにすぐ文字が出力される。 - CPU1-CPU3のエラーが表示される。予想としては、この起動手順だと、bootcode.binが動いていないので、Linuxカーネル起動前にCPU1-CPU3が止まってていないのが原因な気がします。
- カーネルの逆アセンブルだと
$ aarch64-elf-objdump --adjust-vma=0x80000 -D -b binary -m aarch64 vmlinuz-4.14.0-3-arm64
vmlinuz-4.14.0-3-arm64: file format binary
Disassembly of section .data:
0000000000080000 <.data>:
80000: 91005a4d add x13, x18, #0x16
80004: 142affff b 0xb40000
80008: 00080000 .inst 0x00080000 ; undefined
8000c: 00000000 .inst 0x00000000 ; undefined
80010: 01127000 .inst 0x01127000 ; undefined
80014: 00000000 .inst 0x00000000 ; undefined
80018: 0000000a .inst 0x0000000a ; undefined
...
80038: 644d5241 fcmla z1.h, p4/m, z18.h, z13.h, #180
- QEMUのトレースだと80000番地のカーネルのコードの前に何かやってます。 CORE1-CORE3を止めているように見えます。
----------------
IN:
0x00000300: d2801b05 movz x5, #0xd8
0x00000304: d53800a6 mrs x6, mpidr_el1
0x00000308: 924004c6 and x6, x6, #3
0x0000030c: d503205f wfe
0x00000310: f86678a4 ldr x4, [x5, x6, lsl #3]
0x00000314: b4ffffc4 cbz x4, #0x30c
----------------
IN:
0x00000000: 580000c0 ldr x0, #0x18
0x00000004: aa1f03e1 mov x1, xzr
0x00000008: aa1f03e2 mov x2, xzr
0x0000000c: aa1f03e3 mov x3, xzr
0x00000010: 58000084 ldr x4, #0x20
0x00000014: d61f0080 br x4
----------------
IN:
0x0000030c: d503205f wfe
0x00000310: f86678a4 ldr x4, [x5, x6, lsl #3]
0x00000314: b4ffffc4 cbz x4, #0x30c
----------------
IN:
0x00080000: 91005a4d add x13, x18, #0x16
0x00080004: 142affff b #0xb40000
----------------
IN:
0x00b40000: 94000008 bl #0xb40020
- これはQEMUのwrite_smpboot64()で定義されているコードでした。
Raspbian 起動手順
同様にRaspbianを試してみましたが、ログインプロンプトまで、辿り着きませんでした。
Raspbianは、2018-04-18-raspbian-stretch-liteを使いました。
raspi3だと何も表示がでないので、raspi2を使いました。
イメージからファイルを取り出す。
$ sudo guestfish --ro -a 2018-04-18-raspbian-stretch-lite.img
ch-lite.img
/dev/sda1
/dev/sda2
$ sudo guestfish --ro -a 2018-04-18-raspbian-stretch-lite.img -m /dev/sda1
Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.
Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell
><fs> ls /
COPYING.linux
LICENCE.broadcom
LICENSE.oracle
bcm2708-rpi-0-w.dtb
bcm2708-rpi-b-plus.dtb
bcm2708-rpi-b.dtb
bcm2708-rpi-cm.dtb
bcm2709-rpi-2-b.dtb
bcm2710-rpi-3-b-plus.dtb
bcm2710-rpi-3-b.dtb
bcm2710-rpi-cm3.dtb
bootcode.bin
cmdline.txt
config.txt
fixup.dat
fixup_cd.dat
fixup_db.dat
fixup_x.dat
issue.txt
kernel.img
kernel7.img
overlays
start.elf
start_cd.elf
start_db.elf
start_x.elf
><fs> copy-out /bcm2709-rpi-2-b.dtb .
><fs> copy-out /kernel7.img .
><fs> copy-out /cmdline.txt .
><fs> quit
cmdline.txtを確認
$ cat cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=c7cb7e34-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
qemuを起動…してみるが途中で止まる。
qemu-system-arm -M raspi2 -serial mon:stdio \
-kernel kernel7.img \
-dtb bcm2709-rpi-2-b.dtb \
-append "rw earlycon=pl011,0x3f201000 console=tty1 loglevel=8 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes net.ifnames=0 rootwait memtest=1 init=/usr/lib/raspi-config/init_resize.sh" \
-drive file=2018-04-18-raspbian-stretch-lite.img,format=raw,if=sd
SDカードの読み込みでCMD24でエラーが発生して止まりました。
raspi2だとフレームバッファに表示がでました。