]> Zhao Yanbai Git Server - kernel.git/commitdiff
支持读取硬盘的分区表
authoracevest <zhaoyanbai@126.com>
Sat, 14 Oct 2023 09:03:53 +0000 (17:03 +0800)
committeracevest <zhaoyanbai@126.com>
Sat, 14 Oct 2023 09:03:53 +0000 (17:03 +0800)
drivers/ata.c
drivers/ide.h
gdbscript
kernel/task_user.c

index 0df04fa82082ed6941c47fcdf0919982cb218f7c..4a522fe9ce64607c2073ce0fc087196c950a84d4 100644 (file)
@@ -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");
     }
 }
 
index bab04db81e1955e61c9c73cf667503dbf2f9df97..f73851926de9bc6fced6b77e8fc4d98a8c97fda0 100644 (file)
 // 分区定义
 typedef struct ide_part_ {
     uint8_t flags;
+    uint8_t type;
     uint32_t lba_start;
     uint32_t lba_end;
 } ide_part_t;
index 41c063e3684f79ca51488097a59102de39c19590..23043779b9e3ac7c2fb8f232f20063ca112bd6aa 100644 (file)
--- a/gdbscript
+++ b/gdbscript
@@ -8,8 +8,8 @@
 # watch point
 #wa *0x7c00
 
-break *0x100000
-# break *0xC0100000
+#break *0x100000
+
 
 #handle SIGINT nostop noprint
 
index 75977aaa511fc972a353a0fb2367e3b8c24f6560..03d381e73a76e114d9e045cb8508b61b0c2a0825 100644 (file)
@@ -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