制作你的 ToyOS 系列(Ⅱ)

译者:penghuster
作者: Krishnakumar R.



在了解制作一个引导扇区之后,学习切换到保护模式之前,如何使用 BIOS 中断是任何人都要学习的。BIOS 中断使创建操作系统的任务变得容易,本文将学习 BIOS 中断的使用。

1. 引言

1.1 为什么要了解 BIOS ?

BIOS 拷贝启动扇区中的执行代码到 RAM 中。除此之外,BIOS 执行了许多工作。当操作系统启动时,它没有显示驱动、软盘驱动以及任何其他驱动。要包含所有的这些驱动,对于启动扇区来说是不可能的。此时 BIOS 就发挥作用了,BIOS 包含各种需要使用的程序。BIOS中有准备好的各种功能的程序,如检查设备安装、控制打印机、获取内存大小等。这些程序称之为 BIOS 中断。

1.2 如何调用 BIOS 中断?

在一般的程序语言中,通过 call 指令调用一个程序。例如,在 C 语言中,如果存在一个名为 display 的函数,其参数 noofchar 表示显示字符数目,参数 attr 表示显示字符属性,只需要通过此函数名即可调用该函数。这里我们利用中断和汇编指令 int 来执行此功能。

例如,通过下面代码调用 C 函数打印某些东西到屏幕上:
dispaly(noofchar, attr)
用 BIOS 中断完成同样的工作:
int 0x10

1.3 现在,如何传递参数呢?

在调用 BIOS 中断之前,我们需要将某些值以预先设定的格式加载到特定的寄存器中。假设需要使用 BIOS 中断 13h,该中断用于传输软盘数据到内存中。在调用中断 13h 之前,必须指定要拷贝数据的段地址,还需要传参数如,驱动号、磁道号、扇区号,扇区个数等。这就是需要加载到特定寄存器的预先设定值。在解释了构建引导程序之后,这将变得一目了然。有一点需要知晓的是,中断可以被用于几种功能不同目的。中断具体的功能依赖于其选择的功能号,该功能号需写入到寄存器 ah 中。例如中断 13h 能够用于显示一个字符串或获取光标的位置。如果寄存器 ah 中写入 3, 则功能号为 3 的函数将被调用,并返回光标的位置。要在屏幕上显示一个字符串,则需向寄存器 ah 中写入 13h。

2 接下来做什么?

这次源码分为两个汇编程序和一个 C 程序。第一个汇编文件是引导扇区代码。通过执行引导扇区中写入的代码,拷贝软盘第二个扇区中的代码到内存的 0x500 地址段(内存地址为 0x5000)。此拷贝任务是通过 BIOS 中断 13h 完成。第二个汇编文件借助 BIOS 中断 10h 实现再屏幕上显示一段消息。C 程序是用于将第一个汇编程序生成的可执行代码转移到软盘的引导扇区,将第二个汇编程序生成的可执行代码转移到软盘的第二个扇区。

3 引导扇区

利用中断 13h,引导扇区程序加载软盘第二个扇区数据到内存地址 0x5000(段地址为 0x500) 处。起源码如下所示,保存此段代码到文件 bsect.s 中。

LOC1=0x500
entry start
start:
mov ax,#LOC1
mov es,ax
mov bx,#0
mov dl,#0
mov dh,#0
mov ch,#0
mov cl,#2
mov al,#1
mov ah,#2
int 0x13
jmpi 0,#LOC1

第 1 行代码类似于宏定义语句。接下来两个语句你应该已经很熟悉了。然后加载数值 0x500 到 es 寄存器中。这是软盘中第二个扇区(第一个扇区是引导扇区)中的代码被转移到的内存位置。现在指定段偏移为 0(bx 寄存器)。

接着,加载驱动号到 dl 寄存器,磁头号到 dh 寄存器,磁道号到 ch 寄存器中,扇区号到 cl 寄存器,扇区数目到 al 寄存器。故此程序将加载 2 号扇区、0 磁道、0 号磁盘中的数据到内存段 0x500 中。所有这些都与 1.44Mb 软盘想对应。

通过写入数值 2 到寄存器 ah 来选择调用中断的功能号。该功能号根据中断 13h 提供的功能选取。此处选择的功能号 2 表示将软盘指定数据拷贝到指定内存空间的功能。

现在调用中断 13h,最终跳转程序到内存段 0x500 的偏移 0 处。
Now we call interrupt 13h and finally jump to 0th offset in the segment 0x500.

4 第二扇区

第二个扇区的代码如下所示,并保存此段代码到 sect2.s。

entry start
start:
mov ah,#0x03
xor bh,bh
int 0x10
mov cx,#26
mov bx,#0x0007
mov bp,#mymsg
mov ax,#0x1301
int 0x10
loop1: jmp loop1
mymsg:
.byte 13,10
.ascii "Handling BIOS interrupts"

这段代码将被加载到内存段 0x500 并执行。此段代码利用中断 10h 获得光标的位置并打印消息。

头三行(从第 3 行开始)语句被用于获得当前光标的位置。此处选择的中断 13h 的功能号是 3。然后将 bh 寄存器置 0,并将待显示信息的字符数据目赋给寄存器 ch。寄存器 bx 中设置显示字符的属性,这里使字符为白色、背景为黑色。然后将打印信息的地址赋于 bp 寄存器,该消息由字符换行符 CR(ascii 码值为 13)和字符行结束字符 LF(ascii 码值为 10),以及 24 个字符的字符串组成。

接着,设置打印字符和移动光标的功能号 13h 和 01h 到寄存器 ax 中,然后调用中断 10h。最后以一个死循环结束该程序。

5 C 程序

C 程序的源码带如下所示,保存此段代码到 write.c 文件中。

#include <sys/types.h> /* unistd.h needs this */
#include <unistd.h> /* contains read/write */
#include <fcntl.h>
int main()
{
      char boot_buf[512];
      int floppy_desc, file_desc;
      file_desc = open("./bsect", O_RDONLY);
      read(file_desc, boot_buf, 510);
      close(file_desc);
      boot_buf[510] = 0x55;
      boot_buf[511] = 0xaa;
      floppy_desc = open("/dev/fd0", O_RDWR);
      lseek(floppy_desc, 0, SEEK_SET);
      write(floppy_desc, boot_buf, 512);
      file_desc = open("./sect2", O_RDONLY);
      read(file_desc, boot_buf, 512);
      close(file_desc);
      lseek(floppy_desc, 512, SEEK_SET);
      write(floppy_desc, boot_buf, 512);
      close(floppy_desc);
}

在系列(一)中已经给出关于制作启动软盘设备的描述。这里稍有不同,首先拷贝文件 bsect(bsect.s 生成的可执行文件)到软盘的引导扇区,然后拷贝 sect2.s 生成的相应的可执行代码到软盘的第二扇区。使这个软盘成为启动设备的改变也已经执行。

6 编译

makefile文件:

all : bsect sect2 write
bsect  : bsect.o
ld86 -d bsect.o -o bsect
sect2 : sect2.o
ld86 -d sect2.o -o sect2
bsect.o : bsect.s
as86 bsect.s -o bsect.o
sect2.o : sect2.s
as86 sect2.s -o sect2.o
write : write.c
cc write.c -o write
clean :
rm bsect.o sect2.o bsect sect2 write

译者注:进行此实验之前,先借助 dd 命令生成一个容量大于 1024 byte
的虚拟软盘(参见系列一编者注)。然后按照上述说明进行。

6 模拟结果

在 bochs 中模拟的效果图如下:

7 下一步工作

当你从软盘启动并显示字符串后,也就意味着用到了 BIOS 中断。下一个系列文章中,将说明如何切换处理器到保护保护模式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容