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