一,前言
由于之前玩了下qemu觉得效果不错。然后看了下源码,很少的代码就能实现这样的功能,以前只知道虚拟机是和主机共享硬件,其它都不知道了。但是qemu它不单单是虚拟机共享,它还能仿真其它arm内核的芯片。所以好奇它的原理,花点时间了解下,并且学习下它的代码设计思路,取其精华去其糟粕。
二,解决疑问
- qemu是如何仿真其它芯片的。
我们和程序可以运行的原因是通过编译器编译为了机器能识别的二进制码。所以qemu利用了此原理,将需要仿真的targe的二进制bin文件翻译为主机对应的二进制码,所以就可以仿真不同框架的代码了。target->TCG->host。所有不同种类的芯片cpu代码都先翻译为TCG格式,然后翻译为当前的主机cpu代码。 -
qemu是如何仿真的。
qemu可以借助KVM加速模拟速度,属于半虚化。KVM是主机内核的虚化模块,qemu通过访问KVM则可以和主机共享IO。关于全虚化就是qemu自行模拟所有IO,当然速度会比半虚化慢。我现在初步理解了下qemu和KVM的关系。
-
qemu如何二次开发添加自定义开发板的
这个要打开qemu代码看了。简单的了解了下,打开HW文件夹里面有开发板信息,打开后可以看到都是从type_init开始的。看上去和linux的设备驱动模型有点像。官网和网上都搜索下了相关资料。看了下0.9版本1.3版本2.8版本感觉早期版和现在版本区别比较大。最选择看2.8版本。因为我下载了一个2.8版本的STM32特制板源码,通过对比来学习它如何添加设备的,重点内容会比较突出。
- qemu的实现机制
网上了解下qemu源码每个文件夹的主要功能。qemu其实是app代码,要配合内核中的KVM使用来虚拟cpu和内存。然后vl.c里面的main是它的主函数 。先看了下代码,它的main函数通过回调函数注册完成后,在mainloop函数用了glib的poolfd事件触发机制。然后关于内核/dev/kvm需要创建虚拟机vcpu相关部分我还不太清楚。
我现在的理解,简单来说注册了fd的模拟IO读写,然后poolfd后进行对应的回调函数进行截取或模拟,就实现了qemu的虚拟机功能。
三,GDB调试qemu
重新编译qemu使其带调试信息,在ubuntu16.04的虚拟机中运行
./configure --target-list=arm-softmmu --enable-debug
make
很顺利的编译完成,然后运行如下命令
- cd /home/tftpboot/
- export PATH=/work/qemu2_8/qemu-2.8.0/arm-softmmu:$PATH
- 直接运行qemu检验效果
qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/tftpboot/my/zImage -dtb /home/tftpboot/my/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd a9rootfs.ext3 - GDB调试命令
gdb --tui --args /work/qemu2_8/qemu-2.8.0/arm-softmmu/qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/tftpboot/my/zImage -dtb /home/tftpboot/my/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd a9rootfs.ext3
先用gdb调试了下,效果如下
vexpress_machine_init,vexpress_a9_class_init,vexpress_instance_init
四 后续还会有源码分析
周末天好,我先出去运动运动了。关于qemu2.8的源码分析,欲知详情,且看下回分解。