:: commit 46f46ddd155aa4e6ab13f4886cd165cbcf45d0ad

mintsuki <mintsuki@protonmail.com> — 2020-09-02 02:39

parents: b9be2e70c1

When calling into real mode, also pass the segment registers

diff --git a/limine.bin b/limine.bin
index 5276f5f4..d36a50a5 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/src/lib/real.c b/src/lib/real.c
index 5e6cfe75..e4b5c6cf 100644
--- a/src/lib/real.c
+++ b/src/lib/real.c
@@ -40,16 +40,16 @@ void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
         "mov cr0, eax\n\t"
         FARJMP16("0", "1f")
         "1:\n\t"
-        "mov ax, 0\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
+        "xor ax, ax\n\t"
         "mov ss, ax\n\t"
 
         // Load in_regs
-        "mov dword ptr ds:[5f], esp\n\t"
-        "mov esp, dword ptr ds:[7f]\n\t"
+        "mov dword ptr ss:[5f], esp\n\t"
+        "mov esp, dword ptr ss:[7f]\n\t"
+        "pop gs\n\t"
+        "pop fs\n\t"
+        "pop es\n\t"
+        "pop ds\n\t"
         "popfd\n\t"
         "pop ebp\n\t"
         "pop edi\n\t"
@@ -58,7 +58,7 @@ void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
         "pop ecx\n\t"
         "pop ebx\n\t"
         "pop eax\n\t"
-        "mov esp, dword ptr ds:[5f]\n\t"
+        "mov esp, dword ptr ss:[5f]\n\t"
 
         "sti\n\t"
 
@@ -69,9 +69,9 @@ void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
         "cli\n\t"
 
         // Load out_regs
-        "mov dword ptr ds:[5f], esp\n\t"
-        "mov esp, dword ptr ds:[6f]\n\t"
-        "lea esp, [esp + 8*4]\n\t"
+        "mov dword ptr ss:[5f], esp\n\t"
+        "mov esp, dword ptr ss:[6f]\n\t"
+        "lea esp, [esp + 10*4]\n\t"
         "push eax\n\t"
         "push ebx\n\t"
         "push ecx\n\t"
@@ -80,10 +80,14 @@ void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
         "push edi\n\t"
         "push ebp\n\t"
         "pushfd\n\t"
-        "mov esp, dword ptr ds:[5f]\n\t"
+        "push ds\n\t"
+        "push es\n\t"
+        "push fs\n\t"
+        "push gs\n\t"
+        "mov esp, dword ptr ss:[5f]\n\t"
 
         // Restore GDT
-        "lgdt [8f]\n\t"
+        "lgdt ss:[8f]\n\t"
 
         // Jump back to pmode
         "mov eax, cr0\n\t"
diff --git a/src/lib/real.h b/src/lib/real.h
index 545cbded..e2c6843f 100644
--- a/src/lib/real.h
+++ b/src/lib/real.h
@@ -12,6 +12,10 @@
 #define EFLAGS_ZF (1 << 6)
 
 struct rm_regs {
+    uint16_t gs;
+    uint16_t fs;
+    uint16_t es;
+    uint16_t ds;
     uint32_t eflags;
     uint32_t ebp;
     uint32_t edi;
@@ -20,7 +24,7 @@ struct rm_regs {
     uint32_t ecx;
     uint32_t ebx;
     uint32_t eax;
-};
+} __attribute__((packed));
 
 void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs);
 
tab: 248 wrap: offon