代码改变世界

Linux0.11---调试启动程序

2013-11-17 21:41  islandscape  阅读(1470)  评论(0编辑  收藏  举报

    前面一篇文章介绍了最简单的启动程序---从系统上电到屏幕输出“hello world”,linux0.11内核启动程序远比这复杂的多,后面我们会逐步深入。今天给大家介绍下如何调试这个最简单的启动程序。

    “工欲善其事,必先利其器”,我们需要两“器”---编译器和虚拟机。编译器把汇编程序编译成为可执行文件,虚拟机模拟系统上电、BIOS中断等功能。编译器选择nasm,它是一款为可移植性与模块化而设计的80x86的汇编器。官方网址为http://www.nasm.us/。虚拟机选择bochs,bochs是一个模拟x86硬件平台的虚拟机,通过简单的配置即可模拟I/O设备、内存等硬件环境。相关链接:http://www.oschina.net/p/bochs/。不选择vmware的原因是它不能单步调试内核。

    安装好这两个工具后,并将两个工具的安装目录设置为系统环境变量(以便在任何目录下可以使用这两个工具),我们就可以调试“hello world”“启动程序”了,先将上节“hello world”汇编程序保存至文件helloworld.asm,命令行进入汇编程序所在目录,使用命令nasm –o boot.bin  helloworld.asm,生成二进制文件boot.bin。生成的boot.bin文件大小为512字节,否则有问题。

    bochs是通过配置文件来配置模拟的x86硬件环境的,配置文件必须是以 “.bxrc”为后缀的,否则bochs无法识别。在boot.bin目录中创建配置文件helloworld.bxrc,填入配置信息:

megs: 1
romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000 
vgaromimage: $BXSHARE/VGABIOS-elpin-2.40 
floppya: 1_44=boot.bin, status=inserted
boot: floppy

    megs表示虚拟环境可用内存只有1m(这里设大些也没关系),romimage是bios自检,读取配置文件,并跳转至0x7c00地址的模块,默认起始地址为0xf000,在安装bochs的目录下。vgaromimage是屏幕显示模块,同样在bochs安装目录下。安装bochs后会把环境变量BXSHARE设置为bochs的安装目录,如果没有需自行设置。floppya是软盘属性,1_44是软盘类型,(软盘类型共有0.16、 0.18、 0.32、 0.36、 0.72、 1.2、1.44、1.68、1.72和 2.88)。放入的是上面编译生成的boot.bin,状态是插入。boot: floppy表示从软盘启动。更多的bochs配置文档在$BXSHARE/docs目录下。结合上一篇介绍,bios将floppya驱动器的boot.bin程序读入0x7c00地址,扫描最后两个字节,发现是0xAA55,便认为floppya是启动驱动器,boot.bin是启动程序,于是从0x7c00地址开始执行指令。

    写好bochs配置文件,如果没有问题双击helloworld.bxrc就会看到如下画面。

    到这一步我们已经小有成就, bochs单步调试功能让我们更加了解CPU工作原理和编译、链接加载等知识。bochs调试需要使用$BXSHARE/bochsdbg.exe这个文件。在boot.bin目录下执行bochsdbg -q -f helloworld.bxrc开始调试“helloworld”启动程序。使用命令pbreak 0x7c00在物理地址0x7c00(p表示物理地址),还可以使用vberak 0x0000:0x7c00在0x7c00的地址设置断点(v表示虚拟地址)。

    命令c(表示continue),程序会停止在0x7c00地址上,u /10可以看到当前地址向后的10条反汇编指令(u表示反汇编),如下图:

    左侧显示的是指令放置内存的地址,中间是反汇编的语句,右边是对应的机器码。可以看出jmp go被编译器翻译成了jmp 0x7c09。另,info r可以查看寄存器的值,info b可以查看断点信息等,有了这些简单的命令我们就可以单步调试复杂的内核了。

    内核是一个庞大的东东,学习它并非无章可循,让我们耐住性子,恒下心来,慢慢品味linux内核的奥秘吧!