for (int i = 0; i < 4; i++) {
part->flags = (uint8_t)p[0];
+ part->type = (uint8_t)p[4];
part->lba_start = *((uint32_t *)(p + 8));
- part->lba_end = *((uint32_t *)(p + 12));
- part->lba_end += part->lba_start;
+ uint32_t size = *((uint32_t *)(p + 12));
+ part->lba_end = part->lba_start + size;
- printk("part[%d] %02X %u %u\n", i, part->flags, part->lba_start, part->lba_end);
+ printk("part[%d] %02X %02X %u %u\n", i, part->flags, part->type, part->lba_start,
+ part->lba_end == 0 ? 0 : part->lba_end - 1);
// 这里应该再判断一下part->flags,如果是扩展分区还需要再读取
// 先这样实现
}
}
+// ext_lba: 在MBR中的扩展分区记录里的偏移地址
+// offset_lba: 在扩展分区记录里的扩展分区的偏移地址
+void read_partition_table(ide_drive_t *drv, uint32_t ext_lba, uint32_t offset_lba, int depth) {
+ uint32_t base = depth <= 1 ? 0 : ext_lba;
+
+ disk_request_t r;
+ char *sect = kmalloc(SECT_SIZE, 0);
+ r.dev = MAKE_DEV(DEV_MAJOR_IDE0 + (drv->drv_no >> 1), drv->drv_no % 2);
+ r.command = DISK_REQ_READ;
+ r.pos = base + offset_lba;
+ r.count = 1;
+ r.buf = sect;
+ send_disk_request(&r);
+
+ ide_part_t *part = 0;
+ uint32_t part_id = 0;
+ if (depth == 0) {
+ // MBR里的分区占据 [1,4]
+ part_id = 1;
+ } else {
+ // 扩展分区里的逻辑分区占据 [5,MAX_IDE_PARTIONS)
+ part_id = 5 + depth - 1;
+ }
+
+ const char *p = sect + PARTITION_TABLE_OFFSET;
+ for (int i = 0; i < 4; i++) {
+ if (part_id >= MAX_IDE_PARTIONS) {
+ break;
+ }
+ part = drv->partions + part_id;
+ part->flags = (uint8_t)p[0];
+ part->type = (uint8_t)p[4];
+ part->lba_start = *((uint32_t *)(p + 8));
+ uint32_t size = *((uint32_t *)(p + 12));
+ part->lba_end = part->lba_start + size;
+ part->lba_end = size;
+
+ if (part->type == 0x00) {
+ continue;
+ }
+
+ if (part->type == 0x05) {
+ ext_lba = ext_lba != 0 ? ext_lba : part->lba_start;
+ read_partition_table(drv, ext_lba, part->lba_start, depth + 1);
+ } else {
+ printk("part[%d] %02X %u %u\n", part_id + drv->drv_no * MAX_IDE_PARTIONS, part->type, part->lba_start,
+ size);
+ }
+
+ part_id++;
+
+ // 每个分区16个字节
+ p += 16;
+ }
+
+ kfree(sect);
+}
+
void ide_read_partions() {
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
ide_drive_t *drv = ide_drives + i;
if (0 == drv->present) {
continue;
}
- disk_request_t r;
- char *sect = kmalloc(SECT_SIZE, 0);
- r.dev = MAKE_DEV(DEV_MAJOR_IDE0, 0); // IDE0 0代表整个master硬盘
- r.command = DISK_REQ_READ;
- r.pos = 0;
- r.count = 1;
- r.buf = sect;
- send_disk_request(&r);
- ata_read_partions(drv->partions + 1, sect);
- kfree(sect);
+
+ printk("read ide drive %u\n", drv->drv_no);
+ read_partition_table(drv, 0, 0, 0);
+ printk("--------------\n");
}
}