一、 编译要调试的内核,我要调试的内核版本是Linux-2.6.32版本
1. 下载内核源代码:http://www.kernel.org/ 下载2.6.32内核的完整版。
2. 解压内核并进入内核目录
# tar jxvf linux-2.6.32.tar.bz2
# cd linux-2.6.32
3. 清除内核配置
# make mrproper
4.配置内核
a. 拷贝ubuntu默认的x86配置文件 #cp /boot/config-`uname -r` ./.config
b. # cp /boot/config-2.6.28-11-generic //本条是上面一条的真实写法。
c. 使用ubuntu的配置的话可以直接跑起来,但是是针对X86的配置。针对Arm的还没有移植,后续需要对Android的内核,针对
Arm的做移植.
d. 配置内核参数确保下面的配置以及配置.
# make menuconfig
然后我们看到内核的配置菜单. 移动绿色光标到
Load an Alternate Configuration File
行后选择.config文件(包含了当前工作内核的配置)做为配置文件:
Kgdb内核编译选项:
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
选项在 Kernel hacking 里可以找到
同时,为了能在系统运行时中断系统并出发远程 gdb,必须打开内核 Magic Sys-Rq 键选项 :
CONFIG_MAGIC_SYSRQ=y
打开内核符号调试:
CONFIG_DEBUG_INFO=y
注意事项:
CONFIG_DEBUG_RODATA 必须被禁用,否则kgdb讲无法正常使用。
在Kernel Hacking-下面如图
1. Sys-Rq键的选择如下:
2.Kernel Debuging…. 选项
4. Compile the kernel with debug info
5.
-------KGDB: Kernel Debuging with remote gdb
<*> KGDB: use kgdb over the serial console
6.禁止的选项:
修改编译参数, 必须有-g –O –ggdb
重要的一步:修改Makefile 里面的编译选项:
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
CFLAGS += -O //原来是-Os 这个比 –O2 优化的还厉害呢
else
CFLAGS += -O2
Endif
…
ifdef CONFIG_DEBUG_INFO
CFLAGS += -g -ggdb
Endif
然后浏览内核配置菜单, 选择你需要的功能. 完成配置后, 选择Exit, 回答下面的问题(Do you wish to save your
new kernel configuration? 你希望保存新的内核配置吗?), 选择Yes:
e. 可选安装编译需要的安装包
# apt-get install kernel-package libncurses5-dev fakeroot wget bzip2
f. 编译内核 (带ctags cscope编译内核方便阅读内核源代码)
# make bzImage tags cscope
# make modules
g. 编译成功:
#${内核目录} /arch/x86/boot/bzImage -----编译好的压缩的bzImage内核映像
#${内核目录}/vmlinux ------编译好的未压缩的vmlinux内核映像
其中bzImage是用KVM虚拟机器启动的
二、KVM +Kqemu安装
#sudo apt-get install kvm
#lsmod kqemu
#rmmod kqemu
#modprobe kqemu major=0
二、根文件系统的制作
1) 创建rootfs img
#qemu-img create rootfs.img 5G
#mkfs.ext3 -b 2048 rootfs.img
#sudo mount -o loop rootfs.img /mnt
编译busybox的Rootfs
1.下载http://www.busybox.net/ 下在 BusyBox 1.15.2
2. 执行make menuconfig,然后进行设置,我截了几张图,这几张图就是在进行配置时需要重点注意的地方:
(1)在General Configuration中,一定要选择“Support for devfs”选项,现在的Busybox新版本去掉了这
个选项,不过应该可以通过修改配置文件加入。
(2)在Build Options选项中,选择使用“静态库”以及设置交叉编译工具的PREFIX。
(3)在Linux System Utilities选项中,“Support loopback mounts”和“Support for
the old /etc/mtab file”2个选项应该选中。
(4) 在Init Utilities选项中,“Support reading an inittab file”应该选中,这样可以根据自己编写
的inittab文件初始化;“Support running commands with a controlling-tty”应该选中,否则会
提示非常困扰的“/bin/sh: can't access tty; job control turned off”的提示,尽管可以进入控制台
命令行。
(4)在Shell选项中,应该选中默认shell:ash,否则不会生成sh,导致不能解释脚本文件。
(5)其他的选项根据自己的需要设置。
3. 配置完成后,退出保存(最好备份.config文件以供后用),然后开始生成,执行make TARGET_ARCH=arm;此处的
TARGET_ARCH是必须的。生成完成后使用qemu-arm测试:qemu-arm ./busybox ls,如果没有错误的话,会显示出 当
前目录下的文件列表。
说明:在生成的过程中,提示了“/mnt/extdisk/embedded/busybox-1.1.3/include/
bbconfigopts.h:28 hmm, untermina”错误,分析相应的文件,发现应该是一个配置包含文件,在配置后保存
在.config文件中,因此这个文件中的内容应该不是关键内容,因此我将此文件清空保存,然后重新执行上面的生成命令,成功。
4. 生成结束后,执行make install,生成一个_install文件夹,内有一个linuxrc文件和bin、sbin、usr三个文件
夹,删除linuxrc,将三个文件夹打包。
5. 准备生成cramfs文件系统:
(1)创建一个文件夹,比如rootfs,转到rootfs,执行命令mkdir bin dev etc home lib mnt proc
sbin sys tmp var usr,建立相应的文件夹,再建立etc下的init.d文件夹。
(2)准备启动所需的文件:linuxrc、rcS、inittab、fstab四个文件;
linuxrc文件:
----------------------------------------------
#!/bin/sh
echo "mount /etc as ramfs"
/bin/mount -f -t cramfs -o remount,ro /dev/bon/2 /
/bin/mount -t ramfs ramfs /var
/bin/mkdir -p /var/tmp
/bin/mkdir -p /var/run
/bin/mkdir -p /var/log
/bin/mkdir -p /var/lock
/bin/mkdir -p /var/empty
#/bin/mount -t usbdevfs none /proc/bus/usb
exec /sbin/init
------------------------------------------------
rcS文件:
-----------------------------------------------------------------------------------
#!/bin/sh
/bin/mount -a
-----------------------------------------------------------------------------------
这两个文件生成后,应该使其具有执行的权限,可使用chmod 775 linuxrc rcS来修改,linuxrc应该放在rootfs根目录,
rcS应该放在rootfs/etc/init.d/目录。
inittab文件:
-------------------------------------------------
# This is run first except when booting
::sysinit:/etc/init.d/rcS
# Start an "askfirst" shell on the console
#::askfirst:-/bin/bash
::askfirst:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
-------------------------------------------------
fstab文件:
-------------------------------------------------
none /proc proc defaults 0 0
none /dev/pts devpts mode=0622 0 0
tmpfs /dev/shm tmpfs defaults 0 0
-------------------------------------------------
这两个文件应该放在rootfs/etc/目录,应该注意其权限问题。
(3)如果使用linux 2.6.xx内核,应该实现创建节点console、null。转到rootfs/dev/目录来创建:
sudo mknod console c 5 1
sudo mknod null c 1 3
否则就会提示“Warning: unable to open an initial console.
Kernel panic - not syncing: Attempted to kill init!”的类似错误。
(4)将刚才在busybox的_install下的三个文件夹的打包文件复制到rootfs目录,解压后删除打包文件。
(5) 也可以将一些常用的lib文件复制到rootfs/lib/目录下,比如:ld-2.5.so libc-2.5.so
libcrypt.so.1 libgcc_s.so.1 libm.so.6 ld-linux.so.3
libcrypt-2.5.so libc.so.6 libm-2.5.so等文件或符号连接,在复制时应该注意采用图形化的界面复制活
打包后解包方式复制。
(6)转到rootfs的上一级目录,使用mkcramfs制作文件系统:./mkcramfs rootfs xxxxx.cramfs,然后下载、
少录、启动,成功,如下图所示:
6. 后记
(1)qemu-arm仿真工具
花 费了2天多的时间来使用Busybox制作文件系统,时间有点长,主要是开始走了弯路,使用Busybox1.10版本,当时不太清楚有qemu-
arm 仿真arm的工具,借助qemu-arm仿真工具可以很方便的验证自己的busybox编译结果是否正确,可以节省很多时间。就如刚开始我使
用 busybox1.10版本,没有借助qemu-arm仿真,下载后启动出现”Failed to execute /linuxrc.
Attempting defaults...“的错误,这个错误很难排除,这几天一有时间就查资料看解决这个问题的方法,只可惜浪费了时间。
(2)交叉编译工具
看 网上有资料说,linux内核以及busybox最好使用相同的交叉编译工具编译,否则可能会出现问题。我使用的是不同版本的交叉编译工具,没有出
现问 题。因为linux2.6.24内核是几天前编译的,采用的是4.2.1版本;今天编译busybox1.1.3用的是3.3.2版本。
(3)BusyBox
Linux2.6.xx 内核取消了devfs的支持,Busybox也跟上了这个步伐,前面我也提到过,对于busybox的新版本应该可以通过修改
配置文件十七支持 devfs,具体方法:修改Config.in文件,找到menu "General Configuration",然后在其后适
当位置加入如下内容:
config CONFIG_FEATURE_DEVFS
bool "Support for devfs"
default n
help
Enable if you want BusyBox to work with devfs.
这样,在进行配置时就会出现“Support for devfs”选项。只是我加入后,在进行编译,所得到的busybox也没有在qemu-arm
仿真中通过。
三、KVM使用
四、GDb远程调试:
3,启动GDB
gdb vmlinux
设定波特率
set remotebaud 115200
连接到调试系统
target remote localhost:4321
当调试系统就绪时,会有如下信息
Remote debugging using localhost:4321
Malformed response to offset query, QC0000000000000001
重新连接到调试系统
target remote localhost:4321
4,让系统启动完成(不打算调试启动过程的话)
continue
5,让系统陷入调试
在目标系统上输入
echo g > /proc/sysrq-trigge
=======================
使用qemu gdb-stub使用:
A Qemu debug memo
0) 安装qemu
sudo apt-get install qemu qtemu
2) 创建根文件系统
没有?在虚拟机内安装一个精简的ubuntu算了....
3)启动qemu (-S 让qemu停止,并等待gdb的链接)
qemu -kernel export/common_pc-bzImage-WR2.0zz_cgl -hda rootfs.img -
append "root=/dev/hda" -S
4) 在qemu窗口输入
ctrl+alt+2 切换到qemu 控制台
输入gdbserver 6443
5) 启动gdb
gdb common_pc-vmlinux-symbols-WR2.0zz_cgl
>target remote 127.0.0.1:6443
> b start_kernel
> c
6)tips
---比如设置了运行b fork, 在启动的时候可以c 50, 代表忽略50各种break point.
---Ctrl+C 即可停止内核运行, bt可以看到当前运行的函数