明日にはでっかい太陽が昇るかもしれません。

「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ!

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 を接続すると、以下のことがわかった。

  1. CPU の起動方法 ("enable-method") に "spin-table" が設定されている
  2. CPU の起動トリガ ("cpu-release-addr") にアドレスを書き込んだあとに SEV を呼び出している
  3. が、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" だった。。