热度 16
2015-4-23 17:18
1892 次阅读|
0 个评论
十一、 直接读取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 ; // 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 ; // 0x44 ~ 0x6F, Reserved DWORD vendor ; // 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 - 0xFF, Vendor specific registers BYTE vendor ; // 0x100 - 0x10FF, Port control registers //PORT口的空间 HBA_PORT ports ; // 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 ; // 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 ; // Command FIS // 0x40 BYTE acmd ; // ATAPI command, 12 or 16 bytes // 0x50 BYTE rsv ; // Reserved // 0x80 HBA_PRDT_ENTRY prdt_entry ; // 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 ); //源,目的,字节数(应为偶数) }