bochs调试linux内核
1. 构造调试环境
由于bochs内建调试功能, 且支持gdb, 用它调试内核会很方便.
(文章中大部分命令的运行需要root权限,以sudo方式运行)
1.1 构建磁盘镜像
Shell代码
dd if=/dev/zero of=hd0.img count=$((63*16*100))
用这个命令可以构建一个50MB左右的磁盘镜像, 输出结果如下:
100800+0 records in
100800+0 records out
51609600 bytes (52 MB) copied, 0.734578 s, 70.3 MB/s
注意count必须为63*16的倍数, 否则bochs识别硬盘会有问题.
1.2 挂载磁盘镜像
Shell代码
losetup /dev/loop0 hd0.img
这个命令可以将文件绑定到一个loop设备. 如果/dev/loop0不存在, 可以尝试 modprobe loop.
然后进行设备初始化:
Shell代码
cfdisk -s63 -h16/dev/loop0
只创建一个主分区就可以. 写入后, 用命令fdisk检查结果:
Shell代码
fdisk -lu /dev/loop0
Disk /dev/loop0: 51 MB, 51609600 bytes
16 heads, 63 sectors/track, 100 cylinders, total 100800 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
/dev/loop0p1 63 100799 50368+ 83 Linux
将分区1挂载到/dev/loop1.
Shell代码
losetup /dev/loop1 hd0.img -o $((63*512))
格式化/dev/loop1为ext3格式.
Shell代码
mkfs.ext3 /dev/loop1
在mnt下创建img目录, 做以后维护用.
Shell代码
mkdir -p /mnt/img
将loop1挂载到/mnt/img
Shell代码
mount /dev/loop1 /mnt/img/
安装引导程序. 因为我狂热倾向于模块化架构, 所以选择GRUB2.
本文以grub-1.97~beta3为示例, 读者可自行安装其他的引导系统如lilo.
Shell代码
mkdir /mnt/img/boot
cp -r /usr/lib/grub/i386-pc/ /mnt/img/boot/grub
生成一个core.img, biosdisk负责读取磁盘, part_msdos负责处理MBR, ext2负责读取ext3分区.
Shell代码
cd /mnt/img/boot/grub/
grub-mkimage -O i386-pc -o core.img biosdisk part_msdos ext2
Shell代码
ls -lh core.img
-rw-r--r--1 root root 25K Sep2114:28 core.img
只有区区的25K.. 里面甚至还包含一个小的应急shell, 不过作用不大.
安装grub2到(hd0), 根目录在(hd0,1)
Shell代码
echo"(hd0) /dev/loop0" > ./device.map
grub-setup -m ./device.map -d /mnt/img/boot/grub/ -r '(hd0,1)' '(hd0)'
检查一下安装成果:
Shell代码
hexdump -C /dev/loop0 | less
如果你能看到:
Shell代码
00000180 7d e8 2e00 cd18 eb fe4752554220004765|}.......GRUB .Ge|
00000190 6f 6d004861726420446973 6b00526561|om.Hard Disk.Rea|
就说明安装成功.
清理一下.
Shell代码
cd
umount /mnt/img
losetup -d /dev/loop1
losetup -d /dev/loop0
1.3 启动测试.
给上面的hd0.img配一个bochsrc文件, 可以拿bochs示例dlxlinux的配置文件来改, 只需将硬盘换为:
Shell代码
ata0-master: type=disk, path="hd0.img", cylinders=100, heads=16, spt=63
然后启动Bochs, 顺利的话, 你能看到传说中的grub2 shell.
2. 从启动到保护模式.
为我们的bochs虚拟机编译一个内核. 不必太复杂, 目前我们只关心启动部分.
2.1 安装内核
退出bochs, 挂载hd0.img:
Shell代码
mount hd0.img /mnt/img/ -o loop,offset=$((63*512))
拷贝bzImage.
Shell代码
cp /usr/src/linux/arch/i386/boot/bzImage /mnt/img/boot/vmlinuz-3.0.00
这两个步骤可以放到内核的Makefile中, 以后每次编译完成后, 自动更新到hd0.img里.
然后将下列配置写到/mnt/img/boot/grub/grub.cfg
Shell代码
# Timeout for menu
set timeout=10
# Set default boot entry as Entry0
set default=0
# Entry0- Load Linux kernel
menuentry"Linux-3.0.00"{
set root=(hd0,1)
linux /boot/vmlinuz-3.0.00root=/dev/hda1
}
卸载/mnt/img, 启动测试一下, 顺利的话, 你能看到一个panic.