:: commit 039196b0f44459f73fb6ca34ca7c2ca16a645529

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

parents: 764dccadf1

BIOS disk driver: do not make assumptions about sector size being 512 bytes

diff --git a/limine.bin b/limine.bin
index 2d442840..05ca393b 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/drivers/disk.c b/stage2/drivers/disk.c
index bc888e03..693a3363 100644
--- a/stage2/drivers/disk.c
+++ b/stage2/drivers/disk.c
@@ -8,9 +8,8 @@
 #include <lib/print.h>
 #include <mm/pmm.h>
 
-#define SECTOR_SIZE 512
 #define BLOCK_SIZE_IN_SECTORS 16
-#define BLOCK_SIZE  (SECTOR_SIZE * BLOCK_SIZE_IN_SECTORS)
+#define BLOCK_SIZE (sector_size * BLOCK_SIZE_IN_SECTORS)
 
 #define CACHE_INVALID (~((uint64_t)0))
 
@@ -27,7 +26,7 @@ struct dap {
 
 static struct dap *dap = NULL;
 
-static int cache_block(int drive, uint64_t block) {
+static int cache_block(int drive, uint64_t block, int sector_size) {
     if (block == cached_block)
         return 0;
 
@@ -55,8 +54,6 @@ static int cache_block(int drive, uint64_t block) {
     if (r.eflags & EFLAGS_CF) {
         int ah = (r.eax >> 8) & 0xff;
         panic("Disk error %x. Drive %x, LBA %x.\n", ah, drive, dap->lba);
-        cached_block = CACHE_INVALID;
-        return ah;
     }
 
     cached_block = block;
@@ -65,12 +62,31 @@ static int cache_block(int drive, uint64_t block) {
 }
 
 int read(int drive, void *buffer, uint64_t loc, uint64_t count) {
+    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) {
+        int ah = (r.eax >> 8) & 0xff;
+        panic("Disk error %x. Drive %x.\n", ah, drive);
+    }
+
+    int sector_size = drive_params.bytes_per_sect;
+
     uint64_t progress = 0;
     while (progress < count) {
         uint64_t block = (loc + progress) / BLOCK_SIZE;
 
         int ret;
-        if ((ret = cache_block(drive, block)))
+        if ((ret = cache_block(drive, block, sector_size)))
             return ret;
 
         uint64_t chunk = count - progress;
tab: 248 wrap: offon