这是所发的第一篇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
上面代码编译后的机器码:
覆盖掉bochs虚拟机的虚拟硬盘中安装的xp的mbr:
bochs中调试画面:
bochs中成功引导xp: