注意: 如果再 cmake 中想要 make clean 的话, 直接 删除 build 目录就可以了。
1 也是说 是 MBR还是 LBA 硬盘是可以控制的。
LBA 没有 磁盘, 柱面的概念。
2 对于寄存器的说明。
什么是 CHS呢? 就是机械磁盘。
这里只找到了 LBA28 的寄存器。
对于 LBA48 具体的操作是这样的。
3 实现 读取LBA的总体的函数
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);
// 这里每次读取回来的数据都是 16位的,所以指针也是16位的。
uint16_t *data_buf = (uint16_t*) buf;
while (sector_count-- > 0) {
// 每次扇区读之前都要检查,等待数据就绪
while ((inb(0x1F7) & 0x88) != 0x8) {}
// 由于每次读取2个字节的数据,所以这里 处以2 , 一个扇区 512 字节,需要读取 512/2 次
for (int i = 0; i < SECTOR_SIZE / 2; i++) {
*data_buf++ = inw(0x1F0);
}
}
}
注意: 这里是遵循了 LBA48 的读取方式的。
首先是 要读取的扇区数量的高8位 ,
然后是 24---31
然后是 32--39
然后是 40---47
再然后是 要读取的扇区数量的低8位
然后是是 0---7 位
然后是 8---15
然后是 16---32
4 实现inw 指令。
static inline uint16_t inw(uint16_t port) {
uint16_t rv;
__asm__ __volatile__("in %1, %0" : "=a" (rv) : "dN" (port));
return rv;
}
5 为什么要读取两次呢?
读取两次 是因为 这里是 LBA48 而不是 LBA24