这是所发的第一篇blog,是在学习操作系统时的一个问题,内容本是写给一个老师的问题,但最终没收到回复,在此留下,以提示自己思考,若阁下有解决思路,还请一定告知,谢谢!



问题大概是这样,我写了段操作系统的引导代码,试图引导操作系统,而引导操作系统的必要一步就是读取pbr,然后跳转到pbr的代码上,而问题就出在读硬盘上,读硬盘可以通过int13中断(测试成功),但此法不能读较大的硬盘,于是我采用lba48的方式读硬盘,然后我就在bochs虚拟机上测试代码,发现能够引导windows,而接下来问题就出现了,虽然bochs通过,但在物理主机上却不能正常引导,而且我也在vpc虚拟机上测试过,发现也不行,一个虚拟机行,一个虚拟机不行,究竟为何会出现此种情况,还有待思考......
附上代码以及在一些调试图片
cld
mov cx,512
mov ax,0x07c0
mov ds,ax
mov si,0
mov ax,0x2000
mov es,ax
mov di,0
rep movsb        ;将0:7c00的位置腾出,将mbr移到2000:0
jmp 0x2000:0x1b  ;跳到此处继续执行
mov ax,0x07c0
mov ds,ax
push 1    ;读取1个扇区
push 63      ;读取第63扇区,逻辑扇区0~15位
push 0    ;逻辑扇区16~31位
push 0    ;逻辑扇区32~47位
push 0       ;读取代码到内存的偏移位置
call readhd  
mov dx,0
jmp 0x07c0:0


readhd:
mov bp,sp
mov dx,0x1f2
mov al,[bp+11]
out dx,al
mov al,[bp+10]
out dx,al  ;写两次0x1f2端口: 第一次要读的扇区数的高8位,第二次低8位
inc dx
mov al,[bp+7]
out dx,al
mov al,[bp+8]
out dx,al ;写0x1f3: LBA参数的24~31位,写0x1f3: LBA参数的0~7位
inc dx
mov al,[bp+4]
out dx,al
mov al,[bp+9]
out dx,al ;写0x1f4: LBA参数的32~39位,写0x1f4: LBA参数的8~15位
inc dx
mov al,[bp+5]
out dx,al
mov al,[bp+6]
out dx,al  ;写0x1f5:LBA参数的40~47位,写0x1f5: LBA参数的16~23位
inc dx
mov al,0x40 ;lba48 0x40;lba28 0xe0
out dx,al
mov dx,0x1f7
mov al,0x24 ;lba48 0x24;lba24 0x20
out dx,al
mov dx,0x1f7
wai:
in al,dx
and al,0x88
cmp al,0x08
jnz wai

mov ax,256
mov dx,[bp+10]
mul dx
mov cx,ax
mov dx,0x1f0
mov bx,0
r:
in ax,dx
mov [bx],ax
add bx,2
loop r
ret 10
上面代码编译后的机器码:

154418972.jpg

覆盖掉bochs虚拟机的虚拟硬盘中安装的xp的mbr:

154419956.jpg

bochs中调试画面:

154422347.jpg

bochs中成功引导xp:

154423953.jpg