《一个操作系统的实现》(四):让操作系统走进保护模式
2013-05-18 16:13
295 查看
一个操作系统从开机到开始运行,大致经历“引导->加载内核入内存->跳入保护模式->开始执行内核”这样一个过程。
几乎所有的文件系统都会把磁盘划分为若干层次以方便组织和管理,这些层次包括扇区(磁盘上的最小数据单元),簇(一个或多个扇区),分区(通常指整个文件系统)。
对于FAT12文件系统来说,第0号扇区为引导扇区,其中有一个叫做BPB(BIOS Parameter Block)的数据结构,格式如下表,其中BPB_开头的属于BPB,其余的只是引导扇区的一部分。
FAT12引导扇区的格式
接下来扇区号1-9、10-18分别由两个完全相同的表(FAT1和FAT2)占用,接下来是根目录区(长度非固定,需计算),剩余的是数据区(截止到2879号)。
根目录区由若干个目录条目组成,每个条目占32字节,条目最多有BPB_RootEntCht个,即根目录区大小依赖于BPB_RootEntCht。
根目录区中的条目格式
注意,数据区的第一个簇号是2,而不是0或1。
实际上,对于小于512字节的文件来说,FAT表用处不大,但如果文件大于512字节,就需要FAT表来找到所有的簇(扇区)。通常FAT项的值代表的是文件下一个簇号。还需要注意的是一个FAT项可能会跨越两个扇区。
引导扇区需要有BPB等头信息才能被识别,书上BPB的代码如下:
要加载一个文件如内存的话免不了要读软盘。这时候需要用到int 13h中断,此中断参数详见这篇文章。中断参数需要柱面号、磁头号、当前柱面上的扇区号三个分量,这三个分量的计算方法如下:
扇区号/每磁道扇区数(18),得商Q和余数R。柱面号为Q>>1,磁头号为Q&1,起始扇区号为R+1。
Loader要做的事情至少有两件:加载内核入内存;跳入保护模式。因为内核开始执行的时候一定在保护模式下。.COM的内核可以直接放入内存,但是ELF格式的内核不能直接放进内存(下一章会讲)。
---------------------
在编译生成boot.bin后,还需要这样做:首先用bximage生成一个软盘映像(直接执行bximage),然后执行如下命令
nasm loader.asm -o loader.bin
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
sudo mount -o loop a.img /mnt/floppy/
sudo cp loader.bin /mnt/floppy/ -v
sudo umount /mnt/floppy/
几乎所有的文件系统都会把磁盘划分为若干层次以方便组织和管理,这些层次包括扇区(磁盘上的最小数据单元),簇(一个或多个扇区),分区(通常指整个文件系统)。
对于FAT12文件系统来说,第0号扇区为引导扇区,其中有一个叫做BPB(BIOS Parameter Block)的数据结构,格式如下表,其中BPB_开头的属于BPB,其余的只是引导扇区的一部分。
名称 | 偏移 | 长度 | 内容 | Orange's的值 |
---|---|---|---|---|
BS_jmpBoot | 0 | 3 | 一个短跳转指令 | jmp LABEL_START nop |
BS_OEMName | 3 | 8 | 厂商名 | 'ForrestY' |
BPB_BytesPerSec | 11 | 2 | 每扇区字节数 | 0x200 |
BPB_SecPerClus | 13 | 1 | 每簇扇区数 | 0x1 |
BPB_RsvdSecCnt | 14 | 2 | Boot记录占用多少扇区 | 0x1 |
BPB_NumFATs | 16 | 1 | 共有多少FAT表 | 0x2 |
BPB_RootEntCnt | 17 | 2 | 根目录文件最大值 | 0xE0 |
BPB_TotSec16 | 19 | 2 | 扇区总数 | 0xB40 |
BPB_Media | 21 | 1 | 介质描述符 | 0xF0 |
BPB_FATSz16 | 22 | 2 | 每FAT扇区数 | 0x9 |
BPB_SecPerTrk | 24 | 2 | 每磁道扇区数 | 0x12 |
BPB_NumHeads | 26 | 2 | 磁头数(面数) | 0x2 |
BPB_HiddSec | 28 | 4 | 隐藏扇区数 | 0 |
BPB_TotSec32 | 32 | 4 | 如果BPB_TotSec16是0,由这个值记录扇区数 | 0 |
BS_DrvNum | 36 | 1 | 中断13的驱动器号 | 0 |
BS_Reserved1 | 37 | 1 | 未使用 | 0 |
BS_BootSig | 38 | 1 | 扩展引导标记(29h) | 0x29 |
BS_VolID | 39 | 4 | 卷序列号 | 0 |
BS_VolLab | 43 | 11 | 卷标 | 'OrangeS0.02' |
BS_FileSysType | 54 | 8 | 文件系统类型 | 'FAT12' |
引导代码及其他 | 62 | 448 | 引导代码、数据及其他填充字符等 | 引导代码(剩余部分被0填充) |
结束标志 | 510 | 2 | 0xAA55 | 0xAA55 |
根目录区由若干个目录条目组成,每个条目占32字节,条目最多有BPB_RootEntCht个,即根目录区大小依赖于BPB_RootEntCht。
名称 | 偏移 | 长度 | 描述 |
---|---|---|---|
DIR_Name | 0 | 0xB | 文件名8字节,扩展名3字节 |
DIR_Attr | 0xB | 1 | 文件属性 |
保留位 | 0xC | 10 | 保留位 |
DIR_WrtTime | 0x16 | 2 | 最后一次写入时间 |
DIR_WrtDate | 0x18 | 2 | 最后一次写入日期 |
DIR_FstClus | 0x1A | 2 | 此条目对应的开始簇号 |
DIR_FileSize | 0x1C | 4 | 文件大小 |
实际上,对于小于512字节的文件来说,FAT表用处不大,但如果文件大于512字节,就需要FAT表来找到所有的簇(扇区)。通常FAT项的值代表的是文件下一个簇号。还需要注意的是一个FAT项可能会跨越两个扇区。
引导扇区需要有BPB等头信息才能被识别,书上BPB的代码如下:
jmp short LABEL_START ; Start to boot. nop ; 这个 nop 不可少 ; 下面是 FAT12 磁盘的头 BS_OEMName DB 'ForrestY' ; OEM String, 必须 8 个字节 BPB_BytsPerSec DW 512 ; 每扇区字节数 BPB_SecPerClus DB 1 ; 每簇多少扇区 BPB_RsvdSecCnt DW 1 ; Boot 记录占用多少扇区 BPB_NumFATs DB 2 ; 共有多少 FAT 表 BPB_RootEntCnt DW 224 ; 根目录文件数最大值 BPB_TotSec16 DW 2880 ; 逻辑扇区总数 BPB_Media DB 0xF0 ; 媒体描述符 BPB_FATSz16 DW 9 ; 每FAT扇区数 BPB_SecPerTrk DW 18 ; 每磁道扇区数 BPB_NumHeads DW 2 ; 磁头数(面数) BPB_HiddSec DD 0 ; 隐藏扇区数 BPB_TotSec32 DD 0 ; wTotalSectorCount为0时这个值记录扇区数 BS_DrvNum DB 0 ; 中断 13 的驱动器号 BS_Reserved1 DB 0 ; 未使用 BS_BootSig DB 29h ; 扩展引导标记 (29h) BS_VolID DD 0 ; 卷序列号 BS_VolLab DB 'OrangeS0.02'; 卷标, 必须 11 个字节 BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8个字节 LABEL_START:
要加载一个文件如内存的话免不了要读软盘。这时候需要用到int 13h中断,此中断参数详见这篇文章。中断参数需要柱面号、磁头号、当前柱面上的扇区号三个分量,这三个分量的计算方法如下:
扇区号/每磁道扇区数(18),得商Q和余数R。柱面号为Q>>1,磁头号为Q&1,起始扇区号为R+1。
Loader要做的事情至少有两件:加载内核入内存;跳入保护模式。因为内核开始执行的时候一定在保护模式下。.COM的内核可以直接放入内存,但是ELF格式的内核不能直接放进内存(下一章会讲)。
---------------------
在编译生成boot.bin后,还需要这样做:首先用bximage生成一个软盘映像(直接执行bximage),然后执行如下命令
nasm loader.asm -o loader.bin
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
sudo mount -o loop a.img /mnt/floppy/
sudo cp loader.bin /mnt/floppy/ -v
sudo umount /mnt/floppy/
相关文章推荐
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-理论)
- 《Orange's 一个操作系统的实现》学习笔记--保护模式理论初步(一)
- 一个操作系统的实现:保护模式
- 一个操作系统的实现-5_保护模式4
- 一个操作系统的实现(3)-保护模式进阶
- 《Orange's 一个操作系统的实现》读书手记3(4)--- [ 保护模式(Protect Mode)]
- 《Orange's 一个操作系统的实现》读书手记3(3)--- [ 保护模式(Protect Mode)]
- 《Orange's 一个操作系统的实现》学习笔记--保护模式理论初步(二)
- 《Orange’s 一个操作系统的实现》3.保护模式3----DOS加载.EXE过程
- 《Orange’s 一个操作系统的实现》3.保护模式2----认识保护模式A
- 于渊<orange's一个操作系统的实现>保护模式部分详解
- 学习笔记:一个操作系统的实现--保护模式进阶
- 《Orange’s 一个操作系统的实现》3.保护模式3----保护模式进阶
- 《Orange’s 一个操作系统的实现》3.保护模式8-页式存储
- <<orange‘s :一个操作系统的实现>>读书笔记(2) 保护模式
- 《Orange’s 一个操作系统的实现》3.保护模式8-页式存储
- 《Orange’s 一个操作系统的实现》3.保护模式5----特权级概述(转)
- 一个操作系统的实现:第三章 保护模式 调试问题
- 《一个操作系统的实现》阅读笔记 之 保护模式
- 《Orange's 一个操作系统的实现》读书手记3(1)--- [ 保护模式(Protect Mode)]