一、概念
通过一定的规则将物理扇区的柱面、磁头和扇区三维编号转变为线性编号,实现了一维的线性寻址。这种寻址方式可以提高系统效率,避免了烦琐的磁头/柱面/扇区的寻址方式。
二、特性
1.无磁盘,柱面的概念
2.起始序号为0
三、使用LBA读取磁盘
访问序列如下:
//写端口函数
static inline void outb(uint16_t port, uint8_t data){
/*指令格式为
outb al(数据), dx(端口)
*/
__asm__ __volatile__(
"outb %[v], %[p]"
::[v]"a"(data), [p]"d"(port)
);
}
/**
* 使用LBA48位模式读取磁盘
*/
static void read_disk(int sector, int sector_count, uint8_t * buf) {
outb(0x1F6, (uint8_t) (0xE0));
outb(0x1F2, (uint8_t) (sector_count >> 8));
outb(0x1F3, (uint8_t) (sector >> 24)); // LBA参数的24~31位
outb(0x1F4, (uint8_t) (0)); // LBA参数的32~39位
outb(0x1F5, (uint8_t) (0)); // LBA参数的40~47位
outb(0x1F2, (uint8_t) (sector_count));
outb(0x1F3, (uint8_t) (sector)); // LBA参数的0~7位
outb(0x1F4, (uint8_t) (sector >> 8)); // LBA参数的8~15位
outb(0x1F5, (uint8_t) (sector >> 16)); // LBA参数的16~23位
outb(0x1F7, (uint8_t) 0x24);
// 读取数据
uint16_t *data_buf = (uint16_t*) buf;
while (sector_count-- > 0) {
// 每次扇区读之前都要检查,等待数据就绪
while ((inb(0x1F7) & 0x88) != 0x8) {}
// 读取并将数据写入到缓存中
for (int i = 0; i < SECTOR_SIZE / 2; i++) {
*data_buf++ = inw(0x1F0);
}
}
}
使用LBA模式读取磁盘时,各个寄存器说明如图所示(引用bilibili李述铜老师课程截图):
其中0x1F6寄存器对应的位如下(引用bilibili李述铜老师课程截图):
状态寄存器(引用bilibili李述铜老师课程截图):