[Linux]磁盘端口I/O

其实所有的驱动程序最底层不过是使用硬件的command,也就是端口的io操作,ATA设备的命令端口是1f0h-1f7h和170h-177h,控制端口是3f4h-3f7h和374h-377h。这个东西说起来话就长了。我给一个读取Primary的Master的MBR的例子。


nLegacy IO Access
( Debug.exe or Debug32.exe )
o 3F6 04     ; Channel Reset
o 3F6 00
i 1F7     ; 50 – HD exist
o 1F2 1     ; Read 1 sector
o 1F3 0     ; Set Read Start Address
o 1F4 0
o 1F5 0
o 1F6 e0    ; Select PIO Mode
o 1F7 20     ; Send Read Command
i 1F7     ; 58 – HD Data Ready
nRead Data
nByte Read
i 1F0     ; Read Data
nBlock Read
-a 100 ; Use ASM Code at cs:100
mov dx, 1F0h ; Data Port
mov si, 5000h ; Target Address Offset
mov cx, 512 ; Loop Count
Address
in al, dx ; Read Data
mov ds:[si], al ; Move Data to Target
inc si ; Increase Offset
loop address ; Loop Move
int 3 ; Debug Interrupt
-g = 100 ; Run From cs:100 to int3
-d ds:5000 ; Dump Data From cs:5000
这是在debug下操作的过程。是我们的内部学习资料,再多就不可以说了。网络上有这方面的资料,但很是零散。

--------------------------------------------------------
要想知道细节,可以找找ATA的说明书。我看网络上了解这方面的人并不算多,其实除了做硬盘和驱动的人,其他人也没有必要知道这些东西。

例子要一步步做下来,经常作软件的人很难理解硬件控制的步骤。

primary的端口是3f4h-3f7h和1f0h-1f7h。


mov dx, 3F6h ;Control Port
mov al, 04h ;Bit2-Channel Reset Bit
out dx, al ;Reset Channel
out ebh, al ;IO Delay
mov al, 00h
out dx, al ;Reset Complete
mov dx, 1f6h ;Device Select Port
mov al, 0a0h/0b0h
; 0a0h – Master
; 0b0h – Slave
out dx, al ;Select Master or Slave
mov dx, 1f7h ;Command/Status Port
in al, dx ;Read Master Status
nCompare the value of the al:
50h – Attached Device, is Hard Disk
00h – No Device Attached, or the          Attached Device is not Hard Disk
这一段就是选择Master channel的Master设备,
     mov dx, 3f6h ;Control Port
mov al, 04h ;Bit2-Channel Reset Bit
out dx, al ;Reset Channel
重起Primary channel.
  out ebh, al ;IO Delay
等待一会,因为硬件的速度比CPU要慢很多,所以需要CPU等待一会。向ebh端口的写入操作可以使CPU等待一段时间,具体是多少我忘了,大家可以查查资料。
  mov al, 00h
out dx, al ;Reset Complete
  重起完成,要清3f6h端口
   mov dx, 1f6h ;Device Select Port
mov al, 0a0h
; 0a0h – Master
; 0b0h – Slave
out dx, al ;Select Master or Slave
选择Master设备。
    mov dx, 1f7h ;Command/Status Port
in al, dx ;Read Master Status
nCompare the value of the al:
50h – Attached Device, is Hard Disk
00h – No Device Attached, or the          Attached Device is not Hard Disk
检查1f7h端口,如果是50h就说明master设备是硬盘
然后看看读硬盘的操作。
其实就是给1f1h到1f6h设置好参数,然后给1f7h端口下20h命令,这是硬件操作的一般原理,我的理解是,1f7h端口可以理解为函数名,1f2h到1f6h存放参数,返回值在1f0h端口中。
读硬盘的函数就是20h,各参数如下:
1f1h----任意
1f2h----操作的扇区数,我们读MBR,只有一个扇区,设为1
1f3h----起始LBA的bit0-bit7
1f4h----起始LBA的bit8-bit15
1f5h----起始LBA的bit16-bit23
1f6h----低四位是起始LBA的bit24-bit27,第五位是设备选择,0是master,1是slave.我们读的是master,应设为0,第七位设为1表示使用LBA,现在硬盘都使用LBA,应置起来。其他两个bit要求为1
所以,参数设定应该是:
1f2h----1h
起始LBA应该为0,因为MBR是硬盘第一个扇区也就是0扇区。
所以1f3h\1f4h\1f5h\1f6h的低四位都为0
1f6h----e0h
确保都设置好了,现在给1f7和放入20h,等1f7h变成58h,就说明数据准备好了,就可以从1f0h端口中读出数据了。
等一下做个程序发上来

原文地址:https://www.cnblogs.com/huqingyu/p/110013.html