十一、 直接读取SATA硬盘之四、访问AHCI控制器
(1)原理
需要参考INTEL的AHCI规范标准《serial-ata-ahci-spec-rev1-3-1》,非常重要。
网站osdev中,给出了AHCI的通俗介绍、访问AHCI控制器、SATA硬盘的程序,真的是帮助太大了,不然根本无法完成后面的程序。http://wiki.osdev.org/AHCI
内容实在是太多了,这里就不再说明了。
(2)直接读取SATA硬盘的程序――得到硬盘参数
在TC3.0下,HUGE模式编译。DOS运行。
ahci1.c:
// TC3.0 下,HUGE模式,指针是4字节,MK_FP()是4字节,FP_SEG()是2字节
#include
#include
#include
#include
#include
#include "read4g2.h"
#define BYTE unsigned char
#define WORD unsigned int
#define DWORD unsigned long
typedef struct tagFIS_REG_H2D
{
// DWORD 0
BYTE fis_type; // FIS_TYPE_REG_H2D FIS TYPE类型
BYTE pmport:4; // Port multiplier 表示第2个字节的4个bits
BYTE rsv0:3; // Reserved 表示第2个字节的3个bits
BYTE c:1; // 1: Command, 0: Control 表示第2个字节的1个bit
BYTE command; // Command register
BYTE featurel; // Feature register, 7:0
// DWORD 1
BYTE lba0; // LBA low register, 7:0
BYTE lba1; // LBA mid register, 15:8
BYTE lba2; // LBA high register, 23:16
BYTE device; // Device register
// DWORD 2
BYTE lba3; // LBA register, 31:24
BYTE lba4; // LBA register, 39:32
BYTE lba5; // LBA register, 47:40
BYTE featureh; // Feature register, 15:8
// DWORD 3
BYTE countl; // Count register, 7:0
BYTE counth; // Count register, 15:8
BYTE icc; // Isochronous command completion
BYTE control; // Control register
// DWORD 4
BYTE rsv1[4]; // Reserved
} FIS_REG_H2D;
typedef volatile struct tagHBA_PORT //每个PORT口的空间,长80H字节。 即对PORT0来说,是100~17FH空间
{
DWORD clb; // 0x00, command list base address, 1K-byte aligned 指向command list空间
DWORD clbu; // 0x04, command list base address upper 32 bits
DWORD fb; // 0x08, FIS base address, 256-byte aligned 指向Received FIS空间
DWORD fbu; // 0x0C, FIS base address upper 32 bits
DWORD is; // 0x10, interrupt status
DWORD ie; // 0x14, interrupt enable
DWORD cmd; // 0x18, command and status
DWORD rsv0; // 0x1C, Reserved
DWORD tfd; // 0x20, task file data
DWORD sig; // 0x24, signature
DWORD ssts; // 0x28, SATA status (SCR0:SStatus)
DWORD sctl; // 0x2C, SATA control (SCR2:SControl)
DWORD serr; // 0x30, SATA error (SCR1:SError)
DWORD sact; // 0x34, SATA active (SCR3:SActive)
DWORD ci; // 0x38, command issue
DWORD sntf; // 0x3C, SATA notification (SCR4:SNotification)
DWORD fbs; // 0x40, FIS-based switch control
DWORD rsv1[11]; // 0x44 ~ 0x6F, Reserved
DWORD vendor[4]; // 0x70 ~ 0x7F, vendor specific
} HBA_PORT;
typedef volatile struct tagHBA_MEM //整个HBA内存空间
{
// 0x00 - 0x2B, Generic Host Control //即00~2BH空间,Generic Host Control空间
DWORD cap; // 0x00, Host capability
DWORD ghc; // 0x04, Global host control
DWORD is; // 0x08, Interrupt status
DWORD pi; // 0x0C, Port implemented
DWORD vs; // 0x10, Version
DWORD ccc_ctl; // 0x14, Command completion coalescing control
DWORD ccc_pts; // 0x18, Command completion coalescing ports
DWORD em_loc; // 0x1C, Enclosure management location
DWORD em_ctl; // 0x20, Enclosure management control
DWORD cap2; // 0x24, Host capabilities extended
DWORD bohc; // 0x28, BIOS/OS handoff control and status
// 0x2C - 0x9F, Reserved
BYTE rsv[0xA0-0x2C];
// 0xA0 - 0xFF, Vendor specific registers
BYTE vendor[0x100-0xA0];
// 0x100 - 0x10FF, Port control registers //PORT口的空间
HBA_PORT ports[1]; // 1 ~ 32
} HBA_MEM;
typedef struct tagHBA_CMD_HEADER //每个command项(头,SLOT)的结构,长度32字节
{
// DW0
BYTE cfl:5; // Command FIS length in DWORDS, 2 ~ 16
BYTE a:1; // ATAPI
BYTE w:1; // Write, 1: H2D, 0: D2H
BYTE p:1; // Prefetchable
BYTE r:1; // Reset
BYTE b:1; // BIST
BYTE c:1; // Clear busy upon R_OK
BYTE rsv0:1; // Reserved
BYTE pmp:4; // Port multiplier port
WORD prdtl; // Physical region descriptor table length in entries
// DW1
volatile
DWORD prdbc; // Physical region descriptor byte count transferred
// DW2, 3
DWORD ctba; // Command table descriptor base address 128-byte aligned 指向 command table!!!
DWORD ctbau; // Command table descriptor base address upper 32 bits
// DW4 - 7
DWORD rsv1[4]; // Reserved
} HBA_CMD_HEADER;
typedef struct tagHBA_PRDT_ENTRY // PRDT入口,长度16字节
{
DWORD dba; // Data base address 2-byte aligned 指向data空间
DWORD dbau; // Data base address upper 32 bits
DWORD rsv0; // Reserved
// DW3
/* TC3不支持DWORD的bit分组
DWORD dbc:22; // Byte count, 4M max
DWORD rsv1:9; // Reserved
DWORD i:1; // Interrupt on completion
*/
WORD dbc1;
WORD dbc2:6;
WORD rsv1:9;
WORD i:1;
} HBA_PRDT_ENTRY;
typedef struct tagHBA_CMD_TBL //command table的结构
{
// 0x00
BYTE cfis[64]; // Command FIS
// 0x40
BYTE acmd[16]; // ATAPI command, 12 or 16 bytes
// 0x50
BYTE rsv[48]; // Reserved
// 0x80
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
} HBA_CMD_TBL;
void mydisplay(unsigned char *d,int n)
{
int i,i2;
if (n<=0) return;
i2=0;
for(i=0; i;>
{
printf("%02X ",d);
i2++;
if(i2 >=16 ) {i2=0; printf("\n");}
}
printf("\n");
}
unsigned long myREADMEM_DWORD(unsigned long addr)
{
unsigned long lt;
memmove( addr , (unsigned long)FP_SEG(<)*16+(unsigned long)FP_OFF(<) , 4 ); //源,目的,字节数(应为偶数)
return lt;
}
void myWRITEMEM_DWORD(unsigned long addr, unsigned long lt)
{
memmove( (unsigned long)FP_SEG(<)*16+(unsigned long)FP_OFF(<) , addr, 4 ); //源,目的,字节数(应为偶数)
}
文章评论(0条评论)
登录后参与讨论