:: commit b41fa7e20411500be841ccd0553f5b39d38019d5

mintsuki <mintsuki@protonmail.com> — 2020-09-25 20:57

parents: c657e86cc8

Fix bugs related to handling real mode switch in inline assembly sections; reenable LTO as that fixes it

diff --git a/decompressor/Makefile b/decompressor/Makefile
index 9f48cf50..642bca50 100644
--- a/decompressor/Makefile
+++ b/decompressor/Makefile
@@ -2,7 +2,7 @@ CC = i386-elf-gcc
 LD = i386-elf-gcc
 OBJCOPY = i386-elf-objcopy
 
-CFLAGS = -Os -pipe -Wall -Wextra
+CFLAGS = -flto -Os -pipe -Wall -Wextra
 
 INTERNAL_CFLAGS = \
 	-std=gnu11 \
@@ -20,7 +20,7 @@ INTERNAL_CFLAGS = \
 	-MMD \
 	-I.
 
-LDFLAGS = -Os
+LDFLAGS = -flto -Os
 
 INTERNAL_LDFLAGS = \
 	-lgcc \
diff --git a/limine.bin b/limine.bin
index de6fb5bf..0fb21da4 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/Makefile b/stage2/Makefile
index 80cf9a6a..f2051cfe 100644
--- a/stage2/Makefile
+++ b/stage2/Makefile
@@ -2,7 +2,7 @@ CC = i386-elf-gcc
 LD = i386-elf-gcc
 OBJCOPY = i386-elf-objcopy
 
-CFLAGS = -Os -pipe -Wall -Wextra
+CFLAGS = -flto -Os -pipe -Wall -Wextra
 
 INTERNAL_CFLAGS = \
 	-std=gnu11 \
@@ -22,7 +22,7 @@ INTERNAL_CFLAGS = \
 	-I. \
 	-I..
 
-LDFLAGS = -Os
+LDFLAGS = -flto -Os
 
 INTERNAL_LDFLAGS = \
 	-lgcc \
diff --git a/stage2/protos/chainload.c b/stage2/protos/chainload.c
index 26f9e546..f4ee639d 100644
--- a/stage2/protos/chainload.c
+++ b/stage2/protos/chainload.c
@@ -7,34 +7,8 @@
 #include <drivers/disk.h>
 #include <lib/term.h>
 
-void chainload(void) {
-    int part; {
-        char buf[32];
-        if (!config_get_value(buf, 0, 32, "PARTITION")) {
-            part = -1;
-        } else {
-            part = (int)strtoui(buf);
-        }
-    }
-    int drive; {
-        char buf[32];
-        if (!config_get_value(buf, 0, 32, "DRIVE")) {
-            panic("DRIVE not specified");
-        }
-        drive = (int)strtoui(buf);
-    }
-
-    term_deinit();
-
-    if (part != -1) {
-        struct part p;
-        get_part(&p, drive, part);
-
-        read_partition(drive, &p, (void *)0x7c00, 0, 512);
-    } else {
-        read(drive, (void *)0x7c00, 0, 512);
-    }
-
+__attribute__((section(".realmode"), used))
+static void spinup(uint8_t drive) {
     asm volatile (
         // Jump to real mode
         "jmp 0x08:1f\n\t"
@@ -65,3 +39,34 @@ void chainload(void) {
         : "memory"
     );
 }
+
+void chainload(void) {
+    int part; {
+        char buf[32];
+        if (!config_get_value(buf, 0, 32, "PARTITION")) {
+            part = -1;
+        } else {
+            part = (int)strtoui(buf);
+        }
+    }
+    int drive; {
+        char buf[32];
+        if (!config_get_value(buf, 0, 32, "DRIVE")) {
+            panic("DRIVE not specified");
+        }
+        drive = (int)strtoui(buf);
+    }
+
+    term_deinit();
+
+    if (part != -1) {
+        struct part p;
+        get_part(&p, drive, part);
+
+        read_partition(drive, &p, (void *)0x7c00, 0, 512);
+    } else {
+        read(drive, (void *)0x7c00, 0, 512);
+    }
+
+    spinup(drive);
+}
diff --git a/stage2/protos/linux.c b/stage2/protos/linux.c
index 2d9da1d1..4babd397 100644
--- a/stage2/protos/linux.c
+++ b/stage2/protos/linux.c
@@ -12,6 +12,44 @@
 #define KERNEL_LOAD_ADDR ((size_t)0x100000)
 #define INITRD_LOAD_ADDR ((size_t)0x1000000)
 
+__attribute__((section(".realmode"), used))
+static void spinup(uint16_t real_mode_code_seg, uint16_t kernel_entry_seg) {
+    asm volatile (
+        "cli\n\t"
+        "cld\n\t"
+
+        "jmp 0x08:1f\n\t"
+        "1: .code16\n\t"
+        "mov ax, 0x10\n\t"
+        "mov ds, ax\n\t"
+        "mov es, ax\n\t"
+        "mov fs, ax\n\t"
+        "mov gs, ax\n\t"
+        "mov ss, ax\n\t"
+        "mov eax, cr0\n\t"
+        "and al, 0xfe\n\t"
+        "mov cr0, eax\n\t"
+        "jmp 0x0000:1f\n\t"
+        "1:\n\t"
+        "mov ds, bx\n\t"
+        "mov es, bx\n\t"
+        "mov fs, bx\n\t"
+        "mov gs, bx\n\t"
+        "mov ss, bx\n\t"
+
+        "mov sp, 0xfdf0\n\t"
+
+        "push cx\n\t"
+        "push 0\n\t"
+        "retf\n\t"
+
+        ".code32\n\t"
+        :
+        : "b" (real_mode_code_seg), "c" (kernel_entry_seg)
+        : "memory"
+    );
+}
+
 void linux_load(char *cmdline, int boot_drive) {
     int kernel_drive; {
         char buf[32];
@@ -136,36 +174,5 @@ void linux_load(char *cmdline, int boot_drive) {
 
     term_deinit();
 
-    asm volatile (
-        "cli\n\t"
-        "cld\n\t"
-
-        "jmp 0x08:1f\n\t"
-        "1: .code16\n\t"
-        "mov ax, 0x10\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-        "mov eax, cr0\n\t"
-        "and al, 0xfe\n\t"
-        "mov cr0, eax\n\t"
-        "jmp 0x0000:1f\n\t"
-        "1:\n\t"
-        "mov ds, bx\n\t"
-        "mov es, bx\n\t"
-        "mov fs, bx\n\t"
-        "mov gs, bx\n\t"
-        "mov ss, bx\n\t"
-
-        "mov sp, 0xfdf0\n\t"
-
-        "push cx\n\t"
-        "push 0\n\t"
-        "retf\n\t"
-        :
-        : "b" (real_mode_code_seg), "c" (kernel_entry_seg)
-        : "memory"
-    );
+    spinup(real_mode_code_seg, kernel_entry_seg);
 }
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 64c178fc..42fdcdac 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -348,7 +348,7 @@ __attribute__((noreturn)) void stivale_spinup(
             : "memory"
         );
     } else if (bits == 32) {
-        asm volatile(
+        asm volatile (
             "cli\n\t"
             "cld\n\t"
 
@@ -371,7 +371,8 @@ __attribute__((noreturn)) void stivale_spinup(
             "iret\n\t"
             :
             : "b"(&entry_point), "D"(stivale_struct), "S"(&stack)
-            : "memory");
+            : "memory"
+        );
     }
     for (;;);
 }
tab: 248 wrap: offon