当前位置:   article > 正文

QEMU搭建ARM64+Linux环境_qeum

qeum

目录

一、安装交叉编译工具链

二、安装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搭建环境时成功的步骤,便于后续的学习和实践

一、安装交叉编译工具链

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

        安装成功后可以查看版本

  1. user@ubuntu18:/$ aarch64-linux-gnu-gcc -v
  2. Using built-in specs.
  3. COLLECT_GCC=aarch64-linux-gnu-gcc
  4. COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/7/lto-wrapper
  5. Target: aarch64-linux-gnu
  6. 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
  7. Thread model: posix
  8. gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)

二、安装QEMU

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

  1. wget https://download.qemu.org/qemu-4.2.1.tar.xz
  2. tar xvJf qemu-4.2.1.tar.xz
  3. cd qemu-4.2.1
  4. ./configure
  5. make -j 8
  6. sudo make install

        安装成功后可以查看版本

  1. user@ubuntu18:/$ qemu-system-aarch64 --version
  2. QEMU emulator version 4.2.1
  3. 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、制定编译工具链

  1. cd busybox-1.36.1
  2. export ARCH=arm64
  3. export CROSS_COMPILE=aarch64-linux-gnu-

3、编译

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

4、创建需要的目录

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

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

(1)etc目录更新

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

  1. #!/bin/sh
  2. export HOSTNAME=user
  3. export USER=root
  4. export HOME=/home
  5. export PS1="[$USER@$HOSTNAME \W]\# "
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin
  7. LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
  8. export PATH LD_LIBRARY_PATH

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

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

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

  1. #device mount-point type options dump fsck order
  2. proc /proc proc defaults 0 0
  3. tmpfs /tmp tmpfs defaults 0 0
  4. sysfs /sys sysfs defaults 0 0
  5. tmpfs /dev tmpfs defaults 0 0
  6. debugfs /sys/kernel/debug debugfs defaults 0 0
  7. kmod_mount /mnt 9p trans=virtio 0 0

        d.创建init.d目录

  1. mkdir init.d
  2. cd init.d

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

  1. mkdir -p /sys
  2. mkdir -p /tmp
  3. mkdir -p /proc
  4. mkdir -p /mnt
  5. /bin/mount -a
  6. mkdir -p /dev/pts
  7. mount -t devpts devpts /dev/pts
  8. echo /sbin/mdev > /proc/sys/kernel/hotplug
  9. mdev -s

        添加权限

chmod 777 rcS

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

  1. tree
  2. .
  3. ├── fstab
  4. ├── init.d
  5. │ └── rcS
  6. ├── inittab
  7. └── profile
  8. 1 directory, 4 files

(2)dev目录下必要文件

  1. cd dev
  2. sudo mknod console c 5 1

(3)lib下必要文件

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

  1. cd lib
  2. 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、指定编译工具

  1. export ARCH=arm64
  2. export CROSS_COMPILE=aarch64-linux-gnu-

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

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

4、配置生成 .config

        修改defconfig

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

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

  1. a.添加hotplug支持
  2. Device Drivers
  3. -> Generic Driver Options
  4. -> Support for uevent helper
  5. (/sbin/hotplug) path to uevent helper
  6. b.添加initramfs支持
  7. General setup --->
  8. [*]Initial RAM filesystem and RAM disk(initramfs/initrd)
  9. support(_install_arm64) Initramfs souce file(s)
  10. c.Virtual address space配置
  11. Kernel Features --->
  12. Page size(4KB) --->
  13. 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
  1. --- machine virt:使用virt机器类型。
  2. --- cpu cortex-a57:使用Cortex-A57 CPU模型。
  3. --- -m 1024:设置虚拟机内存大小为1024MB。
  4. --- -smp 4:设置虚拟机使用4个CPU核心。
  5. --- -kernel arch/arm64/boot/Image`:指定Linux内核镜像的路径。
  6. --- --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8"`:指定内核启动参数,其中`rdinit`指定init程序的路径,`root`指定根文件系统的设备,`rw`表示以读写模式挂载根文件系统,`console`指定控制台设备,`loglevel`指定内核日志级别。
  7. --- -nographic`:禁用图形界面,使用纯文本控制台。
  8. --- --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none`:创建一个本地文件系统设备,其中`id`指定设备ID,`path`指定设备挂载的本地路径,`security_model`指定安全模型。
  9. --- -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进入控制台

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

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

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

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

        可以在QEMU的mnt目录下看到

  1. [root@user mnt]# ls
  2. hello.txt
  3. [root@user mnt]# cat hello.txt
  4. hello world!

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

        (1)应用测试

  1. 1、编写程序
  2. #include <stdio.h>
  3. int main(int argc, char **argv)
  4. {
  5. printf("Hello World!\n");
  6. return 0;
  7. }
  8. 2、编译
  9. aarch64-linux-gnu-gcc test.c -o run
  10. 3、利用共享目录传递到QEMU中
  11. cp ./run ../../../kmodules/

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

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

          (2)内核module测试

                编写Makefile

  1. export ARCH=arm64
  2. export CROSS_COMPILE=aarch64-linux-gnu-
  3. KERNEL_DIR ?= //此处填写你内核源码的目录
  4. obj-m := module_test.o
  5. modules:
  6. $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
  7. clean:
  8. $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
  9. install:
  10. cp *.ko $(KERNEL_DIR)/kmodules

                a.编写一个简单的module

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. static int __init test_init(void)
  5. {
  6. printk("test_init\n");
  7. return 0;
  8. }
  9. static void __exit test_exit(void)
  10. {
  11. printk("test_exit\n");
  12. }
  13. module_init(test_init);
  14. module_exit(test_exit);
  15. MODULE_LICENSE("GPL");

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

  1. make modules
  2. make install

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

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

5、从磁盘启动QEMU

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

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

        (1)制作磁盘文件

  1. dd if=/dev/zero of=rootfs_ext4.img bs=1M count=8192
  2. mkfs.ext4 rootfs_ext4.img
  3. mkdir -p tmpfs
  4. mount -t ext4 rootfs_ext4.img tmpfs/ -o loop
  5. cp -af _install_arm64/* tmpfs/
  6. umount tmpfs
  7. rm -rf tmpfs
  8. 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也能看到之前在根目录下创建的文件

  1. [root@sofine ]# df -h
  2. Filesystem Size Used Available Use% Mounted on
  3. /dev/root 973.4M 11.5M 894.7M 1% /
  4. devtmpfs 465.0M 0 465.0M 0% /dev
  5. tmpfs 487.1M 0 487.1M 0% /tmp
  6. 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博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/973375
推荐阅读
相关标签
  

闽ICP备14008679号