http://www.devfront.com/?q=node/302一种方便的Linux内核调试方法:VirtualBox + KGDB Sat,
2007-07-21 02:24 — Marchday
基本想法是:配置GUEST OS的串口,使它定向到HOST OS的unix socket文件。然后使用socat把这个unix socket文件定向到UDP某个端口监听。gdb连接这个UDP端口,从而实现对guest OS kernel的调试。 说起来满复杂,做起来并不难。我的HOST OS是Ubuntu 7.04,gcc 3.4,binutils 2.17,基本步骤如下: 1. VirtualBox的准备工作 安装VirtualBox,安装GUEST OS,然后配置串口。假设GUEST OS是CentOS 5.0,名称是CentOS50_00,把它的/dev/ttyS0定向到host OS的/tmp/vboxpipe-CentOS50_00,只要在HOST OS运行如下命令就可以: VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/Config/IRQ" 4 VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/Config/IOBase" 0x3f8 VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/LUN#0/Driver" Char VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Driver" NamedPipe VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Config/Location" "/tmp/vboxpipe-CentOS50_00" VBoxManage setextradata "CentOS50_00" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Config/IsServer" 1 2. 编译内核 从 http://www.kernel.org 上下载内核linux-2.6.15.5.tar.gz,从http://kgdb.linsyssoft.com/下载linux-2.6.15.5- kgdb-2.4.tar.bz2。把linux-2.6.15.5.tar.gz解压到/usr/src,解压后的目录应该是linux- 2.6.15.5,切换到这个目录,把linux-2.6.15.5-kgdb-2.4.tar.bz2解压到这个目录。结果如下: [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# pwd /usr/src/linux-2.6.15.5 [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# ls arch Documentation ipc linux-2.6.15.5-kgdb-2.4 Module.symvers security block drivers Kbuild linux-2.6.15.5-kgdb-2.4.tar.bz2 net sound COPYING fs kernel MAINTAINERS README System.map CREDITS include kgdbfs.txt Makefile REPORTING-BUGS usr crypto init lib mm scripts vmlinux 2.1 给内核打补丁 阅读linux-2.6.15.5-kgdb-2.4目录下面的README,按照所说的文件列表的顺序给内核打补丁。我把需要的补丁文件存为 kgdbfs.txt(见上面的ls列表显示),内容如下: [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# cat kgdbfs.txt core-lite.patch core.patch i386-lite.patch i386.patch 8250.patch eth.patch cfi_annotations.patch sysrq_bugfix.patch module.patch netpoll_pass_skb_to_rx_hook.patch 然后执行如下命令就可以打上补丁: [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# for pp in $(cat kgdbfs.txt);do patch -p 1 < linux-2.6.15.5-kgdb-2.4/$pp;done 会有提示说文件不匹配,不过那是非x86平台用的,我们直接跳过去。 2.2 配置并编译内核 执行 make menuconfig 配置内核,注意在Kernel hacking选项把 KGDB 相关项勾上。我把串口芯片8250的驱动、ext2/ext3文件系统编译进了内核,这样省得加载驱动模块。 接下来是编译内核,make一下就可以。编译的结果会在arch/i386/boot/生成bzImage文件,把该文件拷贝到GUEST OS的/boot目录。 2.3 安装新内核模块 模块安装有一个小技巧,因为你并不想把模块安装到HOST OS吧。可指定模块安装的目标,比如 [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# make modules_install INSTALL_MOD_PATH=/tmp 然后把/tmp/lib目录下的内核模块目录拷贝到GUEST OS的/lib/modules下面。 2.4 准备init ramdisk 本来你还需要制作init ramdisk,以创建控制台设备,进行内核启动前的用户空间初始化。如果需要那么做,可以从usr目录(相对于内核编译目录)寻求帮助。我是直接用 GUEST OS原内核的init ramdisk。 2.5 修改GUEST OS的启动配置文件 修改GUEST OS的/boot/grub/menu.lst文件,新加上 title Kernel Debug (2.6.15.5-kgdb) root (hd0,0) kernel /boot/vmlinuz-2.6.15.5-kgdb ro root=/dev/hda1 kgdbwait initrd /boot/initrd-2.6.18-8.el5.img 3. 调试内核 确保GUEST OS存在新编译的内核,内核相关的模块,grub.conf已设置妥当。重启GUEST OS,选择启动新内核,如没问题就可看到如下提示: Uncompressing Linux... Ok, booting the kernel. 这时候在HOST OS开启一个终端窗口,重定向GUEST OS的串口: [EMAIL PROTECTED]:/tmp# socat udp4-listen:6443 /tmp/vboxpipe-CentOS50_00 再开启另一个终端窗口,调试内核: [EMAIL PROTECTED]:/usr/src/linux-2.6.15.5# gdb ./vmlinux GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) target remote udp:localhost:6443 warning: The remote protocol may be unreliable over UDP. Some events may be lost, rendering further debugging impossible. Remote debugging using udp:localhost:6443 warning: shared library handler failed to enable breakpoint breakpoint () at kernel/kgdb.c:1876 1876 atomic_set(&kgdb_setting_breakpoint, 0); (gdb) l 1871 1872 atomic_set(&kgdb_setting_breakpoint, 1); 1873 wmb(); 1874 BREAKPOINT(); 1875 wmb(); 1876 atomic_set(&kgdb_setting_breakpoint, 0); 1877 } 1878 1879 EXPORT_SYMBOL(breakpoint); 1880 (gdb) 输入gdb命令 c 就会完成内核的启动过程,Ctrl-C中断内核,回到gdb控制。 如果我的文章有疏漏,建议参考 KGDB快速开始 (http://kgdb.linsyssoft.com/downloads/kgdb-2/kgdbquickstart-2.4.pdf)。 相关连接: KGDB官方网站 http://kgdb.linsyssoft.com/ Comments Wed, 2007-07-25
06:08 — Marchday
内核编译技巧安装编译工具 # yum groupinstall 'Development Tools' 或者 # aptitude install build-essential libqt3-mt-dev qt3-dev-tools 查看硬件信息:lshw,lspci,注意使用update-pciids先更新一下。查看cpu信息 cat /proc/cpuinfo。 参考 |
cpio ramdisk的制作办法
参考如下命令
1. 解压ramdisk
[EMAIL PROTECTED]:/tmp# mkdir initfs
[EMAIL PROTECTED]:/tmp# cd initfs
[EMAIL PROTECTED]:/tmp/initfs# scp itvb00:/boot/initrd-2.6.18-8.el5.img ./
[EMAIL PROTECTED]'s password:
initrd-2.6.18-8.el5.img 100% 1365KB 1.3MB/s 00:00
[EMAIL PROTECTED]:/tmp/initfs# ls
initrd-2.6.18-8.el5.img
[EMAIL PROTECTED]:/tmp/initfs# mv initrd-2.6.18-8.el5.img initrd.gz
[EMAIL PROTECTED]:/tmp/initfs# gzip -d initrd.gz
[EMAIL PROTECTED]:/tmp/initfs# ls
initrd
[EMAIL PROTECTED]:/tmp/initfs# cpio -idv < initrd
...
[EMAIL PROTECTED]:/tmp/initfs# ls
bin dev etc init initrd lib proc sbin sys sysroot
主机itvb00是我的GUEST OS。这时候就可以根据需要修改ramdisk了。
2. 生成ramdisk
[EMAIL PROTECTED]:/tmp/initfs# rm initrd
[EMAIL PROTECTED]:/tmp/initfs# find . -print | cpio -ov > /tmp/initrd-new.cpio
[EMAIL PROTECTED]:/tmp/initfs# gzip /tmp/initrd-new.cpio