首页
社区
课程
招聘
[求助]编写一个MBR存在问题,请大家看看。
发表于: 2012-7-3 18:01 4412

[求助]编写一个MBR存在问题,请大家看看。

2012-7-3 18:01
4412
使用FASM汇编器,代码如下:
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:
	sti
	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:

其余的代码在我的博客上http://blog.csdn.net/sidyhe/article/details/7709903
这里有一个问题希望得到解答。
代码当中的分区表是我虚拟机里面的,当我编译出来的时候写到磁盘的MBR后重启,没有反应,或许是MBR读取了MBR再次加载到0x7C00转移控制权?
同样也看不到任何输出,求解。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 692
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
push ax;ax=0
  push MASTER_BOOT_RECORD_BASE
  retf;转移控制权到PBR
这个不时转移到PBR,其实代码里写的很清楚么,
执行retf后相当于
pop ip
pop cs
所以,最后会跳到0x0:7c00
win7的MBR是bios加载到0x7c00后,将自己移动到0x0600,然后加载分区数据到0x7c00,根据分区表例的信息,最后也是个jmp word 0x0:0x7c00
2012-7-3 20:42
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
回楼上,我的思路就是这样,但不知道为什么没有任何输出且可能没有加载PBR
注释我写的也比较清楚,但就是找不到原因,虚拟机也不崩溃,就是一点反应都没有
调试?不知道这个玩意怎么调试。
望解答。
2012-7-3 22:11
0
雪    币: 135
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
调试mbr为什么不用bochs~可以单步跟踪的哦~
话说,不是win7的mbr会加载到0000h:7C00h,而是使用BIOS方式引导的操作系统都会把MBR加载到0000h:7C00h,这是个固定位置
2012-7-3 23:01
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
哦对,书上是有讲bochs,看来还得仔细看看。
我知道MBR加载到07C00是硬性规定的。
统一才有兼容性嘛。
看来不调试是不行了,哎。
2012-7-4 06:49
0
雪    币: 575
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
果断bochs vb 0:0x7c00
2012-7-4 09:33
0
游客
登录 | 注册 方可回帖
返回
//