首页 一个操作系统的实现

一个操作系统的实现

举报
开通vip

一个操作系统的实现 Verum ipsum factum. ──Giambattista Vico 1 马上动手写一个最小的“操作系统” 虽说万事开头难,但有时也未必。比如说,写一个有实用价值的操作系统 是一项艰巨的工作,但一个最小的操作系统或许很容易就实现了。现在我们就 来实现一个小得无法再小的“操作系统”,建议你跟随书中的介绍一起动手来 做,你会发现不但很容易,而且很有趣。 1.1 准备工作 对于写程序,准备工作无非就是硬件和软件两方面,我们来看一下: 1. 硬件 • 一台计算机(Linux操作系统1或Windows操作...

一个操作系统的实现
Verum ipsum factum. ──Giambattista Vico 1 马上动手写一个最小的“操作系统” 虽说万事开头难,但有时也未必。比如说,写一个有实用价值的操作系统 是一项艰巨的工作,但一个最小的操作系统或许很容易就实现了。现在我们就 来实现一个小得无法再小的“操作系统”,建议你跟随书中的介绍一起动手来 做,你会发现不但很容易,而且很有趣。 1.1 准备工作 对于写程序,准备工作无非就是硬件和软件两方面,我们来看一下: 1. 硬件 • 一台计算机(Linux操作系统1或Windows操作系统均可) • 一张空白软盘 2. 软件 • 汇编编译器NASM NASM最新版本可以从其官方网站获得2。此刻你可能会有疑问:这 么多汇编编译器中,为什么选择NASM?对于这一点本书后面会有 解释。 • 软盘绝对扇区读写工具 在Linux 下可使用 dd命令,在Windows 下则需要额外下载一个工具 比如 rawrite3或者图形界面的 rawwritewin4。当然如果你愿意,也可以 自己动手写一个“能用就好”的工具,并不是很复杂5。 1实际上 Linux 并非一种操作系统,而仅仅是操作系统的内核。在这里比较准确的说法是GNU/ Linux,本书提到的Linux泛指所有以Linux为内核的GNU/Linux操作系统。GNU经常被人们遗忘, 但它的贡献无论怎样夸大都不过分,这不仅仅是因为在你所使用的GNU/Linux中,GNU软件的代 码量是 Linux 内核的十倍,更加因为,如果没有以Richard Stallman 为首的GNU项目倡导自由软件 文化并为之付出艰辛努力,如今你我可能根本没有自由软件可用。本书将GNU/Linux简化为Linux, 仅仅是为表达方便,绝不是因为GNU这一字眼可有可无。 2NASM的官方网站位于http://sourceforge.net/projects/nasm。 3rawrite 可以在许多地方找到,比如http://ftp.debian.org/debian/tools/。 4下载地址为http://www.chrysocome.net/rawwrite。 5我们不需要太强大的软盘读写工具,只要能将512字节的数据写入软盘的第一个扇区就足够了。 1.2 十分钟完成的操作系统 1.2 十分钟完成的操作系统 你相不相信,一个“操作系统”的代码可以只有不到20行?请看代码1.1。 代码1.1 chapter1/a/boot.asm 1 org 07c00h ; 告诉编译器程序加载到7c00处 2 mov ax, cs 3 mov ds, ax 4 mov es, ax 5 call DispStr ; 调用显示字符串例程 6 jmp $ ; 无限循环 7 DispStr: 8 mov ax, BootMessage 9 mov bp, ax ; ES:BP = 串地址 10 mov cx, 16 ; CX = 串长度 11 mov ax, 01301h ; AH = 13, AL = 01h 12 mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮) 13 mov dl, 0 14 int 10h ; 10h 号中断 15 ret 16 BootMessage: db ”Hello,␣OS␣world!” 17 times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节 18 dw 0xaa55 ; 结束标志 把这段代码用NASM编译一下: . nasm boot.asm –o boot.bin 我们就得到了一个512字节的boot.bin,让我们使用软盘绝对扇区读写工具将这 个文件写到一张空白软盘的第一个扇区。在Linux下可以这样做6: . dd if=boot.bin of=/dev/fd0 bs=512 count=1 在Windows下可以这样做7: . rawrite2.exe -f boot.bin -d A 好了,你的第一个“操作系统”就已经完成了。这张软盘已经是一张引导盘 了。 把它放到你的软驱中重新启动计算机,从软盘引导,你看到了什么? 计算机显示出你的字符串了!红色的“Hello, OS world!”,多么奇妙啊,你 的“操作系统”在运行了! 如果使用虚拟机比如 Bochs 的话(下文中将会有关于 Bochs 的详细介绍), 你应该能看到如图1.1所示的画面8。 这真的是太棒了,虽然你知道它有多么简陋,但是,毕竟你已经制作了一 个可以引导的软盘了,而且所有工作都是你亲手独立完成的! 6取决于硬件环境和具体的Linux发行版,此命令可能稍有不同。 7rawrite 有多个版本,此处选用的是2.0版。 8画面看上去有点乱,因为我们打印字符前并未进行任何的清屏操作。 3 第 1章 马上动手写一个最小的“操作系统” 图1.1 最小的“操作系统” 1.3 引导扇区 你可能还没有从刚刚的兴奋中走出来,可是我不得不告诉你,实际上,你 刚刚所完成的并不是一个完整的操作系统,而仅仅是一个最最简单的引导扇区 (Boot Sector)。然而不管我们完成的是什么,至少,它是直接在裸机上运行的, 不依赖于任何其他软件,所以,这和我们平时所编写的应用软件有本质的区别。 它不是操作系统,但已经具备了操作系统的一个特性。 我们知道,当计算机电源被打开时,它会先进行加电自检(POST),然后 寻找启动盘,如果是选择从软盘启动,计算机就会检查软盘的 0面 0磁道 1扇 区,如果发现它以0xAA559结束,则BIOS认为它是一个引导扇区。当然,一个 正确的引导扇区除了以0xAA55结束之外,还应该包含一段少于512字节的执行 码。 好了,一旦BIOS发现了引导扇区,就会将这512字节的内容装载到内存地 址0000:7c00处,然后跳转到0000:7c00处将控制权彻底交给这段引导代码。到此 为止,计算机不再由BIOS中固有的程序来控制,而变成由操作系统的一部分来 控制。 现在,你可能明白了为什么在那段代码的第一行会出现“org 07c00”这 样的代码。没错,这行代码就是告诉编译器,将来我们的这段程序要被加载到 内存偏移地址0x7c00处。好了,下面将对代码的其他部分进行详细解释。 1.4 代码解释 其实程序的主体框架只是第2行到第6行这么一点点而已,其中调用了一个 显示字符串的子程序。程序的第2、3、4行是 3个mov指令,使 ds和 es 两个段 9假如把此扇区看做一个字符数组sector[],那么此结束标志相当于sector[510]==0x55, 且sector[511]==0xAA。 4 1.4 代码解释 寄存器指向与 cs相同的段,以便在以后进行数据操作的时候能定位到正确的位 置。第5行调用子程序显示字符串,然后jmp $让程序无限循环下去。 可能有很多人开始学汇编时用的都是MASM,其实NASM的格式跟MASM 总体上是差不多的,在这段程序中,值得说明的地方有以下几点: 1. 方括号[]的使用 在NASM中,任何不被方括号[]括起来的标签或变量名都被认为是地址, 访问标签中的内容必须使用[]。所以, mov ax, BootMessage 将会把“Hello, OS world!”这个字符串的首地址传给寄存器 ax。又 比如,如果有: foo dw 1 则mov ax, foo将把foo的地址传给ax,而 mov bx, [foo]将把bx的 值赋为1。 实际上,在NASM中,变量和标签是一样的,也就是说: foo dw 1 等价于 foo: dw 1 而且你会发现,Offset 这个关键字在NASM也是不需要的。因为不加方括 号时表示的就是Offset。 笔者认为这是NASM的一大优点,要地址就不加方括号,也不必额外地 用什么Offset,想要访问地址中的内容就必须加上方括号。代码规则非常 鲜明,一目了然。 2. 关于 $和 $$ $表示当前行被汇编后的地址。这好像不太容易理解,不要紧,我们把刚 刚生成的二进制代码文件反汇编来看看: . ndisasmw -o 0x7c00 boot.bin >> disboot.asm 打开disboot.asm,你会发现这样一行: 00007C09 EBFE jmp short 0x7c09 明白了吧,$在这里的意思原来就是0x7c09。 那么 $$表示什么呢?它表示一个节(section10)的开始处被汇编后的地 址。在这里,我们的程序只有 1个节,所以,$$实际上就表示程序被编 译后的开始地址,也就是0x7c00。 在写程序的过程中,$-$$可能会被经常用到,它表示本行距离程序开始处 的相对距离。现在,你应该明白510-($-$$)表示什么意思了吧? times 510-($-$$) db 0表示将0这个字节重复510-($-$$)遍,也就 是在剩下的空间中不停地填充0,直到程序有51 0字 个人自传范文3000字为中华之崛起而读书的故事100字新时代好少年事迹1500字绑架的故事5000字个人自传范文2000字 节为止。这样,加上结束标 志0xAA55占用的2字节,恰好是512字节。 10注意:这里的 section属于NASM 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 的一部分,表示一段代码,关于它和 $$更详细的注解请 参考NASM联机技术文档。 5 第 1章 马上动手写一个最小的“操作系统” 1.5 水面下的冰山 即便是非常袖珍的程序,也有可能遇到不能正确运行的情况,对此你一定 并不惊讶,谁都可能少写一个标点,或者在一个小小的逻辑问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 上犯迷糊。好 在我们可以调试,通过调试,可以发现错误,让程序日臻完美。但是对于操作 系统这样的特殊程序,我们没有办法用普通的调试工具来调试。可是,哪怕一 个小小的引导扇区,我们也没有十足的把握一次就写好,那么,遇到不能正确 运行的时候该怎么办呢?在屏幕上没有看到我们所要的东西,甚至于机器一下 子重启了,你该如何是好呢? 每一个问题都是一把锁,你要相信,世界上一定存在一把钥匙可以打开这 把锁。你也一定能找到这把钥匙。 一个引导扇区代码可能只有 20行,如果Copy&Paste 的话,10 秒钟就搞定 了,即便自己敲键盘抄一遍下来,也用不了 10 分钟。可是,在遇到一个问题 时,如果不小心犯了小错,自己到运行时才发现,你可能不得不花费10个10分 钟甚至更长时间来解决它。笔者把这20行的程序称做水面以上的冰山,而把你 花了数小时的时间做的工作称做水面下的冰山。 古人云:“授之以鱼,不如授之以渔。”本书将努力将冰山下的部分展示给 读者。这些都是笔者经历了痛苦的摸索后的一些心得,这些方法可能不是最好 的,但至少可以给你提供一个参考。 好了,就以我们刚刚完成的引导扇区为例,你可以想像得到,将来我们一 定会对这20行进行扩充,最后得到200行甚至更多的代码,我们总得想一个办 法,让它调试起来容易一些。 其实很容易,因为有 Bochs,我们前面提到的虚拟机,它本身就可以作为 调试器使用11。请允许我再次卖一个关子,留待下文分解。但是请相信,调试 一个引导扇区──甚至是一个操作系统,在工具的帮助下都不是很困难的事情。 只不过跟调试一个普通的应用程序相比,细节上难免有一些不同。 如果你使用的是 Windows,还有个可选的方法能够帮助调试,做法也 很简单,就是把“org 07c00h”这一行改成“org 0100h”就可以编译 成一个.COM 文件让它在 DOS 下运行了。我们来试一试,首先把07c00h改 成0100h,编译: . nasm boot.asm –o boot.com 好了,一个易于执行和调试的引导扇区就制作完毕了。如果你是以DOS或 者Windows 为平台学习的编程,那么调试.COM文件一定是你拿手的工作,比 如使用Turbo Debugger。 调试完之后要放到软盘上进行试验,我们需要再把0100h改成07c00h,这 样改来改去比较麻烦,好在强大的NASM给我们提供了预编译宏,把原来的 “org 07c00h”一行变成许多行即可: 代码1.2 chapter1/b/boot.asm 1 ;%define _BOOT_DEBUG_ ; 制作 Boot Sector 时一定将此行注释掉! 2 ; 去掉此行注释后可做成.COM文件易于调试: 11如果你实在性急,请翻到第12页第2.1.4节看一下具体怎么调试。 6 1.6 回顾 3 ; nasm Boot.asm -o Boot.com 4 5 %ifdef _BOOT_DEBUG_ 6 org 0100h ; 调试状态, 做成 .COM 文件, 可调试 7 %else 8 org 07c00h ; BIOS 将把 Boot Sector 加载到 0:7C00 处 9 %endif 这样一来,如果我们想要调试,就让第一行有效,想要做引导扇区时,将 它注释掉就可以了。 这里的预编译命令跟C语言差不多,就不用多解释了。 至此,你不但已经学会了如何写一个简单的引导扇区,更知道了如何进行 调试。这就好比从石器时代走到了铁器时代,宽阔的道路展现在眼前,运用工 具,我们有信心将引导扇区不断扩充,让它变成一个真正的操作系统的一部 分。 1.6 回顾 让我们再回过头看看刚才那段代码吧,大部分代码你一定已经读懂了。如 果你还是一个NASM新手,可能并不是对所有的细节都那么清晰。但是,毕竟 你已经发现,原来可以如此容易地迈出写操作系统的第一步。 是啊,这是个并不十分困难的开头,如果你也这样认为,就请带上百倍的 信心,以及一直以来想要探索OS奥秘的热情,随我一起出发吧! 7 They who can give up essential liberty to obtain a little tempo- rary safety, deserve neither liberty nor safety. ── Benjamin Franklin 2 搭建你的工作环境 我知道,现在你已经开始摩拳擦掌准备大干一场了,因为你发现,开头并 不是那么难的。你可能想到了Linus,或许他在写出第一个引导扇区并调试成功 时也是同样的激动不已;你可能在想,有一天,我也要写出一个 Linux 那样伟 大的操作系统!是的,这一切都有可能,因为一切伟大必定是从平凡开始的。 我知道此刻你踌躇满志,已经迫不及待要进入操作系统的殿堂。 可是先不要着急,古人云:“工欲善其事,必先利其器”,你可能已经发现, 如果每次我们编译好的东西都要写到软盘上,再重启计算机,不但费时费力, 对自己的爱机简直是一种蹂躏。你一定不会满足于这样的现状,还好,我们有 如此多的工具,比如前面提到过的Bochs。 在介绍 Bochs 及其他工具之前,需要说明一点,这些工具并不是不可或缺 的,介绍它们仅仅是为读者提供一些可供选择的方法,用以搭建自己的工作环 境。但是,这并不代表这一章就不重要,因为得心应手的工具不但可以愉悦身 心,并且可以起到让工作事半功倍的功效。 下面就从Bochs开始介绍。 2.1 虚拟计算机 Bochs 即便没有听说过虚拟计算机,你至少应该听说过磁盘映像。如果经历过 DOS时代,你可能就曾经用HD-COPY把一张软盘做成一个 .IMG文件,或者 把一个 .IMG文件恢复成一张软盘。虚拟计算机相当于此概念的外延,它与映像 文件的关系就相当于计算机与磁盘。简单来讲,它相当于运行在计算机内的小 计算机。 2.1.1 Bochs初体验 我们先来看看Bochs是什么样子的,请看图2.1和图2.2这两个屏幕截图。 要看清楚哦,你看到的不是显示器,仅仅是窗口而已。如果你是第一次接 触“虚拟机”这个东西的话,一定会感到很惊讶,你会惊叹:“啊,像真的一 样!”没错,像真的一样,不过窗口的标题栏一行“Bochs x86-64 emulator”明白 2.1 虚拟计算机 Bochs 图2.1 Bochs中的 grub 图 2.2 Bochs中的 Linux 无误地告诉我们,这仅仅是个“emulator”──模拟器而已。在本书中我们把这 种模拟器称为虚拟机,因为这个词使用得更广泛一些。不管是模拟还是虚拟, 我们要的就是它,有了它,我们不再需要频繁地重启计算机,即便程序有严重 的问题,也丝毫伤害不到你的爱机。更加方便的是,你可以用这个虚拟机来进 行操作系统的调试,在它面前,你就好像是上帝,你可以随时让时间停住,然 后钻进这台计算机的内部,CPU的寄存器、内存、硬盘,一切的一切都尽收眼 底。这正是进行操作系统的开发实验所需要的。 好了,既然Bochs这么好,我们就来看看如何安装,以及如何使用。 2.1.2 Bochs的安装 就像大部分软件一样,在不同的操作系统里面安装Bochs 的过程是不同的, 在Windows 中,最方便的方法就是从 Bochs 的官方网站获取安装程序来安装 9 第 2章 搭建你的工作环境 (安装时不妨将“DLX Linux Demo”选中,这样你可以参考它的配置文件)。在 Linux 中,不同的发行版(distribution)处理方法可能不同。比如,如果你用的 是Debian GNU/Linux或其近亲(比如Ubuntu),可以使用这样的命令: . sudo apt-get install vgabios bochs bochs-x bximage 敲入这样一行命令,不一会儿就装好了。 很多 Linux 发行版都有自己的包管理机制,比如上面这行命令就是使用了 Debian 的包管理命令,不过这样安装虽然省事,但有个缺点不得不说,就是默 认安装的Bochs 很可能是没有调试功能的,这显然不能满足我们的需要,所以 最好的方法还是从源代码安装,源代码同样位于Bochs 的官方网站1,假设你下 载的版本是2.3.5,那么安装过程差不多是这样的: . tar vxzf bochs-2.3.5.tar.gz . cd bochs-2.3.5 . ./configure --enable-debugger --enable-disasm . make . sudo make install 注意“./configure”之后的参数便是打开调试功能的开关。在安装过程 中,如果遇到任何困难,不要惊慌,其官方网站上有详细的安装说明。 2.1.3 Bochs的使用 好了,Bochs已经安装完毕,是时候来揭晓第1章的谜底了,下面我们就一 步步来说明图1.1的画面是怎样来的。 在第 1章我们提到过,硬件方面需要的是一台计算机和一张空白软盘,现 在计算机有了──就是刚刚安装好的 Bochs,那么软盘呢?既然计算机都可以 “虚拟”,软盘当然也可以。在刚刚装好的 Bochs 组件中,就有一个工具叫做 bximage,它不但可以生成虚拟软盘,还能生成虚拟硬盘,我们也称它们为磁盘 映像。创建一个软盘映像的过程如下所示: . bximage ======================================================================== bximage Disk Image Creation Tool for Bochs $Id: bximage.c,v 1.32 2006/06/16 07:29:33 vruppert Exp $ ======================================================================== Do you want to create a floppy disk image or a hard disk image? Please type hd or fd. [hd] fd - Choose the size of floppy disk image to create, in megabytes. Please type 0.16, 0.18, 0.32, 0.36, 0.72, 1.2, 1.44, 1.68, 1.72, or 2.88. [1.44] - I will create a floppy image with cyl=80 heads=2 sectors per track=18 total sectors=2880 total bytes=1474560 1实际上通过命令行也可以获取源代码,只不过通常不是最新的,在此不做介绍。 10 2.1 虚拟计算机 Bochs What should I name the image? [a.img] - Writing: [] Done. I wrote 1474560 bytes to a.img. The following line should appear in your bochsrc: floppya: image=”a.img”, status=inserted 凡是有 -记号的地方,都是 bximage 提示输入的地方,如果你想使用默认值, 直接按回车键就可以。在这里我们只有一个地方没有使用默认值,就是被问到 创建硬盘还是软盘映像的时候,我们输入了“fd”。 完成这一步骤之后,当前目录下就多了一个 a.img,这便是我们的软盘映 像了。所谓映像者,你可以理解为原始设备的逐字节复制,也就是说,软盘的 第M个字节对应映像文件的第M个字节。 现在我们已经有了“计算机”,也有了“软盘”,是时候将引导扇区写进软 盘了。我们使用dd命令2: . dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc 注意这里多用了一个参数“conv=notrunc”,如果不用它的话软盘映像文件a.img 会被截断(truncated),因为boot.bin比 a.img要小。第1章中我们使用这个命令 时不需要此参数,因为真实的软盘不可能被“截断”──真的和假的总是会有 一点区别。 现在一切准备就绪,该打开电源启动了。可电源在哪儿呢?不要慌,我们 还剩一样重要的东西没有介绍,那就是Bochs 的配置文件。为什么要有配置文 件呢?因为你需要告诉Bochs,你希望你的虚拟机是什么样子的。比如,内存多 大啊、硬盘映像和软盘映像都是哪些文件啊等内容。不用怕,这配置文件也没 什么难的,代码2.1就是一个Linux下的典型例子。 代码2.1 bochsrc示例 1 ############################################################### 2 # Configuration file for Bochs 3 ############################################################### 4 5 # how much memory the emulated machine will have 6 megs: 32 7 8 # filename of ROM images 9 romimage: file=/usr/share/bochs/BIOS-bochs-latest 10 vgaromimage: file=/usr/share/vgabios/vgabios.bin 11 12 # what disk images will be used 13 floppya: 1_44=a.img, status=inserted 14 15 # choose the boot disk. 16 boot: floppy 17 18 # where do we send log messages? 19 log: bochsout.txt 20 2如果你用Windows,那么使用 Linux 常用命令需要额外一些劳动,比如安装一个 Cygwin,或 者下载某个工具的Windows 版本。在这里你可以简单下载一个“dd for Windows”,其下载地址 为http://www.chrysocome.net/dd。 11 第 2章 搭建你的工作环境 21 # disable the mouse 22 mouse: enabled=0 23 24 # enable key mapping, using US layout as default. 25 keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map 可以看到,这个配置文件本来就不长,除去注释之后内容就更少了,而 且很容易理解,字面上稍微不容易理解的只有 romimage 和 vgaromimage3,它们 指定的文件对应的其实就是真实机器的 BIOS 和 VGA BIOS,读者自己操作的 时候要确保它们的路径是正确的,不然过一会儿虚拟机启动时可能会被提示 “couldn’t open ROM image file”。读者还要注意 floppya一项,它指定我们使用 哪个文件作为软盘映像。 如果你在Windows 下的话,romimage 和 vgaromimage 两项指定的文件应该 是安装目录下的BIOS-bochs-latest和VGABIOS-lgpl-latest。当然,最保险的方法是 参考安装程序自带的DLX linux的配置文件,将其稍作修改即可。 好了,现在一切准备就绪,是时候启动了,输入命令: . bochs -f bochsrc 一个回车4,你想要的画面就呈现在眼前了。是不是很有趣呢? 顺便告诉你个窍门,如果你输入一个不带任何参数的Bochs 并执行之,那 么Bochs将在当前目录顺序寻找以下文件作为默认配置文件: • .bochsrc • bochsrc • bochsrc.txt • bochsrc.bxrc(仅对Windows有效) 所以刚才我们的“-f bochsrc”参数其实是可以省略的。读者在给配置 文件命名时不妨从这些文件里选一个,这样可以省去许多输入命令的时间。 此外,Bochs的配置文件还有许多其他选项,读者如果想详细了解的话,可 以到其主页上看一看。由于本书中所用到的选项有限,在此不一一介绍。 2.1.4 用 Bochs调试操作系统 如果单是需要一个虚拟机的话,你有许许多多的选择,本书下文也会对其 他虚拟机有所介绍,之所以Bochs 称为我们的首选,最重要的还在于它的调试 功能。 假设你正在运行一个有调试功能的Bochs,那么启动后,你会看到控制台出 现若干选项,默认选项为“6. Begin simulation”,所以直接按回车键,Bochs 就 3Bochs 使用的 vgaromimage 来自于 vgabios 项目,如果读者感兴趣,可以去它的主页看看:http: //www.nongnu.org/vgabios/。 4如果你正在使用的是自己编译的有调试功能的 Bochs,回车后还需要再一次回车,并在出现 Bochs 提示符之后输入“c”,再次回车。不要被这些输入吓怕了,下文有妙计可以让你不必总是这 么辛苦。 12 2.1 虚拟计算机 Bochs 启动了,不过既然是可调试的,Bochs 并没有急于让虚拟机进入运转状态,而 是继续出现一个提示符,等待你的输入,这时,你就可以尽情操纵你的虚拟机 了。 还是以我们那个最轻巧的引导扇区为例,假如你想让它一步步地执行,可 以先在07c00h处设一个断点──引导扇区就是从这里开始执行的,所以这里 就是我们的入口地址──然后单步执行,就好像所有其他调试工具一样。在任 何时刻,你都可以查看CPU寄存器,或者查看某个内存地址处的内容。下面我 就来模拟一下这个过程: � � � � � � � � � Next at t=0 (0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0 b 0x7c00 - c - (0) Breakpoint 1, 0x00007c00 in ?? () Next at t=886152 (0) [0x00007c00] 0000:7c00 (unk. ctxt): mov ax, cs ; 8cc8 dump_cpu - eax:0x0fffaa55, ebx:0x00000000, ecx:0x00120001, edx:0x00000000 ebp:0x00000000, esp:0x0000fffe, esi:0x000088d2, edi:0x0000ffde eip:0x00007c00, eflags:0x00000282, inhibit_mask:0 cs:s=0x0000, dl=0x0000ffff, dh=0x00009b00, valid=1 ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7 ds:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1 es:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1 fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1 gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1 ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1 tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1 gdtr:base=0x00000000, limit=0xffff idtr:base=0x00000000, limit=0xffff dr0:0x00000000, dr1:0x00000000, dr2:0x00000000 dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400 cr0:0x00000010, cr1:0x00000000, cr2:0x00000000 cr3:0x00000000, cr4:0x00000000 done x /64xb 0x7c00 - [bochs]: 0x00007c00 : 0x8c 0xc8 0x8e 0xd8 0x8e 0xc0 0xe8 0x02 0x00007c08 : 0x00 0xeb 0xfe 0xb8 0x1e 0x7c 0x89 0xc5 0x00007c10 : 0xb9 0x10 0x00 0xb8 0x01 0x13 0xbb 0x0c 0x00007c18 : 0x00 0xb2 0x00 0xcd 0x10 0xc3 0x48 0x65 0x00007c20 : 0x6c 0x6c 0x6f 0x2c 0x20 0x4f 0x53 0x20 0x00007c28 : 0x77 0x6f 0x72 0x6c 0x64 0x21 0x00 0x00 0x00007c30 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00007c38 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 n - Next at t=886153 (0) [0x00007c02] 0000:7c02 (unk. ctxt): mov ds, ax ; 8ed8 trace-reg on - Register-Tracing enabled for CPU 0 n - Next at t=886154 eax: 0x0fff0000 268369920 ecx: 0x00120001 1179649 edx: 0x00000000 0 ebx: 0x00000000 0 esp: 0x0000fffe 65534 ebp: 0x00000000 0 esi: 0x000088d2 35026 edi: 0x0000ffde 65502 eip: 0x00007c04 eflags 0x00000282 IOPL=0 id vip vif ac vm rf nt of df IF tf SF zf af pf cf 13 第 2章 搭建你的工作环境 (0) [0x00007c04] 0000:7c04 (unk. ctxt): mov es, ax ; 8ec0 c - � � � � � � � � � 以上带有 -符号并以加粗字体显示的是输入,其他均为Bochs 的输出。如 果你用过GDB,你会觉得这个过程很亲切。没错,它跟用GDB调试程序的感 觉是很相似的,最大的区别可能就在于在Bochs的调试模式下我们需要跟CPU、 内存、机器指令等内容打更多交道。 在上面的演示过程中,最开始的“b 0x7c00”在0x7c00处设置了断点, 随后的命令“c”让代码继续执行,一直到我们设置的断点处停止,然后演示的 是用“dump_cpu”指令查看CPU寄存器以及用“x”指令查看内存。随后用 一个“n”指令让代码向下走了一步,“trace-reg on”的功能是让Bochs 每 走一步都显示主要寄存器的值。之所以选择演示这些命令,因为它们基本是调 试过程中最常用到的。 如果你在调试过程中忘记了指令的用法,或者根本就忘记了该使用什么指 令,可以随时使用help命令,所有命令的列表就呈现在眼前了。你将会发现 Bochs 的调试命令并不多,不需要多久就可以悉数掌握。表2.1列出了常用的指 令以及其典型用法。 表2.1 部分Bochs调试指令 行为 指令 举例 在某物理地址设置断点 b addr b 0x30400 显示当前所有断点信息 info break info break 继续执行,直到遇上断点 c c 单步执行 s s 单步执行(遇到函数则跳过) n n info cpu info cpu r r 查看寄存器信息 fp fp sreg sreg creg creg 查看堆栈 print-stack print-stack 查看内存物理地址内容 xp /nuf addr xp /40bx 0x9013e 查看线性地址内容 x /nuf addr x /40bx 0x13e 反汇编一段内存 u start end u 0x30400 0x3040D 反汇编执行的每一条指令 trace-on trace-on 每执行一条指令就打印CPU信息 trace-reg trace-reg on 其中“xp /40bx 0x9013e”这样的格式可能显得有点复杂,读者可以用 “help x”这一指令在Bochs中亲自看一下它代表的意义。 好了,虽然你可能还无法熟练运用 Bochs 进行调试,但至少你应该知道, 即便你的操作系统出现了问题也并不可怕,有强大的工具可以帮助你进行调试。 由于Bochs是开放源代码的,如果你愿意,你甚至可以通过读Bochs的源代码来 间接了解计算机的运行过程──因为Bochs就是一台计算机。 14 2.2 QEMU 2.2 QEMU 如果你选择在Linux下开发,其实Bochs自己就完全够用了。在本书中,今 后的大部分例子均使用Bochs 作为虚拟机来运行。如果你在Windows 下开发的 话,或许你还需要一个运行稍微快一点的虚拟机,它不是用来运行我们自己的 操作系统的,而是用来运行Linux的,因为我们的代码是用Linux来编译的,并 且生成的内核代码是ELF格式的。 之所以不用Bochs 来装一个 Linux,是因为Bochs 速度比较慢,这是由它的 运行机制决定的,它完全模拟硬件及一些外围设备,而很多其他虚拟机大都采 用一定程度的虚拟化(Virtualization)技术5,使得速度大大提高。 我以QEMU为例介绍速度较快的虚拟机,但它绝不是唯一的选择,除它之 外,Virtual Box、Virtual PC、VMWare 等都是很有名气的虚拟机。它们各有自 己的优缺点,QEMU的显著优势是它可以模拟较多的硬件平台,这对于一个操 作系统爱好者而言是很具有吸引力的。 图2.3 QEMU中的Linux 好了,百闻不如一见,图2.3就是QEMU上运行Linux的抓图。这里我安装 的是Debian 4.0,窗口管理器用的是Fvwm。在我并不强大的个人电脑上,安装 整个系统也没用很久,运行起来也相当顺畅。 与Bochs 使用配置文件不同,QEMU运行时需要的参数是通过命令行指定 的6。比如,如果要用QEMU来引导我们之前已经做好的虚拟软盘,可以这样 做: . qemu -fda a.img 5读者如果对这一技术感兴趣,可在网上搜索相应资料,比如维基百科上就有个大致的介绍: http://en.wikipedia.org/wiki/Full_virtualization。 6实际上Bochs也可以用命令行指定参数,详见Bochs联机手册。 15 第 2章 搭建你的工作环境 看起来比Bochs 还要清爽,不是吗?其实如果你不需要调试的话,在Linux 下也可以用QEMU来运行你的操作系统,这样每次都可以更快地看到结果── 这便是我之前说过的“可以让你不必总是这么辛苦”的“妙计”了7。 2.3 平台之争:Windows还是 *nix 读到这里,读者可能发现书中经常出现“如果你用的是Windows”或者 “如果你用的是Linux”这样的字眼。有时这样的字眼甚至可能影响到你的阅读, 如果真的这样请你原谅。我试图照顾尽量多的读者,但是对每一个人来讲,却 必须面临一个选择──在什么平台下开发。本书第一版使用的是Windows平台, 而在第二版中,我投诚了。接下来你会发现,虽然以后的行文会最大限度地兼 顾Windows,但总体是以Linux为默认平台的。 其实在什么平台下开发,有时纯粹是口味问题,或者是环境问题──你开 始接触计算机时使用什么,很大程度上取决于你周围的人使用什么,而这往往 对你的口味产生巨大而深远的影响。然而最早接触的未必是最适合的,在我亲 身体会和比较之后,我决定从Windows 彻底换到 Linux,我想在这里说说为什 么。请注意这不是布道会,更不是你开发自己的操作系统必须阅读的章节,我 仅仅是谈谈我个人的体会,希望能对你有所启发,同时解释一下为什么第二版 会有这样的改动。 在第一版成书的时候,我已经在使用Linux,但是用得并不多,主要是觉得 用不习惯,而现在过了两三年,我已经基本不用Windows,在Windows 下我会 觉得很不习惯。我的这一经历至少有两点启示:第一是 Linux 不好用是个误解 (有一种说法是Windows的桌面更好用,这是个复杂的误解),好不好用是习惯 问题;第二是如果你有兴趣使用一样你不熟悉的东西,不要因为刚开始的不习 惯而放弃。 其实对于 Linux 和Windows 的误解有很多,我把这种误解归结为操作系统 文化上的差异。其实在提起两种系统时,人们往往拿一些具体的事情来做比较。 比如比较它们的安装过程、使用方法,甚至是界面。但实际上隐藏在表面背后 的是两种完全不同类型的文化,或者称之为不同的理念。 对于Windows 而言,它的文化植根于微软公司的愿景,“让每个家庭的每 个桌面上都有一台电脑”,当然他们希望此电脑内运行的是Windows操作系统。 这个理想加上Windows作为商业软件的性质,决定了Windows具有相当程度的 亲和力,用户界面显得相当友好。岂止友好,它简直友好到每个人──无论儿 童还是老人,受过高等教育还是只念过小学──都能比较容易地开始使用电脑, 这无疑是微软对这个社会的巨大贡献。但是界面友好并不一定就完美了,这一 点暂且按下不表,我们先来说说Linux。 Linux 的文化很大程度上来源于UNIX,UNIX所倡导和遵循的文化也被称 为UNIX哲学8,其中很重要的一条原则叫做“做一件事并做好”9,这听上去 7其实妙计不止一条,你也可以在系统内安装两种Bochs,一种是打开调试功能的,一种是没有 打开的,你可以自由选择运行哪一种。 8简单的介绍可参见http://en.wikipedia.org/wiki/Unix_philosophy;若想较全面地了解,建议读者阅 读Eric S. Raymond所著的《UNIX编程艺术》。 9原文作“Do one thing, do it well”。理解这一原则的内涵及外延是理解UNIX世界的基本条件。 16 2.3 平台之争:Windows还是 *nix 跟Windows的界面友好说的不是一码事,但其实仔细 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 起来大有关联。做一 件事并做好意味着两件事情,第一件事就是工具之间可以协同作战,不然各人 做各人的,无法完成复杂应用;第二件事就是接口要统一,不然无法做到协同。 这个统一的接口就是文本流(text stream),这也就意味着,命令行是UNIX文 化的核心。而Windows的做法大有不同,因为要界面友好,于是不能指望用户 开始就知道怎么把工具串接在一起,所以Windows选择任何应用都自己完成所 有功能──至少让用户看起来如此,这使得每个工具都各自为战,从而增加了 每个程序的复杂性和开发成本。不仅如此,由于功能都是软件开发者定好的, 所以你基本上不能指望大部分的程序具备可扩展性,而在UNIX下,大部分的 程序都可以跟其他程序协同起来完成程序不曾“ 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 ”的功能。这也是上文我 说“界面友好并不一定完美”的原因,友好是有代价的。 那么UNIX是一个“不友好”的系统吗?这个问题其实没有看起来那么简 单。首先是UNIX下流行的桌面环境正在越来越“友好”,你甚至可以将其配置 得看上去跟Windows别无二致,不过关键点不在于此,而在于长期来看,UNIX 的学习成本并不比Windows要高,但收益却要高得多。我们刚刚提到,友好是 有代价的,而且代价比想像中要高。对于一个初学者,开始的简单容易使他产 生错觉,认为电脑是个简单器械,但实际情况并非如此,一旦遇到麻烦,用户 很容易陷入束手无策的境地,一旦有一件事情没有现成的软件可以解决,你马 上一筹莫展。而UNIX不同,它的学习曲线比较陡峭,但是你一旦入门,就会 发现自己的工作可以变得如此轻松而且有趣。在Windows中,虽然使用一个工 具第一步往往很容易,但很快你就容易迷失在一堆嵌套很深名字晦涩的菜单里 面,学习这些菜单可不是一件容易的事情,而且在一个工具里学会的东西到了 另一个工具里可能就变了样。如果你想看看程序的帮助,有时也是件困难的事 情,因为为了达到“友好”的效果,帮助经常也是一层一层的,很难找到自己 需要的内容。而在UNIX中,所有的工具都有个手册(Manual),可以通过统一 的命令“man”来查看,而且这些手册都是平坦的,你可以一口气从头看到尾, 可以随时查看你所要的关键字。此外,除了少数极其复杂的工具,手册基本上 是够用的。简而言之,在UNIX中,软件使用看起来复杂了,实际上如果你想 真正掌握一个东西,用的时间不会比Windows中更多。况且,在Windows中你 很难真正掌握一个东西。 我并非故意贬低Windows,我说过它对社会的贡献巨大。对于一个平常只 用电脑来收收邮件看看电影的用户,它的易用性绝对是巨大的优点,但你我不 是这样的用户。我相信阅读本书的人都是程序员,而且都是像我一样喜欢探索 的程序员──不喜欢探索的程序员很难有心思写自己的操作系统做消遣。一个 程序员的要求和普通用户是不同的,程序员需要了解他的电脑,掌握它,并且 可以熟练地让它帮助自己完成工作,从这个角度上讲,UNIX无疑具有巨大的 优势。它里面的每个工具都很锋利,你可以组合着使用,持久地使用,而且许 多年都不会过时。 在这里我可以举一个我自己遇到过的例子。在我编写操作系统的文件系统 时,需要多次查看某几个扇区的内容,并对其中的数据进行分析。在Linux中, 我可以很容易地将od、grep、sed和 awk等工具10串在一起完成这项工作,我也 可以编写一个简单的脚本,将命令放在脚本中方便取用。而在Windows中,我 10这些都是UNIX下的常用工具,读者可以通过联机手册查看它们的用法。更多UNIX下的工具 介绍可参考http://en.wikipedia.org/wiki/List_of_Unix_utilities。 17 第 2章 搭建你的工作环境 通常只能在窗口间反复地单击鼠标,费时费力而且效率低下。类似的例子不胜 枚举,你一旦熟悉了这些工具,就会发现通过组合它们,你能得到比任何图形 界面工具都多的功能。而在Windows下就不得不看具体菜单的眼色了。不仅如 此,UNIX下的工具往往学习一次就能长久使用,很少过时。比如刚才提到的 几个工具大部分有20年以上的历史,到现在它们依然被广泛使用,即便它们学 起来会稍微难一点,平摊在 20年里面,成本也是极低的。这就是UNIX哲学, 你不需要重复学习,每个工具都好用,而且可以因为跟其他工具结合而发挥多 种作用。 大多数Windows下的软件都有个毛病,它经常试图隐藏一些东西。它的本 意是好的,就是让界面更“友好”,但这对程序员有时是件坏事,因为它让人 难以透彻地理解软件的所作所为。或许你会说,如果你想理解,你总能理解的。 没错,这跟“在UNIX下能做的事情在Windows 下都能做”是相似的命题,甚 至于,只要安装一些额外的软件(比如Cygwin11),你可以在Windows 下使用 UNIX的命令。问题是即便能做,你也未必去做,这就是所谓文化的力量。理 论上你在任何地方都能读书学习,但效率最高的地方还是教室和书房,在客厅 舒服的沙发上,你不自主地就拿起了电视遥控器。 所以以我自己的体会而言,一个程序员最好还是使用类UNIX的操作系统。 它能在日常生活中帮你提高自己的水平和工作效率。这一点与摄影有点类似, 市面上数量最多的是傻瓜相机,但一个专业的摄影师总是会选择功能复杂的专 业级设备,不是傻瓜相机不好,而是适应的人群不同,如果你想成为好的摄影 师,那么上手容易的傻瓜相机一定不是你的最终选择。不是好不好的问题,是 适不适合的问题。 上面论及的是两类操作系统文化上的差异,其实即便是纯粹应用层的,也 有诸多误解,比如以下几条: 误解一. Linux 难安装。如果你曾被 Linux 的安装难倒过,我建议你下次试 试Ubuntu12。在本书第一版开始写作之时,Ubuntu的第一个版本还没有发布13, 但短短几年时间,它已经变成全世界最流行的发行版14,这与它的易装和易用 性是分不开的。笔者本人大规模地使用Linux也是从Ubuntu开始的,它的安装 过程一点也不比Windows的难,而且中文资料也相当丰富,很容易找到志同道 合的人。Ubuntu的另一特点是它的驱动程序很丰富,支持很多的硬件,大部分 情况下驱动程序都能自动安装好,甚至不需要用户参与,在这一点上它甚至比 Windows更“友好”。 误解二. Linux难学。希望你永远记住,电脑不是个简单器械,无论是硬件、 操作系统还是应用软件,都经常比看上去复杂得多。所以易用未必是好事,它 肯定向你隐瞒了些什么,花一点时间绝对是值得的,尤其是当你想做一个程序 员的时候。况且 Linux 也
本文档为【一个操作系统的实现】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_839586
暂无简介~
格式:pdf
大小:1MB
软件:PDF阅读器
页数:48
分类:互联网
上传时间:2013-06-26
浏览量:742