linux内核调试环境搭建-

来源:互联网 发布:网络文明调查问卷 编辑:程序博客网 时间:2024/05/16 02:18

kvm系统的前端是qemu-kvm,工作在用户空间,给用户提供一套方便的kvm虚拟化工具集合。下面来介绍一下qemu-kvm-0.11.0的编译过程。

 

1、下载

wget http://sourceforge.net/projects/kvm/files/qemu-kvm/0.11.0/qemu-kvm-0.11.0.tar.gz/download

mv download qemu-kvm-0.11.0.tar.gz

tar -xzvf qemu-kvm-0.11.0.tar.gz

 

2、安装其他库

sudo apt-get install   libpci-dev

sudo apt-get iinstall   libsdl1.2-dev 

下载zlib-1.2.3.tar.gz

解压 tar zxvf zlib-1.2.3.tar.gz

进入目录配置安装:

./configure

make 

sudo make install

安装。

 

3、编译安装qemu

cd qemu-kvm-0.11.0

./configure

make

sudo make install

 

4、将qemu添加到环境变量

进入目录       /usr/local/bin

为 qemu-system-x86_64创建符号链接:

$ sudo ln -s qemu-system-x86_64  qem

打开/etc/profile文件在末尾添加

PATH="$PATH:/usr/local/bin"

export  PATH

使环境变量生效,在终端输入:

source /etc/profile

 

另外打开一个终端输入qemu 可见可以正常启动。

 

但是发现这时提示找不到kvm。

Ubuntu10.10系统有自带的kvm内核模块。

 

打开文件/etc/modules

在其中加入想要加载的模块名

kvm

kvm-amd

注意不要加扩展名 .ko



下载linux内核:

$cd ~/work/

$wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.35.9.tar.bz2

解压

$tar -jxvf linux-2.6.35.9.tar.bz2

拷贝现有系统的内核配置选项

$ cp /boot/config-2.6.35-22-generic .config 

 

确保如下选项被选中:

在这里建议关闭一个选项: DEBUG_RODATA  CONFIG_DEBUG_RODATA = n 该选项是将内核的一些内存区域空间设置为只读,这样可能导致kgdb的设置软断点功能失效。所以推荐将该选项关闭。

Location:

   -> Kernel hacking       ->Write protect kernel read-only data structures

 

KGDB_SERIAL_CONSOLE 打开该选项:使用串口进行通信

 位置: > Kernel hacking

            -> KGDB: kernel debugger

              -> KGDB: use kgdb over the serial console

 

KGDB_LOW_LEVEL_TRAP  使能该选项可以kgdb不依赖notifier_call_chain()机制来获取断点异常,这样就可以对notifier_call_chain()机制实现相关的函数进行单步调试。

 依赖: KGDB [=y] && (X86 [=y] || MIPS [=MIPS])

    位置:     -> Kernel hacking      

                -> KGDB: kernel debugger (KGDB [=y])

                          ->KGDB: Allow debugging with traps in notifiers

 

 

DEBUG_INFO    该选项可以使得编译的内核包含一些调试信息,使得调试更容易。

    位置:

        -> Kernel hacking

             ->compile the kernel with debuginfo

 

FRAME_POINTER  使能该选项将使得内核使用帧指针寄存器来维护堆栈,从而就可以正确地执行堆栈回溯,即函数调用栈信息。

    位置: 

             -> Kernel hacking

                    ->Compile the kernel with frame pointers

 

MAGIC_SYSRQ  (如果你选择了KGDB_SERIAL_CONSOLE,这个选项将自动被选上)激活"魔术SysRq"键.该选项对kgdboc调试非常有用,kgdb向其注册了‘g’魔术键来激活kgdb。

      位置: 

             -> Kernel hacking

                   ->magic SysRq key

当你想手动激活kgdb时,你可以触发SysRq的g键,如:

$ echo "g" > /proc/sysrq-trigger

 

 

修改编译优化等级:

     打开根目录下Makefile文件修改内核Makefile优化选项将KBUILD_CFLAGS += -O2,修改   为:KBUILD_CFLAGS += -O。

 

编译内核:

make && make modules

 

编译完成后,复制bzImage和vmlinux到工作目录下备用

cp arch/x86/boot/bzImage  .

cp vmlinux   .

 

 

编译busybox:

cd  ~/work/busy/

下载 busybox-1.20.1.tar.bz2,

解压缩:

tar -jxvf  busybox-1.20.1.tar.bz2

进入busybox目录:

$ cd busybox-1.20.1/

编译busybox

make menuconfig

 

Busybox Settings  --->

   Build Options  --->

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

   Installation Options  --->

        [ * ] Don't use /usr

Miscellaneous Utilities --->

[ ] flashcp

[ ] flash_lock

[ ] flash_unlock

[ ] flash_eraseall

 

注:[ ]表示不选择

 

保存配置文件后开始编译和安装

make

make install

 

此时在当前目录下生成了一个_install目录,里面就是busybox的执行文件

 

制作文件系统

使用如下命令来创建一个虚拟文件系统磁盘文件,

在当前目录下创建一个名为busybox.img,大小为300M的文件,并将其格式化为ext3的文件系统

dd if=/dev/zero of=./busybox.img bs=1M count=300

mkfs.ext3 busybox.img

 

将这个虚拟磁盘文件到本地系统中,这样我们可以像访问本地文件一样访问它,并将生成好的busybox的文件拷贝到这个文件里。

sudo mkdir /mnt/disk

sudo mount -o loop busybox.img /mnt/disk

sudo cp -rf /dir/to/busybox-1.17.0/_install/* /mnt/disk

 

创建必须的文件系统目录

cd /mnt/disk/

sudo mkdir dev sys proc etc lib mnt

 

使用busybox默认的设置文件

sudo cp -a  /dir/to/busybox-1.17.0/examples/bootfloppy/etc/* /mnt/disk/etc

sudo vi /mnt/disk/etc/init.d/rcS

将下面内容拷贝到rcS里:

[plain] view plaincopy
  1. #! /bin/sh  
  2.   
  3. MAC=08:90:90:59:62:21  
  4.   
  5. IP=192.168.100.2  
  6.   
  7. Mask=255.255.255.0  
  8.   
  9. Gateway=192.168.100.1  
  10.   
  11.    
  12.   
  13. /sbin/ifconfig lo 127.0.0.1  
  14.   
  15. ifconfig eth0 down  
  16.   
  17. ifconfig eth0 hw ether $MAC  
  18.   
  19. ifconfig eth0 $IP netmask $Mask up  
  20.   
  21. route add default gw $Gateway  
  22.   
  23.    
  24.   
  25. /bin/mount -a  
  26.   
  27. /bin/mount -t  sysfs sysfs /sys  
  28.   
  29. /bin/mount -t tmpfs tmpfs /dev  
  30.   
  31. /sbin/mdev -s  
  32.   
  33. mount -o remount,rw,noatime -n /dev/root /  


做完上面对工作后,我们就可以卸载虚拟磁盘文件了。

sudo umount /mnt/disk

 

使用qemu运行自己编译的内核

qemu -m 512 -kernel bzImage -append “root=/dev/sda” -boot c -hda busybox.img -k en-us 

运行如下图所示:

 

qemu与主机之间可以ping通:

在主机放入一脚本nettap.sh

$cd ~

$touchnettap.sh

$gedit nettap.sh

脚本中放入如下内容:

[plain] view plaincopy
  1. tunctl -u gudujian -t tap0   
  2. ifconfig tap0 192.168.100.1 up   
[plain] view plaincopy
  1. echo 1 > /proc/sys/net/ipv4/ip_forward  
  2. iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
  3. iptables -I FORWARD 1 -i tap0 -j ACCEPT  
  4. iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT  

开机后用root权限执行这个脚本。

 

用如下脚本启动虚拟机:

qemu -m 512 -kernel bzImage -append "root=/dev/sda" -boot c -hda busybox.img-initrd initrd.img-2.6.35.9 -k en-us -net nic -net tap,ifname=tap0,script=no

在虚拟机中ping主机可见可以ping的通:

 

qemu与主机共享文件(通过tftp方式):

首先在ubuntu10.10中搭建tftp服务:

http://blog.csdn.net/gudujianjsk/article/details/7655701

只是在busybox中使用tftp客户端命令有些不一样。见后面介绍。

 

使用gdb + kgdb调试内核

使能kgdb可以在内核启动时增加使能参数,这里我们采取在内核启动时增加启动参数(kgdboc=ttyS0,115200 kgdbwait)的方式:

 qemu -m 512 -kernel  bzImage  -append "root=/dev/sda kgdboc=ttyS0,115200

kgdbwait" -boot c –hda busybox.img -k en-us -serial tcp::4321,server

 

这时,运行qemu的终端将提示等待远程连接到本地端口4321

QEMU waiting for connection on: tcp:0.0.0.0:4321,server

 

这时使用另外一个控制台执行:

gdb  vmlinux

(gdb) target remote localhost:4321

 

然后qemu就可以继续正常运行下去,最后停止内核,并显示如下信息:

kgdb: Waiting for connection from remote gdb…

 

这时gdb这边就可以看到如下的提示:

(gdb) target remote localhost:4321

Remote debugging using localhost:4321

kgdb_breakpoint () at kernel/debug/debug_core.c:983

983            wmb(); /* Sync point after breakpoint */

(gdb)

 

开始你的内核之旅吧~~~

 

如果gdb提示如下信息:

warning: Invalid remote reply:

可以使用Ctrl+C来终止当前gdb的操作,再次使用下面命令重新连接一次kgdb即可:

(gdb) target remote localhost:4321

原创粉丝点击