比划着书,反汇编着NTLDR,大概写一个MBR出来了,但貌似进入了死循环???
我把编译出来的文件写入磁盘MBR中,重启,没反应,各种调试输出没错
很大可能是:MBR读取了MBR再次加载到0x7C00转移控制权?
我明明读取的是分区表的PBR呀?贴代码吧。
bios.inc
- include 'macro/struct.inc'
- ;BIOS服务中断定义
-
- ;从下一设备启动
- BIOS_BOOT_FROM_NEXT_DEVICE = 0x18
-
- ;直接磁盘服务,功能号=AH,下面列出
- BIOS_DIRECT_DISK_SERVICE = 0x13
- ;复位驱动器
- BIOS_DDS_RESET_DEVICE = 0x00
- ;读取驱动器参数
- ;成功返回值:DH=磁头,DL=驱动器数,CL低6位=扇区
- BIOS_DDS_READ_DEVICE_PARAMETER = 0x08
- ;读扇区
- ;参数:AL=扇区数,CH=柱面,CL=扇区,DH=磁头
- ;DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
- ;ES:BX=缓冲区的地址
- BIOS_DDS_READ_SECTOR = 0x02
- ;检测扩展DDS是否存在
- ;参数:DL=驱动器,0x80=第一块硬盘,0x81=第二块硬盘......
- BIOS_DDS_CHECK_EXTENSION = 0x41
- ;扩展直接硬盘读写数据包结构
- struct STRUCT_DDS_EXTENSION_PACK
- ;大小必须=0x10
- Size db ?
- ;保留
- Resvered1 db ?
- ;数据块数量
- BlockCount dw ?
- ;缓冲区段偏移
- BufferOffset dw ?
- ;缓冲区段值
- BufferSegment dw ?
- ;要读的数据,扇区(低6位)和柱面(高10位)
- SC_L dw ?
- SC_H dw ?
- ;未知=0
- Unknown1 dd ?
- ends
- BIOS_DDS_EXTENSION_READ = 0x42
- BIOS_DDS_EXTENSION_WRITE = 0x43
fs.inc
- include 'macro/struct.inc'
- ;文件系统定义
-
- FSID_FAT12 = 0x01
- FSID_FAT16 = 0x04
- FSID_FAT16_2 = 0x06
- FSID_FAT16_3 = 0x0E
- FSID_FAT32 = 0x0B
- FSID_FAT32_2 = 0x0C
- FSID_NTFS = 0x07
- FSID_HPFS = FSID_NTFS
- FSID_EXTENDED = 0x05
-
- FS_ACTIVE = 0x80
-
- ;分区表结构=16字节
- struct STRUCT_PARTITION_TABLE
- ;分区状态,0=未激活,0x80=激活
- State db ?
- ;起始磁头号
- BeginHead db ?
- ;起始扇区(低6位)和柱面号(高10位)
- BeginSC dw ?
- ;分区类型
- FSID db ?
- ;结束磁头号
- EndHead db ?
- ;结束扇区和柱面号,同BeginHead
- EndSC dw ?
- ;相对扇区地址,低16+高16=32位
- InfoAreaSectors_L dw ?
- InfoAreaSectors_H dw ?
- ;总扇区数
- Sectors dd ?
- ends
-
- FLAG_BOOT_RECORD = 0xAA55
-
- ;主引导记录,512字节
- struct STRUCT_MASTER_BOOT_RECORD
- Codes rb 446
- Partition1 STRUCT_PARTITION_TABLE
- Partition2 STRUCT_PARTITION_TABLE
- Partition3 STRUCT_PARTITION_TABLE
- Partition4 STRUCT_PARTITION_TABLE
- ;结束标志=0x55AA
- Flag dw ?
- ends
-
- ;FAT磁盘参数表,25字节,FAT12和FAT16应该是一样的
- struct STRUCT_BIOS_PARAMETER_BLOCK_FAT
- ;每扇区字节数
- BytsPerSec dw ?
- ;每簇扇区数
- SecPerClus db ?
- ;Boot记录占用多少扇区
- RsvdSecCnt dw ?
- ;共有多少FAT表
- NumFATs db ?
- ;根目录文件数最大值
- RootEntCnt dw ?
- ;扇区总数
- TotSec16 dw ?
- ;介质描述符
- Media db ?
- ;每FAT扇区数
- FATSz16 dw ?
- ;每磁道扇区数
- SecPerTrk dw ?
- ;磁头数(面数)
- NumHeads dw ?
- ;隐藏扇区数
- HiddSec dd ?
- ;如果TotSec16=0则由这个记录扇区数
- TotSec32 dd ?
- ends
-
- ;分区引导记录=512字节
- struct STRUCT_PARTITION_BOOT_RECORD
- ;短跳转代码
- CodeJmp rb 3
- ;厂商名(字符串)
- OEMName rb 8
- ;BIOS_PARAMETER_BLOCK
- BPB STRUCT_BIOS_PARAMETER_BLOCK_FAT
- ;中断13的驱动器号
- DrvNum db ?
- ;磁头号(书上说这一字节是保留的)
- Head db ?
- ;扩展引导标记=0x29
- BootSig db ?
- ;卷序列号
- VolID dd ?
- ;卷标(字符串)
- VolLab rb 11
- ;文件系统类型(字符串)
- FileSysType rb 8
- ;代码,数据等
- Others rb 448
- ;标志=0x55AA
- Flag dw ?
- ends
-
- ;根目录结构,32字节
- struct STRUCT_ROOT_DIRECTORY_FAT
- ;文件名8字节,扩展名3字节
- Name rb 11
- ;文件属性
- Attr db ?
- ;保留
- Reserved1 rb 10
- ;最后写入时间
- WrtTime dw ?
- ;最后写入日期
- WrtDate dw ?
- ;开始簇号
- FstClus dw ?
- ;文件大小
- FileSize dd ?
- ends
mbr.asm
- include 'bios.inc'
- include 'fs.inc'
- MASTER_BOOT_RECORD_BASE = 0x7C00
- MASTER_BOOT_RECORD_NEW_BASE = 0x0600
-
- use16
- ORG MASTER_BOOT_RECORD_BASE
- Main:;入口,初始化,移动代码,转移控制权
- ;初始化段寄存器
- xor ax, ax
- mov ss, ax
- mov es, ax
- mov ds, ax
- ;初始化堆栈
- mov sp, MASTER_BOOT_RECORD_BASE
- ;移动代码,转移控制权
- mov si, MbrEntry
- mov di, (MASTER_BOOT_RECORD_NEW_BASE + MbrEntry - $$)
- push ax
- push di
- mov cx, (MbrEnd - MbrEntry)
- rep movsb
- retf;ax:di
- ;Main结束
-
- MbrEntry:
- mov bp, (MASTER_BOOT_RECORD_NEW_BASE + par1 - $$)
- mov cx, 4
- .Loop_FindActivePartition:
- cmp [bp + STRUCT_PARTITION_TABLE.State], 0
- jl .ToLoadPbr
- jne .InvalidMbr
- add bp, sizeof.STRUCT_PARTITION_TABLE
- loop .Loop_FindActivePartition
- ;从下一设备启动
- int BIOS_BOOT_FROM_NEXT_DEVICE
- .InvalidMbr:
- mov bp, (MASTER_BOOT_RECORD_NEW_BASE + szMbrError - $$)
- mov cx, 31
- call DisplayMessage
- jmp $
- .ToLoadPbr:;bp=分区表地址
- call LoadPbr
- jb .LoadPbrFail
- cmp word [flag], FLAG_BOOT_RECORD
- jne .PbrError
- push ax;ax=0
- push MASTER_BOOT_RECORD_BASE
- retf;转移控制权到PBR
- .LoadPbrFail:
- mov bp, (MASTER_BOOT_RECORD_NEW_BASE + szLoadPbrFail - $$)
- mov cx, 33
- call DisplayMessage
- jmp $
- .PbrError:
- mov bp, (MASTER_BOOT_RECORD_NEW_BASE + szPbrError - $$)
- mov cx, 30
- call DisplayMessage
- jmp $
- ;MbrEntry结束
-
- LoadPbr:;bp=分区表地址
- mov di, 5;尝试5次ReadPBR
- mov dl, [bp + STRUCT_PARTITION_TABLE.State]
- mov ah, BIOS_DDS_READ_DEVICE_PARAMETER
- int BIOS_DIRECT_DISK_SERVICE
- jb .ReadPBR;失败,尝试直接读取PBR
- mov al, cl;AX=0
- and al, 00111111B;取低6位
- cbw;把AL的符号扩展到AH
- mov bl, dh;磁头数
- mov bh, ah;AH=0
- inc bx;得出总磁头数
- mul bx;扇区*磁头=ax*bx,结果=dx:ax
- mov dx, cx
- xchg dh, dl
- shr dh, 6;取高2位
- inc dx
- ;总的扇区数*总的磁头数*总的柱面数=磁盘容量
- mul dx
- cmp [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_H], dx
- ja .ReadPBREx;无符号比较,大于则跳
- jb .ReadPBR;无符号比较,小于则跳
- cmp [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_L], ax
- jnb .ReadPBREx;无符号比较,大于等于则跳
- .ReadPBR:
- mov ah, BIOS_DDS_READ_SECTOR
- mov al, 1
- mov bx, MASTER_BOOT_RECORD_BASE
- mov cx, [bp + STRUCT_PARTITION_TABLE.BeginSC]
- xor dx, dx
- mov dl, [bp + STRUCT_PARTITION_TABLE.State];dx=FS_ACTIVE=0x80=代表硬盘
- int BIOS_DIRECT_DISK_SERVICE
- jnb .Ret;成功
- dec di
- je .Ret;尝试了5次,直接返回
- ;复位驱动器,继续尝试
- xor ah, ah
- mov dl, [bp + STRUCT_PARTITION_TABLE.State]
- int BIOS_DIRECT_DISK_SERVICE
- jmp .ReadPBR
- .ReadPBREx:
- mov dl, [bp + STRUCT_PARTITION_TABLE.State]
- pusha
- mov bx, 0x55AA;为什么倒过来了?
- mov ah, BIOS_DDS_CHECK_EXTENSION
- int BIOS_DIRECT_DISK_SERVICE
- jb .Failure;不支持
- ;继续检查
- cmp bx, FLAG_BOOT_RECORD
- jne .Failure
- test cl, 1;其他资料没有这个,什么意思?
- je .Failure
- popa
- .Loop_ReadPBREx:
- pusha
- ;使用扩展直接磁盘服务读取
- ;填充数据包.由于转移了代码,所以要修正数据包地址
- mov si, MASTER_BOOT_RECORD_NEW_BASE + Pack_Extend - MASTER_BOOT_RECORD_BASE
- mov [si + STRUCT_DDS_EXTENSION_PACK.BufferOffset], MASTER_BOOT_RECORD_BASE
- mov [si + STRUCT_DDS_EXTENSION_PACK.BufferSegment], 0
- push ax
- mov ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_L]
- mov [si + STRUCT_DDS_EXTENSION_PACK.SC_L], ax
- mov ax, [bp + STRUCT_PARTITION_TABLE.InfoAreaSectors_H]
- mov [si + STRUCT_DDS_EXTENSION_PACK.SC_H], ax
- pop ax
- mov ah, BIOS_DDS_EXTENSION_READ
- int BIOS_DIRECT_DISK_SERVICE
- popa
- dec di
- je .Ret;尝试了5次,直接返回
- ;复位,继续尝试
- xor ah, ah
- mov dl, [bp + STRUCT_PARTITION_TABLE.State]
- int BIOS_DIRECT_DISK_SERVICE
- jmp .Loop_ReadPBREx
- .Failure:
- popa
- stc;设置CF=1
- .Ret:
- retn
- ;LoadPBR结束
-
- DisplayMessage:
- mov ax, 0x1301
- mov bx, 0xC
- xor dl, dl
- int 0x10
- ret
- ;DisplayMessage结束
-
- szMbrError db "Invalid Master Partition Table."
- szLoadPbrFail db "Can't Load Partition Boot Record."
- szPbrError db "Invalid Partition Boot Record."
-
- Pack_Extend STRUCT_DDS_EXTENSION_PACK 0x10, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0
- CodeEnd:;代码结束,四个分区表结构+结束标志
- times sizeof.STRUCT_MASTER_BOOT_RECORD.Codes - ($-$$) db 0
- par1 STRUCT_PARTITION_TABLE 0x80, 0x01, 0x0001, 0x07, 0xFE, 0xBFBF, 0x003F, 0, 0x00AC9281
- par2 STRUCT_PARTITION_TABLE
- par3 STRUCT_PARTITION_TABLE
- par4 STRUCT_PARTITION_TABLE
- flag dw FLAG_BOOT_RECORD
- MbrEnd:
希望有人能帮我解决一下,谢谢。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。