30天自制操作系统——第00天 制作启动镜像


对应书01~27页

很早之前就想照着《30天自制操作系统》这本书把代码实现,但是当时汇编部分没怎么看懂。现在终于能看懂一些了,于是准备重新看这本书。这本书好在大多数代码都是用C语言写的,可读性比较强,光盘里附带的资料也比较齐全,惟一的不足是代码的注释没有翻译成中文,那就让我对着书把中文注释打上去吧,也能看一遍作者写了什么。

​ 第0天的内容有些完全是激发读者的好奇心,但是容易把小白弄得云里雾里。

  • helloos0:

    helloos0直接用二进制编辑器写了一个img镜像文件,虽然镜像文件都是二进制文件没错,但是没有人会用二进制编辑器直接写,而是将想要的内容交给某个能产生镜像文件的软件,交给软件执行这个枯燥的步骤,因此本人觉得helloos0只需看看即可。

  • helloos1

    helloos1把helloos0内容改用汇编语言写了一遍,可惜都是DB、DW等写入命令,我们暂且知道这是往内存里写东西了,但是具体写啥还是要下回分晓。

    注:

    DB指令是向内存写入一个字节(8位)数据;

    DW指令是向内存写入一个字(双字节,也就是16位)数据;

    具体写什么数据,由指令后面跟的数字决定。

  • helloos2
    从这个版本开始我们可以稍稍读懂作者在这个img文件内写了些什么,其中";"后面的内容是注释,编译器在编译成机器码时自动略去这部分内容。
    pigz.nas 代码如下:

	; pigz
	; TAB=4
	
	; 以下为标准FAT12格式软盘专用代码
	
	DB		0xeb, 0x4e, 0x90
	DB		"HELLOIPL"		; 启动区的名字可以是任意字符串(8字节)
	DW		512			; 定义每个扇区的大小(必须为512字节)
	DB		1			; 定义簇的大小(必须为1个扇区)
	DW		1			; FAT的起始位置(一般从第一个扇区开始)
	DB		2			; FAT的个数
	DW		224			; 根目录的大小(一般设成224项)
	DW		2880			; 该磁盘的大小(必须是2880扇区)
	DB		0xf0			; 磁盘的种类(必须是0xf0)
	DW		9			; FAT的长度(必须是9扇区)
	DW		18			; 1个磁道有几个扇区(必须是18)
	DW		2			; 磁头数(必须是2)
	DD		0			; 不使用分区(因此是0)
	DD		2880			; 重写一次磁盘大小
	DB		0,0,0x29		; 意义不明,固定
	DD		0xffffffff		; (可能是)卷标号码
	DB		"HELLO-OS   "	; 磁盘的名称(11字节)
	DB		"FAT12   "		; 磁盘格式名称(8字节)
	RESB	        18			; 先空出18字节
	
	; 程序主体
	
	DB		0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
	DB		0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
	DB		0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
	DB		0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
	DB		0xee, 0xf4, 0xeb, 0xfd
	
	; 信息显示部分
	
	DB		0x0a, 0x0a		; 换行2次
	DB		"hello, world"
	DB		0x0a			; 换行
	DB		0
	
	RESB	        0x1fe-$			; 填写0x00,直到0x01fe
	
	DB		0x55, 0xaa
	
	; 以下是启动区以外部分的输出
	
	DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
	RESB	        4600
	DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
 	RESB	        1469432

在具体分析这段代码之前,我们先了解一些FAT12文件系统的知识。这里节选了FAT12文件系统这篇博客的重要部分,有兴趣可以全文阅读。

FAT12介绍

FAT12是DOS时代就开始使用的文件系统(File System),直到现在仍然在软盘上使用,FAT12软盘的被格式化后为:有两个磁头,每个磁头80个柱面(磁道),每个柱面有18个扇区,每个扇区512个字节空间。所以标准软盘的总空间为:

2 * 80 *18 * 512=1474560B=1440K=1.44M

引导扇区

操作系统之所以认识FAT12格式的磁盘,其秘密就在于逻辑0扇区这512B上。如果这512字节的最后两个字节的内容分别是55和AA(0xAA55低字节在前,高字节在后)的话,BIOS在启动时会将这个扇区读取到0x7C00H~0x7DFFH处,然后跳转到0:7C00h处继续执行指令,操作系统即用此来达到引导系统的目的,而这个磁盘就称为引导磁盘。

操作系统标识FAT12文件系统是因为在逻辑0扇区(即引导扇区)处还存储着一个特定的数据结构,此结构有固定的格式,在操作系统将此磁盘格式化时自动生成,具体数据结构如下表所示:

名称 开始字节 长度 内容 参考值 在代码中行号
BS_jmpBOOT 0 3 一个短跳转指令 jmp short LABEL_STARTnop 6
BS_OEMName 3 8 厂商名 'ZGH' 7
BPB_BytesPerSec 11 2 每扇区字节数(Bytes/Sector) 0x200 8
BPB_SecPerClus 13 1 每簇扇区数(Sector/Cluster) 0x1 9
BPB_ResvdSecCnt 14 2 Boot记录占用多少扇区 0x1 10
BPB_NumFATs 16 1 共有多少FAT表 0x2 11
BPB_RootEntCnt 17 2 根目录区文件最大数 0xE0 12
BPB_TotSec16 19 2 扇区总数 0xB40 13
BPB_Media 21 1 介质描述符 0xF0 14
BPB_FATSz16 22 2 每个FAT表所占扇区数 0x9 15
BPB_SecPerTrk 24 2 每磁道扇区数(Sector/track) 0x12 16
BPB_NumHeads 26 2 磁头数(面数) 0x2 17
BPB_HiddSec 28 4 隐藏扇区数 0 18
BPB_TotSec32 32 4 如果BPB_TotSec16=0,则由这里给出扇区数 0 19
BS_DrvNum 36 1 INT 13H的驱动器号 0 20
BS_Reserved1 37 1 保留,未使用 0 20
BS_BootSig 38 1 扩展引导标记(29h) 0x29 20
BS_VolID 39 4 卷序列号 0 21
BS_VolLab 43 11 卷标 'ZGH' 22
BS_FileSysType 54 8 文件系统类型 'FAT12' 23
引导代码及其他内容 62 448 引导代码及其他数据 引导代码(剩余空间用0填充) 24~42
结束标志0xAA55 510 2 第510字节为0x55,第511字节为0xAA 0xAA55 43

从6~43行内容都是FAT12文件格式的规定的,值得注意的是,当我们使用了软盘启动系统时,首先会把软盘中第一个扇区(512字节)加载到内存,判断从第510字节开始是否为0xAA55,若是则说明这是一张启动盘,BIOS会开始从0x7C00H进行引导。

问题清单1:改注释的时候出现的一些问题

  • notepad++如果出现了中文乱码怎么办?

    菜单栏-->编码-->使用UTF-8编码

    如果切换不了编码就Ctrl+A全选并剪切后切换,切换成功后再粘贴回去。

  • 字体有促又粗有粗有细怎么办?

    设置-->语言格式设置

    字体选择Consolas,并勾选使用全局字体,然后保存并关闭


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM