syslinux引导扇区不支持ntfs_操作系统学习 让启动镜像支持Fat12文件格式

4fc94fd95b911a88e020180b5c0c9faa.png

一、Fat12 文件格式

1. 格式简要说明

  • Fat12是DOS支持的软盘格式。
  • FAT全称是文件分配表(File Allocation Table),用来记录存放文件名、起始扇区等文件信息。
  • 除了文件分配表,还有目录表(File Directory Table)。
  • 软盘有两个磁头,每个磁头80个柱面(磁道),每个柱面有18个扇区,每个扇区512个字节空间

软盘结构:

500d54fe4c3ff469c877a83298c2895b.png

2. 引导扇区

简写格式

  • 面:C
  • 磁道:H
  • 扇区:S(每道18个扇区)

C0-H0-S1用来存放引导区,如果最后两个字节是0x55,0xaa(DW 0xAA55),BIOS就把这512字节读出来执行。

3. FAT

  • C0-H0-S2~C0-H0-S10(9个扇区) 存放 FAT表
  • C0-H0-S11~C1-H0-S1(9个扇区) 存放备用FAT表
  • C1-H0-S2~ C1-H0-S15(14个扇区)用于存放FDT(根目录)

4. FAT结构

  • FAT12的每个文件分配表项占12bit, 每个表项代表一个扇区。
  • 磁盘里所有扇区被线性索引(LBA)
  • FAT12每个表项的值指出文件存放的下一个扇区号
cae9209f5ed403f0e33dfcb0595abf01.png
8a6c1d5d8e2ace85b9e9e695a3906ed0.png

5. 根目录

  • 根目录紧跟着FAT表,从19分区开始。
  • 根目录由若干个目录条目组成,最多有BPB_RootEntCnt个。
  • 根目录中每个条目占32字节:

名称开始字节长度内容DIR_Name00xB文件名8字节,扩展名3字节DIR_Attr0xB1文件属性保留位0xC10保留DIR_WrtTime0x162最后一次写入的时间DIR_WrtDate0x182最后一次写入的日期DIR_FstClus0x1A2此文件在数据区和FAT表中的开始簇号DIR_FileSize0x1C4文件大小

6. 数据区

二、Fat12格式的引导区代码:

;%define _BOOT_DEBUG_   ; 做Boot Sector时把这行注释掉        ; 启用这行就用nasm Boot.asm -o Boot.com生成.com文件用于调试%ifdef _BOOT_DEBUG_   org  0100h%else   org 07c00h%endifCYLS EQU 10; 把软盘按Fat12格式填充   JMP init                ; 跳转指令   DB      0x90            ; 空 DB,DD用来写单字节   DB      "NotOneOS"      ; 厂商名,8字节,DB用来写双字节   DW      512             ; 每个扇区大小512字节,DW用来写4字节   DB      1               ; 每个簇的扇区数   DW      1               ; Boot占的扇区   DB      2               ; 有2个FAT表   DW      224             ; 根目录大小224   DW      2880            ; 磁盘扇区总数 2880   DB      0xf0            ; 介质描述符,磁盘种类必须为0xf0   DW      9               ; 每个FAT扇区数   DW      18              ; 每个磁道18个扇区   DW      2               ; 2个磁头   DD      0               ; 隐藏扇区数   DD      2880            ; 同上,磁盘大小   DB      0, 0, 0x29      ; 0x29 扩展引用标记   DD      0xffffffff      ; 无意义,固定这么写   DB      "NotOneOS   "   ; 磁盘名(卷标),11字节   DB      "FAT12   "      ; 磁盘格式名,8字节   RESB    18              ; 空18个字节,填充0x00init:   MOV AX,0   MOV SS,AX   MOV SP,0x7c00        ; 堆栈空间,从0x7c00向前   MOV DS,AX   MOV AX,0x0820        ; 把磁盘数据加载到内存0x0820处。 0x8000~0x81ff的512字节给启动区用的,所以从0x0820开始   MOV ES,AX            ; 初始化磁盘接口   MOV CH,0             ; 柱面 0   MOV DH,0             ; 磁头 0   MOV CL,2             ; 扇区 2readloop:   MOV SI,0             ; 记录失败次数retry:   MOV    AH,0x02       ; 0x02 读磁盘   MOV    AL,1          ; 读1个扇区   MOV    BX,0   MOV    DL,0x00       ; A驱动器   INT    0x13          ; BIOS 读磁盘功能   JNC    next          ; 成功跳转   ADD    SI,1          ; 失败加一次   CMP    SI,5          ; 到5次就跳到error   JAE    error   MOV    AH,0x00       ; 复位磁盘功能   MOV    DL,0x00   INT    0x13          ; 重置磁盘驱动器   JMP    retry         ; 重试   next:    MOV     AX,ES       ; 内存地址向后移动0x0020    ADD     AX,0x0020       MOV     ES,AX       ; 通过AX给ES加0x0020    ADD     CL,1        ; 扇区+1    CMP     CL,18       ; 有没有到18个扇区    JBE     readloop    ; CL<=18,就跳到 readloop        MOV     CL,1    ADD     DH,1    CMP     DH,2    JB     readloop    ; 如果 DH < 2 ,则跳到readloop        MOV     DH,0    ADD     CH,1    CMP     CH,CYLS    JB     readloop    ; 如果CH

三、 文件读写

使用BIOS中断 int 13h,参数:

9f78b8fec51e3eb8c0e62c66fb7adf4f.png

知道扇区号的时候,要计算int 13h的参数:

设扇区号/每磁道扇区数(18) = 商 Q,余数R ,则:

  • 柱面号= Q >> 1 (相当于 Q/2 无余数)
  • 磁头号=Q & 1
  • 起始扇区号=R+1

四、读磁盘镜像并写入文件,查看文件格式

下面使用VirtualBox读入磁盘镜像,并写入一个文件。(新建虚拟机并加虚拟磁盘的方法前面章节有提到。)

201b1ba9c878118b6da07ef64f7803b0.png


使用VsCode打开磁盘镜像,可以看到存储区域已经有了变化:

e820bef4664f2c06cebfd05f584c1c6f.png

这里使用的是笨方法保存文件,也可以使用edimg.exe程序来做。

  • 文件名保存到 0x002600处
  • 文件的内容存在 0x40200处

后面章节来看如何让程序加载NotOneOS.sys里的代码。

本章代码与编译运行方法已放到gitee:
gitee.com/xundh/learn-os

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值