summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-02-21 20:06:35 +0100
committerAnton Kling <anton@kling.gg>2024-02-21 20:06:35 +0100
commit9b475d3db3275d4c34f02161ae70ced5595a0fdb (patch)
tree0c50e4af3ce52017f295c44f6f4319e4a43de085 /kernel
parent6c9cb0bd8ceb039ce387c850e25adc6f99cfcd6f (diff)
Kernel: Remove all inline assembly.
Now the kernel does not rely upon inline assembly which is often very error prone. This also means that the kernel could probably be compiled with any c99 compiler which would help future bootstrapping.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile5
-rw-r--r--kernel/arch/i386/mmu.c26
-rw-r--r--kernel/cpu/arch_inst.h11
-rw-r--r--kernel/cpu/arch_inst.s60
-rw-r--r--kernel/cpu/gdt.c4
-rw-r--r--kernel/cpu/idt.c19
-rw-r--r--kernel/ipc.c5
-rw-r--r--kernel/kubsan.c6
-rw-r--r--kernel/lib/list.c39
-rw-r--r--kernel/lib/list.h13
-rw-r--r--kernel/libc/exit/assert.c5
-rw-r--r--kernel/log.c4
12 files changed, 151 insertions, 46 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 0cf45ec..7bdb91b 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -1,7 +1,8 @@
CC="i686-sb-gcc"
AS="i686-sb-as"
-OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o ipc.o syscalls/ipc.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o
-CFLAGS = -Ofast -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL
+OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o syscalls/ppoll.o syscalls/ftruncate.o kubsan.o syscalls/mmap.o drivers/serial.o syscalls/accept.o syscalls/bind.o syscalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o syscalls/shm.o elf.o ksbrk.o sched/scheduler.o syscalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o syscalls/msleep.o syscalls/uptime.o syscalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o syscalls/recvfrom.o math.o syscalls/sendto.o signal.o syscalls/kill.o syscalls/sigaction.o network/tcp.o drivers/ahci.o crypto/xoshiro256plusplus/xoshiro256plusplus.o syscalls/chdir.o syscalls/getcwd.o syscalls/isatty.o syscalls/randomfill.o syscalls/open.o syscalls/write.o syscalls/pwrite.o ipc.o syscalls/ipc.o syscalls/port.o syscalls/map_frames.o syscalls/virtual_to_physical.o syscalls/install_irq.o arch/i386/interrupts.o cpu/isr.o lib/stack.o lib/buffered_write.o lib/list.o cpu/arch_inst.o
+CFLAGS = -std=c99 -Ofast -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL
+#CFLAGS = -Ofast -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL
#CFLAGS = -O0 -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign -DKERNEL
LDFLAGS=-flto -Ofast
LDFLAGS=
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c
index 201fa8e..240c9ea 100644
--- a/kernel/arch/i386/mmu.c
+++ b/kernel/arch/i386/mmu.c
@@ -1,4 +1,5 @@
#include <assert.h>
+#include <cpu/arch_inst.h>
#include <ksbrk.h>
#include <log.h>
#include <math.h>
@@ -130,12 +131,6 @@ void *align_page(void *a) {
return a;
}
-void flush_tlb(void) {
- asm volatile("\
- mov %cr3, %eax;\
- mov %eax, %cr3");
-}
-
u32 first_free_frame(void) {
for (u32 i = 1; i < INDEX_FROM_BIT(num_of_frames); i++) {
if (frames[i] == 0xFFFFFFFF) {
@@ -506,8 +501,8 @@ void move_stack(u32 new_stack_address, u32 size) {
u32 old_stack_pointer, old_base_pointer;
- asm volatile("mov %%esp, %0" : "=r"(old_stack_pointer));
- asm volatile("mov %%ebp, %0" : "=r"(old_base_pointer));
+ old_stack_pointer = get_current_sp();
+ old_base_pointer = get_current_sbp();
u32 new_stack_pointer =
old_stack_pointer + ((u32)new_stack_address - inital_esp);
@@ -528,8 +523,8 @@ void move_stack(u32 new_stack_address, u32 size) {
inital_esp = new_stack_pointer;
// Actually change the stack
- asm volatile("mov %0, %%esp" ::"irm"(new_stack_pointer));
- asm volatile("mov %0, %%ebp" ::"irm"(new_base_pointer));
+ set_sp(new_stack_pointer + 8);
+ set_sbp(new_base_pointer);
}
// C strings have a unknown length so it does not makes sense to check
@@ -581,13 +576,7 @@ void *is_valid_userpointer(const void *ptr, size_t s) {
void switch_page_directory(PageDirectory *directory) {
active_directory = directory;
- asm("mov %0, %%cr3" ::"r"(directory->physical_address));
-}
-
-void enable_paging(void) {
- asm("mov %cr0, %eax\n"
- "or 0b10000000000000000000000000000000, %eax\n"
- "mov %eax, %cr0\n");
+ set_cr3(directory->physical_address);
}
void create_table(int table_index) {
@@ -603,8 +592,7 @@ void create_table(int table_index) {
}
void paging_init(u64 memsize) {
- u32 *cr3;
- asm volatile("mov %%cr3, %0" : "=r"(cr3));
+ u32 *cr3 = (void *)get_cr3();
u32 *virtual = (u32 *)((u32)cr3 + 0xC0000000);
frames = ksbrk(1024 * sizeof(u32));
memset(frames, 0, 1024 * sizeof(u32));
diff --git a/kernel/cpu/arch_inst.h b/kernel/cpu/arch_inst.h
new file mode 100644
index 0000000..54faffb
--- /dev/null
+++ b/kernel/cpu/arch_inst.h
@@ -0,0 +1,11 @@
+#include <stdint.h>
+uintptr_t get_current_sp(void);
+uintptr_t get_current_sbp(void);
+__attribute__((__noreturn__)) void halt(void);
+uintptr_t get_cr2(void);
+void flush_tlb(void);
+void set_sp(uintptr_t);
+void set_sbp(uintptr_t);
+void set_cr3(uintptr_t);
+uintptr_t get_cr3(void);
+void enable_paging(void);
diff --git a/kernel/cpu/arch_inst.s b/kernel/cpu/arch_inst.s
new file mode 100644
index 0000000..aaf34b6
--- /dev/null
+++ b/kernel/cpu/arch_inst.s
@@ -0,0 +1,60 @@
+.intel_syntax noprefix
+.global get_current_sp
+.global get_current_sbp
+.global halt
+.global get_cr2
+.global set_sp
+.global set_sbp
+.global flush_tlb
+.global set_cr3
+.global get_cr3
+.global enable_paging
+
+get_current_sp:
+ mov eax, esp
+ sub eax, 4
+ ret
+
+get_current_sbp:
+ mov eax, ebp
+ ret
+
+set_sp:
+ mov ecx, [esp] # store the return address in ecx
+ mov eax, [esp + 4]
+ mov esp, eax
+ jmp ecx # jump to the return address instead of doing a ret as the stack values may have changed
+
+set_sbp:
+ mov eax, [esp + 4]
+ mov ebp, eax
+ ret
+
+halt:
+ hlt
+ jmp $
+ ret
+
+get_cr2:
+ mov eax, cr2
+ ret
+
+flush_tlb:
+ mov eax, cr3
+ mov cr3, eax
+ ret
+
+set_cr3:
+ mov eax, [esp + 4]
+ mov cr3, eax
+ ret
+
+get_cr3:
+ mov eax, cr3
+ ret
+
+enable_paging:
+ mov eax, cr0
+ or eax, 0b10000000000000000000000000000000
+ mov cr0, eax
+ ret
diff --git a/kernel/cpu/gdt.c b/kernel/cpu/gdt.c
index 2f9f90b..d91abed 100644
--- a/kernel/cpu/gdt.c
+++ b/kernel/cpu/gdt.c
@@ -1,4 +1,5 @@
#include "gdt.h"
+#include <cpu/arch_inst.h>
#include <interrupts.h>
extern void flush_tss(void);
@@ -39,8 +40,7 @@ void write_tss(struct GDT_Entry *gdt_entry) {
memset(&tss_entry, 0, sizeof tss_entry);
tss_entry.ss0 = GDT_KERNEL_DATA_SEGMENT * GDT_ENTRY_SIZE;
- register u32 esp asm("esp");
- tss_entry.esp0 = esp;
+ tss_entry.esp0 = get_current_sp();
}
void gdt_init() {
diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c
index 3d866e5..ec7ca63 100644
--- a/kernel/cpu/idt.c
+++ b/kernel/cpu/idt.c
@@ -1,4 +1,6 @@
+#include <cpu/arch_inst.h>
#include <cpu/idt.h>
+#include <interrupts.h>
#include <sched/scheduler.h>
#include <stdio.h>
@@ -52,25 +54,20 @@ void general_protection_fault(reg_t *regs) {
kprintf(" Error Code: %x\n", regs->error_code);
kprintf("Instruction Pointer: %x\n", regs->eip);
dump_backtrace(12);
- asm("hlt");
- for (;;)
- ;
+ halt();
EOI(0xD - 8);
}
void double_fault(registers_t *regs) {
(void)regs;
klog("DOUBLE FAULT", LOG_ERROR);
- asm("hlt");
- for (;;)
- ;
+ halt();
}
void page_fault(reg_t *regs) {
- volatile uint32_t cr2;
- asm volatile("mov %%cr2, %0" : "=r"(cr2));
+ uint32_t cr2 = get_cr2();
if (0xDEADC0DE == cr2) {
- asm("cli");
+ disable_interrupts();
EOI(0xB);
process_pop_restore_context(NULL, regs);
return;
@@ -105,9 +102,7 @@ void page_fault(reg_t *regs) {
}
dump_backtrace(12);
- asm("hlt");
- for (;;)
- ;
+ halt();
}
static inline void io_wait(void) {
diff --git a/kernel/ipc.c b/kernel/ipc.c
index d051ea1..56ca79a 100644
--- a/kernel/ipc.c
+++ b/kernel/ipc.c
@@ -1,4 +1,5 @@
#include <assert.h>
+#include <interrupts.h>
#include <ipc.h>
#include <math.h>
#include <sched/scheduler.h>
@@ -57,13 +58,13 @@ int ipc_read(u8 *buffer, u32 length, u32 *sender_pid) {
return 0;
}
get_current_task()->is_halted = 1;
- asm("sti");
+ enable_interrupts();
continue;
}
break;
}
get_current_task()->is_halted = 0;
- asm("cli");
+ disable_interrupts();
ipc_message->is_used = 0;
// TODO: Verify sender_pid is a valid address
if (sender_pid) {
diff --git a/kernel/kubsan.c b/kernel/kubsan.c
index fc2900d..9bc2631 100644
--- a/kernel/kubsan.c
+++ b/kernel/kubsan.c
@@ -2,15 +2,13 @@
#include <kubsan.h>
#include <log.h>
#include <stdio.h>
+#include <cpu/arch_inst.h>
void ubsan_log(const char *cause, struct source_location source) {
kprintf("%s: %s : %d\n", cause, source.file_name, source.line);
dump_backtrace(5);
disable_interrupts();
- asm volatile("1: jmp 1b");
- asm("hlt");
- for (;;)
- ;
+ halt();
}
void __ubsan_handle_shift_out_of_bounds(struct ShiftOutOfBoundsData *data,
diff --git a/kernel/lib/list.c b/kernel/lib/list.c
new file mode 100644
index 0000000..12104d8
--- /dev/null
+++ b/kernel/lib/list.c
@@ -0,0 +1,39 @@
+#include <assert.h>
+#include <kmalloc.h>
+#include <lib/list.h>
+
+int list_init(struct list *list) {
+ // TODO: Make it dynamic
+ list->entries = kmalloc(sizeof(void *) * 100);
+ if (!list->entries) {
+ return 0;
+ }
+ list->tail_index = -1;
+ return 1;
+}
+
+void list_reset(struct list *list) {
+ list->tail_index = -1;
+}
+
+int list_add(struct list *list, void *entry) {
+ if (list->tail_index > 100 - 1) {
+ kprintf("Error: list has run out of space\n");
+ assert(0);
+ }
+ list->tail_index++;
+ list->entries[list->tail_index] = entry;
+ return 1;
+}
+
+int list_get(const struct list *list, int index, void **out) {
+ if (index > list->tail_index) {
+ return 0;
+ }
+ *out = list->entries[index];
+ return 1;
+}
+
+void list_free(struct list *list) {
+ kfree(list->entries);
+}
diff --git a/kernel/lib/list.h b/kernel/lib/list.h
new file mode 100644
index 0000000..8c3cce4
--- /dev/null
+++ b/kernel/lib/list.h
@@ -0,0 +1,13 @@
+#ifndef LIST_H
+#define LIST_H
+struct list {
+ void **entries;
+ int tail_index;
+};
+
+int list_init(struct list *list);
+void list_reset(struct list *list);
+void list_free(struct list *list);
+int list_add(struct list *list, void *entry);
+int list_get(const struct list *list, int index, void **out);
+#endif
diff --git a/kernel/libc/exit/assert.c b/kernel/libc/exit/assert.c
index 3351249..47c0704 100644
--- a/kernel/libc/exit/assert.c
+++ b/kernel/libc/exit/assert.c
@@ -1,12 +1,11 @@
#include <assert.h>
#include <log.h>
#include <stdio.h>
+#include <cpu/arch_inst.h>
__attribute__((__noreturn__)) void aFailed(char *f, int l) {
kprintf("Assert failed\n");
kprintf("%s : %d\n", f, l);
dump_backtrace(10);
- asm("hlt");
- for (;;)
- ;
+ halt();
}
diff --git a/kernel/log.c b/kernel/log.c
index fddf3b5..8f72b3a 100644
--- a/kernel/log.c
+++ b/kernel/log.c
@@ -1,4 +1,5 @@
#include "log.h"
+#include <cpu/arch_inst.h>
#include <sched/scheduler.h>
struct stackframe {
@@ -7,8 +8,7 @@ struct stackframe {
};
void dump_backtrace(u32 max_frames) {
- struct stackframe *stk;
- asm("mov %%ebp,%0" : "=r"(stk)::);
+ struct stackframe *stk = (void*)get_current_sbp();
kprintf("Stack trace:\n");
for (u32 frame = 0; stk && frame < max_frames; ++frame) {
kprintf(" 0x%x\n", stk->eip);