PIO方式读取硬盘(包括CHS, 24-bit LBA, 48-bit LBA)

来源:互联网 发布:淘宝定制付定金和尾款 编辑:程序博客网 时间:2024/06/06 01:30

IDE通道1,读写0x1f0-0x1f7号端口

IDE通道2,读写0x170-0x17f号端口

 

CHS方式:

写0x1f1: 0

写0x1f2: 要读的扇区数

写0x1f3: 扇区号

写0x1f4: 柱面的低8位

写0x1f5: 柱面的高8位

写0x1f6: 7~5位,101,第4位0表示主盘,1表示从盘,3~0位,磁头号

写0x1f7: 0x20为读, 0x30为写

读0x1f7: 第4位为0表示读写完成,否则要一直循环等待

读0x1f0: 每次读取1个word,反复循环,直到读完所有数据

 

24-bit LBA方式:

写0x1f1: 0

写0x1f2: 要读的扇区数

写0x1f3: LBA参数的0~7位

写0x1f4: LBA参数的8~15位

写0x1f5: LBA参数的16~23位

写0x1f6: 7~5位,111,第4位0表示主盘,1表示从盘,3~0位,LBA参数的24~27位

写0x1f7: 0x20为读, 0x30为写

读0x1f7: 第4位为0表示读写完成,否则要一直循环等待

读0x1f0: 每次读取1个word,反复循环,直到读完所有数据

 

48-bit LBA方式:

写两次0x1f1端口: 0

写两次0x1f2端口: 第一次要读的扇区数的高8位,第二次低8位

写0x1f3: LBA参数的24~31位

写0x1f3: LBA参数的0~7位

写0x1f4: LBA参数的32~39位

写0x1f4: LBA参数的8~15位

写0x1f5: LBA参数的40~47位

写0x1f5: LBA参数的16~23位

写0x1f6: 7~5位,010,第4位0表示主盘,1表示从盘,3~0位,0

写0x1f7: 0x24为读, 0x34为写

 

 

CHS Mode

[cpp] view plaincopy
  1. check_ready:   
  2.     mov  dx, 0x1f7   
  3.     in   al, dx  
  4.     test al, 0x40  
  5.     jz   check_ready   
  6.     ret   
  7.   
  8. check_read_complete:   
  9.     mov  dx, 0x1f7   
  10.     in   al, dx  
  11.     test al, 0x08  
  12.     jz   check_ready   
  13.     ret   
  14.       
  15. pio_delay:   
  16.     nop   
  17.     nop   
  18.     nop   
  19.     nop   
  20.     ret   
  21.   
  22. ;   
  23. ; read sectors to buffer   
  24. void   
  25. ; read_sectors (  
  26. ;   int sector_count,   
  27. ;   int sector_number,   
  28. ;   int cylinder,   
  29. ;   int driver,   
  30. ;   int head,   
  31. ;   int buffer);   
  32. ;   
  33. ; parameters:   
  34. ;   sector_count: the count of sectors to read   
  35. ;   sector_number: the start sector to read   
  36. ;   cylinder: the cylinder of sector to read  
  37. ;   driver: 0: 1st desk, 1: 2nd desk   
  38. ;   head: 0~15  
  39. ;   buffer: the address of buffer  
  40. ;  
  41. _read_sectors:   
  42.     push ebp  
  43.     mov  ebp, esp   
  44.       
  45.     push eax   
  46.     push ebx   
  47.     push ecx   
  48.     push edx   
  49.     push edi   
  50.       
  51.     call check_ready  
  52.       
  53.     mov  dx, 0x1f2   
  54.     mov  eax, dword [ebp+8]  
  55.     ;mov  al, 1  ; sector count=1  
  56.     out  dx, al  
  57.     call pio_delay  
  58.       
  59.     mov  dx, 0x1f3   
  60.     mov  eax, dword [ebp+12]  
  61.     ;mov  al, 1  ; sector number=1  
  62.     out  dx, al   
  63.     call pio_delay   
  64.       
  65.     mov  ebx, dword [ebp+16]  
  66.     and  bx, 0x03ff  
  67.     mov  dx, 0x1f4   
  68.     mov  al, bl  ; cylinder low 8bits=0  
  69.     out  dx, al   
  70.     call pio_delay   
  71.       
  72.     mov  dx, 0x1f5   
  73.     mov  al, bh  ; cylinder high 2bits=0  
  74.     out  dx, al   
  75.     call pio_delay   
  76.       
  77.     mov  ebx, dword [ebp+20]  
  78.     and  ebx, 1  
  79.     shl  bl, 4  
  80.     mov  al, 0xa0  ; reserve=101, driver=0, head=0  
  81.     or   al, bl  
  82.     mov  ebx, dword [ebp+24]  
  83.     and  bl, 0x0f  
  84.     or   al, bl  
  85.     mov  dx, 0x1f6   
  86.     out  dx, al   
  87.       
  88.     mov  dx, 0x1f7   
  89.     mov  al, 0x20  ; read until succeed  
  90.     out  dx, al   
  91.     call check_read_complete  
  92.       
  93.     mov  eax, 256  
  94.     mov  ebx, dword [ebp+8]  
  95.     mul  bx  
  96.     mov  cx,  ax  
  97.     mov  edi, dword [ebp+28]  
  98.     mov  dx,  0x1f0  
  99.     rep  insw  
  100.       
  101.     pop  edi   
  102.     pop  edx   
  103.     pop  ecx   
  104.     pop  ebx   
  105.     pop  eax   
  106.     pop  ebp   
  107.     xor  eax, eax  
  108.     ret   

 

24-bit LBA Mode

[cpp] view plaincopy
  1. ;   
  2. ; read sectors to buffer   
  3. void   
  4. ; read_sectors_lba24 (  
  5. ;   int sector_number,   
  6. ;   int sector_count,   
  7. ;   int driver,   
  8. ;   int buffer);   
  9. ;   
  10. ; parameters:   
  11. ;   sector_number: the start sector to read   
  12. ;   sector_count: the count of sectors to read   
  13. ;   driver: 0: 1st desk, 1: 2nd desk   
  14. ;   buffer: the address of buffer  
  15. ;  
  16. _read_sectors_lba24:   
  17.     push ebp  
  18.     mov  ebp, esp   
  19.       
  20.     push eax   
  21.     push ebx   
  22.     push ecx   
  23.     push edx   
  24.     push edi   
  25.       
  26.     call check_ready  
  27.       
  28.     mov  dx, 0x1f2   
  29.     mov  eax, dword [ebp+12]   
  30.     out  dx, al  ; sector count  
  31.     call pio_delay  
  32.       
  33.     mov  dx, 0x1f3   
  34.     mov  eax, dword [ebp+8]   
  35.     out  dx, al   ; 0~7 bit  
  36.     call pio_delay   
  37.       
  38.     mov  dx, 0x1f4   
  39.     mov  eax, dword [ebp+8]  
  40.     shr  eax, 8  ; 8~15 bit  
  41.     out  dx, al   
  42.     call pio_delay   
  43.       
  44.     mov  dx, 0x1f5   
  45.     mov  eax, dword [ebp+8]  
  46.     shr  eax, 16  ; 16~23 bit  
  47.     out  dx, al   
  48.     call pio_delay   
  49.       
  50.     mov  ebx, dword [ebp+16]  
  51.     and  ebx, 1  
  52.     shl  bl, 4  
  53.     mov  al, 0xe0  ; 5~7: 111, 4: driver, 0~3: 24~27 bit  
  54.     or   al, bl  
  55.     mov  ebx, dword [ebp+8]  
  56.     shr  ebx, 24  ; 24~27 bit  
  57.     and  bl, 0x0f  
  58.     or   al, bl  
  59.     mov  dx, 0x1f6   
  60.     out  dx, al   
  61.       
  62.     mov  dx, 0x1f7   
  63.     mov  al, 0x20  ; read until succeed  
  64.     out  dx, al   
  65.     call check_read_complete  
  66.       
  67.     mov  eax, 256  
  68.     mov  ebx, dword [ebp+12]  
  69.     mul  bx  
  70.     mov  cx,  ax  
  71.     mov  edi, dword [ebp+20]  
  72.     mov  dx,  0x1f0  
  73.     rep  insw  
  74.       
  75.     pop  edi   
  76.     pop  edx   
  77.     pop  ecx   
  78.     pop  ebx   
  79.     pop  eax   
  80.     pop  ebp   
  81.     xor  eax, eax  
  82.     ret   
  

 

48-bit LBA Mode 实现过程类似,不给出具体代码了。。。