准备对Linux的内存管理单元进行学习,单纯阅读源码还是不如一步一步调试内核理解深刻,对于调试内核的方法,网上也有不少,主要是利用Qemu+GDB+IMX6对内核进行调试。
1. Qemu简介
QEMU的英文单词是:QuickEmulator,它是一个小巧的模拟器。还有很多模拟器,比如VMWare、Virtual Box等。但是VMWare、VirtualBox只能模拟x86、AMD64/Intel64等PC系统;而QEMU可以模拟更多硬件:ARM、MIPS、PPC、x86、AMD64/Intel64。QEMU用途广泛,比如Xen、Android模拟器等都是基于QEMU的。在嵌入式领域,很多人使用QEMU来深研Linux,比如研究文件系统、优化等等。
QEMU有两种模式:
- 用户模式:简单地说,一个使用arm-xxx-gcc编译出来的程序,是给ARM板子使用的,它无法在PC机上运行,只能放到ARM板子上去运行。借助qemu,可以在PC机上运行ARM程序。比如:
$ gcc -o hello hello.c -static
$ ./hello // 这个hello程序是使用gcc给PC机编译的,可以直接运行
Hello, world!
$ arm-linux-gnueabihf-gcc -o hello hello.c -static // 它是给ARM板子编译的
$ ./hello // 所以无法在PC上运行
bash: ./hello: cannot execute binary file: Exec format error
$ ./qemu-arm ./hello // 我们可以用QEMU在PC上运行它
Hello, world!
- 系统模式:很多时候我们并不满足于在PC上运行单个ARM程序,我们想模拟出整个ARM单板:在这个模拟出来的虚拟ARM单板上,运行Linux系统,在其中运行各种APP,这时候需要使用QEMU的系统模式。
2. 获取镜像
我们使用的是韦东山提供对于IMX6制作的镜像文件,其下载地址如下:
git clone https://git.dev.tencent.com/weidongshan/ubuntu-18.04_imx6ul_qemu_system.git
镜像目录结构如下:
目录结构及说明如下,在后续的开发过程中,我们有可能更换红框中的文件:
详细的操作过程见
3. QEMU+GDB调试内核
在之前的四个步骤中,已经准备好了全部的工具,下面就可以使用QEMU+GDB进行内核调试了。首先运行qemu-system-arm,运行如下命令:
/home/book/ubuntu-18.04_imx6ul_qemu_system/qemu/bin/qemu-system-arm -M mcimx6ul-evk -m 512M -kernel /home/book/ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image/zImage -dtb /home/book/ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image/100ask_imx6ull_qemu.dtb -serial stdio -drive file=/home/book/ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image/rootfs.img,format=raw,id=mysdcard -device sd-card,drive=mysdcard -append "console=ttymxc0,115200 console=tty1 rootfstype=ext4 root=/dev/mmcblk1 rw rootwait init=/sbin/init loglevel=8" -nic user -s -S
启动图像如下:
此时,开启另一个terminal,然后进入内核源码目录,运行arm-linux-gnueabihf-gdb vmlinux
可以看到gdb运行start_kernel
断点处停下来了,接下来就可以使用gdb的基本命令进行单步调试了。如果运行后,相应的内核打印信息会打印到qemu的service窗口上