您的当前位置:首页正文

搭建基于qemu的linux开发环境

2024-04-27 来源:小奈知识网
搭建基于qemu的linux开发环境

在某些情况下,如果我们没有Mini2440开发板,或者开发板某些硬件损坏了,这时候我们还要继续学习linux内核移植和驱动开发,我们应该怎么办,这⾥我们可以采⽤qemu搭建linux开发环境。

在之前的u-boot系列博客中我们已经介绍了u-boot的移植、以及linux内核移植、根⽂件系统制作。并且尝试将编译后的程序烧录到开发板中运⾏。⽽这⼀节我们将尝试在qemu上搭建这⼀套开发环境。

由于我们要使⽤qemu模拟⼀个开发板,在安装了qemu之后,在系统环境下输⼊: qemu-system-arm -M help 可以查看qemu⽀持的ARM平台的开发板的型号,如下图所⽰:

这⾥是没有smdk2440这块板⼦的,结合⼀下⽹上的资料后发现 有关 的资料和讨论最多,所以我们选择这个开发板来进⾏模拟。

⼀、准备⼯作

1.1 qemu介绍

qemu 是⼀个硬件虚拟化程序( hypervisor that performs hardware virtualization),与传统的 VMware / VirtualBox 之类的虚拟机不同,它可以通过 binary translation 模拟各种硬件平台(⽐如在 x86 机器上模拟 ARM 处理器)。⽽ VirtualBox 等更多是通过虚拟化来进⾏资源隔离,以便在其上运⾏多个 guest os。

基于 qemu 的硬件模拟能⼒,我们可以轻松搭建指定硬件平台的运⾏实验环境。

qemu 与 VirtualBox 另⼀个不同点在于,在 VirtualBox 上必须安装⼀个完整的操作系统套件,⽽通过 qemu 我们可以通过参数直接启动到⼀个裸的 Linux Kernel,连 bootloader 都不需要关⼼。在此之外,按需配置相关⼯具套件与启动好的 Kernel ⼀起⼯作即可。qemu 提供的这种⾼度可定制化的⽩盒能⼒,使得我们可以按需构建快速、轻量级的开发环境,提供流畅的开发体验。1.2 安装qemu

在ubuntu环境下安装qemu:

sudo apt install qemu

⼆、编译linux内核

2.1 编译配置

这⾥我们使⽤linux-5.2.8源码,执⾏如下命令:

cd /work/linux-5.2.8 #源码放在这个路径make ARCH=arm vexpress_defconfig

配置完成后相应的配置项会保存在 .config ⽂件中。下⼀次执⾏ make menuconfig 时可以 load 这份配置⽂件,在此基础上进⾏修改。进⼊菜单配置,进⾏以下设置:

make ARCH=arm menuconfig

System Type -->

[ ] Enable the L2x0 outer cache controller 取消该选项,否则qemu运⾏不起来Kernel Features -->

[*] Use the ARM EABI to compile the kernel 确保该选项被选择2.2 编译内核和模块编译内核镜像时,执⾏:

make ARCH=arm CROSS_COMPILE=arm-linux-

编译成功后,arch/arm/boot⽬录下⽣成内核镜像⽂件zImage。

同时在路径下⽣成设备树⽂件:arch/arm/boot/dts/vexpress-v2p-ca9.dtb

需要注意编译linux内核使⽤的是arm-linux-gcc4.6.4。2.3 运⾏测试

编译好内核以后,我们就可以使⽤qemu启动内核了。只需要使⽤-kernel参数告诉qemu内核⽂件的位置即可:

qemu-system-arm \\-M vexpress-a9 \\-m 512M \\

-kernel /work/linux-5.2.8/arch/arm/boot/zImage \\

-dtb /work/linux-5.2.8/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \\-nographic \\

-append \"console=ttyAMA0\"

-m指定内存⼤⼩;

-kernel:指定内核⽂件路径;

-nographic: 不使⽤图形界⾯,只使⽤串⼝;-dtb: 指定dtb⽂件路径;

-append :内核启动参数,这⾥是告诉内核运⾏的串⼝设备是什么;也可以使⽤ qemu-system-arm --help 来查看其他参数的使⽤说明。

不出意外的话,就可以在启动窗⼝中看到内核的启动⽇志了。在内核启动的最后,会出现⼀条 panic ⽇志:

---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---

从⽇志内容可以看出,内核启动到⼀定阶段后尝试加载根⽂件系统,但我们没有指定任何磁盘设备,所以⽆法挂载根⽂件系统。⽽且编译出来的内核模块现在也没有⽤上,内核模块也需要存放到⽂件系统中供内核需要的时候进⾏加载。所以,接下来需要制作⼀个磁盘镜像⽂件供内核作为根⽂件系统加载。注意:如果需要退出qemu:在qemu中输⼊ctrl+a 抬起后,再输⼊’x’。

三、根⽂件系统制作

根⽂件系统的制作,需要使⽤busybox⼯具,参考之前的⽂章,按照这篇⽂章的前两节进⾏操作,⽣成rootfs⽂件夹即可:

制作SD卡镜像:

cd /work/sambashare

dd if=/dev/zero of=rootfs.ext4.img bs=1M count=32

此时会在当前路径下⽣成rootfs.ext4.img⽂件:

-rw-r--r-- 1 root root 33554432 2⽉ 8 22:24 rootfs.ext4.img

显然,rootfs.ext4.img并不是真正的SD卡设备,它只是我们在磁盘上创建的⼀个⽂件(为qemu创建的虚拟SD卡)。

接下来我们会假装它是⼀张SD卡,并正⼉⼋经的对其进⾏格式化、挂载等操作。先将它按照ext4⽂件系统格式进⾏格式化:

mkfs.ext4 rootfs.ext4.img

成功后显⽰如下:

把这个镜像⽂件按照ext4⽂件系统类型进⾏挂载,从⽽⽅便往⾥⾯拷贝内容。

注意,rootfs.ext4.img不是真正的SD卡,实质是⼀个⽂件,⼀个包含有⽂件系统格式的⽂件,也就是⼀个loop设备。所以挂载的时候要添加loop选项:

mkdir -p /mnt/rootfs # 没有才创建

mount -t ext4 -o loop rootfs.ext4.img /mnt/rootfs

这⾥我们将rootfs.ext4.img挂载到/mnt/rootfs路径下。

最后,将我们通过busybox创建的根⽂件系统拷贝到挂载点/mnt/rootfs上,并卸载rootfs.ext4.img:

cp -a rootfs/* /mnt/rootfs/umount /mnt/rootfs

此时⽂件系统将会被拷贝到rootfs.ext4.img⽂件系统中。

四、在qemu上利⽤启动kernel

制作好根⽂件系统镜像之后,就可以使⽤qemu运⾏kernel了,看看能不能成功挂载根⽂件系统。运⾏如下命令:

qemu-system-arm \\-M vexpress-a9 \\-m 512M \\

-kernel /work/linux-5.2.8/arch/arm/boot/zImage \\

-dtb /work/linux-5.2.8/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \\-nographic \\

-sd /work/sambashare/rootfs.ext4.img \\

-append \"root=/dev/mmcblk0 rw console=ttyAMA0\"

启动成功后,最后出现如下图⽰:

Please press Enter to activate this console.

按提⽰按下 Enter 键之后将会启动 shell,进⾏到我们熟悉的环境,可以执⾏各种常⽤命令了。

⽐如运⾏命令:

[root@zy:/]# ls

bin lib mnt sbin usrdev linuxrc proc sysetc lost+found root tmp

设备⽂件也被⾃动创建了:

[root@zy:/]# ls /dev

console tty10 tty53cpu_dma_latency tty11 tty54full tty12 tty55gpiochip0 tty13 tty56gpiochip1 tty14 tty57...

五、总结

到了这⾥,基于qemu的linux开发环境已经搭建成功了。这⾥从⽹上找到⼀张linux内核启动流程图:

参考⽂章:[1]

[2](部分转载)[3][4]

因篇幅问题不能全部显示,请点此查看更多更全内容