QEMU搭建ARM64+Linux环境

目录

一、安装交叉编译工具链

二、安装QEMU

三、制作根文件系统

1、从busybox下载最新版本源码

2、制定编译工具链

3、编译

4、创建需要的目录

四、编译内核源码

1、下载源码

2、指定编译工具

3、将根文件系统放到源码根目录

4、配置生成 .config

5、编译

五、启动QEMU

1、创建共享文件目录

2、运行 QEMU 模拟器

3、利用共享目录传递文件

4、利用共享目录传递应用程序并在QEMU中执行

5、从磁盘启动QEMU


        QEMU(QuickEmulator)是一套开源的虚拟机软件,可以模拟多个如x86、arm等处理器架构,用于虚拟化、仿真和调试,非常适合没有开发板而又想研究Linux内核结构和工作模式的人使用,对于嵌入式+Linux的学习十分有帮助

        本文也是参考了下方多篇博客,记录下自己在使用QEMU搭建环境时成功的步骤,便于后续的学习和实践

一、安装交叉编译工具链

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

        安装成功后可以查看版本

user@ubuntu18:/$ aarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/7/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include
Thread model: posix
gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)

二、安装QEMU

        这里我采用的是从源码安装,也可以从ubuntu仓库安装

wget https://download.qemu.org/qemu-4.2.1.tar.xz
tar xvJf qemu-4.2.1.tar.xz
cd qemu-4.2.1
./configure
make -j 8
sudo make install

        安装成功后可以查看版本

user@ubuntu18:/$ qemu-system-aarch64 --version
QEMU emulator version 4.2.1
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

三、制作根文件系统

        完成最小的根文件系统,并且可以运行动态编译的应用程序

1、从busybox下载最新版本源码

        下载网址:Index of /downloads

tar jxvf busybox-1.36.1.tar.bz2

2、制定编译工具链

cd busybox-1.36.1
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

3、编译

1、make menuconfig
    Settings --->
     [*] Build static binary (no shared libs)   
2、make
3、make install

4、创建需要的目录

        编译完成后,会生成_install目录

cd _install/
mkdir dev etc lib sys proc tmp var home root mnt

(1)etc目录更新

        a.创建 profile 文件,添加下面内容

#!/bin/sh
export HOSTNAME=user
export USER=root
export HOME=/home
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

        b.创建 inittab 文件,添加下面内容

::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r

        c. 创建 fstab 文件,添加下面内容,指定挂载的文件系统

#device  mount-point    type     options   dump   fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
kmod_mount /mnt 9p trans=virtio 0 0

        d.创建init.d目录

mkdir  init.d
cd init.d

        创建 rcS文件,添加下面内容

mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

        添加权限

chmod 777 rcS

        e.利用tree命令查看etc下目录结构如下所示

tree
.
├── fstab
├── init.d
│   └── rcS
├── inittab
└── profile

1 directory, 4 files

(2)dev目录下必要文件

cd dev
sudo mknod console c 5 1

(3)lib下必要文件

        为了支持动态编译的应用程序的执行,根文件系统需要支持动态库,所以我们添加arm64相关的动态库文件到lib下

cd lib
cp /usr/aarch64-linux-gnu/lib/*.so* -a .

四、编译内核源码

1、下载源码

        下载Linux内核源码,https://www.kernel.org

        我这边是linux-6.1.83的,直接点击tarball就能下载

tar xvf linux-6.1.83.tar.xz

2、指定编译工具

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

3、将根文件系统放到源码根目录

cd linux-6.1.83
cp  ../../busybox-1.36.1/_install  _install_arm64 -a

4、配置生成 .config

        修改defconfig

添加hotplug支持:
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
添加initramfs的支持:
+CONFIG_INITRAMFS_SOURCE="_install_arm64"
make defconfig 生成.config

        或者不修改defconfig,直接make defconfig,然后make menuconfig 会基于现在的.config以图形化方式去配置,按照下面添加即可   

a.添加hotplug支持
    Device Drivers                                                                                                 
        -> Generic Driver Options                                                                                             
            -> Support for uevent helper                                                                                                                
                (/sbin/hotplug) path to uevent helper
b.添加initramfs支持
    General setup --->
        [*]Initial RAM filesystem and RAM disk(initramfs/initrd) 
        support(_install_arm64) Initramfs souce file(s)
c.Virtual address space配置
    Kernel Features  --->
        Page size(4KB)  --->
        Virtual address space size(48-bit)--->

5、编译

make all -j8

五、启动QEMU

1、创建共享文件目录

        在内核源码目录下创建目录

mkdir kmodules

2、运行 QEMU 模拟器

        在内核源码目录下执行下面的命令

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt  -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8"  -nographic  --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none  -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
--- machine virt:使用virt机器类型。
--- cpu cortex-a57:使用Cortex-A57 CPU模型。
--- -m 1024:设置虚拟机内存大小为1024MB。
--- -smp 4:设置虚拟机使用4个CPU核心。
--- -kernel arch/arm64/boot/Image`:指定Linux内核镜像的路径。
--- --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8"`:指定内核启动参数,其中`rdinit`指定init程序的路径,`root`指定根文件系统的设备,`rw`表示以读写模式挂载根文件系统,`console`指定控制台设备,`loglevel`指定内核日志级别。
--- -nographic`:禁用图形界面,使用纯文本控制台。
--- --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none`:创建一个本地文件系统设备,其中`id`指定设备ID,`path`指定设备挂载的本地路径,`security_model`指定安全模型。
--- -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount`:将本地文件系统设备挂载到虚拟机中,其中`fsdev`指定设备ID,`mount_tag`指定设备挂载的标签。

        a.如果出现下面的错误,大概率是qemu版本的问题,换个新版本进行测试

qemu-system-aarch64: rom check and register reset failed

        b.出现下面报错,加上Config即可

mount: mounting debugfs on /sys/kernel/debug failed: No such file or directory

        启动成功后会打印如下内容,点击Enter进入控制台

[    0.926519] EXT4-fs (vda): recovery complete
[    0.949860] EXT4-fs (vda): mounted filesystem with ordered data mode. Quota mode: none.
[    0.951653] VFS: Mounted root (ext4 filesystem) on device 254:0.
[    0.961548] devtmpfs: mounted
[    1.019640] Freeing unused kernel memory: 12416K
[    1.020514] Run /sbin/init as init process
[    1.020595]   with arguments:
[    1.020660]     /sbin/init
[    1.020721]   with environment:
[    1.020784]     HOME=/
[    1.020870]     TERM=linux
Please press Enter to activate this console. 
[root@user ]# ls
bin      etc      lib      mnt      root     sys      usr
dev      home     linuxrc  proc     sbin     tmp      var

3、利用共享目录传递文件

        在内核源码的kmodules目录中echo一个文件

…linux/kmodules$ echo "hello world!" > hello.txt

        可以在QEMU的mnt目录下看到

[root@user mnt]# ls 
hello.txt
[root@user mnt]# cat hello.txt 
hello world!

4、利用共享目录传递应用程序并在QEMU中执行

        (1)应用测试

1、编写程序
#include <stdio.h>
  
int main(int argc, char **argv)
{
    printf("Hello World!\n");
    return 0;
}

2、编译
aarch64-linux-gnu-gcc test.c -o run

3、利用共享目录传递到QEMU中
cp ./run ../../../kmodules/

        在QEMU中可以正常运行,说明应用程序可以使用动态链接库

[root@user mnt]# ls
hello.txt  run
[root@user mnt]# ./run
Hello World!

          (2)内核module测试

                编写Makefile

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

KERNEL_DIR ?= //此处填写你内核源码的目录
obj-m := module_test.o

modules:
	 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

clean:
	 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

install:
	 cp *.ko $(KERNEL_DIR)/kmodules

                a.编写一个简单的module

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
  
static int __init test_init(void)
{
    printk("test_init\n");
    return 0;
}    

static void __exit test_exit(void)
{
    printk("test_exit\n");
}
  
  
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");

                b.编译module,拷贝到共享目录

make modules
make install

                c.在QEUM执行module的插入与卸载,可以看到成功执行并打印log

[root@user mnt]# ls
hello.txt       module_test.ko  run
[root@user mnt]# insmod module_test.ko 
[  570.643309] module_test: loading out-of-tree module taints kernel.
[  570.649633] test_init
[root@user mnt]# lsmod
module_test 16384 0 - Live 0xffff800000ff0000 (O)
[root@user mnt]# rmmod module_test.ko 
[  582.596130] test_exit

5、从磁盘启动QEMU

        initramfs的方式将我们的根文件系统的目录直接打包到内核源码,成为了内核的一部分,当然这个时候可以操作文件,但是系统重启就会丢失,你可以试试新建一些文件后关闭再进入QEMU,会发现文件不见了,因为所有的文件改动都是在内存中

        所以下面使用模拟磁盘的方式来挂载根文件系统,永久保存数据

        (1)制作磁盘文件

dd if=/dev/zero of=rootfs_ext4.img bs=1M count=8192
mkfs.ext4 rootfs_ext4.img
mkdir -p tmpfs
mount -t ext4 rootfs_ext4.img tmpfs/ -o loop
cp -af _install_arm64/* tmpfs/
umount tmpfs
rm -rf tmpfs
chmod 777 rootfs_ext4.img

        (2)执行QEMU从磁盘启动      

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8"  -nographic -drive if=none,file=rootfs_ext4.img,id=hd0 -device virtio-blk-device,drive=hd0 --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount

        可以看到800多M可以被我们使用,重新进入QEMU也能看到之前在根目录下创建的文件

[root@sofine ]# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root               973.4M     11.5M    894.7M   1% /
devtmpfs                465.0M         0    465.0M   0% /dev
tmpfs                   487.1M         0    487.1M   0% /tmp
kmod_mount                1.8T    349.5G      1.4T  20% /mnt

【参考博客】

[1] 掌握QEMU虚拟化技术:搭建ARM64+Linux调试环境实战指南 - 知乎

[2] 使用QEMU搭建ARM64实验环境

[3] https://www.cnblogs.com/lvzh/p/14907592.html

[4] (2023)从零开始用qemu搭建虚拟arm环境_qemu虚拟机-CSDN博客  

[5] QEMU环境搭建_qemu搭建-CSDN博客

[6] 使用QEMU(x86)模拟运行ARM64架构并进行内核调试_qemu86-CSDN博客

[7] qemu-system-aarch64使用和相关参数介绍-CSDN博客

[8] Linux内核编译,使用qemu启动 - 知乎

[9] Qemu安装之后如何卸载_ubuntu卸载qemu-CSDN博客

  • 34
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值