Linux (aarch64) on Qemu を動作させたい (1)
U-Boot をひと通り動かすことができるようになったので、引き続き Linux を動作させていく。
Linux も、 NXP-SDK 付属のものを使用して、ターゲット向けのバイナリをそのまま動作させることを目指す。
FIT ファイルの作成
ビルドしたあと、 U-Boot からよみこむために FIT (Flattened uImage Tree) ファイルを作成する。
its ファイルは、 NXP-SDK 付属のものをベースにしている。
$ cat kernel.its /dts-v1/; / { description = "Image file for the LS1046A Linux Kernel"; #address-cells = <1>; images { kernel@1 { description = "ARM64 Linux kernel"; data = /incbin/("path/to/arch/arm64/boot/Image.gz"); type = "kernel"; arch = "arm64"; os = "linux"; compression = "gzip"; load = <0x80080000>; entry = <0x80080000>; }; fdt@1 { description = "Flattened Device Tree blob"; data = /incbin/("path/to/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dtb"); type = "flat_dt"; arch = "arm64"; compression = "none"; load = <0x90000000>; }; ramdisk@1 { description = "LS1046 Ramdisk"; data = /incbin/("path/to/fsl-image-minimal-ls1046ardb.ext2.gz"); type = "ramdisk"; arch = "arm64"; os = "linux"; compression = "gzip"; }; }; configurations { default = "config@1"; config@1 { description = "Boot Linux kernel"; kernel = "kernel@1"; fdt = "fdt@1"; ramdisk = "ramdisk@1"; }; }; }; $ mkimage -f kernel.its kernel.itb
作成した itb ファイルは emmc イメージにコピーしておく。
Linux kernel の起動
U-Boot を起動したあと、
=> print load_addr load_addr=0xa0000000 => print emmc_bootcmd emmc_bootcmd=echo Trying load from eMMC ..;mmcinfo; ext2load mmc 0:1 $load_addr /kernel.itb; bootm $load_addr => run emmc_bootcmd
で Linux をロードできる。
で、動作はというと、2番目以降のコアを起動するところで、起動させることができずに起動待ちループで止まってしまった。
... 省略 ... [ 0.064447] Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=625000) [ 0.068584] pid_max: default: 32768 minimum: 301 [ 0.078346] Security Framework initialized [ 0.092536] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes) [ 0.093597] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes) [ 0.211129] Initializing cgroup subsys memory [ 0.217881] Initializing cgroup subsys hugetlb [ 0.320269] hw perfevents: enabled with arm/armv8-pmuv3 PMU driver, 1 counters available [ 0.324401] EFI services will not be available. ... ここで止まる ...
U-Boot のとき同様、 Qemu 経由で kernel に GDB を接続すると、以下のことがわかった。
- CPU の起動方法 ("enable-method") に "spin-table" が設定されている
- CPU の起動トリガ ("cpu-release-addr") にアドレスを書き込んだあとに SEV を呼び出している
- が、Qemu 側が SEV / WFE 命令に対応していないため、何も起こらない
という状況っぽい。
CPU 起動待ちのタイムアウトも発生していないのが気になるが、今は Qemu を SEV に対応させることを考えている。
でも、 Qemu の aarch64 が smp に対応していないということはないはずなので、何かが間違っているから動いていないだけの可能性もあるので、まずは Qemu の aarch64 で smp 可能なボードがどう動いているかを解析してみることにする。
追記 (2017-12-11 21:55)
とりあえず、 U-Boot のときも比較に使用していた Xilinx の Zynq MP ボードは CPU の起動方法が "psci" となっており、起動方法が異なるので参考にはならなさそう。
仮想ボードが virt の場合とかはどう動くんだろう?
追記 (2017-12-17 12:34)
仮想ボードが virt の場合も起動方法は "psci" だった。。