Closed26

M1 MacでQEMUでARM64用Linuxカーネルを起動する。

🤨🤔😑😨😱🤨🤔😑😨😱

M1 Mac上のCLionでカーネルとか組み込みデバイスをいい感じにデバッグしたい。
そのためにLinuxカーネルに対して、qemuやkgdbでデバッグの設定をしてみる。

🤨🤔😑😨😱🤨🤔😑😨😱

Linuxカーネルのビルド

🤨🤔😑😨😱🤨🤔😑😨😱

とりあえず起動してみる。

$ qemu-system-aarch64 \
     -M virt \
     -cpu cortex-a53 \
     -kernel ./linux-6.10.4/arch/arm64/boot/Image \
     -nographic \
     -append "console=ttyAMA0"

Kernel Panicとなった。

[    0.588364] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---

Ctrl-a xでQEMUを終了できる。

🤨🤔😑😨😱🤨🤔😑😨😱

initramfsを準備する。

🤨🤔😑😨😱🤨🤔😑😨😱

簡単なinitramfsを準備する。

$ vim init.c
#include <stdio.h>

int main(void) {
  printf("Hello, World!\n");

  for(;;) {
    42;
  }

  return 0;
}
$ gcc -static -o init init.c -O0
$ echo init | cpio -o -H newc | gzip > initramfs.cpio.gz
🤨🤔😑😨😱🤨🤔😑😨😱

起動してみる。

$ qemu-system-aarch64 \
     -M virt \
     -cpu cortex-a53 \
     -kernel ./linux-6.10.4/arch/arm64/boot/Image \
     -nographic \
     -append "console=ttyAMA0" \
     -initrd ./initramfs.cpio.gz 

Hello, World!が表示される。

Hello, World!

Ctrl-a xでQEMUを終了できる。

🤨🤔😑😨😱🤨🤔😑😨😱

BusyBoxのビルド

🤨🤔😑😨😱🤨🤔😑😨😱

busyboxを設定してビルドする。

$ tar -jxvf  busybox-1.36.1.tar.bz2
$ cd busybox-1.36.1/
$ make defconfig
$ make menuconfig

Setting->Build static binary (no shared libs)を有効にする

$ vim .config

CONFIG_TC=yCONFIG_TC=nに変更する。

$ make
$ make install

_installにバイナリが作成される。

🤨🤔😑😨😱🤨🤔😑😨😱

必要なファイルを作成する。

$ cd _install
$ mkdir proc
$ mkdir sys
$ mkdir dev
$ sudo mknod dev/null c 1 3 # これはなくても起動した
$ vim init
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
exec  /bin/sh
$ chmod +x init
$ find . | cpio -o --format=newc > ../rootfs.img

最終的にinitramfsを作成する。

🤨🤔😑😨😱🤨🤔😑😨😱

busyboxをinitrdとして起動してみる。

$ qemu-system-aarch64 \
     -M virt \
     -cpu cortex-a53 \
     -kernel ./linux-6.10.4/arch/arm64/boot/Image \
     -nographic \
     -append "console=ttyAMA0" \
     -initrd ./busybox-1.36.1/rootfs.img

lsやpwdなどが利用できる。

🤨🤔😑😨😱🤨🤔😑😨😱

CLionによるLinuxカーネルのデバッグ

🤨🤔😑😨😱🤨🤔😑😨😱

Linuxカーネルのオプションを有効かしてビルドしなおす。

$ make menuconfig

DEBUG_INFO=y
DEBUG_KERNEL=y
RELOCATABLE=n
CONFIG_DEBUG_INFO_DWARF4=y

オプションを有効化したら再度ビルド

$ make -j
🤨🤔😑😨😱🤨🤔😑😨😱

QEMUでLinuxを起動する。

$ qemu-system-aarch64 \
     -M virt \
     -cpu cortex-a53 \
     -kernel ./linux-6.10.4/arch/arm64/boot/Image \
     -nographic \
     -append "console=ttyAMA0" \
     -initrd ./busybox-1.36.1/rootfs.img \
     -s \
     -S
  • -s: gdbサーバーがport 1234で起動する。
  • -S: gdbが接続されるまで待機する。
🤨🤔😑😨😱🤨🤔😑😨😱

CLionを設定する。

リモートデバッグ

  • デバッガー:バンドルされたGDB
  • target remote 引数: :1234
  • シンボルファイル: linux-6.10.4/vmlinux
🤨🤔😑😨😱🤨🤔😑😨😱

linux-6.10.4/init/main.c内のstart_kernel関数にブレイクポイントを設定してデバッグボタンを押す。

GUIでステップ実行できるようになった。

🤨🤔😑😨😱🤨🤔😑😨😱

devcontainerを利用する方法

🤨🤔😑😨😱🤨🤔😑😨😱

.devcontainer/devcontainer.json

{
	"name": "ubuntu",
	"dockerFile": "Dockerfile",
	"remoteUser": "vscode",
}

.devcontainer/Dockerfile

FROM ubuntu:latest

ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME


RUN apt-get update \
    && apt-get install -y build-essential bc bison flex libncurses-dev libelf-dev libssl-dev git wget gawk openssl libudev-dev libpci-dev libiberty-dev autoconf llvm qemu-system cpio

USER $USERNAME
🤨🤔😑😨😱🤨🤔😑😨😱

UTMの場合と同様にLinuxやBusyBoxをビルドする。

  • ソースコードを解凍するときは、Mac上ではなくてLinuxコマンドを用いる。
  • rootfs.imgを作成するときのmknodコマンドはスキップしても起動した。
🤨🤔😑😨😱🤨🤔😑😨😱

docker内でQEMUを起動する。

$  qemu-system-aarch64 -M virt -cpu cortex-a53 -kernel ./linux-6.10.5/arch/arm64/boot/Image -nographic -append "console=ttyAMA0" -initrd ./busybox-1.36.1/rootfs.img

Mac上にインストールしたQEMUでも起動可能

このスクラップは2024/08/17にクローズされました