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);
