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程序,即可看到输出结果:

相关推荐
A小辣椒20 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式