]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
partition: add MBR parser (Etapa 2)
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 03:56:35 +0000 (00:56 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 04:02:35 +0000 (01:02 -0300)
- Added mbr_partition_entry_t structure for 16-byte partition entries
- Implemented partition_scan_mbr() to read and parse MBR sector
- Validates MBR signature (0xAA55) at offset 510
- Parses 4 primary partition entries starting at offset 446
- Skips empty partitions (type 0)
- Generates partition names (e.g. hda1, vda2)
- Silently skips devices without valid MBR (no errors)
- Tests: 124/124 PASS

include/partition.h
src/kernel/init.c
src/kernel/partition.c

index 8990fba676e43b3fc59a768cf7af7d69e88bcaa2..07bdf5fa15a907949ff72dfc18acf75166fc96a6 100644 (file)
@@ -58,4 +58,17 @@ void partition_release(partition_t* part);
 /* Initialize partition subsystem lock */
 void partition_init_lock(void);
 
+/* MBR partition entry structure (16 bytes) */
+typedef struct __attribute__((packed)) {
+    uint8_t boot_indicator;
+    uint8_t chs_start[3];
+    uint8_t partition_type;
+    uint8_t chs_end[3];
+    uint32_t start_lba;
+    uint32_t sector_count;
+} mbr_partition_entry_t;
+
+/* Scan a block device for MBR partitions and register them */
+int partition_scan_mbr(block_device_t* bdev);
+
 #endif /* PARTITION_H */
index b004ab8bf8fccc095abc53b2d8a39e6acab8eb76..2591986bf5c9980c058eeade0b4cace0af442018 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "ata_pio.h"
 #include "blockdev.h"
+#include "partition.h"
 #include "hal/mm.h"
 #include "heap.h"
 #include "kernel/cmdline.h"
@@ -290,6 +291,9 @@ int init_start(const struct boot_info* bi) {
     blockdev_init_lock();
     blockdev_register_ata();
 
+    /* Initialize partition subsystem (scan will be done later) */
+    partition_init_lock();
+
     /* If root= is specified on the kernel command line, mount that device
      * as the disk root filesystem.  The filesystem type is auto-detected
      * by trying each supported type in order.
index 46b0eac392c15826ef8c05783be59dc501d50522..51f59457051d5b6cd02bc5deca40f8617ee76ab9 100644 (file)
@@ -94,3 +94,74 @@ void partition_release(partition_t* part) {
         part->refcount--;
     spin_unlock_irqrestore(&g_partition_lock, flags);
 }
+
+/* MBR signature at offset 510-511 */
+#define MBR_SIGNATURE 0xAA55
+
+int partition_scan_mbr(block_device_t* bdev) {
+    if (!bdev) return -EINVAL;
+
+    /* Skip devices with unknown sector count (likely not present) */
+    if (bdev->sector_count == 0) {
+        return 0;
+    }
+
+    /* Read MBR sector (LBA 0) */
+    uint8_t mbr_sector[512];
+    int rc = blockdev_read(bdev, 0, mbr_sector);
+    if (rc < 0) {
+        return 0;
+    }
+
+    /* Check MBR signature */
+    uint16_t signature = *(uint16_t*)(mbr_sector + 510);
+    if (signature != MBR_SIGNATURE) {
+        return 0;
+    }
+
+    /* Parse 4 primary partition entries (starting at offset 446) */
+    mbr_partition_entry_t* entries = (mbr_partition_entry_t*)(mbr_sector + 446);
+    int partitions_found = 0;
+
+    for (int i = 0; i < 4; i++) {
+        mbr_partition_entry_t* entry = &entries[i];
+
+        /* Skip empty partitions (type 0) */
+        if (entry->partition_type == PART_TYPE_EMPTY)
+            continue;
+
+        /* Create partition structure */
+        partition_t part;
+        memset(&part, 0, sizeof(part));
+
+        part.parent = bdev;
+        part.start_lba = entry->start_lba;
+        part.sector_count = entry->sector_count;
+        part.partition_type = entry->partition_type;
+        part.partition_number = i + 1; /* 1-4 for primary partitions */
+        part.refcount = 0;
+
+        /* Generate partition name (e.g. "hda1", "vda2") */
+        strcpy(part.name, bdev->name);
+        int name_len = strlen(part.name);
+        if (name_len < (int)sizeof(part.name) - 2) {
+            part.name[name_len] = '0' + (i + 1);
+            part.name[name_len + 1] = '\0';
+        }
+
+        /* Register the partition */
+        rc = partition_register(&part);
+        if (rc < 0) {
+            continue;
+        }
+
+        kprintf("[PARTITION] %s: type=0x%02X, start_lba=%u, sectors=%u\n",
+                part.name, part.partition_type, part.start_lba, part.sector_count);
+        partitions_found++;
+    }
+
+    if (partitions_found > 0) {
+        kprintf("[PARTITION] Scanned %s: found %d partition(s)\n", bdev->name, partitions_found);
+    }
+    return partitions_found;
+}