Linux下qemu的安装并搭建虚拟arm环境(带helloworld测试)【超详细】

qemu的安装并搭建虚拟arm环境

1、准备工作

1.1 安装交叉汇编工具

交叉编译器的作用就不需要详细解释了,因为我们是在x86平台上进行编译,而运行的平台是ARM系统,这2个平台的指令集不一样,所以需要交叉编译得到ARM系统上可以执行的程序。

bash 复制代码
sudo apt-get install gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf

验证安装结果:

bash 复制代码
dpkg -l gcc-arm-linux-gnueabi

1.2 编译内核kernel

下载内核kernel压缩包:

bash 复制代码
wget https://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/linux-5.10.tar.xz

使用 vexpress-a9 这款开发板。vexpress-a9 是 Arm 公司自己设计的一款 4 核 Cortex-A9 开发板,U-Boot、Linux Kernel 和 QEMU 对这款开发板都做了完整的支持。

解压:

bash 复制代码
tar -xvf linux-5.10.tar.xz

在解压后的linux-5.10目录下,生成vexpress开发板子的config文件:

bash 复制代码
cd linux-5.10
bash 复制代码
make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm vexpress_defconfig

编译32位kernel:

bash 复制代码
make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm

生成的内核镱像位于arch/arm/boot/zImage

设备树 arch/arm/boot/dts/vexpress-v2p-ca9.dtb

1.3 u-boot编译

注意更改当前路径

bash 复制代码
wget https://ftp.denx.de/pub/u-boot/u-boot-2020.10.tar.bz2

解压:

bash 复制代码
tar -xvf u-boot-2020.10.tar.bz

解压完后,可以看到 configs 目录下有针对这款开发板的配置文件。ca9x4表示cortexA9架构,4核心,vexpress_ca9x4_defconfig

bash 复制代码
ls configs/ | grep vexpress

编译:

bash 复制代码
make vexpress_ca9x4_defconfig
bash 复制代码
make CROSS_COMPILE=arm-linux-gnueabihf- all

编译时可能会出现提示:Your GCC is older than 6.0 and is not supported,解决方式如下:

更改uboot的源码:/arch/arm/config.mk

makefile 复制代码
# Only test once
ifeq ($(CONFIG_$(SPL_)SYS_THUMB_BUILD),y)
#archprepare: checkthumb checkgcc6
archprepare: checkthumb 
 
checkthumb:
    @if test "$(call cc-name)" = "gcc" -a \
            "$(call cc-version)" -lt "0404"; then \
        echo -n '*** Your GCC does not produce working '; \
        echo 'binaries in THUMB mode.'; \
        echo '*** Your board is configured for THUMB mode.'; \
        false; \
    fi
#else
#archprepare: checkgcc6
endif
 
#checkgcc6:
#   @if test "$(call cc-name)" = "gcc" -a \
#           "$(call cc-version)" -lt "0600"; then \
#       echo '*** Your GCC is older than 6.0 and is not supported'; \
#       false; \
#   fi

最终编译生成 elf 格式的可执行文件 u-boot 和纯二进制文件u-boot.bin,其中 QEMU 可以启动的为 elf 格式的可执行文件 u-boot :

1.4 制作根文件系统-busybox

根文件系统放在哪里?

其实依赖于每个开发板支持的存储设备,可以放到Nor Flash上,也可以放到SD卡,甚至外部磁盘上。最关键的一点是你要清楚知道开发板有什么存储设备。本次使用SD卡做为存储空间,文件格式为ext3格式。

①下载、编译和安装busybox:(注意更改当前路径)

链接:busybox - BusyBox: The Swiss Army Knife of Embedded Linux

版本:busybox-1_30_0

解压,并进入该目录下:

bash 复制代码
tar xjvf  busybox-1_30_0.tar.bz2
bash 复制代码
cd busybox-1_30_0

因为是配置arm环境,交叉编译到arm上运行, 需要修改Makefile:

bash 复制代码
vim Makefile

修改成这样:

编译,安装:

bash 复制代码
make menuconfig			

执行上述指令会出现如下界面,点击Settings->,再设置静态编译:

编译:

bash 复制代码
make -j6

编译完成后检查,成功:

bash 复制代码
ls -l busybox

安装(在busybox-1_30_0/_install目录下安装):

bash 复制代码
make install

安装完成后会形成_install目录:

②形成根目录结构:

在Ubuntu主机环境下,形成目录结构,里面存放的文件和目录与单板上运行所需要的目录结构完全一样,然后再打包成镜像(在开发板看来就是SD卡),这个临时的目录结构称为根目录。

首先创建rootfs目录(根目录),根文件系统内的文件全部放到这里:

bash 复制代码
mkdir -p rootfs/{dev,etc/init.d,lib}

把busybox中的文件复制到rootfs根目录下,主要是一些基本的命令:

bash 复制代码
sudo cp busybox-1_30_0/_install/* -r rootfs/

把交叉编译工具链中的库文件复制到rootfs根目录的lib文件夹下:

bash 复制代码
sudo cp -P /usr/arm-linux-gnueabi/lib/* rootfs/lib/

创建4个tty端终设备:

bash 复制代码
sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4

③制作根文件系统镜像:

根文件系统镜像就相当于一个硬盘,就是把上面rootfs根目录中的所有文件复制到这个硬盘中。

生成512M大小的镜像:

bash 复制代码
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32

格式化成ext3文件系统:

bash 复制代码
mkfs.ext3 a9rootfs.ext3

挂载,将文件拷贝到镜像中:

bash 复制代码
sudo mkdir tmpfs
bash 复制代码
sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
bash 复制代码
sudo cp -r rootfs/*  tmpfs/
bash 复制代码
sudo umount tmpfs

2、启动qemu(arm)

目录结构:

启动qemu(arm环境):

bash 复制代码
qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-5.10/arch/arm/boot/zImage -dtb linux-5.10/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0  console=ttyAMA0" -sd a9rootfs.ext3

启动完成:

退出qemu:Ctrl+A 松开后按 X 退出qemu。

关于qemu启动ARM虚拟机运行指令解析:

bash 复制代码
qemu-system-arm 											#qemu主要配置
-M vexpress-a9 												#模拟vexpress-a9单板
-m 512M 													#内存配置
-kernel linux-5.10/arch/arm/boot/zImage 					#内核路径
-dtb linux-5.10/arch/arm/boot/dts/vexpress-v2p-ca9.dtb 		#设备树路径
-nographic 													#不使用图形化界面,只使用串口
-append "root=/dev/mmcblk0  console=ttyAMA0" 				#内核启动参数(vexpress单板运行)
-sd a9rootfs.ext3											#SD卡印像

3、helloworld测试

在Ubuntu任意一个目录,编写HelloWorld可执行程序hello.c:

bash 复制代码
vim hello.c
c 复制代码
#include <stdio.h> 
int main() 
{     
    printf("HelloWorld! \n");
    return 0; 
}

交叉编译hello.c,得到arm的可执行程序hello:

bash 复制代码
arm-linux-gnueabi-gcc hello.c -g -o hello.exe  #带上-g选项编译debug版本

通过file指令,可查看hello.exe程序:

bash 复制代码
file hello.exe

把hello可执行程序复制到磁盘镜像disk.img中:

挂载(路径/home/kevin/kernel510):

bash 复制代码
sudo mount -o loop ./a9rootfs.ext3 tmpfs/ 

复制文件(注意路径):

bash 复制代码
sudo cp /home/kevin/hello.exe /home/kevin/kernel510/tmpfs/

卸载:

bash 复制代码
sudo umount tmpfs

再次启动虚拟机:

bash 复制代码
qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-5.10/arch/arm/boot/zImage -dtb linux-5.10/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0  console=ttyAMA0" -sd a9rootfs.ext3 -S -gdb tcp::8080

执行hello.exe程序,即可看到输出结果:

相关推荐
IT果果日记17 分钟前
ubuntu 安装 conda
linux·ubuntu·conda
Python私教20 分钟前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
羑悻的小杀马特33 分钟前
环境变量简介
linux
小陈phd1 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
运维&陈同学1 小时前
【zookeeper01】消息队列与微服务之zookeeper工作原理
运维·分布式·微服务·zookeeper·云原生·架构·消息队列
是阿建吖!1 小时前
【Linux】进程状态
linux·运维
明明跟你说过2 小时前
Linux中的【tcpdump】:深入介绍与实战使用
linux·运维·测试工具·tcpdump
Komorebi.py3 小时前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh3 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
内核程序员kevin6 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip