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

一、背景

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

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

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

二、构建流程

1、qemu

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

bash 复制代码
git clone https://github.com/qemu/qemu.git

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

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

以 git clone 为例编译源码:

bash 复制代码
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用户模式网络连接-CSDN博客https://blog.csdn.net/plmm__/article/details/142701489?spm=1001.2014.3001.5502

2、交叉编译工具链

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

bash 复制代码
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官方的也是可以的。

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

设置ARCH和CORSS_COMPILE。

bash 复制代码
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

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

bash 复制代码
make defconfig
make Image -j8

4、debian根文件

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

下载工具:

bash 复制代码
git clone https://github.com/orangepi-xunlong/orangepi-build.git -b next

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

bash 复制代码
sudo ./build

选择构建Rootfs and all deb packages:

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

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

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

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

选择标准:

这一步回车跳过:

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

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

bash 复制代码
qemu-img create -f raw rootfs.img 5G

(2)格式化磁盘镜像

bash 复制代码
sudo mkfs.ext4 rootfs.img

(3)挂载磁盘镜像

bash 复制代码
sudo mkdir -p /mnt/rootfs
sudo mount -o loop rootfs.img /mnt/rootfs

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

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

bash 复制代码
sudo lz4 -d --stdout bookworm-cli-arm64.tar.lz4 | sudo tar -x -C /mnt/rootfs/

(5)卸载磁盘镜像

bash 复制代码
sudo umount /mnt/rootfs

三、启动虚拟机

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

新建启动脚本 start.sh

bash 复制代码
#!/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分析,其中用于挂载根文件的指令:

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

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

bash 复制代码
-virtfs local,path=./share_dir,mount_tag=host0,security_model=passthrough,id=host0 \

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

bash 复制代码
-netdev user,id=net0,hostfwd=tcp::10022-:22 \
-device virtio-net-pci,netdev=net0

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

四、挂载和联网

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

1、挂载共享文件夹

bash 复制代码
#!/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

bash 复制代码
#!/bin/bash

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

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

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

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

五、其他

如果使用busybox构建最小根文件系统,在编译根文件时交叉编译器最好使用arm官方原生的,使用其他第三方定制的工具链会引发内核崩溃。血的教训!排列组合三天才找到问题。

相关推荐
zjsnh_Z1 小时前
Linux 操作系统中的 main 函数参数和环境变量
linux·服务器
南棱笑笑生1 小时前
20241005给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12时使用iperf3测网速
linux·运维·网络
@haihi2 小时前
每天一道面试题5——Linux内核包含哪些部分?
java·linux·运维·服务器
xflm2 小时前
wsl(3) -- USB使用
linux
陌殇殇殇2 小时前
kubeadm部署k8s1.28.0主从集群(cri-dockerd)
linux·云原生·容器·kubernetes·云计算
猪猪很Ok2 小时前
大数据开发--1.3 Linux的常用命令大全
linux·运维·服务器
小小不董3 小时前
《Linux从小白到高手》理论篇:一文概览常用Linux重要配置文件
linux·运维·服务器·数据库·dba
威桑3 小时前
Linux下Socket编程
linux·运维·网络
肥or胖3 小时前
【MySQL】复合查询
linux·数据库·mysql
龙智DevSecOps解决方案3 小时前
Perforce静态分析工具2024.2新增功能:Helix QAC全新CI/CD集成支持、Klocwork分析引擎改进和安全增强
linux·安全·ci/cd·代码规范·perforce