关于IDE访问的问题

zhoulm   2008-11-14 15:56 楼主
我想自己编写一个小型的OS,仅仅为了学习的目的
在访问IDE时碰到一些问题想请教大家
我的开发环境是virtualPC 2007
部分32位引导代码如下

; ebx= start sector
; ecx= sector number to read 0 ; edi= buffer address


  mov        dx, 3f6h           ;reset hd disk
  mov        al, 04h
  out        dx, al             ;SRST=1
  xor        al, al
  out        dx, al             ;SRST=0

wait_ready:
  mov dx, 1f7h
  in al, dx
  and al, 01000000b
  jz wait_ready            ;Wait DRDY=1

  sub dl, 6
  xor al, al
  out dx, al               ;out 1f1h, 0
  inc dl
  mov al, cl
  out dx, al               ;out 1f2h, sectorsToRead
  inc dl
  mov al, 40h
  shl eax, 24
  add eax, ebx
  out dx, eax              ;out 1f3h, ebx | 0x40000000
  add dl, 4
  mov al, 20h
  out dx, al               ;out 1f7h, 20h

  shl ecx, 8               ;ecx=ecx*256
waitHDD:
  in al, dx
  and al, 00001000b
  jz waitHDD               ;wait next data ready
  sub dl, 7

  ;rep insw
  mov ax, dx
  stosw
  add dl, 7
  loop waitHDD

这段代码是在刚开机bootsector中的,
问题是很奇怪,如果用rep insw就有一定的可能读不全数据
而用mov ax, dx
stosw
add dl, 7
loop waitHDD
则每次都能读对
不知道大家有么有碰到过这个问题
全部的代码在http://minios2.googlecode.com/svn/trunk/codes/可以用svn check out出来
可以跟大家一起学习

回复评论 (2)

更奇怪的是boot起来之后
用ide.c中的ide_readpio4读取ide则每次都可以成功
ide_readpio4地实现基本和上面的代码相同
难道是virtualPC的问题?

另外一个问题是采用DMA方式读,数据是读出来了,但是中断迟迟不触发
以下是代码的片断,详细的代码都可以check out 出来
struct _DMABUFDES
{
        uint32 base;
        uint16 eot;
        uint16 len;
} idedmabuf = {0x10000, 0x8000, 0};

uint32 ide_readdma(uint32 start, uint32 number)
{
        start |= 0x40000000;

        _out(PCIIDE_CTRL, 0);
        _out(PCIIDE_CTRL + 2, 0x06);
        _out32(PCIIDE_CTRL + 4, (uint32)&idedmabuf);        // Setup dma buffer
        _out(PRIMARY_CTRL, 0);                                // enable interrupt

        _out32(PRIMARY_ATA + 6, 0x40);
        while((_in(PRIMARY_ATA + 7) & 0x40) == 0)
                ;
        _out(PRIMARY_ATA + 2, number);
        _out32(PRIMARY_ATA + 3, start);
        _out(PRIMARY_ATA + 7, 0xC8);
        while((_in(PRIMARY_ATA + 7) & 0x0f) == 0)
                ;
       
        _out(PCIIDE_CTRL, 9);
        return 0;
}
点赞  2008-11-14 16:05
好象不能用insw,记不清了,改成insb或insd试试。
点赞  2008-11-14 16:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复