使用Bochs调试Linux kernel 随笔 -- 准备
一 创建虚机测试用的磁盘镜像文件
使用bximage命令创建一个10M的hdd.img(如果没有bximage,安装bochs)。
当然,也可以使用dd命令来创建,这里不在赘述,可以参考man dd。
接着,创建一个连接到hdd.img 文件的loop device。
losetup /dev/loop1 hdd.img
在创建完loop device之后,你可以同过/dev/loop1 设备文件访问该hdd.img 镜像文件,如同访问一个真正的块设备文件一样。 所以,我们通过fdisk来对hdd.img 进行分区。
fdisk /dev/loop1
为方便,在这里仅分一个primary分区包含所有扇区,建立分区后分区表如下:
Command (m for help): p
Disk /dev/loop1: 104 MB, 104767488 bytes
255 heads, 63 sectors/track, 12 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x9b23eaac
Device Boot Start End Blocks Id System
/dev/loop1p1 1 12 96358+ 83 Linux
可以看到,磁盘文件hdd.img 共有CHS为12/255/63。
这里的start 和 end是以cylinder为单位的。
为了以更细的粒度来查看分区表,通过给fdisk的-ul选项,以扇区问单位查看分区表:
$ sudo fdisk -ul /dev/loop1
Disk /dev/loop1: 104 MB, 104767488 bytes
255 heads, 63 sectors/track, 12 cylinders, total 204624 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x9b23eaac
Device Boot Start End Blocks Id System
/dev/loop1p1 63 192779 96358+ 83 Linux
接下来,在新建的分区上创建文件系统。但是当前/dev/loop1 指向的是整个hdd.img文件,而不是hdd.img的分区loop1p1,所以,需要创建另外一个loop device来指向该分区,进而可以对该分区建立文件系统,就像是多一个真正的硬盘进行的操作一样。
从上面的输出结果可以看到,第一个分区是从扇区63开始,硬盘每一个分区的大小512 byte,所以第一个扇区的起始位移为63*512=32256。
到这里我们就可以将一个loop device连接到hdd.img的第一个扇区。
losetup –o 33256 /dev/loop2 /dev/loop1
然后,就可以通过访问/dev/loop2对hdd.img的第一个扇区进行操作。通过mkfs.ext2命令为/dev/loop2建立文件系统。
mkfs.ext2 /dev/loop2
在为/dev/loop2 创建文件系统之后,就可以将其mount到系统的挂载点,从而可以对其进行文件相关的操作。
我们将/dev/loop2 挂载到/mnt/hdd 挂载点下。
mount /dev/loop2 /mnt/hdd
在这里我们选用grub 0.97作为bootloader。
创建相应的grub相关的目录
mkdir –p /mnt/hdd/boot/grub
cp –r /usr/lib/grub/i386-pc/stage1 /usr/lib/grub/i386-pc/stage2 /mnt/hdd/boot/grub
cp –r the_kernel /mnt/hdd
接下来,到/mnt/hdd/boot/grub 目录下,创建menu.lst 文件
default 0
timeout 10
title=YuboOS
root (hd0,0)
kernel /bzImage
接下来,我们将安装grub bootloader到hdd.img 的MBR中去。
grub –device-map=/dev/null
这会到grub command line界面
在grub shell的提示符下执行命令:
grub>device (hd0) hdd.img
grub>root (hd0,0)
grub>setup (hd0)
注意,这里device的参数是hdd.img文件,而不是loop device,这是因为grub 0.97的bug原因。
到此,整个虚拟机的磁盘镜像文件建立完毕。
你可以将hdd.img的第一个分区一直挂载在/mnt/hdd 挂载点下,这样你就可以随时更新kernel,然后修改menu.lst 文件,从而可以达到测试kernel的目的。
二 使用bochs软件来学习调试kernel。
我们假设已经有一个创建好的hdd.img可以使用。
为了达到可以调试kernel目的,我们需要自己动手编译bochs,以为目前一般随linux 发行版一起的bochs没有打开其internal debugger或没有安装gdb-stub。
在这里使用的是bochs的2.4.6版本。编译和安装的一般过程是./configure && make && make install。
注意,为了使用bochs的内部调试功能,需要在configure 阶段加上 –enable-debugger 和—enable-disasm 选项。
接下来,编辑bochs虚机配置文件: bochsrc
1: megs: 32
2: romimage: file=$BXSHARE/BIOS-bochs-latest
3: vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
4: vga: extension=vbe
5: floppya: 1_44=a.img, status=ejected
6: floppyb: 1_44=b.img, status=ejected
7: ata0-master: type=disk, path=hdd.img, cylinders=203, heads=16, spt=63
8: boot: c
9: log: bochsout.txt
10: mouse: enabled=0
11: #ips: 15000000
12: clock: sync=slowdown
13: vga_update_interval: 150000
最后,使用bochs –f bochsrc 就可以运行虚机了。