<自己动手写操作系统>2011031801

来源:<使用开源软件-自己动手写操作系统> 杨文博

在Blog<自己动手写操作系统>2011031601中把编译好的bin写出到虚拟软驱中,在启动虚拟机以软驱启动,能出现:hello ,OS world!

重新启动另一虚拟器(已装Xp),以虚拟机默认启动进入到Xp,双击软驱,会出现磁盘需要格式化的问句

这里要涉及到一个概念:文件系统
FAT12文件系统
FAT(File Allocation Table)文件系统规格在20世纪70年代末和80年代初形成,是微软的MS-DOS操作系统使用的文件系统格式,主要有:FAT12,FAT16,FAT32

FAT文件系统的主要信息,都被提供在前几个扇区内,其中第0号扇区尤其重要。这个扇区隐藏了一个叫做BPB(BIOS Parameter Block)的数据结构,一旦我们把这个数据结构谢对了,格式化过程基本完成了。

引导扇区是软盘的第0个扇区,在这个扇区中有一个很重要的数据结构叫BPB(BIOS Parameter Block),下面是引导扇区格式,其中BPB_开头的属于BPB,以BS_开头的只是BOOT Sector的一部分,不属于BPB。

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

整理一份完整的代码:
    org    07c00h            ; 告诉编译器程序加载到7c00处
    jmp SHORT Main
    nop
BS_OEMName:db "HHHHHHHH"
BPB_BytePerSec:dw 512
BPB_SecPerCluster:db 1
BPB_ResvdSecCnt:dw 1
BPB_NumFATs:db 2
BPB_RootEntCnt:dw 224
BPB_TotSec16:dw 2880
BPB_Media:db 0xf0
BPB_FATSz16:dw 9
BPB_SecPerTrk:dw 18
BPB_NumHeads:dw 2
BPB_HiddSec:dd 0
BPB_TotSec32:dd 0
BS_DrvNum:db 0
BS_Reserved1:db 0
BS_BootSig:db 29h
BS_VolID:dd 0
BS_VolLab:db "Solrex 0.01"
BS_FileSysType:db "FAT12   "

Main:
    mov    ax, cs
    mov    ds, ax
    mov    es, ax
    call    DispStr            ; 调用显示字符串例程
    jmp    $            ; 无限循环
DispStr:
    mov    ax, BootMessage
    mov    bp, ax            ; ES:BP = 串地址
    mov    cx, 16            ; CX = 串长度
    mov    ax, 01301h        ; AH = 13,  AL = 01h
    mov    bx, 000ch        ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
    mov    dl, 0
    int    10h            ; 10h 号中断
    ret
BootMessage:        db    "Hello, OS world!"
times     510-($-$$)    db    0    ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw     0xaa55                ; 结束标志

PS:特别注意第二句,应该是jmp SHORT Main,而不是jmp Main.如果按此书中所写jmp Main,最后编译出来是4个字节,比预计要多1个字节,原因在于反编译bin那句话成了jmp word 0x????

原文地址:https://www.cnblogs.com/GoGoagg/p/1988036.html