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
$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里:
做完上面对工作后,我们就可以卸载虚拟磁盘文件了。
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
脚本中放入如下内容:
开机后用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