Enable lto and move naked assembly functions to own files
diff --git a/limine.bin b/limine.bin
index 90577a52..1bf49b19 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/src/Makefile b/src/Makefile
index 27e1c32f..0679154e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
CC = ../toolchain/bin/i386-elf-gcc
LD = ../toolchain/bin/i386-elf-gcc
-CFLAGS = -Os -pipe -Wall -Wextra
+CFLAGS = -flto -Os -pipe -Wall -Wextra
INTERNAL_CFLAGS = \
-std=gnu99 \
@@ -15,7 +15,7 @@ INTERNAL_CFLAGS = \
-I. \
-Wno-address-of-packed-member
-LDFLAGS = -O2
+LDFLAGS = -flto -Os
INTERNAL_LDFLAGS = \
-nostdlib \
@@ -27,7 +27,8 @@ INTERNAL_LDFLAGS = \
.PHONY: all clean
C_FILES := $(shell find ./ -type f -name '*.c' | sort)
-OBJ := $(C_FILES:.c=.o)
+ASM_FILES := $(shell find ./ -type f -name '*.asm' | grep -v bootsect | sort)
+OBJ := $(C_FILES:.c=.o) $(ASM_FILES:.asm=.o)
all: limine.bin
@@ -38,5 +39,8 @@ limine.bin: $(OBJ)
%.o: %.c
$(CC) $(CFLAGS) $(INTERNAL_CFLAGS) -c $< -o $@
+%.o: %.asm
+ nasm $< -f elf32 -o $@
+
clean:
rm -f $(OBJ)
diff --git a/src/lib/blib.c b/src/lib/blib.c
index 6f598cd3..7fab85c8 100644
--- a/src/lib/blib.c
+++ b/src/lib/blib.c
@@ -68,127 +68,6 @@ void *balloc_aligned(size_t count, size_t alignment) {
return ret;
}
-__attribute__((used)) static uint32_t int_08_ticks_counter;
-
-__attribute__((naked)) static void int_08_isr(void) {
- ASM_BASIC(
- ".code16\n\t"
- "inc dword ptr cs:[int_08_ticks_counter]\n\t"
- "int 0x40\n\t" // call callback
- "iret\n\t"
- ".code32\n\t"
- );
-}
-
-uint32_t *ivt = 0; // this variable is not static else gcc will optimise the
- // 0 ptr to a ud2
-
-__attribute__((used)) static void hook_int_08(void) {
- ivt[0x40] = ivt[0x08]; // int 0x40 is callback interrupt
- ivt[0x08] = (uint16_t)(size_t)int_08_isr;
-}
-
-__attribute__((used)) static void dehook_int_08(void) {
- ivt[0x08] = ivt[0x40];
-}
-
-// This is a dirty hack but we need to execute this full function in real mode
-__attribute__((naked))
-int pit_sleep_and_quit_on_keypress(uint32_t ticks) {
- ASM_BASIC(
- "call hook_int_08\n\t"
-
- // pit_ticks in edx
- "mov edx, dword ptr ss:[esp+4]\n\t"
-
- "lea ecx, int_08_ticks_counter\n\t"
-
- "mov dword ptr ds:[ecx], 0\n\t"
-
- // Save non-scratch GPRs
- "push ebx\n\t"
- "push esi\n\t"
- "push edi\n\t"
- "push ebp\n\t"
-
- // Jump to real mode
- FARJMP32("0x08", "1f")
- "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"
- 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"
- "mov ss, ax\n\t"
-
- "sti\n\t"
-
- "10:\n\t"
-
- "cmp dword ptr ds:[ecx], edx\n\t"
- "je 30f\n\t" // out on timeout
-
- "push ecx\n\t"
- "push edx\n\t"
- "mov ah, 0x01\n\t"
- "xor al, al\n\t"
- "int 0x16\n\t"
- "pop edx\n\t"
- "pop ecx\n\t"
-
- "jz 10b\n\t" // loop
-
- // on keypress
- "xor ax, ax\n\t"
- "int 0x16\n\t"
- "mov eax, 1\n\t"
- "jmp 20f\n\t" // out
-
- "30:\n\t" // out on timeout
- "xor eax, eax\n\t"
-
- "20:\n\t"
-
- "cli\n\t"
-
- // Jump back to pmode
- "mov ebx, cr0\n\t"
- "or bl, 1\n\t"
- "mov cr0, ebx\n\t"
- FARJMP16("0x18", "1f")
- "1: .code32\n\t"
- "mov bx, 0x20\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"
-
- // Restore non-scratch GPRs
- "pop ebp\n\t"
- "pop edi\n\t"
- "pop esi\n\t"
- "pop ebx\n\t"
-
- // Exit
- "push eax\n\t"
- "call dehook_int_08\n\t"
- "pop eax\n\t"
- "ret\n\t"
- );
-}
-
uint64_t strtoui(const char *s) {
uint64_t n = 0;
while (*s)
diff --git a/src/lib/builtins.asm b/src/lib/builtins.asm
new file mode 100644
index 00000000..924cbe16
--- /dev/null
+++ b/src/lib/builtins.asm
@@ -0,0 +1,75 @@
+section .text
+
+global memcpy
+memcpy:
+ push esi
+ push edi
+ mov eax, dword [esp+12]
+ mov edi, eax
+ mov esi, dword [esp+16]
+ mov ecx, dword [esp+20]
+ rep movsb
+ pop edi
+ pop esi
+ ret
+
+global memset
+memset:
+ push edi
+ mov edx, dword [esp+8]
+ mov edi, edx
+ mov eax, dword [esp+12]
+ mov ecx, dword [esp+16]
+ rep stosb
+ mov eax, edx
+ pop edi
+ ret
+
+global memmove
+memmove:
+ push esi
+ push edi
+ mov eax, dword [esp+12]
+ mov edi, eax
+ mov esi, dword [esp+16]
+ mov ecx, dword [esp+20]
+
+ cmp edi, esi
+ ja .copy_backwards
+
+ rep movsb
+ jmp .done
+
+ .copy_backwards:
+ lea edi, [edi+ecx-1]
+ lea esi, [esi+ecx-1]
+ std
+ rep movsb
+ cld
+
+ .done:
+ pop edi
+ pop esi
+ ret
+
+global memcmp
+memcmp:
+ push esi
+ push edi
+ mov edi, dword [esp+12]
+ mov esi, dword [esp+16]
+ mov ecx, dword [esp+20]
+ repe cmpsb
+ jecxz .equal
+ mov al, byte [edi-1]
+ sub al, byte [esi-1]
+ movsx eax, al
+ jmp .done
+
+ .equal:
+ mov eax, ecx
+
+ .done:
+ pop edi
+ pop esi
+ ret
diff --git a/src/lib/libc.c b/src/lib/libc.c
index d8038002..11b46fc3 100644
--- a/src/lib/libc.c
+++ b/src/lib/libc.c
@@ -17,90 +17,6 @@ int tolower(int c) {
return c;
}
-__attribute__((naked))
-void *memcpy(void *dest, const void *src, size_t n) {
- ASM_BASIC(
- "push esi\n\t"
- "push edi\n\t"
- "mov eax, dword ptr [esp+12]\n\t"
- "mov edi, eax\n\t"
- "mov esi, dword ptr [esp+16]\n\t"
- "mov ecx, dword ptr [esp+20]\n\t"
- "rep movsb\n\t"
- "pop edi\n\t"
- "pop esi\n\t"
- "ret\n\t"
- );
-}
-
-__attribute__((naked))
-void *memset(void *s, int c, size_t n) {
- ASM_BASIC(
- "push edi\n\t"
- "mov edx, dword ptr [esp+8]\n\t"
- "mov edi, edx\n\t"
- "mov eax, dword ptr [esp+12]\n\t"
- "mov ecx, dword ptr [esp+16]\n\t"
- "rep stosb\n\t"
- "mov eax, edx\n\t"
- "pop edi\n\t"
- "ret\n\t"
- );
-}
-
-__attribute__((naked))
-void *memmove(void *dest, const void *src, size_t n) {
- ASM_BASIC(
- "push esi\n\t"
- "push edi\n\t"
- "mov eax, dword ptr [esp+12]\n\t"
- "mov edi, eax\n\t"
- "mov esi, dword ptr [esp+16]\n\t"
- "mov ecx, dword ptr [esp+20]\n\t"
-
- "cmp edi, esi\n\t"
- "ja 1f\n\t"
-
- "rep movsb\n\t"
- "jmp 2f\n\t"
-
- "1:\n\t"
- "lea edi, [edi+ecx-1]\n\t"
- "lea esi, [esi+ecx-1]\n\t"
- "std\n\t"
- "rep movsb\n\t"
- "cld\n\t"
-
- "2:\n\t"
- "pop edi\n\t"
- "pop esi\n\t"
- "ret\n\t"
- );
-}
-
-__attribute__((naked))
-int memcmp(const void *s1, const void *s2, size_t n) {
- ASM_BASIC(
- "push esi\n\t"
- "push edi\n\t"
- "mov edi, dword ptr [esp+12]\n\t"
- "mov esi, dword ptr [esp+16]\n\t"
- "mov ecx, dword ptr [esp+20]\n\t"
- "repe cmpsb\n\t"
- "jecxz 1f\n\t"
- "mov al, byte ptr [edi-1]\n\t"
- "sub al, byte ptr [esi-1]\n\t"
- "movsx eax, al\n\t"
- "jmp 2f\n\t"
- "1:\n\t"
- "mov eax, ecx\n\t"
- "2:\n\t"
- "pop edi\n\t"
- "pop esi\n\t"
- "ret\n\t"
- );
-}
-
char *strcpy(char *dest, const char *src) {
size_t i;
diff --git a/src/lib/part.c b/src/lib/part.c
index f9952712..a2cf71a4 100644
--- a/src/lib/part.c
+++ b/src/lib/part.c
@@ -93,22 +93,22 @@ struct mbr_entry {
} __attribute__((packed));
static int mbr_get_part(struct part *ret, int drive, int partition) {
- // Variables.
+ // Check if actually valid mbr
+ uint16_t hint;
+ read(drive, &hint, 444, sizeof(uint16_t));
+ if (hint && hint != 0x5a5a)
+ return INVALID_TABLE;
+
struct mbr_entry entry;
- const size_t entry_address = 0x1be + sizeof(struct mbr_entry) * partition;
+ size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
- // Read the entry of the MBR.
- int r;
- if ((r = read(drive, &entry, entry_address, sizeof(struct mbr_entry)))) {
+ int r = read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
+ if (r)
return r;
- }
- // Check if the partition exists, fail if it doesnt.
- if (entry.type == 0) {
+ if (entry.type == 0)
return NO_PARTITION;
- }
- // Assign the final fields and return.
ret->first_sect = entry.first_sect;
ret->sect_count = entry.sect_count;
return 0;
diff --git a/src/lib/real.asm b/src/lib/real.asm
new file mode 100644
index 00000000..5b815aa6
--- /dev/null
+++ b/src/lib/real.asm
@@ -0,0 +1,118 @@
+section .text
+
+global rm_int
+rm_int:
+ ; Self-modifying code: int $int_no
+ mov al, byte [esp+4]
+ mov byte [.int_no], al
+
+ ; Save out_regs
+ mov eax, dword [esp+8]
+ mov dword [.out_regs], eax
+
+ ; Save in_regs
+ mov eax, dword [esp+12]
+ mov dword [.in_regs], eax
+
+ ; Save GDT in case BIOS overwrites it
+ sgdt [.gdt]
+
+ ; Save non-scratch GPRs
+ push ebx
+ push esi
+ push edi
+ push ebp
+
+ ; Jump to real mode
+ jmp 0x08:.bits16
+ .bits16:
+ bits 16
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov eax, cr0
+ and al, 0xfe
+ mov cr0, eax
+ jmp 0x00:.cszero
+ .cszero:
+ xor ax, ax
+ mov ss, ax
+
+ ; Load in_regs
+ mov dword [ss:.esp], esp
+ mov esp, dword [ss:.in_regs]
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ popfd
+ pop ebp
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ mov esp, dword [ss:.esp]
+
+ sti
+
+ ; Indirect interrupt call
+ db 0xcd
+ .int_no:
+ db 0
+
+ cli
+
+ ; Load out_regs
+ mov dword [ss:.esp], esp
+ mov esp, dword [ss:.out_regs]
+ lea esp, [esp + 10*4]
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+ push edi
+ push ebp
+ pushfd
+ push ds
+ push es
+ push fs
+ push gs
+ mov esp, dword [ss:.esp]
+
+ ; Restore GDT
+ lgdt [ss:.gdt]
+
+ ; Jump back to pmode
+ mov eax, cr0
+ or al, 1
+ mov cr0, eax
+ jmp 0x18:.bits32
+ .bits32:
+ bits 32
+ mov ax, 0x20
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ; Restore non-scratch GPRs
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+
+ ; Exit
+ ret
+
+align 16
+ .esp: dd 0
+ .out_regs: dd 0
+ .in_regs: dd 0
+ .gdt: dq 0
diff --git a/src/lib/real.c b/src/lib/real.c
deleted file mode 100644
index e4b5c6cf..00000000
--- a/src/lib/real.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <stdint.h>
-#include <lib/real.h>
-#include <lib/asm.h>
-
-__attribute__((naked))
-void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
- ASM_BASIC(
- // Self-modifying code: int $int_no
- "mov al, byte ptr ss:[esp+4]\n\t"
- "mov byte ptr ds:[3f], al\n\t"
-
- // Save out_regs
- "mov eax, dword ptr ss:[esp+8]\n\t"
- "mov dword ptr ds:[6f], eax\n\t"
-
- // Save in_regs
- "mov eax, dword ptr ss:[esp+12]\n\t"
- "mov dword ptr ds:[7f], eax\n\t"
-
- // Save GDT in case BIOS overwrites it
- "sgdt [8f]\n\t"
-
- // Save non-scratch GPRs
- "push ebx\n\t"
- "push esi\n\t"
- "push edi\n\t"
- "push ebp\n\t"
-
- // Jump to real mode
- FARJMP32("0x08", "1f")
- "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"
- FARJMP16("0", "1f")
- "1:\n\t"
- "xor ax, ax\n\t"
- "mov ss, ax\n\t"
-
- // Load in_regs
- "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"
- "pop esi\n\t"
- "pop edx\n\t"
- "pop ecx\n\t"
- "pop ebx\n\t"
- "pop eax\n\t"
- "mov esp, dword ptr ss:[5f]\n\t"
-
- "sti\n\t"
-
- // Indirect interrupt call
- ".byte 0xcd\n\t"
- "3: .byte 0\n\t"
-
- "cli\n\t"
-
- // Load out_regs
- "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"
- "push edx\n\t"
- "push esi\n\t"
- "push edi\n\t"
- "push ebp\n\t"
- "pushfd\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 ss:[8f]\n\t"
-
- // Jump back to pmode
- "mov eax, cr0\n\t"
- "or al, 1\n\t"
- "mov cr0, eax\n\t"
- FARJMP16("0x18", "1f")
- "1: .code32\n\t"
- "mov ax, 0x20\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"
-
- // Restore non-scratch GPRs
- "pop ebp\n\t"
- "pop edi\n\t"
- "pop esi\n\t"
- "pop ebx\n\t"
-
- // Exit
- "ret\n\t"
-
- // ESP
- "5: .long 0\n\t"
- // out_regs
- "6: .long 0\n\t"
- // in_regs
- "7: .long 0\n\t"
- // gdt
- "8: .long 0\n\t"
- " .long 0\n\t"
- );
-}
diff --git a/src/lib/sleep.asm b/src/lib/sleep.asm
new file mode 100644
index 00000000..9f0bcef5
--- /dev/null
+++ b/src/lib/sleep.asm
@@ -0,0 +1,105 @@
+section .text
+
+int_08_ticks_counter: dd 0
+
+int_08_isr:
+ bits 16
+ inc dword [cs:int_08_ticks_counter]
+ int 0x80 ; call callback
+ iret
+ bits 32
+
+global pit_sleep_and_quit_on_keypress
+pit_sleep_and_quit_on_keypress:
+ ; Hook int 0x08
+ mov edx, dword [0x08*4]
+ mov dword [0x80*4], edx
+ mov edx, int_08_isr
+ mov dword [0x08*4], int_08_isr
+
+ ; pit_ticks in edx
+ mov edx, dword [esp+4]
+
+ mov dword [int_08_ticks_counter], 0
+
+ ; Save non-scratch GPRs
+ push ebx
+ push esi
+ push edi
+ push ebp
+
+ ; Jump to real mode
+ jmp 0x08:.bits16
+ .bits16:
+ bits 16
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov eax, cr0
+ and al, 0xfe
+ mov cr0, eax
+ jmp 0x00:.cszero
+ .cszero:
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ sti
+
+ .loop:
+ cmp dword [int_08_ticks_counter], edx
+ je .timeout
+
+ push ecx
+ push edx
+ mov ah, 0x01
+ xor al, al
+ int 0x16
+ pop edx
+ pop ecx
+
+ jz .loop
+
+ ; on keypress
+ xor ax, ax
+ int 0x16
+ mov eax, 1
+ jmp .done
+
+ .timeout:
+ xor eax, eax
+
+ .done:
+ cli
+
+ ; Jump back to pmode
+ mov ebx, cr0
+ or bl, 1
+ mov cr0, ebx
+ jmp 0x18:.bits32
+ .bits32:
+ bits 32
+ mov bx, 0x20
+ mov ds, bx
+ mov es, bx
+ mov fs, bx
+ mov gs, bx
+ mov ss, bx
+
+ ; Restore non-scratch GPRs
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+
+ ; Dehook int 0x08
+ mov edx, dword [0x80*4]
+ mov dword [0x08*4], edx
+
+ ret
