qemu模拟arm64环境-构建6.1内核以及debian12

时间:2024-10-07 16:37:54

一、背景

        手头没有合适的arm64开发板,但是需要arm的环境,于是想到qemu模拟一个。除了硬件交互以外,软件层面的开发还是都可以实现的。

        虚拟机还能自定义内存大小和镜像大小,非常适合上板前的验证,合适的话再买也不迟。

        为了提高配置效率与实用性,我直接使用香橙派的构建脚本编译根文件。没有和其他作者一样使用busybox制作根文件系统,我使用debian来提供apt等常用功能。

二、构建流程

       1、qemu

        建议使用git clone 源码进行编译,减少匹配问题。

git clone https://github.com/qemu/qemu.git

        或者官网压缩包下载地址:

Download QEMU - QEMUhttps://www.qemu.org/download/

        以 git clone 为例编译源码:

cd qemu
./configure --enable-kvm --enable-debug --enable-vnc --enable-user --enable-slirp --target-list="aarch64-softmmu"
make -j8
sudo make install

需要注意配置源码时的configure指令,如果想要了解参数的配置见我另一篇文章。

        qemu-system-aarch64开启user用户模式网络连接-****博客https://blog.****.net/plmm__/article/details/142701489?spm=1001.2014.3001.5502

        2、交叉编译工具链

       可以使用apt安装,也可以下载arm官方的压缩包,解压后记得配置PATH环境变量。

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

https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xzhttps://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
 

        3、kernel

        内核源码我使用香橙派提供的6.1版本,使用Linux官方的也是可以的。

git clone --depth=1 -b orange-pi-6.1-rk35xx https://github.com/orangepi-xunlong/linux-orangepi

        设置ARCH和CORSS_COMPILE。

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

        内核config配置文件建议使用defconfig,使用rockchip的默认配置无法通过qemu启动,暂时不知道原因。对于qemu的虚拟机,不需要设备树,只需要镜像即可。

make defconfig
make Image -j8

       

        4、debian根文件

        使用香橙派的 orangepi-build 工具构建,这里只是简单介绍过程,详细流程可以查看任意开发板的使用手册。

        下载工具:

git clone https://github.com/orangepi-xunlong/orangepi-build.git -b next

        下载完成后,执行build脚本:

sudo ./build

        选择构建Rootfs and all deb packages:

        然后需要选择开发板类型,看心情选即可。

        下一步是选择内核版本,由于内核选的6.1,这里需要选current。如果内核选择5.4,这里要选legacy。

        选择rootfs类型,看需要选即可:

        选择服务器版本还是桌面版本,建议服务器版本:

        选择标准:

        这一步回车跳过:

        等待构建完成可以在external/cache/rootfs/目录下找到 lz4 压缩包,需要解压后创建一个可挂载的ext4文件镜像。        

(1)创建一个空的磁盘镜像文件

qemu-img create -f raw rootfs.img 5G

(2)格式化磁盘镜像

sudo mkfs.ext4 rootfs.img

(3)挂载磁盘镜像

sudo mkdir -p /mnt/rootfs
sudo mount -o loop rootfs.img /mnt/rootfs

(4)将解压后的内容直接写入到挂载的目录

压缩包替换为生成的文件名。

sudo lz4 -d --stdout bookworm-cli-arm64.tar.lz4 | sudo tar -x -C /mnt/rootfs/

(5)卸载磁盘镜像

sudo umount /mnt/rootfs

三、启动虚拟机

        创建一个工作目录 qemu_arm64,将生成的内核镜像,根文件系统放到目录。创建一个文件夹share_dir用于共享文件。

        新建启动脚本 start.sh:

#!/bin/bash

sudo qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-nographic \
-smp 4 \
-m 2048 \
-kernel Image \
-drive if=none,file=rootfs.img,format=raw,index=0,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8" \
-virtfs local,path=./share_dir,mount_tag=host0,security_model=passthrough,id=host0 \
-netdev user,id=net0,hostfwd=tcp::10022-:22 \
-device virtio-net-pci,netdev=net0

        加sudo主要是用于隔离环境变量,防止意外。参数的大部分可以通过chatgpt分析,其中用于挂载根文件的指令:

-drive if=none,file=rootfs.img,format=raw,index=0,id=hd0 \
-device virtio-blk-device,drive=hd0 \

        用于挂载共享文件的指令:

-virtfs local,path=./share_dir,mount_tag=host0,security_model=passthrough,id=host0 \

        网络我没有使用桥接的方式,而是使用qemu自带的user方式联网,缺点是不能和宿主机通信。用于连接网络的指令:

-netdev user,id=net0,hostfwd=tcp::10022-:22 \
-device virtio-net-pci,netdev=net0

执行start.sh脚本即可启动虚拟机:

四、挂载和联网

        启动虚拟机后,需要挂载共享文件夹,并根据模拟的网卡进行dhcp。

        1、挂载共享文件夹

#!/bin/bash

mkdir -p /mnt/share
mount -t 9p -o trans=virtio,version=9p2000.L,access=any,rw host0 /mnt/share

        这里的文件夹就是启动指令中的share_dir,宿主机可以将文件放到文件夹内,虚拟机可以读和访问,但是不能写,提示没有权限,暂时还未解决。

        不过在网络设置成功后,可以使用scp命令传输文件到宿主机,形成数据回环。

        2、dhcp

#!/bin/bash

INTERFACE=$(ls /sys/class/net/ | grep -v lo)

sudo ip link set dev $INTERFACE up
sudo dhclient $INTERFACE

        这个脚本我采用临时设置的方式,原因是虚拟机有时候网卡名字会变,直接写入网络配置文件可能会失效。执行后会查询当前的网卡名,然后执行dhcp。

        获取到ip后就可以apt更新了。