VirtualBox Ubuntu KGDB内核调试技术

一、首先安装VirtualBox并在VirtualBox中安装Ubuntu的虚拟机
======================================================
1.安装VirtualBox OSE版
----------------------
sudo apt-get install virtualbox-ose
2.新建一个Ubuntu虚拟机
----------------------
2.1 常规及硬盘配置较简单,可以参考默认配置。
2.2 配置虚拟光驱,从ISO文件安装系统
2.3 软驱不怎么需要
2.4 声音用Host OS的就可以了
2.5 网络配置主要有NAT和桥接方式两种,NAT较简单。 还可以用桥接方式的网络连接而且不用DHCP而采用静态IP。
3.配置桥接网络的静态IP
----------------------
3.1 安装用于桥接网络的库
sudo apt-get install uml-utilities bridge-utils
3.2 将自己加入uml-net组,以便以当前帐户启动VirtualBox时有网络配置权限
sudo gpasswd -a yourusername uml-net 
3.3 修改网络接口配置文件
sudo gedit /etc/network/interfaces
配置前:cat /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.0.212
netmask 255.255.255.0
gateway 192.168.0.3
配置后:
auto eth0
iface eth0 inet static
address 192.168.0.212
netmask 255.255.255.0
gateway 192.168.0.3
auto vbox0
iface vbox0 inet static
address 192.168.0.214
netmask 255.255.255.0
gateway 192.168.0.3
tunctl_user yourusername
auto br0
iface br0 inet static
address 192.168.0.213
netmask 255.255.255.0
gateway 192.168.0.3
bridge_ports all vbox0
除此之外还需要下面一步,否则打开虚拟机时会出现Failed to initialize Host Interface Networking的错误。
添加vbox0接口到网桥br0
sudo /usr/bin/VBoxAddIF vbox0 yourusername br0
这时会在/etc/vbox/interfaces里产生一行
vbox0 yourusername br0
如果有必要,你还需要重启计算机
运行ifconfig后会发现有br0, eth0, lo, vbox0四个接口,这说明网络配置是正确的。
接下来在VirtualBox OSE中选择新建的虚拟机,设置->网络,选中启用网络连接,Attach to: Host Interface, 选中接入网线,Interface Name中写上vbox0,确定。
最后一步就是运行虚拟机,用虚拟光驱里的iso安装系统。
虚拟机中的Guest OS的安装过程和Host OS一模一样,它在网络中和Host OS处于对等地位,因此网络配置也是一样。这就是为什么要使用网桥的原因. 
二、在虚拟机中编译debug版的内核
==============================
1. 安装内核工具
---------------
apt-get install build-essential kernel-package libncurses5-dev
2. 下载源码
-----------
使用发行版自带内核源码
. 搜索源码包
apt-cache search linux-source
. 下载源码包
apt-get install linux-source-2.6.xx
解压源码包
tar jxvf linux-source-2.6.xx.tar.bz2
3. 配置内核
-----------
1)make menuconfig
2) make gconfig
#安装gconfig依赖包
apt-get install libglade2-dev
3) make xconfig
#安装xconfig依赖包
apt-get install libqt3-headers libqt3-mt-dev libqt3-compat-headers  libqt3-mt
4. 编译内核
-----------
make all && make modules_install && make install && mkinitramfs -o /boot/initrd.img-2.6.36 2.6.36
四、克隆虚拟机
===============
Linux方式:
----------
编译好内核之后,可以再来克隆一台上面的机器。
使用VBoxManager clonevdi来克隆VirtualBox的虚拟硬盘镜像。
cd ~/.VirtualBox/VDI/ (默认地这里存放着VirtualBox的硬盘镜像文件,你可以再克隆一个镜像)
VBoxManage clonevdi Ubuntu10.10TargetOS.vdi Ubuntu10.10DevOS.vdi
然后新建一个虚拟机,在创建硬盘时可以注册这个克隆的硬盘,这样开发机就是目标机的克隆体了。
五、串口配置
============
VirtualBox虚拟机的串口通信机制有两种,一种是通过将虚拟机的串口连接到主机的串口,另外一种是将虚拟机的串口连接到主机上的一个命名管道,第一种方式到现在
我还没有实践出来,目前只是对命名管道的方式实践成功。
1.启用串口
----------
新建虚拟机后在设置中会出现串口面板,可以进行串口设置,默认是不起用的,一般端口选择使用COM1对应虚拟机的/dev/ttyS0,端口模式选择Host Pipe,表示将虚拟机
的串口连接到主机的一个命名管道,创建通道表示启动虚拟机时VirtualBox会在HostOS中对应地创建一个命名管道,并使它与虚拟机的对应串口相连。端口路径在选择Host Pipe时
表示命名管道的路径,在Windows系统上,它是//./pipe/xxx的形式,在Linux可以设任何路径,比如我们将它设为/tmp/vbox。注意,如果端口路径对应的命名管道不能创建的话,
虚拟机启动会失败;端口路径的命名管道不能重复创建。
你也可以使用命令行启用并创建一个虚拟机到主机命名管道的连接,下面的命令就将虚拟机Ubuntu10.10DevOS的COM1串口和主机的/tmp/vbox命名管道连接起来:
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/Config/IRQ" 4
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/Config/IOBase" 0x3f8
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/LUN#0/Driver" Char
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Driver" NamedPipe
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Config/Location" "/tmp/vbox"
VBoxManage setextradata "Ubuntu8.10DevOS" "VBoxInternal/Devices/serial/0/LUN#0/AttachedDriver/Config/IsServer" 1
2.虚拟机和主机HostOS间的串口通信
--------------------------------
启动虚拟机Ubuntu10.10DevOS,这时会在主机的/tmp/目录下创建vbox新文件,可以用ls -l看到它是一个sock类型的文件,使用来进行通信的。
在HostOS中安装minicom,minicom可以用来作为串口测试:sudo apt-get install minicom
接下来我们可以配置minicom,让它指向/tmp/vbox,执行命令
sudo gedit /etc/minicom/minirc.dfl并修改为
pu port             unix#/tmp/vbox
也可以在minicom中通过串口设置来修改。
测试前应保证minicom中的串口设置的波特率和虚拟机中的串口一样。
虚拟机中的串口波特率设置可以参考下文,minicom的波特率设置可以直接在程序中Ctrl+A, O后修改,或修改配置文件。
测试过程,
1)在HostOS中启动minicom:
sudo minicom
在虚拟机中的终端中执行:
echo is that ok? > /dev/ttyS0
会在HostOS中的minicom中回显对应内容
2)在虚拟机中的终端中执行:
cat /dev/ttyS0
这时主机中的minicom中会出现输入状态,在其中输入的信息也会在虚拟机终端上回显。
3.虚拟机和虚拟机之间的串口通信
------------------------------
两台虚拟机间的通信也可以通过利用主机的命名管道来完成。
原理可以简单的这样描述:一台虚拟机在主机中创建的命名管道并其串口相连,另外一台虚拟机也将自己的串口连到主机的命名管道上,这样两个虚拟机的串口就能连起来了。
这里两台虚拟机都使用各自的COM1端口,主机的命名管道为同一管道/tmp/vbox,在配置时一台创建通道(假设为Ubuntu10.10DevOS),另一台不创建。
启动时先启动创建通道的虚拟机,然后启动另一台虚拟机,分别打开两台虚拟机的终端,通过如下命令将各自的COM1口的输入输出波特率都设为115200
stty ispeed 115200 ospeed 115200 -F /dev/ttyS0
测试过程:
在其中一台虚拟机A终端上执行
cat /dev/ttyS0
在另一台虚拟机B上执行
echo ok > /dev/ttyS0
这时虚拟机A的终端会接受到B发来的ok消息
这里要补充说明一下的是,
这里两台虚拟机都将自身的com 1口连到主机的一个命名管道/tmp/vbox,两者的com 1口就连接到一起了,另外,两台虚拟机有且只有一台能够选择创建通道,并且只能是
创建通道的一方先启动,因此推荐让开发机创建通道而目标机只使用/tmp/vbox命名通道,这样每次目标机重启调试时,开发机不用重启。
六、配置目标机的启动项
=======================
在目标机里
sudo gedit /boot/grub/menu.lst ;建议备份原menu.lst如下:
title        Ubuntu 10.10, kernel 2.6.27-7-generic
uuid        d77795b1-d4b4-466c-8989-d828d7eba4c5
kernel        /boot/vmlinuz-2.6.27-7-generic root=UUID=d77795b1-d4b4-466c-8989-d828d7eba4c5 ro locale=zh_CN quiet splash 
initrd        /boot/initrd.img-2.6.27-7-generic
quiet
...
(修改后为)
title        Ubuntu 10.10, kernel 2.6.27-7-generic
uuid        d77795b1-d4b4-466c-8989-d828d7eba4c5
kernel        /boot/vmlinuz-2.6.27-7-generic root=UUID=d77795b1-d4b4-466c-8989-d828d7eba4c5 ro locale=zh_CN quiet splash 
initrd        /boot/initrd.img-2.6.27-7-generic
quiet
title        Ubuntu 10.10, kernel 2.6.36-with kgdb
uuid        d77795b1-d4b4-466c-8989-d828d7eba4c5
kernel        /boot/vmlinuz-2.6.36 root=UUID=d77795b1-d4b4-466c-8989-d828d7eba4c5 ro kgdboc=ttyS0,115200 kgdbwait
initrd        /boot/initrd.img-2.6.36
...
七、开始kgdb调试
================
先启动开发机。然后启动目标机,开机时按Esc建选择有kgdb的内核启动,等待一下后启动过程会暂停并提示等待远程gdb调试,
这时切换到开发机并进入到源码目录下,运行
gdb ./vmlinux,gdb
启动后,在gdb中设置波特率和调试终端
(gdb)set remotebaud 115200
(gdb)target remote /dev/ttyS0
这样就可以调试内核了
八、使用kgdb调试技巧(未完待续...)
=================================

你可能感兴趣的:(8,Linux内核)