基于FAT32文件系统的引导扇区
前言
在之前看《一个64位操作系统的设计与实现》时,书籍引导扇区的文件系统是FAT12,即使在高级部分(使用物理机启动而不是虚拟机启动)也是使用小型U盘(好像是没超过16MB大小),而现在买不到这么小的U盘,最后我在某宝买了一个30MB大小的,但仍然无法正常编写引导扇区(我记得当时U盘太大会导致无法将U盘格式化为FAT12),对于如何编写基于FAT32文件系统的引导扇区在网上搜寻一圈未发现比较完整细致的讲解和代码(详细看boot.asm,本篇不贴代码),所以本篇Blog自己实现了一段可以运行的引导扇区(U盘方式启动)。
注意:本篇不是一篇教学型Blog,需要一定基础!
准备环境
- VMware
- DiskGenius
- Windows平台+Vscode
参考链接
正文
零、关于FAT12与FAT32的一点补充
在首次从FAT12更新到FAT32时,面临两个问题:
- 当rootEntCnt(根目录可容纳的目录项数)在FAT32文件系统为0时,如何判断根目录下文件的数量?或者说什么时候停止搜寻loader/kernel程序?
- 获取表项的算法有变化;(更新:加上挂载时出现的表项异常)
一、使用DiskGenius
准备好一个空U盘,使用DiskGenius将其格式化为FAT32文件系统,簇大小设置为512字节,如下:
然后使用DiskGenius查看一些相关信息并记录,关于FAT32文件系统结构使用其他Blog参考即可(在上面的参考链接中)。
这个界面主要是查看FAT1扇区号、根目录扇区号等等:
这个界面主要是查看文件系统结构数据:
二、从扇区数据从提取信息
在扇区编辑的图中,可以看到关于FAT32文件系统结构的数据,将之提取出,有(详细见boot.asm文件):
其中,oemName、bootSig,volumeID、volumeName、fileSysType是自己定的;
(注意!! 这里的命名有点不那么规范,应当有前缀BS_/BPB_,自己写随意点)
三、Boot程序的自述
当上电自检后,BIOS会将引导扇区(第一个扇区若是以55AA结尾)加载到内存0X7C00处并且执行,boot程序主要是查询是否存在loader.bin程序,若存在则将loader程序加载到内存位置1MB处,在当中涉及FAT32文件系统的组织,查询根目录,在根目录处查找loader程序的簇号,并根据FAT表和loader程序的簇号将loader程序的实体加载到内存中。
四、编写
我是在Windows平台下使用Vscode编写,在Ubuntu下使用nasm指令转为bin文件,然后烧写至U盘中;通过VMware虚拟机(添加U盘启动)运行,运行截图如下,‘C’字符是在loader程序输出:
为什么要跨平台?使用VMware虚拟机调试系统很麻烦,后面考虑使用bximage+bochs调试;
使用bochs
原本打算使用bximage生成一个硬盘镜像,但无奈发现存在一些问题(包括挂载、镜像结构),使之不能运行;解决办法是使用winHex将U盘(尽量选个小一点的U盘,我7.6G用了4个多小时)转成img格式(先保证此img可以在VMware运行,然后再转换),然后在bochs配置文件中更改镜像位置,运行即可。
后记
鉴于代码与注解比较多(350行,大部分是注解),所以将代码文件上传到CSDN,下载即可;免积分!!
文件地址
写引导扇区并不难,主要是理解FAT32文件系统结构,然后编写一些逻辑就好了,所以在这里并不多讲,主要是代码!
更新
原有的boot程序在获取表项时出现点问题;当使用Ubuntu将文件拷贝到挂载点时,竟然不是覆盖!!! 每挂载一次,文件在FAT表项中的位置会往后移动一次(偏移量是所有文件大小所占FAT表项数)。那么此时就出现了一个问题,在原有文件中,只需要读取FAT表第一个扇区就好了,但随着表项的往后移动,就要计算出