我的操作系统现在处于保护模式,所以我现在无法使用中断访问磁盘。我不知道如何切换到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
答案 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;