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官方原生的,使用其他第三方定制的工具链会引发内核崩溃。血的教训!排列组合三天才找到问题。

相关推荐
cominglately2 小时前
centos单机部署seata
linux·运维·centos
魏 无羡2 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
CircleMouse2 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
木子Linux2 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
mit6.8243 小时前
Ubuntu 系统下性能剖析工具: perf
linux·运维·ubuntu
鹏大师运维3 小时前
聊聊开源的虚拟化平台--PVE
linux·开源·虚拟化·虚拟机·pve·存储·nfs
watermelonoops3 小时前
Windows安装Ubuntu,Deepin三系统启动问题(XXX has invalid signature 您需要先加载内核)
linux·运维·ubuntu·deepin
滴水之功4 小时前
VMware OpenWrt怎么桥接模式联网
linux·openwrt
ldinvicible4 小时前
How to run Flutter on an Embedded Device
linux
YRr YRr5 小时前
解决Ubuntu 20.04上编译OpenCV 3.2时遇到的stdlib.h缺失错误
linux·opencv·ubuntu