From: acevest Date: Sat, 14 Oct 2023 09:03:53 +0000 (+0800) Subject: 支持读取硬盘的分区表 X-Git-Url: http://zhaoyanbai.com/repos/README?a=commitdiff_plain;h=d959545c0ca683688ae9a9e5798ca3194c2ff1da;p=kernel.git 支持读取硬盘的分区表 --- diff --git a/drivers/ata.c b/drivers/ata.c index 0df04fa..4a522fe 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -75,11 +75,13 @@ void ata_read_partions(ide_part_t *part, const char *buf) { 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,如果是扩展分区还需要再读取 // 先这样实现 @@ -218,6 +220,64 @@ void ide_ata_init() { } } +// 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; @@ -226,16 +286,10 @@ void ide_read_partions() { 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"); } } diff --git a/drivers/ide.h b/drivers/ide.h index bab04db..f738519 100644 --- a/drivers/ide.h +++ b/drivers/ide.h @@ -156,6 +156,7 @@ // 分区定义 typedef struct ide_part_ { uint8_t flags; + uint8_t type; uint32_t lba_start; uint32_t lba_end; } ide_part_t; diff --git a/gdbscript b/gdbscript index 41c063e..2304377 100644 --- a/gdbscript +++ b/gdbscript @@ -8,8 +8,8 @@ # watch point #wa *0x7c00 -break *0x100000 -# break *0xC0100000 +#break *0x100000 + #handle SIGINT nostop noprint diff --git a/kernel/task_user.c b/kernel/task_user.c index 75977aa..03d381e 100644 --- a/kernel/task_user.c +++ b/kernel/task_user.c @@ -71,7 +71,7 @@ void user_task_entry() { unsigned long *p = (unsigned long *)(pa2va(current->cr3)); printd("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page); - printd("pt bss page %x %x", pt_bss_page, ring3_bss_page); + printd("pt bss page %x %x\n", pt_bss_page, ring3_bss_page); // text: 0x0800_0000 // bss: 0x3000_0000