基于qemu的linux kernel学习平台准备--aarch64版

1,201 阅读5分钟

编译安装qemu-system-aarch64

# 1. 下载qemu源码
wget https://download.qemu.org/qemu-9.1.2.tar.xz
# 2. 解压
tar xvJf qemu-9.0.0.tar.xz
# 3. 安装编译文档所需要的依赖
sudo emerge dev-python/sphinx dev-python/sphinx-rtd-theme
# 4. 配置
./configure --target-list=aarch64-softmmu --enable-docs
# 5. 编译
make -j$(nproc)
# 6. 安装
sudo make install

安装交叉编译工具链

sudo emerge sys-devel/crossdev
sudo crossdev --target aarch64-unknown-linux-gnu

编译linux内核

# 1. 下载源码
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# 2. 配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig 
# 3. 编译
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

准备文件系统

方法一:基于busybox构建

方法二:基于buildroot构建

www.51cto.com/article/667… www.cnblogs.com/xingboy/p/1…

# 1. 下载源码
wget https://buildroot.org/downloads/buildroot-2024.11-rc3.tar.gz
tar -zxvf ./buildroot-2024.11-rc3.tar.gz
# 2. 配置
cd buildroot-2024.11-rc3
make menuconfig  # 主要是Target options/Toolchian的配置
# 3. 编译
sudo make

编译后的产物在output/images目录中

方法三:基于yocto构建

方法四:准备debian文件系统

ubuntu上调通了,在gentoo上暂时未调通

# 创建一个镜像
dd if=/dev/zero of=./debian-rootfs-ext4.img bs=1MB count=8192

# 格式化
mkfs.ext4 ./debian-rootfs-ext4.img

# 挂载到本地
mkdir -p debian-rootfs
sudo mount -t ext4 -o loop ./debian-rootfs-ext4.img ./debian-rootfs

需要准备一下qemu-aarch64-static可执行程序:

# 进入之前下载的qemu的源码目录准备qemu-aarch64-static可执行程序
sudo vim /etc/portage/package.use/01-qemu
# 写入以下内容
dev-libs/glib static-libs
dev-libs/libpcre2 static-libs
sys-libs/zlib static-libs
# 然后重新编译一下libglib.a libpcre2.a zlib.a
sudo emerge -av dev-libs/glib dev-libs/libpcre2
# 编译qemu-aarch-user
./configure --target-list=aarch64-linux-user --static 
make -j$(nproc)
sudo make install

sudo ln -s $(which qemu-aarch64) /usr/local/bin/qemu-aarch64-static

还需要处理binfmt, 参考wiki

sudo vim /etc/binfmt.d/qemu-aarch64-static.conf
# 写入以下内容
:aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64:

sudo systemctl restart systemd-binfmt
sudo systemctl status systemd-binfmt
# 之后可以在/proc/sys/fs/binfmt_misc/目录下看到多了一个aarch64的文件

image.png

继续下载debian的文件系统

# 下载debian根文件系统
sudo emerge dev-util/debootstrap 
sudo debootstrap --verbose --arch=arm64 bullseye  ./debian-rootfs https://mirrors.tuna.tsinghua.edu.cn/debian

执行到最后不知道为什么报错了

image.png 日志中的报错如下:

image.png

# chroot之前做一些的定制
sudo cp /usr/bin/qemu-aarch64-static debian-rootfs/usr/bin
sudo cp /etc/resolv.conf debian-rootfs/etc/
sudo mount -t proc /proc debian-rootfs/proc
sudo mount -t sysfs /sys debian-rootfs/sys
sudo mount -o bind /dev debian-rootfs/dev
sudo mount -o bind /dev/pts debian-rootfs/dev/pts
sudo chroot debian-rootfs

执行chroot的时候还是报错: image.png

# 卸载
sudo umount debian-rootfs/proc
sudo umount debian-rootfs/sys
sudo umount debian-rootfs/dev/pts
sudo umount debian-rootfs/dev
sudo umount debian-rootfs

qemu-system-aarch64启动linux kernel

sudo qemu-system-aarch64 \
    -M virt -cpu cortex-a57 \
    -nographic \
    -smp 2 -m 2G \
    -kernel ./linux/arch/arm64/boot/Image \
    -append "nokaslr console=ttyAMA0 rootwait root=/dev/vda rw rootfstype=ext4 noinitrd" \
    -drive if=none,file=./buildroot-2024.11-rc3/output/images/rootfs.ext4,id=hd0,format=raw \
    -device virtio-blk-device,drive=hd0
  • Ctrl+A : 进入QEMU的控制台快捷键模式;
  • x : 退出QEMU模拟器;
  • c:进入 QEMU Monitor 控制台(命令行界面);
  • h : 打印帮助信息,显示所有可用的快捷键;

在 QEMU 启动虚拟机时,-drive 和 -device 参数用于定义虚拟机的存储设备及其具体配置。这两个参数相互关联,分别定义存储的后端前端,类似于物理主机中的硬盘和控制器。

-drive [if=type,]file=filename[,format=format][,id=id][,cache=mode][,readonly]

• file=filename 指定存储设备的镜像文件路径,例如磁盘镜像或 CD-ROM 镜像。

• format=format 指定镜像文件的格式。例如:

  • raw:裸镜像文件,直接表示磁盘内容。
  • qcow2:支持压缩、快照等功能的 QEMU 镜像格式。
  • vmdk:VMware 镜像格式。
  • 如果未指定,QEMU 会尝试自动检测,但这可能带来风险(如出现你的警告)。

• if=type 指定镜像连接到虚拟机的接口类型。常见的有:

  • none:只定义后端存储,不直接连接到前端设备。必须配合 -device 使用。
  • virtio:VirtIO 硬盘,适用于高性能的虚拟机 I/O。
  • ide:IDE 接口。
  • scsi:SCSI 接口。

• id=id 给存储设备指定一个唯一标识符(与 -device 配合使用时必需)。
• cache=mode 定义存储设备的缓存模式:
• none:直接写入磁盘,不使用主机缓存。
• writeback:使用主机缓存,性能较高但可能丢失数据。
• writethrough:写入时同时更新主机缓存和磁盘,数据更安全。
• readonly 以只读模式加载镜像。

-device 参数用于定义虚拟机的存储前端,即存储设备在虚拟机中的表现形式(如硬盘、网卡、显卡等硬件设备)。

-device device_name[,drive=id][,bus=bus_name][,addr=addr][,bootindex=n]

• device_name 指定虚拟设备的类型。例如:

  • virtio-blk-device:VirtIO 块设备(高性能磁盘接口)。
  • ide-hd:IDE 硬盘设备。
  • scsi-hd:SCSI 硬盘设备。

• drive=id 指定与此设备绑定的存储后端(由 -drive 定义的 id)。
• bus=bus_name 指定此设备挂载到的总线。例如:

  • 对于 VirtIO 设备,使用 virtio-mmio。
  • 对于 IDE 设备,挂载到 IDE 控制器。

• addr=addr 指定设备在总线上的地址(适用于 PCI 或其他可配置总线)。
• bootindex=n 定义设备的引导顺序。数字越小,优先级越高。例如:

  • bootindex=0:第一个引导设备。
  • bootindex=1:第二个引导设备。

gdb连接qemu

qemu-system-aarch64 -nographic -s -S ...

  • -s:监听 tcp::1234 的默认 GDB 端口。
  • -S:在启动后暂停虚拟机。
    启动gdb后通过以下指令连接qemu
sudo emerge cross-aarch64-linux-gnu/gdb
aarch64-linux-gnu-gdb ./linux/vmlinux
target remote :1234
b start_kernel
c

clangdvscode阅读源码

cd ./linux
python ./scripts/clang-tools/gen_compile_commands.py -d ./