内核编程:保护模式下读取磁盘绝对扇区

来源:互联网 发布:建筑工程记账软件 编辑:程序博客网 时间:2024/06/08 18:05

在实模式下,可通过13号BIOS中断读取磁盘扇区。

但保护模式下,中断方式发生改变。中断处理程序的段基址通过IDT表中的描述符得到,而非实模式下的中断向量表。

故保护模式下,已无法使用实模式下的中断处理程序。

磁盘读写属于I/O,可通过直接的IO读写来完成,实际上BIOS的中断处理程序也是这样完成的。

以下是读取磁盘扇区的DEMO代码:

 

#include "../plib.h"
#define Cs 0
#define Hs 0
#define Ss 1
#define READSECTOR_TIMEOUT 10000;


unsigned 
int readSector(unsigned long partitionOffset, unsigned long driveNumber, unsigned long lba, unsigned char *data, int limit)
{
    
//print("readSector start=%x ",data);
    lba += partitionOffset;
    
/*
    unsigned short c = lba / (getMaxHead () * getMaxSector ()) + Cs;
    unsigned char h = (lba / getMaxSector ()) % getMaxHead () + Hs;
    unsigned char s = lba % getMaxSector () + Ss;
    print("lba=%lu,c=%u,h=%u,s=%u ",lba,c,h,s);
    return readSector (driverNumber, c, h, s, data, limit);
    
*/
 
    
//print("limit=%d, numberOfSector=%d ",limit, numberOfSector);
    unsigned int numberOfSector;
    
if (limit == 0) {
        
return 0;
    } 
else if (limit < 512) {
        numberOfSector 
= 1;
    } 
else {
        numberOfSector 
= (limit % 512 == 0? limit / 512 : (limit / 512+ 1;
    }
    
//print("numberOfSector=%u ",numberOfSector);
    outport(0x1f2, numberOfSector);
    outport(
0x1f3, lba);
    outport(
0x1f4, lba >> 8);
    outport(
0x1f5, (lba >> 16& 0xff);
    outport(
0x1f60xe0 | (driveNumber << 4));
    outport(
0x1f70x20);
    
//print("end outport ");
    
//sleep(1);
    
//print("readSector 2 ");
 
    unsigned 
char status = 0;
    
int timeout = READSECTOR_TIMEOUT;
    
do {
        status 
= inport(0x1f7);
        
if (timeout-- == 0) {
            
return 0;
        }
    } 
while ((status & 0x8!= 0x8);
    
//} while ((status & 0x89) != 0x8);
    
//print("end while ");
    for (unsigned short x = 0; x < numberOfSector * 512; x += 2) {
        
//print("x=%u",x);
        if (x >= limit && limit != -1) {
            
break;
        } 
else {
            
//print("start in ");
            short inChar = inWordFromPort(0x1f0);
            
//print("end in ");
            
//char s=inport(0x1f1);
            
//print("statur=%u ", s);
            char first = inChar & 0xff;
            
char second = inChar >> 8;
            
if (x < limit || limit == -1) {
                data[x] 
= first;
            }
            
if (x + 1 < limit || limit == -1) {
                data[x 
+ 1= second;
            }
        }
    }
    
//print("end for ");
    
//print("   readSector end, limit=%d ",limit);
    if (limit != -1) {
        
//print("returning... ");
        return limit;
    } 
else {
        
return numberOfSector * 512;
    }
}