215 lines
6.8 KiB
NASM
215 lines
6.8 KiB
NASM
;==============================================================================================================================
|
||
BaseOfStack equ 0x07c00 ; Boot状态下堆栈基地址
|
||
STACK_ADDR equ BaseOfStack-28 ; 堆栈栈顶
|
||
|
||
BaseOfBoot equ 1000h ; added by mingxuan 2020-9-12
|
||
OffsetOfBoot equ 7c00h ; load Boot sector to BaseOfBoot:OffsetOfBoot
|
||
OffsetOfActiPartStartSec equ 7e00h ; 活动分区的起始扇区号相对于BaseOfBoot的偏移量 ;added by mingxuan 2020-9-12
|
||
; 该变量来自分区表,保存在该内存地址,用于在os_boot和loader中查找FAT32文件
|
||
BOOT_FAT32_INFO equ 0x5A ; 位于boot中的FAT32配置信息的长度
|
||
|
||
OSLOADER_SEG equ 0x1000 ; 段地址
|
||
OSLOADER_OFF equ 0x5000 ; 段偏移
|
||
OSLOADER_ADDR equ 0x15000 ; loader地址
|
||
BUF_OFF equ 0x0000 ; 加载FAT表的临时存储
|
||
BUF_ADDR equ 0x10000 ; 加载FAT表的临时存储
|
||
|
||
DIR_PER_SECTOR equ 0x10 ; 每个扇区所容纳的目录 BYTE
|
||
|
||
; 扩展磁盘服务所使用的地址包
|
||
DAP_SECTOR equ 8 ; 起始扇区号
|
||
DAP_BUFFER_SEG equ 10 ; 缓冲区地址
|
||
DAP_BUFFER_OFF equ 12 ; 缓冲区地址
|
||
DAP_READ_SECTORS equ 14 ; 要处理的扇区数
|
||
DAP_PACKET_SIZE equ 16 ; 包的大小为24字节
|
||
CURRENT_CLUSTER equ 20 ; 当前正在处理的簇号 DWORD
|
||
FAT_START_SECTOR equ 24 ; FAT表的起始扇区号 ;added by mingxuan 2020-9-17
|
||
DATA_START_SECTOR equ 28 ; 数据区起始扇区号 ;added by mingxuan 2020-9-17
|
||
|
||
; 目录项结构
|
||
OFF_START_CLUSTER_HIGH equ 20 ; 起始簇号高位 WORD
|
||
OFF_START_CLUSTER_LOW equ 26 ; 起始簇号低位 WORD
|
||
|
||
; 相关常量
|
||
DIR_NAME_FREE equ 0x00 ; 该项是空闲的
|
||
DIR_ENTRY_SIZE equ 32 ; 每个目录项的尺寸
|
||
; 簇属性
|
||
CLUSTER_MASK equ 0FFFFFFFH ; 簇号掩码
|
||
CLUSTER_LAST equ 0FFFFFF8H ;0xFFFFFFF8-0xFFFFFFFF表示文件的最后一个簇
|
||
|
||
; added by mingxuan 2020-9-12
|
||
BPB_BytesPerSec equ (OffsetOfBoot + 0xb) ;每扇区字节数
|
||
BPB_SecPerClu equ (OffsetOfBoot + 0xd) ;每簇扇区数
|
||
BPB_RsvdSecCnt equ (OffsetOfBoot + 0xe) ;保留扇区数
|
||
BPB_NumFATs equ (OffsetOfBoot + 0x10) ;FAT表数
|
||
BPB_RootEntCnt equ (OffsetOfBoot + 0x11) ;FAT32不使用
|
||
BPB_TotSec16 equ (OffsetOfBoot + 0x13) ;扇区总数
|
||
BPB_Media equ (OffsetOfBoot + 0x15) ;介质描述符
|
||
BPB_FATSz16 equ (OffsetOfBoot + 0x16) ;每个FAT表的大小扇区数(FAT32不使用)
|
||
BPB_SecPerTrk equ (OffsetOfBoot + 0x18) ;每磁道扇区数
|
||
BPB_NumHeads equ (OffsetOfBoot + 0x1a) ;磁头数
|
||
BPB_HiddSec equ (OffsetOfBoot + 0x1c) ;分区已使用扇区数
|
||
BPB_TotSec32 equ (OffsetOfBoot + 0x20) ;文件系统大小扇区数
|
||
BPB_FATSz32 equ (OffsetOfBoot + 0x24) ;每个FAT表大小扇区数
|
||
BPB_ExtFlags equ (OffsetOfBoot + 0x28) ;标记
|
||
BPB_FSVer equ (OffsetOfBoot + 0x2a) ;版本号
|
||
BPB_RootClus equ (OffsetOfBoot + 0x2c) ;根目录簇号
|
||
BPB_FSInfo equ (OffsetOfBoot + 0x30) ;FSINFO扇区号
|
||
BS_BackBootSec equ (OffsetOfBoot + 0x32) ;备份引导扇区位置
|
||
BPB_Reserved equ (OffsetOfBoot + 0x34) ;未使用
|
||
BS_DrvNum equ (OffsetOfBoot + 0x40) ;设备号
|
||
BS_Reserved1 equ (OffsetOfBoot + 0x41) ;未使用
|
||
BS_BootSig equ (OffsetOfBoot + 0x42) ;扩展引导标志
|
||
BS_VolID equ (OffsetOfBoot + 0x43) ;卷序列号
|
||
BS_VolLab equ (OffsetOfBoot + 0x47) ;卷标
|
||
BS_FilSysType equ (OffsetOfBoot + 0x52) ;文件系统类型
|
||
;==============================================================================================================================
|
||
org (07c00h + BOOT_FAT32_INFO) ;FAT322规范规定第90~512个字节(共423个字节)是引导程序
|
||
;modified by mingxuan 2020-9-16
|
||
START:
|
||
cld
|
||
mov ax, cs
|
||
mov ds, ax
|
||
mov ss, ax
|
||
mov ax, OSLOADER_SEG
|
||
mov es, ax ;deleted by mingxuan 2020-9-13
|
||
|
||
mov bp, BaseOfStack
|
||
mov sp, STACK_ADDR
|
||
|
||
movzx eax, word [BPB_RsvdSecCnt]
|
||
mov [bp - FAT_START_SECTOR], eax
|
||
|
||
; 计算数据区起始扇区号 ; added by mingxuan 2020-9-17
|
||
movzx cx, byte [BPB_NumFATs]
|
||
_CALC_DATA_START:
|
||
add eax, [BPB_FATSz32]
|
||
loop _CALC_DATA_START
|
||
|
||
mov [bp - DATA_START_SECTOR], eax
|
||
|
||
mov word [bp - DAP_PACKET_SIZE], 10h
|
||
mov word [bp - DAP_BUFFER_SEG], OSLOADER_SEG
|
||
|
||
jmp _SEARCH_LOADER
|
||
|
||
LoaderName db "LOADER BIN" ; 第二阶段启动程序 FDOSLDR.BIN
|
||
ReadSector:
|
||
pusha
|
||
|
||
mov ah, 42h ;ah是功能号,扩展读对应0x42
|
||
lea si, [bp - DAP_PACKET_SIZE] ;使用扩展int13时DAP结构体首地址传给si
|
||
mov dl, [BS_DrvNum] ;modified by mingxuan 2020-9-17
|
||
int 13h
|
||
jc $
|
||
|
||
popa
|
||
ret
|
||
|
||
InlineReadDataSector:
|
||
sub eax, 2
|
||
movzx edx, byte [BPB_SecPerClu]
|
||
mul edx
|
||
add eax, [bp - DATA_START_SECTOR]
|
||
mov [bp - DAP_SECTOR], eax
|
||
|
||
movzx edx, byte [BPB_SecPerClu]
|
||
mov [bp - DAP_READ_SECTORS], dx
|
||
|
||
mov [bp - DAP_BUFFER_OFF], bx
|
||
call ReadSector
|
||
ret
|
||
|
||
; 根据簇号计算扇区号
|
||
; Comments, added by mingxuan 2020-9-10
|
||
;====================================================================
|
||
; 检查是否还有下一个簇(读取FAT表的相关信息)
|
||
; N = 数据簇号
|
||
; FAT_BYTES(在FAT表中的偏移) = N*4 (FAT32)
|
||
; FAT_SECTOR = FAT_BYTES / BPB_BytesPerSec
|
||
; FAT_OFFSET = FAT_BYTES % BPB_BytesPerSec
|
||
;====================================================================
|
||
NextCluster: ;added by yangxiaofeng 2021-12-1
|
||
pushad
|
||
|
||
mov eax, [bp - CURRENT_CLUSTER]
|
||
mov ebx, 4
|
||
mul ebx
|
||
movzx ebx, word [BPB_BytesPerSec]
|
||
div ebx
|
||
add eax, [bp - FAT_START_SECTOR]
|
||
mov [bp - DAP_SECTOR], eax
|
||
|
||
mov word [bp - DAP_READ_SECTORS], 1
|
||
|
||
mov word [bp - DAP_BUFFER_OFF], BUF_OFF
|
||
|
||
call ReadSector
|
||
mov bx, dx
|
||
mov eax, [es:bx + BUF_OFF]
|
||
mov [bp - DATA_START_SECTOR - 6], eax
|
||
|
||
popad
|
||
ret
|
||
|
||
_SEARCH_LOADER:
|
||
mov eax, [BPB_RootClus]
|
||
|
||
_NEXT_ROOT_CLUSTER: ;这个时候eax拿着的是当前的簇号
|
||
mov [bp - CURRENT_CLUSTER], eax
|
||
mov bx, BUF_OFF
|
||
|
||
call InlineReadDataSector
|
||
|
||
mov di, BUF_OFF
|
||
; 这里dl拿着的是BPB_SecPerClu
|
||
_NEXT_ROOT_SECTOR:
|
||
mov bl, DIR_PER_SECTOR
|
||
|
||
_NEXT_ROOT_ENTRY:
|
||
mov si, LoaderName
|
||
mov cx, 11
|
||
repe cmpsb
|
||
and di, DIR_ENTRY_SIZE
|
||
jcxz _FOUND_LOADER
|
||
add di, DIR_ENTRY_SIZE
|
||
|
||
dec bl
|
||
jnz _NEXT_ROOT_ENTRY
|
||
|
||
dec dl
|
||
jz _CHECK_NEXT_ROOT_CLUSTER
|
||
|
||
jmp _NEXT_ROOT_SECTOR
|
||
|
||
_CHECK_NEXT_ROOT_CLUSTER: ; 检查是否还有下一个簇
|
||
call NextCluster ;added by yangxiaofeng 2021-12-1
|
||
cmp eax, CLUSTER_LAST ;CX >= 0FFFFFF8H,则意味着没有更多的簇了
|
||
jb _NEXT_ROOT_CLUSTER
|
||
jmp $
|
||
|
||
_FOUND_LOADER:
|
||
movzx eax, word [es:di + OFF_START_CLUSTER_HIGH]; 起始簇号高32位
|
||
shl eax, 16
|
||
mov ax, [es:di + OFF_START_CLUSTER_LOW] ; 起始簇号低32位
|
||
mov bx, OSLOADER_OFF
|
||
;这个时候eax拿着的是当前的簇号,ebx存放加载的地址
|
||
_LOAD_LOADER:
|
||
mov dword [bp - CURRENT_CLUSTER], eax
|
||
|
||
call InlineReadDataSector
|
||
|
||
movzx eax, byte [BPB_SecPerClu]
|
||
mov cx, [BPB_BytesPerSec]
|
||
mul cx
|
||
add ebx, eax
|
||
|
||
call NextCluster
|
||
cmp eax, CLUSTER_LAST ;CX >= 0FFFFFF8H,则意味着没有更多的簇了
|
||
jb _LOAD_LOADER
|
||
|
||
_RUN_LOADER:
|
||
jmp OSLOADER_SEG : OSLOADER_OFF
|
||
|
||
times 510 - BOOT_FAT32_INFO - ($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
|
||
dw 0xaa55 ; 结束标志 |