:: commit a82dc582c71203b6e27655a1a0a654bb276e2139

mintsuki <mintsuki@protonmail.com> — 2020-10-18 04:23

parents: a9864a0ab4

Add BIOS drive indexing

diff --git a/limine.bin b/limine.bin
index b9d1a300..5069e1e8 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/Makefile b/stage2/Makefile
index 48b4d9a8..8ac4c472 100644
--- a/stage2/Makefile
+++ b/stage2/Makefile
@@ -2,7 +2,8 @@ CC = i386-elf-gcc
 LD = i386-elf-gcc
 OBJCOPY = i386-elf-objcopy
 
-CFLAGS = -flto -Os -pipe -Wall -Wextra -Werror
+WERROR = -Werror
+CFLAGS = -flto -Os -pipe -Wall -Wextra $(WERROR)
 
 INTERNAL_CFLAGS = \
 	-std=gnu11 \
diff --git a/stage2/drivers/disk.h b/stage2/drivers/disk.h
index daacbf56..843d0fac 100644
--- a/stage2/drivers/disk.h
+++ b/stage2/drivers/disk.h
@@ -5,6 +5,17 @@
 #include <stdint.h>
 #include <lib/part.h>
 
+struct bios_drive_params {
+    uint16_t buf_size;
+    uint16_t info_flags;
+    uint32_t cyl;
+    uint32_t heads;
+    uint32_t sects;
+    uint64_t lba_count;
+    uint16_t bytes_per_sect;
+    uint32_t edd;
+} __attribute__((packed));
+
 int read(int drive, void *buffer, uint64_t loc, uint64_t count);
 int read_partition(int drive, struct part *part, void *buffer, uint64_t loc, uint64_t count);
 
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index f6b018a1..d2d2e1a6 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -168,7 +168,7 @@ bool string_to_guid(struct guid *guid, const char *s) {
     guid_convert_le_cluster((uint8_t *)guid + 4,  s + 9,  4);
     guid_convert_le_cluster((uint8_t *)guid + 6,  s + 14, 4);
     guid_convert_be_cluster((uint8_t *)guid + 8,  s + 19, 4);
-    guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 16);
+    guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
 
     return true;
 }
diff --git a/stage2/lib/part.c b/stage2/lib/part.c
index 9c3fe988..a3d764e2 100644
--- a/stage2/lib/part.c
+++ b/stage2/lib/part.c
@@ -4,9 +4,13 @@
 #include <drivers/disk.h>
 #include <lib/libc.h>
 #include <lib/blib.h>
+#include <lib/real.h>
+#include <lib/print.h>
+#include <mm/pmm.h>
 
 #define NO_PARTITION  (-1)
 #define INVALID_TABLE (-2)
+#define END_OF_TABLE  (-3)
 
 struct gpt_table_header {
     // the head
@@ -53,12 +57,14 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
 
     // check the header
     // 'EFI PART'
-    if (strncmp(header.signature, "EFI PART", 8)) return INVALID_TABLE;
-    if (header.revision != 0x00010000) return NO_PARTITION;
+    if (strncmp(header.signature, "EFI PART", 8))
+        return INVALID_TABLE;
+    if (header.revision != 0x00010000)
+        return END_OF_TABLE;
 
     // parse the entries if reached here
     if ((uint32_t)partition >= header.number_of_partition_entries)
-        return NO_PARTITION;
+        return END_OF_TABLE;
 
     struct gpt_entry entry = {0};
     read(drive, &entry,
@@ -71,6 +77,7 @@ static int gpt_get_part(struct part *ret, int drive, int partition) {
 
     ret->first_sect = entry.starting_lba;
     ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
+    ret->guid       = entry.unique_partition_guid;
 
     return 0;
 }
@@ -91,6 +98,12 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
     if (hint && hint != 0x5a5a)
         return INVALID_TABLE;
 
+    if (partition > 3)
+        return END_OF_TABLE;
+
+    uint32_t disk_signature;
+    read(drive, &disk_signature, 440, sizeof(uint32_t));
+
     struct mbr_entry entry;
     size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
 
@@ -103,6 +116,13 @@ static int mbr_get_part(struct part *ret, int drive, int partition) {
 
     ret->first_sect = entry.first_sect;
     ret->sect_count = entry.sect_count;
+
+    // We use the same method of generating GUIDs for MBR partitions as Linux
+    struct guid empty_guid = {0};
+    ret->guid   = empty_guid;
+    ret->guid.a = disk_signature;
+    ret->guid.b = (partition + 1) << 8;
+
     return 0;
 }
 
@@ -119,3 +139,58 @@ int get_part(struct part *part, int drive, int partition) {
 
     return -1;
 }
+
+static struct part *part_index = NULL;
+static size_t part_index_i = 0;
+
+void part_create_index(void) {
+    part_index = conv_mem_alloc(0);
+
+    for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
+        struct rm_regs r = {0};
+        struct bios_drive_params drive_params;
+
+        r.eax = 0x4800;
+        r.edx = drive;
+        r.ds  = rm_seg(&drive_params);
+        r.esi = rm_off(&drive_params);
+
+        drive_params.buf_size = sizeof(struct bios_drive_params);
+
+        rm_int(0x13, &r, &r);
+
+        if (r.eflags & EFLAGS_CF)
+            continue;
+
+        print("Found BIOS drive %x\n", drive);
+        print(" ... %X total %u-byte sectors\n",
+              drive_params.lba_count, drive_params.bytes_per_sect);
+
+        size_t part_count = 0;
+        for (int part = 0; ; part++) {
+            struct part p;
+            int ret = get_part(&p, drive, part);
+
+            if (ret == END_OF_TABLE)
+                break;
+            if (ret == NO_PARTITION)
+                continue;
+
+            part_count++;
+        }
+
+        part_index = conv_mem_alloc(sizeof(struct part) * part_count);
+
+        for (int part = 0; ; part++) {
+            struct part p;
+            int ret = get_part(&p, drive, part);
+
+            if (ret == END_OF_TABLE)
+                break;
+            if (ret == NO_PARTITION)
+                continue;
+
+            part_index[part_index_i++] = p;
+        }
+    }
+}
diff --git a/stage2/lib/part.h b/stage2/lib/part.h
index ad142af5..135c32f5 100644
--- a/stage2/lib/part.h
+++ b/stage2/lib/part.h
@@ -2,12 +2,17 @@
 #define __LIB__PART_H__
 
 #include <stdint.h>
+#include <stdbool.h>
+#include <lib/blib.h>
 
 struct part {
-	uint64_t first_sect;
-	uint64_t sect_count;
+    uint64_t first_sect;
+    uint64_t sect_count;
+    struct guid guid;
 };
 
 int get_part(struct part *part, int drive, int partition);
 
+void part_create_index(void);
+
 #endif
diff --git a/stage2/main.c b/stage2/main.c
index 801b055d..ae754e1d 100644
--- a/stage2/main.c
+++ b/stage2/main.c
@@ -32,6 +32,8 @@ void entry(uint8_t _boot_drive) {
 
     print("Boot drive: %x\n", boot_drive);
 
+    part_create_index();
+
     // Look for config file.
     print("Searching for config file...\n");
     struct part parts[4];
tab: 248 wrap: offon