《ORANGE’S:一个操作系统的实现》读书笔记(三十八)尾声(二)

这篇文章是尾声的第二部分,记录如何将Orange’S安装到硬盘上,并实现从硬盘启动。

目录

从硬盘引导

编写硬盘引导扇区和硬盘版loader

“安装”hdboot.bin和hdldr.bin

grub

小结


从硬盘引导

虽然我们的硬盘上已经有不少内容了,但到目前为止,我们的系统始终是从软盘启动的。下面我们要做的事情就是将Orange’S安装到硬盘上,并实现硬盘启动。

我们先回忆一下从软盘启动的过程:

  1. BIOS将引导扇区读入内存0000:7c00处;
  2. 跳转到0000:7c00处开始执行引导代码;
  3. 引导代码从软盘中找到loader.bin,并将其读入内存;
  4. 跳转到loader.bin开始执行;
  5. loader.bin从软盘中找到kernel.bin,并将其读入内存;
  6. 跳转到kernel.bin开始执行,到此可认为启动过程结束;
  7. 系统运行中。

在第1步中,BIOS到底读软盘还是硬盘是由CMOS设置决定的,通常你可以找到一个叫做“Boot Sequence”的选项,从中选择首选启动设备。在第3步和第5步中,对于软盘启动,代码将在软盘中寻找loader.bin和kernel.bin,对于硬盘启动,我们需要让引导扇区代码从硬盘中寻找loader.bin并让loader从硬盘中寻找kernel.bin。这便是软盘和硬盘启动的区别了。剩下的几步中,软盘和硬盘启动没有分别。

因此我们需要重写boot.asm和loader.asm,让它们读取硬盘而不是软盘。新的文件我们起名为hdboot.asm和hdldr.asm。

编写硬盘引导扇区和硬盘版loader

我们先来完成hdboot.asm。它跟boot.asm的区别主要在两方面,一是读取软盘和硬盘扇区的方法有所不同;二是软盘的文件系统(FAT12)跟硬盘的文件系统(Orange’S FS)不同,所以寻找loader的方式肯定也不一样。

我们在之前的记录中讲到如何用int 13h读取软盘扇区,实际上这个中断也可用来读取硬盘,见下表。

中断号 寄存器 作用
13h ah: 02h al: 要读扇区数 从磁盘读数据入es:bx指向的缓冲区中
ch: 柱面号低八位

cl:            第0~5位:起始扇区号

               第6~7为:柱面号高二位

dh: 磁头号 dl: 驱动器号(置第7位 表示硬盘操作)

根据这个表我们知道,以这种方式读取磁盘,允许的磁头数最大为256,柱面数最大为1024,扇区数最大为64,所以容易算出所支持的硬盘最多有16777216(256*1024*64)个扇区,合8GB。这实在是个太严重的限制了,因为目前的硬盘很少小于8GB,显然这个方法读取硬盘不太好。

好在我们并不是最先不满于这个限制的第一批人,West Digital和Phoenix Technologies联合推出了EDD标准(BIOS Enhanced Disk Drive Services),它支持64位LBA。它的具体做法是将原来放进寄存器的参数放进内存中的数据结构,这个数据结构叫做Disk Address Packed,见下表。

偏移 位数 描述
0 8 Packet有多少字节
1 8 保留
2 8 要传输的块数(最大值为127;0表示不传输数据)
3 8 保留
4 32 读操作的目的地址(段:偏移)
8 64 LBA地址

当读磁盘扇区时,只需要将AH设为42h,DL设为驱动器号,DS:SI设为Disk Address Packet的地址,然后调用int 13h就可以了。

了解了读取硬盘的方法,我们就可以开始写hdboot.asm了,代码如下所示。

代码 boot/hdboot.asm。

org 0x7c00      ; bios always loads boot sector to 0000:7C00

    jmp boot_start

%include "load.inc"

STACK_BASE      equ 0x7C00      ; base address of stack when booting
TRANS_SECT_NR   equ 2
SECT_BUF_SIZE   equ TRANS_SECT_NR * 512

disk_address_packet:    db 0x10             ; [ 0] Packet size in bytes.
                        db 0                ; [ 1] Reserved, must be 0.
                        db TRANS_SECT_NR    ; [ 2] Nr of blocks to transfer.
                        db 0              

你可能感兴趣的:(《ORANGE’S:一个操作系统的实现》读书笔记(三十八)尾声(二))