使用汇编中的端口进行磁盘读/写故障

时间:2016-06-26 20:03:23

标签: assembly x86 operating-system disk protected-mode

我的操作系统现在处于保护模式,所以我现在无法使用中断访问磁盘。我不知道如何切换到v86模式。我需要使用端口进行磁盘访问。

我决定尝试在forum.osdev.org上找到的代码。在模拟器中,它显示磁盘读取或写入成功Done.But当我检查硬盘它是空的或当我测试读取时,缓冲区是全是空的。

此代码或我的操作系统有什么问题? (也许是堆栈问题造成的?) 代码:

set_up_buffer:
xor ax,ax
mov es,ax
mov di,[buffer]
mov al,0xCD
stosb
mov al,0x19
       stosb
       WriteToMbr:
       mov     dx,1f6h         ;Drive and head port
       mov     al,0a0h         ;Drive 0, head 0
       out     dx,al

       mov     dx,1f2h         ;Sector count port
       mov     al,1            ;Write one sector
       out     dx,al

       mov     dx,1f3h         ;Sector number port
       mov     al,1           ;Wrote to sector one
       out     dx,al

       mov     dx,1f4h         ;Cylinder low port
       mov     al,0            ;Cylinder 0
       out     dx,al

       mov     dx,1f5h         ;Cylinder high port
       mov     al,0            ;The rest of the cylinder 0
       out     dx,al

       mov     dx,1f7h         ;Command port
       mov     al,30h          ;Write with retry.
       out     dx,al
    oogle:
       in      al,dx
       test    al,8            ;Wait for sector buffer ready.
       jz      oogle

       mov     cx,512/2        ;One sector /2
       mov     si,[buffer]
       mov     dx,1f0h         ;Data port - data comes in and out of here.
       rep     outsw           ;Send it.
       leave
       ret
buffer:
times 512 db 0

1 个答案:

答案 0 :(得分:0)

我发现了问题,问题发生在 rep outw ,所以我编写了一个循环代码,在没有该命令的情况下将字发送到数据寄存器。
 OK这是我写的代码在pascal中:




 使用...;
 var
 RawData:Word的数组[0..255];
 ATA_INDEX:整数;
实现
 //...
函数DiskReadSector(Drive,Head,Cylinder,SecNum:integer):Integer; stdcall;
 var
 xstat:Word ;
 i:整数;
 BaseAdress:Word;
开始
如果ATA_INDEX = 0则
 BaseAdress:= $ 1f0 else
 BaseAdress:= $ 170;&# xA; outb(BaseAdress + 6,$ 0a0或(Drive shl 4)或head);
 outb(BaseAdress + 2,1); // Count
 outb(BaseAdress + 3,SecNum); //扇区号
 outb(BaseAdress + 4,Cylinder和$ 00FF); // LOW Cylinder
 outb(BaseAdress + 5,Cylinder shr 8); // HIGH Cylinder
 outb(BaseAdress + 7,$ 20) ; // READ COMMAND $ 30 for WRITE
 asm //检查数据准备
 mov dx,1f7h
 @still_going:
在al,dx
 test al,8
 jz @still_going
 en d;
对于i:= 0到255,开始//将数据复制到WORD ARRAY
 xstat:= inw(BaseAdress); 
 RAWDATA [I]:= xstat;
端;
 DiskReadSector:= INB(BaseAdress + 7); // DEBUG&#XA末端
  




用法:




  procedure kmain; stdcall; [public,alias:'kmain'];
 begin
 //...
 ATA_INDEX:= 0; //为Secondary辅助的其他人为零
 DiskReadSector(0,0,0,1); //为Master 1为从属驱动器0示例:
 // ATA_INDEX = 0且Drive = 0表示Primary Master
 //此代码将读取IDE Primary Master的主引导记录
 //简单检查第一扇区的引导签名在主要主服务器上:
如果RawData [255] = $ AA55则
 WriteLn('检测到引导签名!');
结束;
  
&# XA;