您的位置:首页 > 其它

<<自己动手写操作系统>>学习笔记(一)---后记

2012-07-02 21:46 537 查看
比划着书,反汇编着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:


希望有人能帮我解决一下,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐