wsl使用qemu

Posted by 婷 on July 30, 2023 本文总阅读量

简介

记录在wsl上使用qemu的过程,基本是按照参考链接一步步来的。

过程

安装工具

sudo apt-get install qemu-system-arm libncurses5-dev gcc-aarch64-linux-gnu build-essential bison flex libssl-dev

image-20230723104048419

编译内核

下载4.19.171的内核源码

https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.171.tar.xz

创建文件夹,mkdir qemu_linux,解压源码

image-20230730105626668

 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

image-20230730105855958

 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4

image-20230730110029598

编译好了后在arch/arm64/boot下可以找到编译好之后的Image文件

image-20230730110933343

qemu第一次启动内核

在当前的qemu_linux目录下,输入命令

qemu-system-aarch64 -machine virt -cpu cortex-a53  -nographic -smp 1 -m 2048 -kernel arch/arm64/boot/Image

可以看到启动成功,但是没有挂载上文件系统,就kernel panic

image-20230730111200208

添加根文件系统的支持

内核支持

使用ramfs的方式来为内核提供根文件系统

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

勾选上RAM block device support,也即CONFIG_BLK_DEV_RAM=y

Device Drivers  --->
[*] Block devices  --->
 <*>   RAM block device support                                                                                 (16)    Default number of RAM disks (NEW)                                     
   (4096)  Default RAM disk size (kbytes) (NEW)  

选择Device Drivers

image-20230730111431027

选择Block devices

image-20230730111539764

选择RAM block device support ,我这里是按照默认配置,没有修改

image-20230730111624774

然后重新编译内核

image-20230730111736796

制作根文件系统

这里我们自己手动制作一个非常简单的根文件系统,就先不使用busybox或者buildroot去建立根文件系统。

创建qemu_rootfs文件夹,我们的目标就是将这个文件夹打包成 ramfs文件系统的形式

image-20230730112234451

接着输入命令,将这个文件夹制作成ramfs文件系统的格式

./mkinitramfs.sh  qemu_rootfs/ initramfs.cpio.gz

image-20230730112431140

在当前目录下生成了initramffs.cpio.gz

image-20230730154545362

mkinitramfs.sh脚本内容如下

#!/bin/bash

# Copyright 2006 Rob Landley <rob@landley.net> and TimeSys Corporation.
# Licensed under GPL version 2

if [ $# -ne 2 ]
then
    echo "usage: mkinitramfs directory imagename.cpio.gz"
    exit 1
fi 



if [ -d "$1" ]
then
    echo "creating $2 from $1"
    (cd "$1"; find . | cpio -o -H newc | gzip) > "$2"
else
    echo "First argument must be a directory"
    exit 1
fi

qemu第二次启动支持根文件系统

内核支持了ramfs设备之后,我们通过给qemu传递参数指定本机的相关文件作为ramfs的文件系统传递到内核,修改qemu启动命令,这次输入命令

qemu-system-aarch64 -machine virt -cpu cortex-a53  -nographic -smp 1 -m 2048 -kernel arch/arm64/boot/Image -append "root=/dev/ram0 rootfstype=ramfs rw init=/init"  -initrd initramfs.cpio.gz

这里可以看到已经挂载根文件系统成功,但是提示错误,因为上一步打包的根文件系统里面没有init进程

image-20230730153436753

添加init进程,重新打包根文件系统

本地编译一个简单的init可执行文件

init.c文件

#include <stdio.h>

int main()
{
    printf("hello world!\n");
    while(1);

    return 0;
}

编译命令:aarch64-linux-gnu-gcc init.c -o init -static

image-20230730114539897

再重新打包文件系统

image-20230730114716561

qemu第三次启动成功

输入命令

qemu-system-aarch64 -machine virt -cpu cortex-a53  -nographic -smp 1 -m 2048 -kernel arch/arm64/boot/Image -append "root=/dev/ram0 rootfstype=ramfs rw init=/init"  -initrd initramfs.cpio.gz

image-20230730114824746

退出qemu

按下Ctrl + a键,然后按下x键。

image-20230730152446879

qemu参数解释

  • -machine virt :指定qemu模拟的设备,这里就是指一个通用的armv8架构的芯片

  • -cpu cortex-a53 :指定具体的核心

  • -nographic:表示启动时没有图形界面

  • -smp 1 :设置该设备只有1个核

  • -m 2048 :表示设置该设备有2048MB的内存

  • -kernel arch/arm64/boot/Image:指定用于启动的内核文件

  • -initrd initramfs.cpio.gz:表示指定使用这个文件作为ramfs的内容,也即我们自己生成的根文件系统

  • -append "root=/dev/ram0 rootfstype=ramfs rw init=/init:表示了传递给内核的参数

    • root 表示根文件系统的设备为 /dev/ram0, 除此之外制定了文件系统的类型是 ramfs
    • init 表示系统启动的第一个进程名称,内核会从文件系统中加载该进程去执行

后续

后面有空的话,考虑用busybox或者buildroot来构建根文件系统

参考链接