經常會有學習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代碼之後,文件結構如下:
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文件夾,該目錄是編譯好的文件系統需要的一些命令集合。
hayden@ubuntu:~/_install$ mkdir etc dev mnt
hayden@ubuntu:~/_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配置內核
hayden@ubuntu:~$ cdworkspace/linux-4.16.6/
hayden@ubuntu:~/workspace/linux-4.16.6$vim Makefile
在打開的Makefile文件中做如下修改:
-ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH ?= arm
+CROSS_COMPILE ?= arm-linux-gnueabi-
hayden@ubuntu:~/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 編譯內核
hayden@ubuntu:~/workspace/linux-4.16.6$make bzImage -j8
hayden@ubuntu:~/workspace/linux-4.16.6$make dtbs
到此關於配置kernel, busybox全部完成,接下就是運行qemu模擬ARM了。
3. 運行qemu模擬ARM
Vexpress是基於4核的Cortex-A9的開發平臺,就下來就是運行qemu的命令:
hayden@ubuntu:~/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模擬環境了。
hayden@ubuntu:~$ killallqemu-system-arm
4 qemu調試linux內核
4.1 安裝armgdb調試工具
hayden@ubuntu:~$ sudo apt-getinstall gdb-arm-none-eabi
如果確定要用gdb去調試內核,在步驟2.3.1配置內核的編譯選項是,需要打開
Kernel hacking --->
Compile-time checks and compileroptions 一一->
[*] Compile the kernel with debuginfo
之後在終端輸入:
hayden@ubuntu:~/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的調試連接。
之後,我們重新打開一個終端,輸入如下命令
hayden@ubuntu:~/workspace/linux-4.16.6$arm-none-eabi-gdb --tui vmlinux
在gdb命令行中,輸入如下命令
(gdb) target remote localhost:1234
(gdb) b start_kernel
(gdb) c
由此,便可以通過gdb的命令行來調試kernel了,正如上述命令,在start_kernel中設置了一個斷點,界面如下: