QEMU调试linux内核

时间:2024-05-22 16:10:44

经常会有学习linux的朋友在问学习linux是否一定要买发开版,答案是否定的,但如果你需要在产品级别的验证,买一块开发板做开发板还是非常有必要的。本文主要介绍使用QEMU来调试ARM linux内核,一台PC全部搞定,调试内核非常方便。当然也参考了网上的其他一些资料,这里主要基于的是ARM公司提供的开发板express,通过模拟的方法同样可以达到学习的目的。

1. 准备工作

在ubuntu16.04中安装如下工具:

sudo apt-get install qemu gcc-arm-linux-gnueabi

之后需要下载kernel和busybox的源码包:

Kernel的源码下载网址如下:https://mirrors.edge.kernel.org/pub/linux/kernel/

注:可以根据个人需要选择不同的kernel版本,我选择的是4.16.6

Busybox的源码下载网址如下: https://busybox.net/downloads/

注:本文介绍是以busybox-1.25.1为基础。

2. 编译最小文件系统和kernel

2.1 利用busybox编译最小文件系统

    进入busybox代码之后,文件结构如下:

QEMU调试linux内核

vim Makefile,并在其中添加如下

ARCH ?= arm

CROSS_COMPILE ?= arm-linux-gnueabi-

其次, 开始配置busybox, 终端运行make menuconfig

进入menuconfig之后,配置成静态编译。

Busybox Settings --->

Build Options --->

[*] BuildBusyBox as a static binary (no shared libs)

2.2 添加命令结合

最后,运行make install就可以编译busybox了。编译结束之后,在代码的根目录下会生成_install文件夹,该目录是编译好的文件系统需要的一些命令集合。

[email protected]:~/_install$ mkdir etc dev mnt

[email protected]:~/_install$ mkdir -p etc/init.d

在—install /etc/init.d/目录下新创建一个rcS文件,并写入如下内容。

mkdir -p /proc

mkdir -p /tmp

mkdir -p /sys

mkdir 一p/mnt

/bin/mount -a

mkdir -p /dev/pts

mount -t devpts devpts /dev/pts

echo /sbin/mdev >/proc/sys/kernel/hotplug

mdev –s

在rcS中添加上述内容以后,赋予rcS可执行权限,chmod +x /etc/init.d/rcS.

在_install/etc目录下创建fstab文件,并写入如下内容:

proc /proc proc defaults 0 0

tmpfs /tmp tmpfs defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /dev tmpfs defaults 0 0

debugfs /sys/kernel/debug debugfsdefaults 0 0

在_install/etc目录下创建一个inittab文件,并写入如下内容:

::sysinit:/etc/init.d/rcS

::respawn:-/bin/sh

::askfirst:-/bin/sh

::ctrlaltdel:/bin/umount -a –r

在_install/dev目录先创建如下的设备节点,注意需要root权限:

sudo mknod console c 5 1

sudo mknod null c 1 3

最后一步,将busybox中的_install文件夹copy到linux源代码的根目录下即可。

2.3 编译内核

2.3.1配置内核

[email protected]:~$ cdworkspace/linux-4.16.6/

[email protected]:~/workspace/linux-4.16.6$vim Makefile

在打开的Makefile文件中做如下修改:

-ARCH           ?= $(SUBARCH)

-CROSS_COMPILE  ?= $(CONFIG_CROSS_COMPILE:"%"=%)

+ARCH           ?= arm

+CROSS_COMPILE  ?= arm-linux-gnueabi-

[email protected]:~/workspace/linux-4.16.6$make vexpress_defconfig

配置initramfs,在initramfs source file中填入_install,同时把Default kernel command string清空,如下所示:

General setup --->

[*] InitialRAM filesystem and RAM disk (initramfs/initrd) support

(_install)Initramfs source file(s)

Boot options -->

()Default kernel command string

配置memory split为“3G/1G user/kernel split”, 并打开高端内存。

Kernel Features --->

Memory split: (3G/1G user/kernelsplit:)

[*] High Memory Support

2.3.2 编译内核

[email protected]:~/workspace/linux-4.16.6$make bzImage -j8

[email protected]:~/workspace/linux-4.16.6$make dtbs

到此关于配置kernel, busybox全部完成,接下就是运行qemu模拟ARM了。

3. 运行qemu模拟ARM

Vexpress是基于4核的Cortex-A9的开发平台,就下来就是运行qemu的命令:

 

[email protected]:~/workspace/linux-4.16.6$qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage-append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtbarch/arm/boot/dts/vexpress-v2p-ca9.dtb –nographic

这个地方也是很明确了,-M制定了vexpress-a9,smp(对称multiprocessor)为4核,-m制定只用的1G内存.

QEMU调试linux内核

用过的朋友会发现进入调试窗口之后,就无法在本终端中通过命令退出来了。我们可以重新打开一个终端,输入如下命令就可以关闭qemu模拟环境了。

[email protected]:~$ killallqemu-system-arm

4 qemu调试linux内核

4.1 安装armgdb调试工具

[email protected]:~$ sudo apt-getinstall gdb-arm-none-eabi

如果确定要用gdb去调试内核,在步骤2.3.1配置内核的编译选项是,需要打开

Kernel hacking --->

Compile-time checks and compileroptions 一一->

[*] Compile the kernel with debuginfo

之后在终端输入:

[email protected]:~/workspace/linux-4.16.6$qemu-system-arm -nographic -M vexpress-a9 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtbarch/arm/ boot/dts/vexpress-v2p-ca9.dtb -S –s

 

(*)-S:表示QEMU虚拟机会冻结CPU,直到远程的GDB输入相应控制命令。

(*)-s:表示在1234端口接受GDB的调试连接。

之后,我们重新打开一个终端,输入如下命令

[email protected]:~/workspace/linux-4.16.6$arm-none-eabi-gdb --tui vmlinux

QEMU调试linux内核

在gdb命令行中,输入如下命令

(gdb) target remote localhost:1234

(gdb) b start_kernel

(gdb) c

由此,便可以通过gdb的命令行来调试kernel了,正如上述命令,在start_kernel中设置了一个断点,界面如下:

QEMU调试linux内核