From 7fb04f134b93f0e98fa3475cef61e400d1d59f56 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 11 May 2025 18:43:28 +0200 Subject: [PATCH 01/30] repo: Added contributing guidelines. --- CONTRIBUTING.MD | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CONTRIBUTING.MD diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD new file mode 100644 index 0000000..e6ff9ee --- /dev/null +++ b/CONTRIBUTING.MD @@ -0,0 +1,5 @@ +# Contribute to Soaplin! +Do you want to improve Soaplin? You can by contributing to the project! + +## Contributing guidelines +* Before making a commit, please run `make format`. This will run clang-format over all the C source files in kernel/src. From a838d99a5a8cd8295031ae51428b98661a35af90 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 11 May 2025 23:54:14 +0200 Subject: [PATCH 02/30] kernel: various changes. + kernel: replace sk-hello test executable with a test initramfs + panic: start implementing a proper kernel panic screen + lib: added a new string.h library for string manipulation. + kernel: replace all the strlen implementations with the strlen() function --- CONTRIBUTING.MD | 4 ++ GNUmakefile | 3 +- initramfs.tar | Bin 0 -> 10240 bytes initramfs/dir/subtest.txt | 1 + initramfs/test.txt | 1 + kernel/src/fs/vfs.c | 0 kernel/src/fs/vfs.h | 28 -------- kernel/src/lib/string.c | 57 ++++++++++++++++ kernel/src/lib/string.h | 8 +++ kernel/src/main.c | 60 ++--------------- kernel/src/mm/vmm.c | 4 +- kernel/src/sched/sched.c | 17 +---- kernel/src/sys/arch/x86_64/interrupts.c | 25 +------ kernel/src/sys/error_handling/panic.c | 76 +++++++++++++++++++++- kernel/src/sys/error_handling/panic.h | 1 + kernel/src/sys/gfx/flanterm/backends/fb.h | 10 +-- kernel/src/sys/log.c | 17 ++--- kernel/src/sys/printf.c | 8 +-- limine.conf | 2 +- 19 files changed, 173 insertions(+), 149 deletions(-) create mode 100644 initramfs.tar create mode 100644 initramfs/dir/subtest.txt create mode 100644 initramfs/test.txt delete mode 100644 kernel/src/fs/vfs.c delete mode 100644 kernel/src/fs/vfs.h create mode 100644 kernel/src/lib/string.c create mode 100644 kernel/src/lib/string.h create mode 100644 kernel/src/sys/error_handling/panic.h diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD index e6ff9ee..4b8e29d 100644 --- a/CONTRIBUTING.MD +++ b/CONTRIBUTING.MD @@ -3,3 +3,7 @@ Do you want to improve Soaplin? You can by contributing to the project! ## Contributing guidelines * Before making a commit, please run `make format`. This will run clang-format over all the C source files in kernel/src. +* Large language model-generated code is **allowed**, with the condition that you do extensive testing over that code. + You must also know how to make the LLM-generated code by yourself. + + Note: Even if LLM-generated code is allowed, please try to not use it. \ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile index d3896ee..6ff16cd 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -83,7 +83,6 @@ run-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso .PHONY: run-hdd-aarch64 run-hdd-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd - @echo " Starting QEMU with $(IMAGE_NAME).hdd" @qemu-system-$(ARCH) \ -M virt \ -cpu cortex-a72 \ @@ -204,8 +203,8 @@ $(IMAGE_NAME).iso: limine/limine kernel @mkdir -p iso_root/boot/limine @cp -v limine.conf iso_root/boot/limine/ @mkdir -p iso_root/EFI/BOOT + @cp -v initramfs.tar iso_root/ ifeq ($(ARCH),x86_64) - @cp -v testing/sk-hello.elf iso_root/ @cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ @cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ @cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ diff --git a/initramfs.tar b/initramfs.tar new file mode 100644 index 0000000000000000000000000000000000000000..d5c2b82cb86e10a48a277e0de24648a33f8137ca GIT binary patch literal 10240 zcmeIzO%8%E5Cve4QZG>2(w{4M1J@`RO&~R;CVG3PF$ybmVTlQ^8%PSY`CggfWs!Xd z8qS!4F47q>y{4%&3TcECN@#28Il42dU?%&{Xo2ex>p)uy_2tyhEcj`D=GA|m;$>`y z$m1>M+hq#aYCX;Ubq>-LoeKTV-|33-m(EiDBHxzAFRwiRZQFI8?R@B(&4_}#wFvOC zIfu+WApPQB*MFzd|1Xq9{a@k?KJy>0`;2WM12tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa J0SNp+-~mP@UY`H} literal 0 HcmV?d00001 diff --git a/initramfs/dir/subtest.txt b/initramfs/dir/subtest.txt new file mode 100644 index 0000000..0688709 --- /dev/null +++ b/initramfs/dir/subtest.txt @@ -0,0 +1 @@ +Hello World from a subdirectory! \ No newline at end of file diff --git a/initramfs/test.txt b/initramfs/test.txt new file mode 100644 index 0000000..c57eff5 --- /dev/null +++ b/initramfs/test.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c deleted file mode 100644 index e69de29..0000000 diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h deleted file mode 100644 index bbaa364..0000000 --- a/kernel/src/fs/vfs.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// btw fuck sun - -#include - -#define VNODE_TYPE_FILE 0 -#define VNODE_TYPE_DIR 1 -#define VNODE_TYPE_DEV 2 - -typedef struct __vnode { - char name[128]; - int type; - - struct __vnode *children; - struct __vnode *next; - struct __vnode *parent; - - void (*write)(void *buffer, uint64_t off, uint64_t size); - void (*read)(void *buffer, uint64_t off, uint64_t size); -} vnode; - -typedef struct __vfs_mount { - struct vfs_node - *mount_point; // The directory in the main VFS where this is mounted - struct vfs_node *mounted_root; // The root node of the mounted filesystem - struct vfs_mount *next; // Pointer to next mount point -} vfs_mount; diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c new file mode 100644 index 0000000..216e6dd --- /dev/null +++ b/kernel/src/lib/string.c @@ -0,0 +1,57 @@ +#include +#include + +int strlen(const char *str) { + int len = 0; + while (str[len]) + len++; + return len; +} + +int strcmp(const char *s1, const char *s2) { + while (*s1 && *s1 == *s2) { + s1++; + s2++; + } + return *s1 - *s2; +} + +char *strcpy(char *dest, const char *src) +{ + if (dest == NULL || src == NULL) + return NULL; + + char *temp = dest; + while((*dest++ = *src++) != '\0'); + return temp; +} + +char *strchr(const char *s, int c) { + while (*s++) { + if (*s == c) + return (char *)s; + } + return NULL; +} + +char *strrchr(const char *s, int c) { + const char *p = NULL; + + for (;;) { + if (*s == (char)c) + p = s; + if (*s++ == '\0') + return (char *)p; + } +} + +int oct2bin(unsigned char *str, int size) { + int n = 0; + unsigned char *c = str; + while (size-- > 0) { + n *= 8; + n += *c - '0'; + c++; + } + return n; +} \ No newline at end of file diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h new file mode 100644 index 0000000..da1cdd6 --- /dev/null +++ b/kernel/src/lib/string.h @@ -0,0 +1,8 @@ +#pragma once + +int strlen(const char *str); +int strcmp(const char *s1, const char *s2); +char *strchr(const char *s, int c); +char *strcpy(char *dest, const char *src); +char *strrchr(const char *s, int c); +int oct2bin(unsigned char *str, int size); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 9c27252..fd9b080 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,5 +1,7 @@ #include "exec/elf.h" #include "exec/exec.h" +#include "fs/tapefs.h" +#include "fs/vfs.h" #include "mm/liballoc/liballoc.h" #include "mm/pmm.h" #include "mm/vma.h" @@ -11,29 +13,22 @@ #include "sys/syscall.h" #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include -// Set the base revision to 3, this is recommended as this is the latest -// base revision described by the Limine boot protocol specification. -// See specification for further info. - __attribute__(( used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); -// The Limine requests can be placed anywhere, but it is important that -// the compiler does not optimise them away, so, usually, they should -// be made volatile or equivalent, _and_ they should be accessed at least -// once or marked as used with the "used" attribute as done here. - __attribute__(( used, section( @@ -45,14 +40,6 @@ __attribute__(( section(".limine_requests"))) static volatile struct limine_module_request module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0}; -/*__attribute__((used, section(".limine_requests"))) -static volatile struct limine_entry_point_request entrypoint_request = { - .id = LIMINE_ENTRY_POINT_REQUEST, - .revision = 3 -};*/ -// Finally, define the start and end markers for the Limine requests. -// These can also be moved anywhere, to any .c file, as seen fit. - __attribute__((used, section(".limine_requests_" "start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -62,38 +49,14 @@ __attribute__(( section( ".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; -// Halt and catch fire function. -static void hcf(void) { - for (;;) { -#if defined(__x86_64__) - asm("hlt"); -#elif defined(__aarch64__) || defined(__riscv) - asm("wfi"); -#elif defined(__loongarch64) - asm("idle 0"); -#endif - } -} - struct limine_framebuffer *fb; struct flanterm_context *ft_ctx; -uint32_t fg = 0xFFFFFF; char kstack[8192]; -// The following will be our kernel's entry point. -// If renaming kmain() to something else, make sure to change the -// linker script accordingly. void kmain(void) { - // Ensure the bootloader actually understands our base revision (see spec). - /*if (LIMINE_BASE_REVISION_SUPPORTED == false) { - hcf(); - }*/ - - // Ensure we got a framebuffer. if (framebuffer_request.response != NULL) { - // Fetch the first framebuffer. struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; fb = framebuffer; @@ -103,12 +66,11 @@ void kmain(void) { framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size, framebuffer->red_mask_shift, framebuffer->green_mask_size, framebuffer->green_mask_shift, framebuffer->blue_mask_size, - framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, &fg, NULL, NULL, + framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, NULL, NULL, NULL, VGA8, 8, 16, 0, 0, 0, 0); } printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); - // printf("Physical kernel EP: %p", entrypoint_request.entry); gdt_init(&kstack[8192]); idt_init(); @@ -125,21 +87,13 @@ void kmain(void) { asm("hlt"); } - // acpi_init(); syscall_init(); pit_init(1000); sched_init(); - // user_init(); - - struct limine_file *f = module_request.response->modules[0]; - log("kmain - %s\n", f->path); - - program_t *prog = elf_load((char *)f->address, 1); - - sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS); log("kernel - Soaplin initialized sucessfully.\n"); + while (1) ; - ; //__asm__ volatile ("hlt"); + ; } diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index e2a183f..cc246f0 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -211,8 +211,8 @@ void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE, + uint64_t *pml3 = + __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE, true); // PML3 / Page Directory Pointer Entry uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags | VMM_WRITABLE, true); // PML2 / Page Directory Entry diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index 907f83a..f16f6b6 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -4,6 +4,7 @@ #include "mm/vmm.h" #include "sys/arch/x86_64/idt.h" #include "sys/log.h" +#include #include sched_process *proc_list; @@ -47,16 +48,11 @@ void sched_init() { sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags) { - // TODO: implement a separate strlen function - // as there's like 4 strlen impls in the kernel. - int i = 0; - while (name[i] != 0) - i++; sched_process *proc = pmm_request_page(); memset(proc, 0, sizeof(sched_process)); - memcpy(proc->name, name, i); + memcpy(proc->name, name, strlen(name) > 128 ? 128 : strlen(name)); proc->pid = current_pid; proc->type = SCHED_RUNNING; proc->flags = flags; @@ -141,7 +137,6 @@ void schedule(registers_t *regs) { prev_proc->next = curr_proc->next; - // Now, it is safe to free the process's memory. vmm_release_pm(curr_proc->pm); pmm_free_page(curr_proc->stack_base_physical); @@ -155,15 +150,7 @@ void schedule(registers_t *regs) { if (curr_proc == NULL) curr_proc = proc_list; - //log("sched - I choosed process %d\n", curr_proc->pid); - - //log("sched - I choosed process %d (pm: %s, rip: %p)\n", curr_proc->pid, curr_proc->pm == vmm_kernel_pm ? "kernel" : "user", curr_proc->regs.rip); memcpy(regs, &curr_proc->regs, sizeof(registers_t)); - // Finally, load our pagemap - // if (memcmp(curr_proc->name, "Init", 4)== 0) { vmm_load_pagemap(curr_proc->pm); - // asm("cli"); - // while (1) - // asm("hlt");} } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c index 8e3643c..41c4621 100644 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -1,5 +1,3 @@ -// #include "mm/pmm.h" -// #include "mm/vmm.h" #include "mm/pmm.h" #include "mm/vmm.h" #include "sched/sched.h" @@ -7,39 +5,20 @@ #include "sys/arch/x86_64/rtc.h" #include "sys/log.h" #include "sys/syscall.h" -// #include "sys/sched.h" #include #include #include -// #include int pit_millis = 0; int pit_secs = 0; extern int vmm_kernel_pm_exists; -struct Idt_StackFrame { - struct Idt_StackFrame *rbp; - uint64_t rip; -} __attribute__((packed)); - -void dump_backtrace(registers_t *r) { - log("ints - backtrace : \n"); - struct Idt_StackFrame *frame = (struct Idt_StackFrame *)r->rbp; - - while (frame) { - log("ints - %s (ip: %p)\n", frame->rip); - frame = frame->rbp; - } - log("ints - \n"); -} - void pit_handler(registers_t *regs); void exception_handler(registers_t *regs) { vmm_load_pagemap(vmm_kernel_pm); if (regs->int_no < 32) { - // panic(kmode_cpu_exception, regs); log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); @@ -53,7 +32,6 @@ void exception_handler(registers_t *regs) { log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); } - // dump_backtrace(regs); asm("cli"); while (1) asm("hlt"); @@ -73,7 +51,6 @@ void exception_handler(registers_t *regs) { } else if (regs->int_no == 0x80) { syscall_handle(regs); } - // logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); - //vmm_load_pagemap(curr_proc->pm); + pic_ack(regs->int_no - 32); } \ No newline at end of file diff --git a/kernel/src/sys/error_handling/panic.c b/kernel/src/sys/error_handling/panic.c index c867ff3..f9ee767 100644 --- a/kernel/src/sys/error_handling/panic.c +++ b/kernel/src/sys/error_handling/panic.c @@ -1 +1,75 @@ -void panic_ctx() {} \ No newline at end of file +#include "sys/arch/x86_64/idt.h" +#include + +static registers_t __panic_regdump; + +static void __panic_dump_regs() { + asm volatile( + // Save general purpose registers + "movq %%r15, %0\n\t" + "movq %%r14, %1\n\t" + "movq %%r13, %2\n\t" + "movq %%r12, %3\n\t" + "movq %%r11, %4\n\t" + "movq %%r10, %5\n\t" + "movq %%r9, %6\n\t" + "movq %%r8, %7\n\t" + "movq %%rdi, %8\n\t" + "movq %%rsi, %9\n\t" + "movq %%rbp, %10\n\t" + "movq %%rbx, %11\n\t" + "movq %%rdx, %12\n\t" + "movq %%rcx, %13\n\t" + "movq %%rax, %14\n\t" + + // The rest of the registers (rip, cs, rflags, rsp, ss) would typically + // be captured in the interrupt/exception handler context and passed in + // We'll zero them out here since we don't have direct access + : "=m"(__panic_regdump.r15), "=m"(__panic_regdump.r14), + "=m"(__panic_regdump.r13), "=m"(__panic_regdump.r12), + "=m"(__panic_regdump.r11), "=m"(__panic_regdump.r10), + "=m"(__panic_regdump.r9), "=m"(__panic_regdump.r8), + "=m"(__panic_regdump.rdi), "=m"(__panic_regdump.rsi), + "=m"(__panic_regdump.rbp), "=m"(__panic_regdump.rbx), + "=m"(__panic_regdump.rdx), "=m"(__panic_regdump.rcx), + "=m"(__panic_regdump.rax) + : + : "memory"); + + // Zero out the registers we can't directly access in this context + __panic_regdump.int_no = 0; + __panic_regdump.err_code = 0; + __panic_regdump.rip = 0; + __panic_regdump.cs = 0; + __panic_regdump.rflags = 0; + __panic_regdump.rsp = 0; + __panic_regdump.ss = 0; +} + +void panic() { + __panic_dump_regs(); + + log(" _ __ _ ___ _ \n"); + log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n"); + log("| ' +#include #include #include @@ -14,12 +15,8 @@ void log(char *format, ...) { // TODO: replace this call with a call to printf() when the RTC is // implemented. char *date = "1970-01-01 00:00:00 | "; - int i2 = 0; - for (i2; date[i2] != 0; i2++) - ; - ; if (ft_ctx) - flanterm_write(ft_ctx, date, i2); + flanterm_write(ft_ctx, date, strlen(date)); char buf[2048]; va_list l; @@ -27,14 +24,10 @@ void log(char *format, ...) { npf_vsnprintf(buf, 2048, format, l); va_end(l); - int i = 0; - for (i; buf[i] != 0; i++) - ; - ; if (ft_ctx) - flanterm_write(ft_ctx, buf, i); + flanterm_write(ft_ctx, buf, strlen(buf)); - for (int i = 0;; i++) { + /*for (int i = 0;; i++) { if (date[i] == '\0') break; @@ -46,7 +39,7 @@ void log(char *format, ...) { break; outb(0xE9, buf[i]); - } + }*/ // spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/printf.c b/kernel/src/sys/printf.c index 9097ac6..b453bcf 100644 --- a/kernel/src/sys/printf.c +++ b/kernel/src/sys/printf.c @@ -2,6 +2,7 @@ // This code is part of the Soaplin kernel and is licensed under the terms of // the MIT License. #include "sys/gfx/flanterm/flanterm.h" +#include #include #define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 @@ -25,11 +26,6 @@ void printf(char *format, ...) { va_end(lst); // rt_print(buf); - int i = 0; - for (i; buf[i] != 0; i++) - ; - ; - if (ft_ctx) - flanterm_write(ft_ctx, buf, i); + flanterm_write(ft_ctx, buf, strlen(buf)); } \ No newline at end of file diff --git a/limine.conf b/limine.conf index df98d06..fd0bd86 100755 --- a/limine.conf +++ b/limine.conf @@ -6,4 +6,4 @@ verbose: yes protocol: limine path: boot():/boot/soaplin - module_path: boot():/sk-hello.elf \ No newline at end of file + module_path: boot():/initramfs.tar \ No newline at end of file From 6af9752e2458a631f013438ed698efb835d4e00b Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 12 May 2025 08:53:17 +0200 Subject: [PATCH 03/30] kernel: now panics since there's no init --- kernel/src/main.c | 4 +-- kernel/src/sys/error_handling/panic.c | 38 ++++++++++++++++----------- kernel/src/sys/error_handling/panic.h | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/kernel/src/main.c b/kernel/src/main.c index fd9b080..6e60f5a 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,7 +1,5 @@ #include "exec/elf.h" #include "exec/exec.h" -#include "fs/tapefs.h" -#include "fs/vfs.h" #include "mm/liballoc/liballoc.h" #include "mm/pmm.h" #include "mm/vma.h" @@ -91,6 +89,8 @@ void kmain(void) { pit_init(1000); sched_init(); + panic("No working initialization program found. (This is normal due to Soaplin's current state, so please do not report this as a bug)"); + log("kernel - Soaplin initialized sucessfully.\n"); while (1) diff --git a/kernel/src/sys/error_handling/panic.c b/kernel/src/sys/error_handling/panic.c index f9ee767..095c1bf 100644 --- a/kernel/src/sys/error_handling/panic.c +++ b/kernel/src/sys/error_handling/panic.c @@ -44,20 +44,6 @@ static void __panic_dump_regs() { __panic_regdump.rflags = 0; __panic_regdump.rsp = 0; __panic_regdump.ss = 0; -} - -void panic() { - __panic_dump_regs(); - - log(" _ __ _ ___ _ \n"); - log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n"); - log("| ' Date: Mon, 12 May 2025 10:24:48 +0200 Subject: [PATCH 04/30] rtc - try implementing RTC / kernel: removed rt from the codebase (released separately) --- deprecated/rt.c | 85 ------------------------- deprecated/rt.h | 41 ------------ kernel/src/sys/arch/x86_64/idt.c | 1 + kernel/src/sys/arch/x86_64/interrupts.c | 2 +- kernel/src/sys/arch/x86_64/rtc.c | 59 ++++++++++------- kernel/src/sys/arch/x86_64/rtc.h | 20 ++++-- 6 files changed, 54 insertions(+), 154 deletions(-) delete mode 100755 deprecated/rt.c delete mode 100755 deprecated/rt.h diff --git a/deprecated/rt.c b/deprecated/rt.c deleted file mode 100755 index fd34f05..0000000 --- a/deprecated/rt.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "rt.h" -#include -#include -#include - -static rt_context _curctx; - -void _rt_drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor) -{ - int cx,cy; - int mask[8]={128, 64, 32, 16, 8, 4, 2, 1}; - unsigned char *glyph=VGA8+(int)c*16; - - uint32_t *buf = _curctx.framebuffer; - - for(cy=0;cy<16;cy++){ - for(cx=0;cx<8;cx++){ - buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = glyph[cy]&mask[cx]?fgcolor:bgcolor; - } - } -} -void _rt_draw_fillchar(int x, int y, int bgcolor, int fgcolor) { - int cx,cy; - uint32_t *buf = _curctx.framebuffer; - for(cy=0;cy<16;cy++){ - for(cx=0;cx<8;cx++){ - buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = cy > 12 ? fgcolor : bgcolor; - } - } -} - -int _rt_strlen(char *str) { - int i = 0; - while (str[i] != '\0') i++; - return i; -} - -void rt_init(rt_context ctx) { - // Copy the structure - char *src = (char*)&ctx; - char *dst = (char*)&_curctx; - for (unsigned long i = 0; i < sizeof(rt_context); i++) { - dst[i] = src[i]; - } - - // Fill fields - _curctx.term_width = _curctx.framebuffer_width / 8; - _curctx.term_height = _curctx.framebuffer_height / 16; -} - -void rt_print(char *str) { - _rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0x0); - - for (int i = 0; i < _rt_strlen(str); i++) { - if (str[i] == '\n' && _curctx.use_crlf_ending) - if (_curctx.y * 16 >= (int)_curctx.framebuffer_height) { - _curctx.y = 0; - memset( - _curctx.framebuffer, _curctx.bg_color, - _curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t)); - } else { - _curctx.y++; - } - else if (str[i] == '\n') - { - if (_curctx.y * 16 >= (int)_curctx.framebuffer_height) { - _curctx.y = 0; - memset( - _curctx.framebuffer, _curctx.bg_color, - _curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t)); - } else { - _curctx.y++; - } - _curctx.x = 0; - } - else if (str[i] == '\r') - _curctx.x = 0; - else { - _rt_drawchar(str[i], _curctx.x * 8, _curctx.y * 16, 0xFFFFFF, 0x0); - _curctx.x++; - } - } - - _rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0xFFFFFF); -} \ No newline at end of file diff --git a/deprecated/rt.h b/deprecated/rt.h deleted file mode 100755 index fcd601c..0000000 --- a/deprecated/rt.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -typedef struct _rt_ctx { - // A pointer to the framebuffer. - void *framebuffer; - - // The framebuffer width, in pixels. - uint32_t framebuffer_width; - - // The framebuffer height, in pixels. - uint32_t framebuffer_height; - - // Set this to 1 if you prefer using DOS line endings to UNIX line endings. - int use_crlf_ending; - - // Do we need to show a cursor after printing text? - int show_cursor; - - // The background color - uint32_t bg_color; - - // The foreground color - uint32_t fg_color; - - /* - * Do NOT modify everything below me! - */ - // The terminal's width, in columns of 8 pixels. - int term_width; - // The terminal's height, in rows of 16 pixels. - int term_height; - // The X position of the cursor, in columns of 8 pixels. - int x; - // The Y position of the cursor, in rows of 16 pixels. - int y; -} rt_context; - -void rt_init(rt_context ctx); -void rt_print(char *str); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c index f82700c..5f1012f 100644 --- a/kernel/src/sys/arch/x86_64/idt.c +++ b/kernel/src/sys/arch/x86_64/idt.c @@ -41,6 +41,7 @@ void idt_init() { pic_init(); pic_unmask_irq(1); + pic_unmask_irq(8); __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("sti"); // set the interrupt flag diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c index 41c4621..c808c80 100644 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -45,7 +45,7 @@ void exception_handler(registers_t *regs) { log("ints - keyboard\n"); } else if (regs->int_no == 32 + 8) { - rtc_handle_interrupt(regs); + log("rtc\n"); } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { pit_handler(regs); } else if (regs->int_no == 0x80) { diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/sys/arch/x86_64/rtc.c index 9b277ef..c5468d8 100644 --- a/kernel/src/sys/arch/x86_64/rtc.c +++ b/kernel/src/sys/arch/x86_64/rtc.c @@ -1,28 +1,41 @@ -#include "sys/arch/x86_64/idt.h" -#include "sys/arch/x86_64/io.h" -#include -#include -#include +#include "rtc.h" +#include "io.h" -void rtc_init() { - asm("cli"); - outb(0x70, 0x8A); - outb(0x71, 0x20); - asm("sti"); +char bcd; - asm("cli"); // disable interrupts - outb(0x70, 0x8B); // select register B, and disable NMI - char prev = inb(0x71); // read the current value of register B - outb(0x70, - 0x8B); // set the index again (a read will reset the index to register D) - outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This - // turns on bit 6 of register B - asm("sti"); - - // pic_unmask_irq(8); +unsigned char read_register(unsigned char reg) { + __asm__ volatile("cli"); + outb(RTC_COMMAND, reg); + return inb(RTC_DATA); + __asm__ volatile("sti"); } -void rtc_handle_interrupt(registers_t *regs) { - (void)regs; - printf("RTC!\n"); +void write_register(unsigned char reg, unsigned char value) { + __asm__ volatile("cli"); + outb(RTC_COMMAND, reg); + outb(RTC_DATA, value); + __asm__ volatile("sti"); +} + +unsigned char bcd2bin(unsigned char in_bcd) { + return (bcd) ? ((in_bcd >> 4) * 10) + (in_bcd & 0x0F) : in_bcd; +} + +int rtc_init() { + __asm__ volatile("cli"); + unsigned char status; + status = read_register(RTC_STATUS); + status |= 0x02; // 24 hour clock + status |= 0x10; // update ended interrupts + status &= ~0x20; // no alarm interrupts + status &= ~0x40; // no periodic interrupt + bcd = !(status & 0x04); // check if data type is BCD + write_register(RTC_STATUS, status); + + outb(0x70, 0x8B); // select register B, and disable NMI + char prev=inb(0x71); // read the current value of register B + outb(0x70, 0x8B); // set the index again (a read will reset the index to register D) + outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B + __asm__ volatile("sti"); + return 0; } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.h b/kernel/src/sys/arch/x86_64/rtc.h index a81996d..8f34e7e 100755 --- a/kernel/src/sys/arch/x86_64/rtc.h +++ b/kernel/src/sys/arch/x86_64/rtc.h @@ -1,6 +1,18 @@ -#pragma once +#ifndef __TIME_H +#define __TIME_H -#include "sys/arch/x86_64/idt.h" +#define RTC_COMMAND 0x70 +#define RTC_DATA 0x71 +#define RTC_STATUS 0x0B -void rtc_init(); -void rtc_handle_interrupt(registers_t *regs); \ No newline at end of file +#define RTC_SECONDS 0x00 +#define RTC_MINUTES 0x02 +#define RTC_HOURS 0x04 +#define RTC_DAY_OF_WEEK 0x06 +#define RTC_DAY 0x07 +#define RTC_MONTH 0x08 +#define RTC_YEAR 0x09 + +int rtc_init(); + +#endif // __TIME_H__ \ No newline at end of file From 8fb363f831441434ea24099f0ad671910b6b9207 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 12 May 2025 10:31:26 +0200 Subject: [PATCH 05/30] gitignore - added "compile_commands.json" --- .gitignore | 1 + compile_commands.json | 78 ------------------------------------------- 2 files changed, 1 insertion(+), 78 deletions(-) delete mode 100644 compile_commands.json diff --git a/.gitignore b/.gitignore index 1c9bfac..31c65c9 100755 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /.cache *.iso *.hdd +/compile_commands.json \ No newline at end of file diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index cf2888f..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,78 +0,0 @@ -[ - { - "arguments": [ - "/usr/bin/cc", - "-g", - "-O2", - "-pipe", - "-Wall", - "-Wextra", - "-std=gnu11", - "-nostdinc", - "-ffreestanding", - "-fno-stack-protector", - "-fno-stack-check", - "-fno-PIC", - "-ffunction-sections", - "-fdata-sections", - "-m64", - "-march=x86-64", - "-mno-80387", - "-mno-mmx", - "-mno-sse", - "-mno-sse2", - "-mno-red-zone", - "-mcmodel=kernel", - "-I", - "src", - "-isystem", - "freestnd-c-hdrs", - "-DLIMINE_API_REVISION=3", - "-c", - "-o", - "obj-x86_64/main.c.o", - "src/main.c" - ], - "directory": "/home/raphm/Projets/sild/soaplin/kernel", - "file": "/home/raphm/Projets/sild/soaplin/kernel/src/main.c", - "output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/main.c.o" - }, - { - "arguments": [ - "/usr/bin/cc", - "-g", - "-O2", - "-pipe", - "-Wall", - "-Wextra", - "-std=gnu11", - "-nostdinc", - "-ffreestanding", - "-fno-stack-protector", - "-fno-stack-check", - "-fno-PIC", - "-ffunction-sections", - "-fdata-sections", - "-m64", - "-march=x86-64", - "-mno-80387", - "-mno-mmx", - "-mno-sse", - "-mno-sse2", - "-mno-red-zone", - "-mcmodel=kernel", - "-I", - "src", - "-isystem", - "freestnd-c-hdrs", - "-DLIMINE_API_REVISION=3", - "-c", - "-o", - "obj-x86_64/mm/vmm.c.o", - "src/mm/vmm.c" - ], - "directory": "/home/raphm/Projets/sild/soaplin/kernel", - "file": "/home/raphm/Projets/sild/soaplin/kernel/src/mm/vmm.c", - "output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/mm/vmm.c.o" - } -] From 8b75d8d5e606f29aeabe9b0a6edf16e75fc46c91 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 12 May 2025 13:33:52 +0200 Subject: [PATCH 06/30] readme: Add some basic building instructions --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 73f84a3..94c4a72 100755 --- a/README.md +++ b/README.md @@ -20,4 +20,12 @@ The Soaplin kernel is a new Unix-like operating system kernel. * Video driver for Bochs graphics adapter, and the VMware display adapter. ## Known bugs -* If a user process calls the syscall handler by using interrupts, the system may crash due to a Page Fault. \ No newline at end of file +* If a user process calls the syscall handler by using interrupts, the system may crash due to a Page Fault. + +## Building +To build Soaplin, you must ensure you have these: +* The Netwide Assembler (nasm) +* A compiler (In the future, a custom toolchain would be built.) +* A linker + +Clone the repo, and run "make" in it! \ No newline at end of file From 6a77b066e835da55c51f45eaa6942ec4fddaec19 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 12 May 2025 22:26:19 +0200 Subject: [PATCH 07/30] vfs - start making the VFS --- kernel/src/fs/vfs.h | 37 ++++++++++++ kernel/src/lib/string.c | 60 ++++++++++++------- kernel/src/lib/string.h | 3 +- kernel/src/main.c | 18 +++++- kernel/src/sys/arch/x86_64/rtc.c | 50 ++++++++-------- kernel/src/sys/arch/x86_64/rtc.h | 20 +++---- .../sys/{error_handling => errhnd}/panic.c | 3 +- .../sys/{error_handling => errhnd}/panic.h | 0 8 files changed, 128 insertions(+), 63 deletions(-) create mode 100644 kernel/src/fs/vfs.h mode change 100755 => 100644 kernel/src/sys/arch/x86_64/rtc.h rename kernel/src/sys/{error_handling => errhnd}/panic.c (99%) rename kernel/src/sys/{error_handling => errhnd}/panic.h (100%) diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h new file mode 100644 index 0000000..9a58668 --- /dev/null +++ b/kernel/src/fs/vfs.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +struct vnode; + +#define VN_FILE 1 +#define VN_DIR 2 + +typedef uint32_t vnode_type_t; + +typedef struct vnode_ops { + int (*read)(struct vnode* vn, void* buf, size_t size); +} vnode_ops_t; + +typedef struct vnode { + char name[256]; + vnode_type_t type; + struct vnode* parent; + struct vnode* child; + struct vnode* next; + + struct vnode_ops* ops; + void* internal; +} vnode_t; + +typedef struct fs { + char name[32]; + int (*mount)(struct vnode** root); +} fs_t; + +void vfs_init(void); +int vfs_mount(char *path, fs_t* fs); +int vfs_unmount(char *path); +int vfs_open(const char* path, vnode_t** result); +int vfs_read(vnode_t* vn, void* buf, size_t size); diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index 216e6dd..1e39b6a 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -1,4 +1,5 @@ #include +#include #include int strlen(const char *str) { @@ -16,14 +17,14 @@ int strcmp(const char *s1, const char *s2) { return *s1 - *s2; } -char *strcpy(char *dest, const char *src) -{ - if (dest == NULL || src == NULL) - return NULL; - - char *temp = dest; - while((*dest++ = *src++) != '\0'); - return temp; +char *strcpy(char *dest, const char *src) { + if (dest == NULL || src == NULL) + return NULL; + + char *temp = dest; + while ((*dest++ = *src++) != '\0') + ; + return temp; } char *strchr(const char *s, int c) { @@ -35,23 +36,36 @@ char *strchr(const char *s, int c) { } char *strrchr(const char *s, int c) { - const char *p = NULL; + const char *p = NULL; - for (;;) { - if (*s == (char)c) - p = s; - if (*s++ == '\0') - return (char *)p; - } + for (;;) { + if (*s == (char)c) + p = s; + if (*s++ == '\0') + return (char *)p; + } } int oct2bin(unsigned char *str, int size) { - int n = 0; - unsigned char *c = str; - while (size-- > 0) { - n *= 8; - n += *c - '0'; - c++; - } - return n; + int n = 0; + unsigned char *c = str; + while (size-- > 0) { + n *= 8; + n += *c - '0'; + c++; + } + return n; +} + +char *strdup(const char *str) { + if (str == NULL) + return NULL; + + int len = strlen(str); + char *dup = (char *)malloc(len + 1); + if (dup == NULL) + return NULL; + + strcpy(dup, str); + return dup; } \ No newline at end of file diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h index da1cdd6..ecfd14d 100644 --- a/kernel/src/lib/string.h +++ b/kernel/src/lib/string.h @@ -5,4 +5,5 @@ int strcmp(const char *s1, const char *s2); char *strchr(const char *s, int c); char *strcpy(char *dest, const char *src); char *strrchr(const char *s, int c); -int oct2bin(unsigned char *str, int size); \ No newline at end of file +int oct2bin(unsigned char *str, int size); +char *strdup(const char *str); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 6e60f5a..4e122bd 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -18,11 +18,13 @@ #include #include #include -#include +#include #include #include #include #include +#include +#include __attribute__(( used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); @@ -84,12 +86,22 @@ void kmain(void) { while (1) asm("hlt"); } - + syscall_init(); pit_init(1000); sched_init(); + + vfs_init(); + if (hellofs_init() < 0) { + log("kernel - Failed to initialize HelloFS\n"); + } else { + log("kernel - HelloFS initialized successfully\n"); + } - panic("No working initialization program found. (This is normal due to Soaplin's current state, so please do not report this as a bug)"); + + + panic("No working initialization program found. (This is normal due to " + "Soaplin's current state, so please do not report this as a bug)"); log("kernel - Soaplin initialized sucessfully.\n"); diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/sys/arch/x86_64/rtc.c index c5468d8..7836045 100644 --- a/kernel/src/sys/arch/x86_64/rtc.c +++ b/kernel/src/sys/arch/x86_64/rtc.c @@ -4,38 +4,40 @@ char bcd; unsigned char read_register(unsigned char reg) { - __asm__ volatile("cli"); - outb(RTC_COMMAND, reg); - return inb(RTC_DATA); - __asm__ volatile("sti"); + __asm__ volatile("cli"); + outb(RTC_COMMAND, reg); + return inb(RTC_DATA); + __asm__ volatile("sti"); } void write_register(unsigned char reg, unsigned char value) { - __asm__ volatile("cli"); - outb(RTC_COMMAND, reg); - outb(RTC_DATA, value); - __asm__ volatile("sti"); + __asm__ volatile("cli"); + outb(RTC_COMMAND, reg); + outb(RTC_DATA, value); + __asm__ volatile("sti"); } unsigned char bcd2bin(unsigned char in_bcd) { - return (bcd) ? ((in_bcd >> 4) * 10) + (in_bcd & 0x0F) : in_bcd; + return (bcd) ? ((in_bcd >> 4) * 10) + (in_bcd & 0x0F) : in_bcd; } int rtc_init() { - __asm__ volatile("cli"); - unsigned char status; - status = read_register(RTC_STATUS); - status |= 0x02; // 24 hour clock - status |= 0x10; // update ended interrupts - status &= ~0x20; // no alarm interrupts - status &= ~0x40; // no periodic interrupt - bcd = !(status & 0x04); // check if data type is BCD - write_register(RTC_STATUS, status); + __asm__ volatile("cli"); + unsigned char status; + status = read_register(RTC_STATUS); + status |= 0x02; // 24 hour clock + status |= 0x10; // update ended interrupts + status &= ~0x20; // no alarm interrupts + status &= ~0x40; // no periodic interrupt + bcd = !(status & 0x04); // check if data type is BCD + write_register(RTC_STATUS, status); - outb(0x70, 0x8B); // select register B, and disable NMI - char prev=inb(0x71); // read the current value of register B - outb(0x70, 0x8B); // set the index again (a read will reset the index to register D) - outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B - __asm__ volatile("sti"); - return 0; + outb(0x70, 0x8B); // select register B, and disable NMI + char prev = inb(0x71); // read the current value of register B + outb(0x70, + 0x8B); // set the index again (a read will reset the index to register D) + outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This + // turns on bit 6 of register B + __asm__ volatile("sti"); + return 0; } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.h b/kernel/src/sys/arch/x86_64/rtc.h old mode 100755 new mode 100644 index 8f34e7e..51fb46c --- a/kernel/src/sys/arch/x86_64/rtc.h +++ b/kernel/src/sys/arch/x86_64/rtc.h @@ -1,17 +1,17 @@ #ifndef __TIME_H #define __TIME_H -#define RTC_COMMAND 0x70 -#define RTC_DATA 0x71 -#define RTC_STATUS 0x0B +#define RTC_COMMAND 0x70 +#define RTC_DATA 0x71 +#define RTC_STATUS 0x0B -#define RTC_SECONDS 0x00 -#define RTC_MINUTES 0x02 -#define RTC_HOURS 0x04 -#define RTC_DAY_OF_WEEK 0x06 -#define RTC_DAY 0x07 -#define RTC_MONTH 0x08 -#define RTC_YEAR 0x09 +#define RTC_SECONDS 0x00 +#define RTC_MINUTES 0x02 +#define RTC_HOURS 0x04 +#define RTC_DAY_OF_WEEK 0x06 +#define RTC_DAY 0x07 +#define RTC_MONTH 0x08 +#define RTC_YEAR 0x09 int rtc_init(); diff --git a/kernel/src/sys/error_handling/panic.c b/kernel/src/sys/errhnd/panic.c similarity index 99% rename from kernel/src/sys/error_handling/panic.c rename to kernel/src/sys/errhnd/panic.c index 095c1bf..8c244e0 100644 --- a/kernel/src/sys/error_handling/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -65,10 +65,9 @@ void __panic_display_ascii_art() { "halt the PC.\n"); } - void panic(char *msg) { __panic_display_ascii_art(); - + log("\n"); log("%s\n", msg); log("\n"); diff --git a/kernel/src/sys/error_handling/panic.h b/kernel/src/sys/errhnd/panic.h similarity index 100% rename from kernel/src/sys/error_handling/panic.h rename to kernel/src/sys/errhnd/panic.h From 0772a48c29810e0b6c33fa90f603990981b10a35 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Tue, 13 May 2025 11:24:20 +0200 Subject: [PATCH 08/30] kmain - fix a missing include --- kernel/src/main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/kernel/src/main.c b/kernel/src/main.c index 4e122bd..c1a7d5c 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -24,7 +24,6 @@ #include #include #include -#include __attribute__(( used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); @@ -91,14 +90,9 @@ void kmain(void) { pit_init(1000); sched_init(); - vfs_init(); - if (hellofs_init() < 0) { - log("kernel - Failed to initialize HelloFS\n"); - } else { - log("kernel - HelloFS initialized successfully\n"); - } + //vfs_init(); + - panic("No working initialization program found. (This is normal due to " "Soaplin's current state, so please do not report this as a bug)"); From 31e53e88b9dc3e285f9cf82d87f9d40b981dfabe Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Wed, 14 May 2025 18:15:15 +0200 Subject: [PATCH 09/30] kernel - whatever --- kernel/src/fs/vfs.c | 19 +++++++++++ kernel/src/fs/vfs.h | 21 +++++++++---- kernel/src/fs/vnodes.md | 2 ++ kernel/src/lib/string.c | 12 ++++++- kernel/src/lib/string.h | 4 ++- kernel/src/sys/arch/x86_64/interrupts.c | 32 ++++++++++--------- kernel/src/sys/errhnd/panic.c | 42 +++++++++++++++++++++---- kernel/src/sys/errhnd/panic.h | 6 +++- kernel/src/sys/log.c | 4 +-- kernel/src/sys/syscalls/syscalls_proc.c | 2 +- 10 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 kernel/src/fs/vfs.c create mode 100644 kernel/src/fs/vnodes.md diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c new file mode 100644 index 0000000..72cd25d --- /dev/null +++ b/kernel/src/fs/vfs.c @@ -0,0 +1,19 @@ +#include "fs/vfs.h" +#include "mm/liballoc/liballoc.h" +#include "mm/memop.h" +#include "lib/string.h" + +vnode_t *vfs_create_node(char *name, vnode_type_t type) { + vnode_t *node = (vnode_t *)malloc(sizeof(vnode_t)); + if (!node) { + return NULL; + } + memset(node, 0, sizeof(vnode_t)); + strncpy(node->name, name, sizeof(node->name) - 1); + node->type = type; + node->ops = NULL; + //node->parent = NULL; + //node->child = NULL; + //node->next = NULL; + return node; +} \ No newline at end of file diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h index 9a58668..6a1c4c2 100644 --- a/kernel/src/fs/vfs.h +++ b/kernel/src/fs/vfs.h @@ -11,27 +11,36 @@ struct vnode; typedef uint32_t vnode_type_t; typedef struct vnode_ops { - int (*read)(struct vnode* vn, void* buf, size_t size); + int (*read)(struct vnode* vn, void* buf, size_t off, size_t size); + struct vnode* (*lookup)(struct vnode* vn, const char* name); } vnode_ops_t; typedef struct vnode { char name[256]; vnode_type_t type; - struct vnode* parent; - struct vnode* child; - struct vnode* next; + uint32_t refcount; + //struct vnode* parent; + //struct vnode* child; + //struct vnode* next; struct vnode_ops* ops; void* internal; } vnode_t; +typedef struct mountpoint { + char name[32]; + struct fs* fs; + vnode_t* mountpoint; +} mountpoint_t; + typedef struct fs { char name[32]; - int (*mount)(struct vnode** root); + struct vnode* root; + int (*mount)(struct vnode* mountpoint); } fs_t; void vfs_init(void); int vfs_mount(char *path, fs_t* fs); int vfs_unmount(char *path); int vfs_open(const char* path, vnode_t** result); -int vfs_read(vnode_t* vn, void* buf, size_t size); +int vfs_read(vnode_t* vn, void* buf, size_t off, size_t size); diff --git a/kernel/src/fs/vnodes.md b/kernel/src/fs/vnodes.md new file mode 100644 index 0000000..e33911c --- /dev/null +++ b/kernel/src/fs/vnodes.md @@ -0,0 +1,2 @@ +# Soaplin vnodes +... \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index 1e39b6a..35caf14 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -68,4 +68,14 @@ char *strdup(const char *str) { strcpy(dup, str); return dup; -} \ No newline at end of file +} + +char *strncpy(char *dest, const char *src, size_t n) { + size_t i; + for (i = 0; i < n && src[i] != '\0'; i++) + dest[i] = src[i]; + for (; i < n; i++) + dest[i] = '\0'; + return dest; +} + diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h index ecfd14d..3f4be59 100644 --- a/kernel/src/lib/string.h +++ b/kernel/src/lib/string.h @@ -1,4 +1,5 @@ #pragma once +#include int strlen(const char *str); int strcmp(const char *s1, const char *s2); @@ -6,4 +7,5 @@ char *strchr(const char *s, int c); char *strcpy(char *dest, const char *src); char *strrchr(const char *s, int c); int oct2bin(unsigned char *str, int size); -char *strdup(const char *str); \ No newline at end of file +char *strdup(const char *str); +char *strncpy(char *dest, const char *src, size_t n); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c index c808c80..6d7e3d1 100644 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -8,6 +8,7 @@ #include #include #include +#include int pit_millis = 0; int pit_secs = 0; @@ -19,22 +20,25 @@ void exception_handler(registers_t *regs) { vmm_load_pagemap(vmm_kernel_pm); if (regs->int_no < 32) { - log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, - regs->err_code); - if (regs->int_no == 0xe && vmm_kernel_pm_exists) { - uint64_t cr2; - asm("mov %%cr2, %0" : "=r"(cr2)); - log("ints - PF: Faulting location: %p (%p)\n", cr2, - virt_to_phys(vmm_current_pm, cr2)); - log("ints - PF: Faulting page flags: %p\n", - vmm_get_flags(vmm_current_pm, cr2)); - log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); - } + // Should only be called if the exception is unrecoverable. + panic_ctx("A CPU exception occured.", regs); + //log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, + // regs->err_code); - asm("cli"); - while (1) - asm("hlt"); + //if (regs->int_no == 0xe && vmm_kernel_pm_exists) { + // uint64_t cr2; + // asm("mov %%cr2, %0" : "=r"(cr2)); + // log("ints - PF: Faulting location: %p (%p)\n", cr2, + // virt_to_phys(vmm_current_pm, cr2)); + // log("ints - PF: Faulting page flags: %p\n", + // vmm_get_flags(vmm_current_pm, cr2)); + // log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); + //} + + //asm("cli"); + //while (1) + // asm("hlt"); } if (regs->int_no == 1 + 32) { diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index 8c244e0..e6e770e 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,9 +1,12 @@ #include "sys/arch/x86_64/idt.h" +#include #include static registers_t __panic_regdump; static void __panic_dump_regs() { + memset(&__panic_regdump, 0, sizeof(registers_t)); + asm volatile( // Save general purpose registers "movq %%r15, %0\n\t" @@ -44,15 +47,22 @@ static void __panic_dump_regs() { __panic_regdump.rflags = 0; __panic_regdump.rsp = 0; __panic_regdump.ss = 0; +} + +static void __panic_display_regs(registers_t *regs) { log("-- REGISTER DUMP --\n"); log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", - __panic_regdump.rdi, __panic_regdump.rsi, __panic_regdump.rdx, - __panic_regdump.rcx, __panic_regdump.r8, __panic_regdump.r9); + regs->rdi, regs->rsi, regs->rdx, + regs->rcx, regs->r8, regs->r9); log("RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p\n", - __panic_regdump.rax, __panic_regdump.rbp, __panic_regdump.rbx, - __panic_regdump.r10, __panic_regdump.r11, __panic_regdump.r12); - log("R13: %p, R14: %p, R15: %p\n", __panic_regdump.r13, __panic_regdump.r14, - __panic_regdump.r15); + regs->rax, regs->rbp, regs->rbx, + regs->r10, regs->r11, regs->r12); + log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, + regs->r15); + log("RIP: %p, CS: %d, SS: %d, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", + regs->rip, regs->cs, regs->ss, + regs->rflags, regs->int_no, regs->err_code); + log("RSP: %p\n", regs->rsp); } void __panic_display_ascii_art() { @@ -73,6 +83,26 @@ void panic(char *msg) { log("\n"); __panic_dump_regs(); + __panic_display_regs(&__panic_regdump); + + log("System halted: Please restart your computer manually.\n"); + + asm("cli"); + for (;;) + asm("hlt"); +} + +void panic_ctx(char *msg, registers_t *regs) { + __panic_display_ascii_art(); + + log("\n"); + log("%s\n", msg); + log("\n"); + + if (regs) + __panic_display_regs(regs); + else + log("No register context provided.\n"); log("System halted: Please restart your computer manually.\n"); diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h index 9f5bf6d..5e84ca5 100644 --- a/kernel/src/sys/errhnd/panic.h +++ b/kernel/src/sys/errhnd/panic.h @@ -1 +1,5 @@ -void panic(char *msg); \ No newline at end of file +#pragma once + +#include "sys/arch/x86_64/idt.h" +void panic(char *msg); +void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c index ac77628..20bd1b0 100644 --- a/kernel/src/sys/log.c +++ b/kernel/src/sys/log.c @@ -27,7 +27,7 @@ void log(char *format, ...) { if (ft_ctx) flanterm_write(ft_ctx, buf, strlen(buf)); - /*for (int i = 0;; i++) { + for (int i = 0;; i++) { if (date[i] == '\0') break; @@ -39,7 +39,7 @@ void log(char *format, ...) { break; outb(0xE9, buf[i]); - }*/ + } // spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_proc.c b/kernel/src/sys/syscalls/syscalls_proc.c index 13bca78..962d341 100644 --- a/kernel/src/sys/syscalls/syscalls_proc.c +++ b/kernel/src/sys/syscalls/syscalls_proc.c @@ -1,6 +1,6 @@ #include int syscall_exit(int exit_code) { - // sched_exit(exit_code); + sched_exit(exit_code); return 0; } \ No newline at end of file From 4d52bac946e0de119c6519c24ae97b0b62a6d321 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Wed, 14 May 2025 20:32:26 +0200 Subject: [PATCH 10/30] acpi - start implementing acpi --- kernel/src/main.c | 9 ++- kernel/src/sys/acpi.c | 99 ++++++++++---------------------- kernel/src/sys/acpi.h | 73 +++++++++++------------ kernel/src/sys/arch/x86_64/idt.c | 9 ++- 4 files changed, 76 insertions(+), 114 deletions(-) diff --git a/kernel/src/main.c b/kernel/src/main.c index c1a7d5c..3b47f50 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -73,11 +73,9 @@ void kmain(void) { gdt_init(&kstack[8192]); idt_init(); - fpu_activate(); - sse_init(); - pmm_init(); vmm_init(); + kernel_vma_context = vma_create_context(vmm_kernel_pm); if (!kernel_vma_context) { log("kernel - vma ctx creation failed. halting\n"); @@ -86,9 +84,10 @@ void kmain(void) { asm("hlt"); } + acpi_init(); syscall_init(); - pit_init(1000); - sched_init(); + //pit_init(1000); + //sched_init(); //vfs_init(); diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c index 6c056ae..aee1d31 100644 --- a/kernel/src/sys/acpi.c +++ b/kernel/src/sys/acpi.c @@ -3,48 +3,38 @@ #include "sys/log.h" #include #include +#include #include +#include __attribute__(( used, section(".limine_requests"))) static volatile struct limine_rsdp_request rsdp_req = {.revision = 0, .id = LIMINE_RSDP_REQUEST}; -rsdp_t *rsdp; -int acpi_available = 0; +static int __acpi_uses_xsdt = 0; +static void *__acpi_rsdt_ptr; -int is_xsdt = 0; -xsdt_t *xsdt; -rsdt_t *rsdt; -int item_count = 0; +void *acpi_find_table(const char *name) { + if (!__acpi_uses_xsdt) { + acpi_rsdt *rsdt = (acpi_rsdt *)__acpi_rsdt_ptr; + uint32_t entries = (rsdt->sdt.len - sizeof(rsdt->sdt)) / 4; -static int acpi_validate_rsdp(char *byte_array, size_t size) { - uint32_t sum = 0; - for (int i = 0; i < size; i++) { - sum += byte_array[i]; - } - return (sum & 0xFF) == 0; -} - -void *acpi_find_table(char *sign, int sign_size) { - if (!acpi_available) - return NULL; - - if (is_xsdt) { - for (int i = 0; i < item_count; i++) { - uint64_t *lst = - (uint64_t *)HIGHER_HALF((uint64_t)xsdt->PointerToOtherSDT); - acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF(lst[i]); - - if (!memcmp(ptr->Signature, sign, sign_size)) - return (void *)ptr; + for (uint32_t i = 0; i < entries; i++) { + acpi_sdt *sdt = (acpi_sdt *)HIGHER_HALF(*((uint32_t *)rsdt->table + i)); + if (!memcmp(sdt->sign, name, 4)) + return (void *)sdt; } - } else { - for (int i = 0; i < item_count; i++) { - acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF( - (uint64_t)rsdt->PointerToOtherSDT[i]); - if (!memcmp(ptr->Signature, sign, sign_size)) - return (void *)ptr; + return NULL; + } + + acpi_xsdt *xsdt = (acpi_xsdt *)__acpi_rsdt_ptr; + uint32_t entries = (xsdt->sdt.len - sizeof(xsdt->sdt)) / 8; + + for (uint32_t i = 0; i < entries; i++) { + acpi_sdt *sdt = (acpi_sdt *)HIGHER_HALF(*((uint64_t *)xsdt->table + i)); + if (!memcmp(sdt->sign, name, 4)) { + return (void *)sdt; } } @@ -52,44 +42,17 @@ void *acpi_find_table(char *sign, int sign_size) { } void acpi_init() { - rsdp_t *rsdp = (rsdp_t *)HIGHER_HALF(rsdp_req.response->address); + acpi_rsdp *rsdp = (acpi_rsdp *)rsdp_req.response->address; - if (!rsdp) { - log("acpi - not available: RSDP is NULL!\n"); + if (memcmp(rsdp->sign, "RSD PTR", 7)) + panic("acpi: Invalid RSDP signature!"); + + if (rsdp->revision != 0) { + __acpi_uses_xsdt = 1; + acpi_xsdp *xsdp = (acpi_xsdp *)rsdp; + __acpi_rsdt_ptr = (acpi_xsdt *)HIGHER_HALF((uint64_t)xsdp->xsdt_addr); return; } - if (rsdp->rev < 2) { - if (!acpi_validate_rsdp((char *)rsdp, sizeof(rsdp_t))) { - log("acpi - not available: Was the RSDP hijacked?\n"); - return; - } - rsdt = (rsdt_t *)HIGHER_HALF((uint64_t)rsdp->rsdt_addr); - log("acpi - RSDT found at %p\n", rsdt); - item_count = (rsdt->h.Length - sizeof(acpi_table_header_t)) / 4; - log("acpi - RSDT contains %d entries\n", item_count); - } else { - is_xsdt = 1; - if (!acpi_validate_rsdp((char *)rsdp, sizeof(xsdp_t))) { - log("acpi - not available: Was the XSDP hijacked?\n"); - return; - } - - xsdt = (xsdt_t *)HIGHER_HALF((uint64_t)((xsdp_t *)rsdp)->xsdt_addr); - log("acpi - XSDT found at %p\n", xsdt); - item_count = (xsdt->h.Length - sizeof(acpi_table_header_t)) / 8; - log("acpi - XSDT contains %d entries\n", item_count); - } - - acpi_available = 1; - - void *fadt = acpi_find_table("FACP", 4); - if (!fadt) { - log("acpi - FADT not found\n"); - acpi_available = 0; - return; - } else { - log("acpi - FADT found at %p\n", fadt); - log("acpi - ACPI initialized successfully\n"); - } + __acpi_rsdt_ptr = (acpi_rsdt *)HIGHER_HALF((uint64_t)rsdp->rsdt_addr); } \ No newline at end of file diff --git a/kernel/src/sys/acpi.h b/kernel/src/sys/acpi.h index da28bd6..1e47f4a 100644 --- a/kernel/src/sys/acpi.h +++ b/kernel/src/sys/acpi.h @@ -5,47 +5,48 @@ #define ACPI_RSDP_SIGNATURE "RSD PTR " #define ACPI_RSDP_SIGNATURE_LEN 7 -typedef struct __acpi_table_header { - char Signature[4]; - uint32_t Length; - uint8_t Revision; - uint8_t Checksum; - char OEMID[6]; - char OEMTableID[8]; - uint32_t OEMRevision; - uint32_t CreatorID; - uint32_t CreatorRevision; -} acpi_table_header_t; - -typedef struct __rsdp { - char signature[8]; - uint8_t chksum; - char oemid[6]; - uint8_t rev; +typedef struct { + char sign[8]; + uint8_t checksum; + char oem_id[6]; + uint8_t revision; uint32_t rsdt_addr; -} __attribute__((packed)) rsdp_t; +} __attribute__((packed)) acpi_rsdp; -typedef struct __xsdp { - char signature[8]; - uint8_t chksum; - char oemid[6]; - uint8_t rev; - uint32_t rsdt_addr; // deprecated since version 2.0 +typedef struct { + char sign[8]; + uint8_t checksum; + char oem_id[6]; + uint8_t revision; + uint32_t resv; - uint32_t len; + uint32_t length; uint64_t xsdt_addr; - uint8_t chksum_ex; - uint8_t reserved[3]; -} __attribute__((packed)) xsdp_t; + uint8_t extended_checksum; + uint8_t resv1[3]; +} __attribute__((packed)) acpi_xsdp; -typedef struct __rsdt { - acpi_table_header_t h; - uint32_t *PointerToOtherSDT; -} rsdt_t; +typedef struct { + char sign[4]; + uint32_t len; + uint8_t revision; + uint8_t checksum; + char oem_id[6]; + char oem_table_id[8]; + uint32_t oem_revision; + uint32_t creator_id; + uint32_t creator_revision; +} __attribute__((packed)) acpi_sdt; -typedef struct __xsdt { - acpi_table_header_t h; - uint64_t *PointerToOtherSDT; -} xsdt_t; +typedef struct { + acpi_sdt sdt; + char table[]; +} acpi_rsdt; +typedef struct { + acpi_sdt sdt; + char table[]; +} acpi_xsdt; + +void *acpi_find_table(const char *name); void acpi_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c index 5f1012f..55d4f52 100644 --- a/kernel/src/sys/arch/x86_64/idt.c +++ b/kernel/src/sys/arch/x86_64/idt.c @@ -39,14 +39,13 @@ void idt_init() { idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); vectors[vector] = 1; - pic_init(); - pic_unmask_irq(1); - pic_unmask_irq(8); + // Do not use the legacy PIC. + //pic_init(); + //pic_unmask_irq(1); + //pic_unmask_irq(8); __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("sti"); // set the interrupt flag - // logln(progress, "kinit stage 1", "IDT initialized! Time to receive - // interrupts!\n"); log("idt - initialized\n"); } \ No newline at end of file From a8e919b033825979e39d1c1edb06245eebc3753b Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Thu, 15 May 2025 18:49:09 +0200 Subject: [PATCH 11/30] kernel - v0.7 beta + acpi: add acpi support + lapic: add lapic support + ioapic: add ioapic support + arch/x86_64: add support for "syscall"/"sysret" --- GNUmakefile | 3 +- README.md | 8 +- kernel/src/{sys => }/arch/arch.h | 0 kernel/src/{sys => }/arch/x86_64/cpuid.h | 0 kernel/src/{sys => }/arch/x86_64/fpu.c | 0 kernel/src/{sys => }/arch/x86_64/fpu.h | 0 kernel/src/{sys => }/arch/x86_64/gdt.c | 2 +- kernel/src/{sys => }/arch/x86_64/gdt.h | 0 .../interrupts.asm => arch/x86_64/idt.asm} | 6 +- kernel/src/arch/x86_64/idt.c | 83 ++++++++++++++ kernel/src/{sys => }/arch/x86_64/idt.h | 8 ++ kernel/src/{sys => }/arch/x86_64/io.c | 0 kernel/src/{sys => }/arch/x86_64/io.h | 0 kernel/src/arch/x86_64/msr.h | 28 +++++ kernel/src/arch/x86_64/pit.c | 29 +++++ kernel/src/arch/x86_64/pit.h | 12 ++ kernel/src/{sys => }/arch/x86_64/rtc.c | 0 kernel/src/{sys => }/arch/x86_64/rtc.h | 0 kernel/src/arch/x86_64/smp.c | 49 ++++++++ kernel/src/arch/x86_64/smp.h | 7 ++ kernel/src/{sys => }/arch/x86_64/sse.c | 2 +- kernel/src/{sys => }/arch/x86_64/sse.h | 0 kernel/src/arch/x86_64/syscall.asm | 53 +++++++++ kernel/src/arch/x86_64/syscall.c | 18 +++ kernel/src/arch/x86_64/syscall.h | 7 ++ kernel/src/dev/ioapic.c | 105 ++++++++++++++++++ kernel/src/dev/ioapic.h | 24 ++++ kernel/src/dev/lapic.c | 64 +++++++++++ kernel/src/dev/lapic.h | 52 +++++++++ kernel/src/lib/spinlock.h | 28 +++-- kernel/src/main.c | 34 ++++-- kernel/src/sched/sched.c | 15 ++- kernel/src/sched/sched.h | 6 +- kernel/src/sys/acpi/madt.c | 42 +++++++ kernel/src/sys/acpi/madt.h | 56 ++++++++++ kernel/src/sys/arch/x86_64/idt.c | 51 --------- kernel/src/sys/arch/x86_64/interrupts.c | 60 ---------- kernel/src/sys/arch/x86_64/pic.c | 76 ------------- kernel/src/sys/arch/x86_64/pic.h | 23 ---- kernel/src/sys/arch/x86_64/pit.c | 52 --------- kernel/src/sys/arch/x86_64/pit.h | 17 --- kernel/src/sys/arch/x86_64/smp.c | 4 - kernel/src/sys/arch/x86_64/smp.h | 3 - kernel/src/sys/errhnd/panic.c | 43 ++++++- kernel/src/sys/errhnd/panic.h | 2 +- kernel/src/sys/log.c | 11 +- kernel/src/sys/syscall.c | 8 +- kernel/src/sys/syscall.h | 2 +- limine.conf | 2 +- testing/sk-hello.elf | Bin 4320 -> 4312 bytes testing/test.asm | 7 +- testing/test.bin | 1 + testing/test.o | Bin 608 -> 608 bytes 53 files changed, 772 insertions(+), 331 deletions(-) rename kernel/src/{sys => }/arch/arch.h (100%) rename kernel/src/{sys => }/arch/x86_64/cpuid.h (100%) rename kernel/src/{sys => }/arch/x86_64/fpu.c (100%) rename kernel/src/{sys => }/arch/x86_64/fpu.h (100%) rename kernel/src/{sys => }/arch/x86_64/gdt.c (98%) rename kernel/src/{sys => }/arch/x86_64/gdt.h (100%) rename kernel/src/{sys/arch/x86_64/interrupts.asm => arch/x86_64/idt.asm} (98%) create mode 100644 kernel/src/arch/x86_64/idt.c rename kernel/src/{sys => }/arch/x86_64/idt.h (85%) rename kernel/src/{sys => }/arch/x86_64/io.c (100%) rename kernel/src/{sys => }/arch/x86_64/io.h (100%) create mode 100644 kernel/src/arch/x86_64/msr.h create mode 100644 kernel/src/arch/x86_64/pit.c create mode 100755 kernel/src/arch/x86_64/pit.h rename kernel/src/{sys => }/arch/x86_64/rtc.c (100%) rename kernel/src/{sys => }/arch/x86_64/rtc.h (100%) create mode 100644 kernel/src/arch/x86_64/smp.c create mode 100644 kernel/src/arch/x86_64/smp.h rename kernel/src/{sys => }/arch/x86_64/sse.c (97%) rename kernel/src/{sys => }/arch/x86_64/sse.h (100%) create mode 100644 kernel/src/arch/x86_64/syscall.asm create mode 100644 kernel/src/arch/x86_64/syscall.c create mode 100644 kernel/src/arch/x86_64/syscall.h create mode 100644 kernel/src/dev/ioapic.c create mode 100644 kernel/src/dev/ioapic.h create mode 100644 kernel/src/dev/lapic.c create mode 100644 kernel/src/dev/lapic.h create mode 100644 kernel/src/sys/acpi/madt.c create mode 100644 kernel/src/sys/acpi/madt.h delete mode 100644 kernel/src/sys/arch/x86_64/idt.c delete mode 100644 kernel/src/sys/arch/x86_64/interrupts.c delete mode 100644 kernel/src/sys/arch/x86_64/pic.c delete mode 100755 kernel/src/sys/arch/x86_64/pic.h delete mode 100644 kernel/src/sys/arch/x86_64/pit.c delete mode 100755 kernel/src/sys/arch/x86_64/pit.h delete mode 100644 kernel/src/sys/arch/x86_64/smp.c delete mode 100644 kernel/src/sys/arch/x86_64/smp.h create mode 100644 testing/test.bin diff --git a/GNUmakefile b/GNUmakefile index 6ff16cd..5745a01 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -203,7 +203,8 @@ $(IMAGE_NAME).iso: limine/limine kernel @mkdir -p iso_root/boot/limine @cp -v limine.conf iso_root/boot/limine/ @mkdir -p iso_root/EFI/BOOT - @cp -v initramfs.tar iso_root/ + @cp -v testing/sk-hello.elf iso_root/ +# @cp -v initramfs.tar iso_root/ ifeq ($(ARCH),x86_64) @cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ @cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ diff --git a/README.md b/README.md index 94c4a72..f6fbc5b 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The Soaplin kernel is a new Unix-like operating system kernel. * Simple pre-emptive scheduler * Ring 3 (user mode) support * ELF loader +* ACPI ## In the works * Virtual File System @@ -28,4 +29,9 @@ To build Soaplin, you must ensure you have these: * A compiler (In the future, a custom toolchain would be built.) * A linker -Clone the repo, and run "make" in it! \ No newline at end of file +Clone the repo, and run "make" in it! + +## Acknowledgements +Thanks to all these people :heart: +* Kevin Alavik (kevinalavik): VMAs implementation +* Astrido (asterd-og): IOAPIC/LAPIC (from ZanOS) \ No newline at end of file diff --git a/kernel/src/sys/arch/arch.h b/kernel/src/arch/arch.h similarity index 100% rename from kernel/src/sys/arch/arch.h rename to kernel/src/arch/arch.h diff --git a/kernel/src/sys/arch/x86_64/cpuid.h b/kernel/src/arch/x86_64/cpuid.h similarity index 100% rename from kernel/src/sys/arch/x86_64/cpuid.h rename to kernel/src/arch/x86_64/cpuid.h diff --git a/kernel/src/sys/arch/x86_64/fpu.c b/kernel/src/arch/x86_64/fpu.c similarity index 100% rename from kernel/src/sys/arch/x86_64/fpu.c rename to kernel/src/arch/x86_64/fpu.c diff --git a/kernel/src/sys/arch/x86_64/fpu.h b/kernel/src/arch/x86_64/fpu.h similarity index 100% rename from kernel/src/sys/arch/x86_64/fpu.h rename to kernel/src/arch/x86_64/fpu.h diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c similarity index 98% rename from kernel/src/sys/arch/x86_64/gdt.c rename to kernel/src/arch/x86_64/gdt.c index 61b6ae4..5f18fb0 100644 --- a/kernel/src/sys/arch/x86_64/gdt.c +++ b/kernel/src/arch/x86_64/gdt.c @@ -1,7 +1,7 @@ // #include "sys/log.h" +#include #include #include -#include #include gdt_table def_table = {{ diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/arch/x86_64/gdt.h similarity index 100% rename from kernel/src/sys/arch/x86_64/gdt.h rename to kernel/src/arch/x86_64/gdt.h diff --git a/kernel/src/sys/arch/x86_64/interrupts.asm b/kernel/src/arch/x86_64/idt.asm similarity index 98% rename from kernel/src/sys/arch/x86_64/interrupts.asm rename to kernel/src/arch/x86_64/idt.asm index 860dc37..c7b8f8e 100755 --- a/kernel/src/sys/arch/x86_64/interrupts.asm +++ b/kernel/src/arch/x86_64/idt.asm @@ -42,7 +42,7 @@ isr_stub_%+%1: mov rdi, rsp - call exception_handler + call idt_int_handler popall @@ -58,7 +58,7 @@ isr_stub_%+%1: mov rdi, rsp - call exception_handler + call idt_int_handler popall @@ -66,7 +66,7 @@ isr_stub_%+%1: iretq %endmacro -extern exception_handler +extern idt_int_handler isr_no_err_stub 0 isr_no_err_stub 1 isr_no_err_stub 2 diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c new file mode 100644 index 0000000..2e7ab3f --- /dev/null +++ b/kernel/src/arch/x86_64/idt.c @@ -0,0 +1,83 @@ +// #include "sys/log.h" +#include "dev/ioapic.h" +#include "dev/lapic.h" +#include "mm/vmm.h" +#include "arch/x86_64/smp.h" +#include "sys/errhnd/panic.h" +#include +#include +#include + +__attribute__((aligned(0x10))) static idt_entry_t idt[256]; + +static idtr_t idtr; +static int vectors[256]; +extern void *isr_stub_table[]; +idt_irq_handler_t irq_handler_table[256 - 32]; + +void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { + idt_entry_t *descriptor = &idt[vector]; + + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x28; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; +} + +void idt_register_irq(uint8_t vector, void *isr) { + if (vector <= 14) + ioapic_redirect_irq(bootstrap_lapic_id, vector + 32, vector, false); + + irq_handler_table[vector] = isr; + vectors[vector <= 14 ? vector + 32 : vector] = IDT_VT_IRQ; +} + +void idt_init() { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; + + for (uint16_t vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = IDT_VT_EXCEPTION; + } + + for (uint16_t vector = 32; vector < 256; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = IDT_VT_UNDEFINED; + } + + // Do not use the legacy PIC. + //pic_init(); + //pic_unmask_irq(1); + //pic_unmask_irq(8); + + __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile("sti"); // set the interrupt flag + + log("idt - initialized\n"); +} + + +void idt_int_handler(registers_t *regs) { + vmm_load_pagemap(vmm_kernel_pm); + //log("kernel - Interrupt %d\n", regs->int_no); + + if (regs->int_no < 32) { + panic_ctx("A CPU exception occured.", regs); + } + + int vec = regs->int_no; + if (vec >= 32 && vec < 47) + vec -= 32; + + if (vectors[regs->int_no] == IDT_VT_IRQ) { + idt_irq_handler_t i = irq_handler_table[vec]; + i(regs); + } + + lapic_eoi(); + //pic_ack(regs->int_no - 32); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h similarity index 85% rename from kernel/src/sys/arch/x86_64/idt.h rename to kernel/src/arch/x86_64/idt.h index 015a379..32569f2 100644 --- a/kernel/src/sys/arch/x86_64/idt.h +++ b/kernel/src/arch/x86_64/idt.h @@ -2,6 +2,11 @@ #include +// VT = Vector type +#define IDT_VT_UNDEFINED 0 +#define IDT_VT_EXCEPTION 1 +#define IDT_VT_IRQ 2 + typedef struct { uint64_t r15; uint64_t r14; @@ -50,5 +55,8 @@ typedef struct { uint64_t base; } __attribute__((packed)) idtr_t; +typedef void(*idt_irq_handler_t)(registers_t *regs); + +void idt_register_irq(uint8_t vector, void *isr); void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags); void idt_init(void); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/io.c b/kernel/src/arch/x86_64/io.c similarity index 100% rename from kernel/src/sys/arch/x86_64/io.c rename to kernel/src/arch/x86_64/io.c diff --git a/kernel/src/sys/arch/x86_64/io.h b/kernel/src/arch/x86_64/io.h similarity index 100% rename from kernel/src/sys/arch/x86_64/io.h rename to kernel/src/arch/x86_64/io.h diff --git a/kernel/src/arch/x86_64/msr.h b/kernel/src/arch/x86_64/msr.h new file mode 100644 index 0000000..1761298 --- /dev/null +++ b/kernel/src/arch/x86_64/msr.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#define IA32_GS_MSR 0xC0000101 +#define IA32_GS_KERNEL_MSR 0xC0000102 + +static inline void wrmsr(uint64_t msr, uint64_t value) +{ + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + asm volatile ( + "wrmsr" + : + : "c"(msr), "a"(low), "d"(high) + ); +} + +static inline uint64_t rdmsr(uint64_t msr) +{ + uint32_t low, high; + asm volatile ( + "rdmsr" + : "=a"(low), "=d"(high) + : "c"(msr) + ); + return ((uint64_t)high << 32) | low; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c new file mode 100644 index 0000000..bc64f81 --- /dev/null +++ b/kernel/src/arch/x86_64/pit.c @@ -0,0 +1,29 @@ +#include "arch//x86_64/idt.h" +#include "sched/sched.h" +#include +#include +#include +#include + +uint32_t tick = 0; + +void pit_handler(registers_t *regs) { + //log("PIT"); + tick++; + schedule(regs); +} + +void pit_init() { + outb(0x43, 0x36); + uint16_t div = (uint16_t)(1193180 / 1000); + outb(0x40, (uint8_t)div); + outb(0x40, (uint8_t)(div >> 8)); + idt_register_irq(0, pit_handler); +} + +void pit_sleep(uint32_t ms) { + uint64_t start = tick; + while (tick - start < ms) { + __asm__ volatile ("nop"); + } +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.h b/kernel/src/arch/x86_64/pit.h new file mode 100755 index 0000000..1884a1e --- /dev/null +++ b/kernel/src/arch/x86_64/pit.h @@ -0,0 +1,12 @@ +#ifndef PIT_H +#define PIT_H + +#include +#include + +extern uint32_t tick; + +void pit_init(); +void pit_sleep(uint32_t ms); + +#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/arch/x86_64/rtc.c similarity index 100% rename from kernel/src/sys/arch/x86_64/rtc.c rename to kernel/src/arch/x86_64/rtc.c diff --git a/kernel/src/sys/arch/x86_64/rtc.h b/kernel/src/arch/x86_64/rtc.h similarity index 100% rename from kernel/src/sys/arch/x86_64/rtc.h rename to kernel/src/arch/x86_64/rtc.h diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c new file mode 100644 index 0000000..2355478 --- /dev/null +++ b/kernel/src/arch/x86_64/smp.c @@ -0,0 +1,49 @@ +#include "arch//x86_64/smp.h" +#include "lib/spinlock.h" +#include "sys/log.h" +#include "limine.h" +#include + +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_mp_request + smp_request = {.id = LIMINE_MP_REQUEST, .revision = 0}; + +uint32_t bootstrap_lapic_id = 0; +uint32_t smp_cpu_count = 0; // Number of processors +spinlock_t smp_lock = { 0 }; + +uint32_t ctr = 0; + +void smp_entry(struct limine_mp_info* smp_info) { + //spinlock_acquire(&smp_lock); + + log("smp - CPU %d started (LAPIC ID: %d)\n", smp_info->processor_id, smp_info->lapic_id); + __atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST); + + while (1) + ;; + //spinlock_release(&smp_lock); +} + +void smp_init() { + bootstrap_lapic_id = smp_request.response->bsp_lapic_id; + smp_cpu_count = smp_request.response->cpu_count; + + log("smp - detected %d CPUs\n", smp_cpu_count); + + for (uint64_t i = 0; i < smp_cpu_count; i++) { + if (smp_request.response->cpus[i]->lapic_id != bootstrap_lapic_id) { + uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST); + + __atomic_store_n(&smp_request.response->cpus[i]->goto_address, smp_entry, __ATOMIC_SEQ_CST); + + while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr) + ; + } else { + log("smp - CPU %d is the bootstrap processor (LAPIC ID: %d)\n", i, smp_request.response->cpus[i]->lapic_id); + } + } + + log("smp - initialized\n"); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.h b/kernel/src/arch/x86_64/smp.h new file mode 100644 index 0000000..b375f5f --- /dev/null +++ b/kernel/src/arch/x86_64/smp.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +extern uint32_t bootstrap_lapic_id; + +void smp_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/sse.c b/kernel/src/arch/x86_64/sse.c similarity index 97% rename from kernel/src/sys/arch/x86_64/sse.c rename to kernel/src/arch/x86_64/sse.c index 2f3f021..1fe79ce 100644 --- a/kernel/src/sys/arch/x86_64/sse.c +++ b/kernel/src/arch/x86_64/sse.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/kernel/src/sys/arch/x86_64/sse.h b/kernel/src/arch/x86_64/sse.h similarity index 100% rename from kernel/src/sys/arch/x86_64/sse.h rename to kernel/src/arch/x86_64/sse.h diff --git a/kernel/src/arch/x86_64/syscall.asm b/kernel/src/arch/x86_64/syscall.asm new file mode 100644 index 0000000..de88abe --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.asm @@ -0,0 +1,53 @@ +bits 64 + +section .text + global syscall_entry + extern syscall_handle + +syscall_entry: + swapgs ; switch + mov [gs:0], rsp + mov rsp, [gs:8] + + push 0 + push 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov rdi, rsp + call syscall_handle + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax + add rsp, 16 + + mov [gs:8], rsp + mov rsp, [gs:0] + swapgs + o64 sysret diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c new file mode 100644 index 0000000..34e7df3 --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.c @@ -0,0 +1,18 @@ +#include +#include +#include + +extern void syscall_entry(); + +void __x86_64_syscall_init() { + uint64_t efer = rdmsr(IA32_EFER); + efer |= (1 << 0); + wrmsr(IA32_EFER, efer); + uint64_t star = 0; + star |= ((uint64_t)0x28 << 32); // kernel cs + star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + wrmsr(IA32_STAR, star); + wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); + wrmsr(IA32_CSTAR, 0x0); + wrmsr(IA32_CSTAR + 1, 0x200); +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscall.h b/kernel/src/arch/x86_64/syscall.h new file mode 100644 index 0000000..c64911c --- /dev/null +++ b/kernel/src/arch/x86_64/syscall.h @@ -0,0 +1,7 @@ +#pragma once + +#define IA32_EFER 0xC0000080 +#define IA32_STAR 0xC0000081 +#define IA32_LSTAR 0xC0000082 +#define IA32_CSTAR 0xC0000083 +#define IA32_SFMASK 0xC0000084 diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c new file mode 100644 index 0000000..8c216ce --- /dev/null +++ b/kernel/src/dev/ioapic.c @@ -0,0 +1,105 @@ +#include "sys/acpi/madt.h" +#include +#include +#include + +void ioapic_init() { + madt_ioapic* ioapic = acpi_madt_ioapic_list[0]; + + uint32_t val = ioapic_read(ioapic, IOAPIC_VER); + uint32_t count = ((val >> 16) & 0xFF); + + if ((ioapic_read(ioapic, 0) >> 24) != ioapic->apic_id) { + return; + } + + for (uint8_t i = 0; i <= count; ++i) { + ioapic_write(ioapic, IOAPIC_REDTBL+2*i, 0x00010000 | (32 + i)); + ioapic_write(ioapic, IOAPIC_REDTBL+2*i+1, 0); + } + + log("ioapic - initialized\n"); +} + +void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val) { + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)) = val; +} + +uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg) { + *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; + return *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)); +} + +void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data) { + ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2), (uint32_t)data); + ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), (uint32_t)(data >> 32)); +} + + +uint64_t ioapic_gsi_count(madt_ioapic* ioapic) { + return (ioapic_read(ioapic, 1) & 0xff0000) >> 16; +} + +madt_ioapic* ioapic_get_gsi(uint32_t gsi) { + for (uint64_t i = 0; i < acpi_madt_ioapic_length; i++) { + madt_ioapic* ioapic = acpi_madt_ioapic_list[i]; + if (ioapic->gsi_base <= gsi && ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) + return ioapic; + } + return (madt_ioapic*)0; +} + +void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t flags, bool mask) { + madt_ioapic* ioapic = ioapic_get_gsi(gsi); + + uint64_t redirect = vec; + + if ((flags & (1 << 1)) != 0) { + redirect |= (1 << 13); + } + + if ((flags & (1 << 3)) != 0) { + redirect |= (1 << 15); + } + + if (mask) redirect |= (1 << 16); + else redirect &= ~(1 << 16); + + redirect |= (uint64_t)lapic_id << 56; + + uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + 16; + ioapic_write(ioapic, redir_table, (uint32_t)redirect); + ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); +} + +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) { + uint8_t idx = 0; + madt_iso* iso = (madt_iso*)0; + + while (idx < acpi_madt_iso_length) { + iso = acpi_madt_iso_list[idx]; + if (iso->irq_src == irq) { + ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); + return; + } + idx++; + } + + ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); +} + +uint32_t ioapic_get_redirect_irq(uint8_t irq) { + uint8_t idx = 0; + madt_iso* iso; + + while (idx < acpi_madt_iso_length) { + iso = acpi_madt_iso_list[idx]; + if (iso->irq_src == irq) { + return iso->gsi; + } + idx++; + } + + return irq; +} \ No newline at end of file diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h new file mode 100644 index 0000000..a5c1793 --- /dev/null +++ b/kernel/src/dev/ioapic.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +#define IOAPIC_REGSEL 0x0 +#define IOAPIC_IOWIN 0x10 + +#define IOAPIC_ID 0x0 +#define IOAPIC_VER 0x01 +#define IOAPIC_ARB 0x02 +#define IOAPIC_REDTBL 0x10 + + +void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val); +uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg); + +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask); +uint32_t ioapic_get_redirect_irq(uint8_t irq); + +void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data); + +void ioapic_init(); \ No newline at end of file diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c new file mode 100644 index 0000000..8b3c83f --- /dev/null +++ b/kernel/src/dev/lapic.c @@ -0,0 +1,64 @@ +#include "mm/pmm.h" +#include +#include + +uint64_t apic_ticks = 0; + +void lapic_init() { + lapic_write(0xf0, 0x1ff); + log("lapic - initialized\n"); +} + +void lapic_stop_timer() { + // We do this to avoid overlapping oneshots + lapic_write(LAPIC_TIMER_INITCNT, 0); + lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); +} + +void lapic_oneshot(uint8_t vec, uint64_t ms) { + lapic_stop_timer(); + lapic_write(LAPIC_TIMER_DIV, 0); + lapic_write(LAPIC_TIMER_LVT, vec); + lapic_write(LAPIC_TIMER_INITCNT, apic_ticks * ms); +} + +void lapic_calibrate_timer() { + lapic_stop_timer(); + lapic_write(LAPIC_TIMER_DIV, 0); + lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff); + lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF); + //pit_sleep(1); // 1 ms + lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); + uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT); + apic_ticks = ticks; + lapic_stop_timer(); +} + +void lapic_write(uint32_t reg, uint32_t val) { + *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)) = val; +} + +uint32_t lapic_read(uint32_t reg) { + return *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)); +} + +void lapic_eoi() { + lapic_write((uint8_t)0xb0, 0x0); +} + +void lapic_ipi(uint32_t id, uint8_t dat) { + lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT); + lapic_write(LAPIC_ICRLO, dat); +} + +void lapic_send_all_int(uint32_t id, uint32_t vec) { + lapic_ipi(id, vec | LAPIC_ICRAIS); +} + +void lapic_send_others_int(uint32_t id, uint32_t vec) { + lapic_ipi(id, vec | LAPIC_ICRAES); +} + +uint32_t lapic_get_id() { + return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; +} \ No newline at end of file diff --git a/kernel/src/dev/lapic.h b/kernel/src/dev/lapic.h new file mode 100644 index 0000000..a4b5fed --- /dev/null +++ b/kernel/src/dev/lapic.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +#define LAPIC_PPR 0x00a0 + +#define LAPIC_ICRLO 0x0300 +#define LAPIC_ICRHI 0x0310 + +#define LAPIC_ICINI 0x0500 +#define LAPIC_ICSTR 0x0600 + +#define LAPIC_ICEDGE 0x0000 + +#define LAPIC_ICPEND 0x00001000 +#define LAPIC_ICPHYS 0x00000000 +#define LAPIC_ICASSR 0x00004000 +#define LAPIC_ICSHRTHND 0x00000000 +#define LAPIC_ICDESTSHIFT 24 + +#define LAPIC_ICRAIS 0x00080000 +#define LAPIC_ICRAES 0x000c0000 + +// Timer + +#define LAPIC_TIMER_DIV 0x3E0 +#define LAPIC_TIMER_INITCNT 0x380 +#define LAPIC_TIMER_LVT 0x320 +#define LAPIC_TIMER_DISABLE 0x10000 +#define LAPIC_TIMER_CURCNT 0x390 +#define LAPIC_TIMER_PERIODIC 0x20000 + +void lapic_init(); + +void lapic_stop_timer(); +void lapic_oneshot(uint8_t vec, uint64_t ms); +void lapic_calibrate_timer(); + +void lapic_write(uint32_t reg, uint32_t val); +uint32_t lapic_read(uint32_t reg); + +void lapic_eoi(); + +void lapic_ipi(uint32_t id, uint8_t dat); + +void lapic_send_all_int(uint32_t id, uint32_t vec); +void lapic_send_others_int(uint32_t id, uint32_t vec); + +void lapic_init_cpu(uint32_t id); +void lapic_start_cpu(uint32_t id, uint32_t vec); +uint32_t lapic_get_id(); \ No newline at end of file diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h index 894ff5b..49229f7 100644 --- a/kernel/src/lib/spinlock.h +++ b/kernel/src/lib/spinlock.h @@ -1,17 +1,31 @@ #pragma once +#include #include typedef struct spinlock { - volatile int locked; + volatile int locked; } spinlock_t; -inline void spinlock_acquire(spinlock_t *lock) { - while (__sync_lock_test_and_set(&(lock)->locked, 1)) - while ((lock)->locked) - __asm__ volatile("pause"); +static inline void spinlock_acquire(spinlock_t *lock) { + //uint64_t timeout = 1000000; // Adjust this value based on your needs + + for (;;) { + if (__atomic_exchange_n(&lock->locked, 1, __ATOMIC_ACQUIRE) == 0) { + return; + } + + while (__atomic_load_n(&lock->locked, __ATOMIC_RELAXED)) { + /**if (--timeout == 0) { + // Force unlock after too many attempts + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); + continue; + }**/ + __asm__ volatile("pause" ::: "memory"); + } + } } -inline void spinlock_release(spinlock_t *lock) { - __sync_lock_release(&(lock)->locked); +static inline void spinlock_release(spinlock_t *lock) { + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); } \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 3b47f50..746aab4 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,3 +1,5 @@ +#include "dev/ioapic.h" +#include "dev/lapic.h" #include "exec/elf.h" #include "exec/exec.h" #include "mm/liballoc/liballoc.h" @@ -6,8 +8,10 @@ #include "mm/vmm.h" #include "sched/sched.h" #include "sys/acpi.h" -#include "sys/arch/x86_64/pit.h" -#include "sys/arch/x86_64/sse.h" +#include "sys/acpi/madt.h" +#include "arch//x86_64/pit.h" +#include "arch//x86_64/smp.h" +#include "arch//x86_64/sse.h" #include "sys/syscall.h" #include #include @@ -15,9 +19,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -69,7 +73,7 @@ void kmain(void) { VGA8, 8, 16, 0, 0, 0, 0); } - printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); + printf("\n Soaplin 0.7-sild is booting up your computer...\n\n"); gdt_init(&kstack[8192]); idt_init(); @@ -85,16 +89,26 @@ void kmain(void) { } acpi_init(); + madt_init(); + ioapic_init(); + lapic_init(); + pit_init(); + smp_init(); + syscall_init(); - //pit_init(1000); - //sched_init(); + sched_init(); //vfs_init(); - panic("No working initialization program found. (This is normal due to " - "Soaplin's current state, so please do not report this as a bug)"); + //panic("No working initialization program found. (This is normal due to " + // "Soaplin's current state, so please do not report this as a bug)"); + + program_t *p = elf_load(module_request.response->modules[0]->address, 1); + + sched_process *proc = sched_create("Test", p->entry, p->pm, + SCHED_USER_PROCESS); log("kernel - Soaplin initialized sucessfully.\n"); diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index f16f6b6..3ebb371 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -1,11 +1,13 @@ #include "sched/sched.h" +#include "arch/x86_64/msr.h" #include "mm/memop.h" #include "mm/pmm.h" #include "mm/vmm.h" -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" #include "sys/log.h" #include #include +#include sched_process *proc_list; sched_process *curr_proc; @@ -31,7 +33,7 @@ void sched_init() { // We must initialize the process list. // By default, sched_create will append to this list. - proc_list = pmm_request_page(); + proc_list = malloc(sizeof(sched_process)); memcpy(proc_list->name, "System\0", 7); proc_list->pid = -1; proc_list->type = SCHED_EMPTY; @@ -49,7 +51,7 @@ void sched_init() { sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags) { - sched_process *proc = pmm_request_page(); + sched_process *proc = malloc(sizeof(sched_process)); memset(proc, 0, sizeof(sched_process)); memcpy(proc->name, name, strlen(name) > 128 ? 128 : strlen(name)); @@ -64,10 +66,12 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, proc->pm = pm; uint64_t *stack_phys = pmm_request_page(); + uint64_t *kstack_phys = pmm_request_page(); uint64_t *stack_virt = (uint64_t *)0x40000000; + proc->kernel_stack = HIGHER_HALF(kstack_phys) + PMM_PAGE_SIZE; if (flags == SCHED_KERNEL_PROCESS) { - proc->stack_base = stack_phys; + proc->stack_base = HIGHER_HALF(stack_phys); proc->stack_base_physical = stack_phys; proc->stack_end = proc->stack_base + PMM_PAGE_SIZE; } else if (flags == SCHED_USER_PROCESS) { @@ -110,6 +114,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, "disabled.\n"); } + log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip); return proc; @@ -152,5 +157,7 @@ void schedule(registers_t *regs) { memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); + //log("sched - proc %d\n", curr_proc->pid); vmm_load_pagemap(curr_proc->pm); } \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index f328d7a..4a05629 100644 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -1,7 +1,7 @@ #pragma once #include "mm/vmm.h" -#include "sys/arch/x86_64/idt.h" +#include "arch/x86_64/idt.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. #define SCHED_USER_PROCESS \ @@ -11,6 +11,9 @@ typedef enum { SCHED_RUNNING, SCHED_DIED, SCHED_EMPTY } sched_proc_type; typedef struct _sched_process { + uint64_t *stack_base; + uint64_t *kernel_stack; // Kernel-mode stack used for "syscall" + char name[128]; int pid; int type; @@ -20,7 +23,6 @@ typedef struct _sched_process { pagemap_t *pm; uint64_t *stack_end; - uint64_t *stack_base; uint64_t *stack_base_physical; struct _sched_process *next; diff --git a/kernel/src/sys/acpi/madt.c b/kernel/src/sys/acpi/madt.c new file mode 100644 index 0000000..f41dc04 --- /dev/null +++ b/kernel/src/sys/acpi/madt.c @@ -0,0 +1,42 @@ +#include "sys/acpi.h" +#include +#include +#include +#include + +madt_ioapic* acpi_madt_ioapic_list[256] = {0}; +madt_iso* acpi_madt_iso_list[256] = {0}; + +uint32_t acpi_madt_ioapic_length = 0; +uint32_t acpi_madt_iso_length = 0; + +uint64_t* acpi_lapic_addr = 0; + +void madt_init() { + void *addr = acpi_find_table("APIC"); + if (!addr) + panic("madt: Failed to find MADT table!"); + + acpi_madt *madt = (acpi_madt *)addr; + + uint64_t offset = 0; + int i = 0; + + while (1) { + if (offset > madt->sdt.len - sizeof(acpi_madt)) + break; + + madt_entry* entry = (madt_entry*)(madt->table + offset); + + if (entry->type == 0) + i++; + else if (entry->type == 1) + acpi_madt_ioapic_list[acpi_madt_ioapic_length++] = (madt_ioapic*)entry; + else if (entry->type == 2) + acpi_madt_iso_list[acpi_madt_iso_length++] = (madt_iso*)entry; + else if (entry->type == 5) + acpi_lapic_addr = (uint64_t*)((madt_lapic_addr*)entry)->phys_lapic; + + offset += entry->length; + } +} \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.h b/kernel/src/sys/acpi/madt.h new file mode 100644 index 0000000..1ce1138 --- /dev/null +++ b/kernel/src/sys/acpi/madt.h @@ -0,0 +1,56 @@ +#pragma once + +#include "sys/acpi.h" +#include +typedef struct { + acpi_sdt sdt; + + uint32_t lapic_address; + uint32_t flags; + + char table[]; +} acpi_madt; + +typedef struct { + uint8_t type; + uint8_t length; +} madt_entry; + +typedef struct { + madt_entry un; + uint8_t cpu_id; + uint8_t apic_id; + uint32_t flags; +} madt_cpu_lapic; + +typedef struct { + madt_entry un; + uint8_t apic_id; + uint8_t reserved; + uint32_t apic_addr; + uint32_t gsi_base; +} madt_ioapic; + +typedef struct { + madt_entry un; + uint8_t bus_src; + uint8_t irq_src; + uint32_t gsi; + uint16_t flags; +} madt_iso; + +typedef struct { + madt_entry un; + uint16_t reserved; + uint64_t phys_lapic; +} madt_lapic_addr; + +extern madt_ioapic* acpi_madt_ioapic_list[256]; +extern madt_iso* acpi_madt_iso_list[256]; + +extern uint32_t acpi_madt_ioapic_length; +extern uint32_t acpi_madt_iso_length; + +extern uint64_t* acpi_lapic_addr; + +void madt_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c deleted file mode 100644 index 55d4f52..0000000 --- a/kernel/src/sys/arch/x86_64/idt.c +++ /dev/null @@ -1,51 +0,0 @@ -// #include "sys/log.h" -#include "sys/arch/x86_64/pic.h" -#include -#include - -__attribute__((aligned(0x10))) static idt_entry_t idt[256]; - -static idtr_t idtr; - -void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { - idt_entry_t *descriptor = &idt[vector]; - - descriptor->isr_low = (uint64_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x28; - descriptor->ist = 0; - descriptor->attributes = flags; - descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; - descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; - descriptor->reserved = 0; -} - -static int vectors[256]; - -extern void *isr_stub_table[]; - -void idt_init() { - idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - - for (uint16_t vector = 0; vector <= 256; vector++) { - if (vector == 0x80) - continue; // We skip the syscall handler, since it should be called from - // user space. - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = 1; - } - - uint16_t vector = 0x80; - idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); - vectors[vector] = 1; - - // Do not use the legacy PIC. - //pic_init(); - //pic_unmask_irq(1); - //pic_unmask_irq(8); - - __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT - __asm__ volatile("sti"); // set the interrupt flag - - log("idt - initialized\n"); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c deleted file mode 100644 index 6d7e3d1..0000000 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "mm/pmm.h" -#include "mm/vmm.h" -#include "sched/sched.h" -#include "sys/arch/x86_64/pic.h" -#include "sys/arch/x86_64/rtc.h" -#include "sys/log.h" -#include "sys/syscall.h" -#include -#include -#include -#include - -int pit_millis = 0; -int pit_secs = 0; -extern int vmm_kernel_pm_exists; - -void pit_handler(registers_t *regs); - -void exception_handler(registers_t *regs) { - vmm_load_pagemap(vmm_kernel_pm); - - if (regs->int_no < 32) { - - // Should only be called if the exception is unrecoverable. - panic_ctx("A CPU exception occured.", regs); - //log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, - // regs->err_code); - - //if (regs->int_no == 0xe && vmm_kernel_pm_exists) { - // uint64_t cr2; - // asm("mov %%cr2, %0" : "=r"(cr2)); - // log("ints - PF: Faulting location: %p (%p)\n", cr2, - // virt_to_phys(vmm_current_pm, cr2)); - // log("ints - PF: Faulting page flags: %p\n", - // vmm_get_flags(vmm_current_pm, cr2)); - // log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); - //} - - //asm("cli"); - //while (1) - // asm("hlt"); - } - - if (regs->int_no == 1 + 32) { - if (inb(0x60) & 0x80) { - pic_ack(regs->int_no - 32); - return; - } - - log("ints - keyboard\n"); - } else if (regs->int_no == 32 + 8) { - log("rtc\n"); - } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { - pit_handler(regs); - } else if (regs->int_no == 0x80) { - syscall_handle(regs); - } - - pic_ack(regs->int_no - 32); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.c b/kernel/src/sys/arch/x86_64/pic.c deleted file mode 100644 index 53ce230..0000000 --- a/kernel/src/sys/arch/x86_64/pic.c +++ /dev/null @@ -1,76 +0,0 @@ -// #include "sys/log.h" -#include -// #include -#include - -void pic_init() { - // if (acpi_available) - // return; - - uint8_t a1, a2; - - a1 = inb(PIC1_DATA); - a2 = inb(PIC2_DATA); - - outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(PIC1_DATA, 0x20); - io_wait(); - outb(PIC2_DATA, 8); - io_wait(); - outb(PIC1_DATA, 4); - io_wait(); - outb(PIC2_DATA, 2); - io_wait(); - outb(PIC1_DATA, ICW4_8086); - io_wait(); - outb(PIC2_DATA, ICW4_8086); - io_wait(); - - outb(PIC1_DATA, a1); - outb(PIC2_DATA, a2); -} - -void pic_ack(int intno) { - if (intno >= 8) { - outb(PIC2_COMMAND, 0x20); - } - - outb(PIC1_COMMAND, 0x20); -} - -void pic_disable() // if we want APIC -{ - outb(PIC2_DATA, 0xff); - outb(PIC1_DATA, 0xff); -} - -void pic_mask_irq(uint8_t irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) | (1 << irq); - outb(port, value); -} - -void pic_unmask_irq(uint8_t irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) & ~(1 << irq); - outb(port, value); -} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.h b/kernel/src/sys/arch/x86_64/pic.h deleted file mode 100755 index 8365bbc..0000000 --- a/kernel/src/sys/arch/x86_64/pic.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - -#pragma once - -#include - -#define PIC1_COMMAND 0x20 -#define PIC1_DATA 0x21 -#define PIC2_COMMAND 0xA0 -#define PIC2_DATA 0xA1 -#define PIC_EOI 0x20 - -#define ICW1_INIT 0x10 -#define ICW1_ICW4 0x01 -#define ICW4_8086 0x01 - -void pic_init(); -void pic_ack(int intno); -void pic_disable(); // if we want APIC -void pic_mask_irq(uint8_t irq); -void pic_unmask_irq(uint8_t irq); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.c b/kernel/src/sys/arch/x86_64/pit.c deleted file mode 100644 index 32b60c3..0000000 --- a/kernel/src/sys/arch/x86_64/pit.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "sched/sched.h" -#include "sys/arch/x86_64/idt.h" -#include "sys/arch/x86_64/pic.h" -#include -#include -#ifdef __x86_64__ - -#include -#include -// #include - -uint32_t tick = 0; - -void pit_handler(registers_t *regs) { - tick++; - - schedule(regs); - // Scheduler_Schedule(regs); -} - -void pit_init(uint32_t frequency) { - uint32_t divisor = PIT_FREQUENCY / frequency; - outb(0x43, 0x34); - outb(0x40, (uint8_t)(divisor & 0xFF)); - outb(0x40, (uint8_t)((divisor >> 8) & 0xFF)); - - pic_unmask_irq(0); -} - -void sleep(uint32_t seconds) { - uint32_t eticks = tick + seconds * HZ; - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -void sleep_ms(uint32_t milliseconds) { - uint32_t eticks = tick + (milliseconds * HZ) / 1000; - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -// todo: unistd: add usleep function -void usleep(uint32_t usecs) { - uint32_t eticks = tick + (usecs * HZ); - while (tick < eticks) { - __asm__ __volatile__("hlt"); - } -} - -#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.h b/kernel/src/sys/arch/x86_64/pit.h deleted file mode 100755 index 0131be8..0000000 --- a/kernel/src/sys/arch/x86_64/pit.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef PIT_H -#define PIT_H - -#include -#include - -#define PIT_FREQUENCY 1193182 -#define HZ 1000 - -extern uint32_t tick; - -void pit_init(uint32_t frequency); -void sleep(uint32_t seconds); -void sleep_ms(uint32_t milliseconds); -void usleep(uint32_t usecs); - -#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/smp.c b/kernel/src/sys/arch/x86_64/smp.c deleted file mode 100644 index 33183b6..0000000 --- a/kernel/src/sys/arch/x86_64/smp.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "sys/arch/x86_64/smp.h" -#include "limine.h" - -void smp_init() {} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/smp.h b/kernel/src/sys/arch/x86_64/smp.h deleted file mode 100644 index a5c81cb..0000000 --- a/kernel/src/sys/arch/x86_64/smp.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void smp_init(); \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index e6e770e..dd71a1b 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,4 +1,5 @@ -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" +#include "lib/spinlock.h" #include #include @@ -49,6 +50,39 @@ static void __panic_dump_regs() { __panic_regdump.ss = 0; } +static void __panic_display_page_fault(registers_t *regs) { + if (regs->int_no != 14) // 14 is the page fault interrupt number + return; + + uint64_t cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2)); + + log("Page Fault Details:\n"); + log("Faulting Address (CR2): 0x%lx\n", cr2); + log("Error Code: %d\n", regs->err_code); + log("Flags:\n"); + if (!(regs->err_code & (1 << 0))) + log(" - Page Not Present\n"); + else + log(" - Protection Violation\n"); + + if (regs->err_code & (1 << 1)) + log(" - Write Access\n"); + else + log(" - Read Access\n"); + + if (regs->err_code & (1 << 2)) + log(" - User-Mode Access\n"); + else + log(" - Kernel-Mode Access\n"); + + if (regs->err_code & (1 << 3)) + log(" - Reserved Bits Set\n"); + + if (regs->err_code & (1 << 4)) + log(" - Instruction Fetch\n"); +} + static void __panic_display_regs(registers_t *regs) { log("-- REGISTER DUMP --\n"); log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", @@ -59,10 +93,13 @@ static void __panic_display_regs(registers_t *regs) { regs->r10, regs->r11, regs->r12); log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, regs->r15); - log("RIP: %p, CS: %d, SS: %d, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", + log("RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, regs->err_code); log("RSP: %p\n", regs->rsp); + + if (regs->int_no == 14) // If it's a page fault + __panic_display_page_fault(regs); } void __panic_display_ascii_art() { @@ -104,6 +141,8 @@ void panic_ctx(char *msg, registers_t *regs) { else log("No register context provided.\n"); + + log("System halted: Please restart your computer manually.\n"); asm("cli"); diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h index 5e84ca5..147263b 100644 --- a/kernel/src/sys/errhnd/panic.h +++ b/kernel/src/sys/errhnd/panic.h @@ -1,5 +1,5 @@ #pragma once -#include "sys/arch/x86_64/idt.h" +#include "arch/x86_64/idt.h" void panic(char *msg); void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c index 20bd1b0..e6f3988 100644 --- a/kernel/src/sys/log.c +++ b/kernel/src/sys/log.c @@ -1,4 +1,4 @@ -#include "sys/arch/x86_64/io.h" +#include "arch//x86_64/io.h" #include "sys/gfx/flanterm/flanterm.h" #include #include @@ -10,10 +10,11 @@ extern struct flanterm_context *ft_ctx; static spinlock_t log_lock = {0}; void log(char *format, ...) { - // spinlock_acquire(&log_lock); - // TODO: replace this call with a call to printf() when the RTC is // implemented. + + //spinlock_acquire(&log_lock); + char *date = "1970-01-01 00:00:00 | "; if (ft_ctx) flanterm_write(ft_ctx, date, strlen(date)); @@ -40,6 +41,6 @@ void log(char *format, ...) { outb(0xE9, buf[i]); } - - // spinlock_release(&log_lock); + + //spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 0a3567c..c132998 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -8,6 +8,8 @@ static syscall syscall_table[1024]; static int syscall_initialized = 0; +extern void __x86_64_syscall_init(); + // Stub function for undefined syscalls. static uint64_t __syscall_undefined() { return 0; } @@ -30,6 +32,8 @@ void syscall_handle(registers_t *regs) { return; } + log("Hello!\n"); + regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); return; @@ -48,9 +52,11 @@ void syscall_register(int id, syscall handler) { extern void syscall_exit(int exit_code); -void syscall_init() { +void syscall_init() { for (int i = 0; i < 1024; i++) syscall_table[i] = (syscall)__syscall_undefined; syscall_register(0, (syscall)syscall_exit); + + __x86_64_syscall_init(); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.h b/kernel/src/sys/syscall.h index 5fce348..1d0f3f0 100644 --- a/kernel/src/sys/syscall.h +++ b/kernel/src/sys/syscall.h @@ -1,6 +1,6 @@ #pragma once -#include "sys/arch/x86_64/idt.h" +#include "arch//x86_64/idt.h" #include /// A function that defines a system call. diff --git a/limine.conf b/limine.conf index fd0bd86..df98d06 100755 --- a/limine.conf +++ b/limine.conf @@ -6,4 +6,4 @@ verbose: yes protocol: limine path: boot():/boot/soaplin - module_path: boot():/initramfs.tar \ No newline at end of file + module_path: boot():/sk-hello.elf \ No newline at end of file diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index b36d9a6f1dee0312bd55559d73aa3cdf9027b654..257f986d7fe37189320b805fea11bfba94db923b 100755 GIT binary patch delta 50 zcmaE$ctdf52BXA8O><5b1_)r;m^q!Fg`f5HzscMJA(ImX6c|}1Hwu^o$(;h~06|L( AoB#j- delta 64 zcmcbi_&{-j2BX46O><6e1_e1PJAfO&CmM!9|HtT?q+OdWST6<e1OnfNMy@QK^fx)Bs0ORXlle-yP8CfR_GP!ePq*elj85jVa COAf~X From b2ec0360554df404f149a58e79c4d5d2f6f55263 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Fri, 16 May 2025 08:01:37 +0200 Subject: [PATCH 12/30] =?UTF-8?q?kernel=20-=20various=20changes=20+=20vmm:?= =?UTF-8?q?=20higher=20half=20should=20not=20be=20identify-mapped=20+=20pa?= =?UTF-8?q?nic:=20now=20displays=20current=20process=20+=20kernel:=20fix?= =?UTF-8?q?=20physical=20addresses=20(d=CC=B7=CC=93=CD=83=CD=8A=CD=81?= =?UTF-8?q?=CC=92=CC=A7=CC=A9=CC=9C=CC=A6=CC=A5=CC=B0=CD=94=CC=BB=CD=94?= =?UTF-8?q?=CC=96=CD=8E=CD=9C=CC=B3=CC=97=CC=ABo=CC=B8=CC=9B=CC=91=CC=90?= =?UTF-8?q?=CC=BF=CD=A0=CC=BF=CD=9D=CD=86=CD=99=CD=8E=CC=A0=CD=8E=CC=A9?= =?UTF-8?q?=CC=A4=CC=AD=CC=AC=CC=99=CD=9A=CC=AC=CC=A3=CD=87=CC=A4=CC=BC=20?= =?UTF-8?q?=CC=B7=CC=82=CD=9B=CD=86=CD=9D=CD=A0=CD=81=CD=82=CC=97=CC=9F?= =?UTF-8?q?=CD=85=CC=98=CD=8E=CC=A5=CC=A4=CC=ADN=CC=B4=CC=8A=CC=90=CC=85?= =?UTF-8?q?=CC=80=CC=8C=CC=8F=CD=9D=CC=9B=CC=95=CD=86=CC=8B=CD=A0=CC=A8?= =?UTF-8?q?=CC=A5=CC=A9=CD=85=CC=BA=CD=9C=CD=9A=CC=BA=CC=A0=CD=99=CC=BC?= =?UTF-8?q?=CC=99=CC=AF=CC=B1=CD=9A=CC=ABo=CC=B5=CD=84=CC=81=CC=8D=CD=80?= =?UTF-8?q?=CC=83=CC=8B=CC=87=CC=84=CD=83=CD=9D=CD=8A=CC=8E=CC=AA=CD=9A?= =?UTF-8?q?=CC=9E=CC=9E=CC=9C=CD=8E=CD=89=CC=A6t=CC=B6=CC=82=CC=91=CC=93?= =?UTF-8?q?=CD=8C=CD=82=CC=BE=CC=91=CD=84=CD=92=CC=BE=CC=BE=CC=81=CD=90?= =?UTF-8?q?=CD=86=CD=8A=CD=82=CD=8D=CC=A9=CC=A1=CC=A4=CC=B9=CC=A4=20=CC=B4?= =?UTF-8?q?=CD=98=CC=9A=CD=9D=CC=8A=CC=9A=CC=8D=CC=92=CD=9B=CD=8C=CD=98?= =?UTF-8?q?=CC=8C=CD=82=CD=98=CC=AB=CC=BA=CC=A8=CC=A6I=CC=B6=CD=82=CC=81?= =?UTF-8?q?=CD=9C=CC=A5=CD=9A=CC=AF=CC=96=CC=99=CC=A9d=CC=B8=CC=92=CD=A0?= =?UTF-8?q?=CC=A2=CC=97=CD=89=CC=A0=CC=A1=CC=B9e=CC=B8=CC=9A=CD=91=CC=88?= =?UTF-8?q?=CC=8B=CC=89=CC=8B=CD=98=CC=93=CC=90=CC=8A=CC=AA=CC=BA=CC=A1?= =?UTF-8?q?=CD=8E=CD=96=CD=9A=CC=97=CC=9F=CC=9F=CC=A5=CD=8D=CD=9Cn=CC=B8?= =?UTF-8?q?=CC=8D=CD=90=CD=97=CC=88=CD=8C=CC=80=CD=83=CD=A0=CC=83=CC=81?= =?UTF-8?q?=CD=81=CC=A1t=CC=B6=CC=92=CC=84=CD=92=CC=83=CC=90=CD=88=CD=88?= =?UTF-8?q?=CD=9C=CC=A6=CC=A2=CC=BB=CC=B0=CD=8E=CC=AA=CC=B0i=CC=B4=CC=83?= =?UTF-8?q?=CC=90=CC=8D=CC=81=CC=BE=CC=80=CC=8F=CC=8F=CC=91=CC=9A=CD=92?= =?UTF-8?q?=CD=95=CC=BC=CC=BB=CD=93=CD=9A=CD=85=CD=95=CC=B2=CC=AC=CC=A4?= =?UTF-8?q?=CD=88=CC=9C=CC=A3f=CC=B7=CD=9B=CC=BC=CC=BB=CC=A0=CC=A0=CC=A1?= =?UTF-8?q?=CD=94=CC=AA=CD=8D=CC=A8y=CC=B4=CC=93=CD=92=CC=9A=CC=86=CC=8E?= =?UTF-8?q?=CD=89=CD=93=20=CC=B6=CC=8C=CC=89=CC=95=CC=81=CC=91=CD=97=CD=8B?= =?UTF-8?q?=CC=80=CD=85=CC=9F=CD=99=CD=96=CC=99=CC=9F=CD=8D=CC=9F=CD=95?= =?UTF-8?q?=CC=9E=CC=A5=CC=B9=CD=87=CD=85M=CC=B7=CD=83=CD=99=CC=AC=CC=B2a?= =?UTF-8?q?=CC=B6=CC=8D=CD=80=CC=AB=CC=B0=CC=9E=CC=BA=CC=96p=CC=B6=CD=8B?= =?UTF-8?q?=CD=82=CC=8F=CC=8D=CC=BE=CC=BD=CC=A1=CC=97=CC=96=CC=A8=CC=B9?= =?UTF-8?q?=CC=A9=CC=AB=CC=A1=CC=AF=CC=9E=CC=AC=CD=9C=CD=85=20=CC=B6=CC=80?= =?UTF-8?q?=CC=BD=CD=98=CD=91=CC=82=CC=BF=CC=84=CC=88=CC=87=CD=83=CC=A7?= =?UTF-8?q?=CC=AB=CD=89=CC=9D=CC=AE=CC=B3=CC=A8=CD=8E=CD=8D=CC=A7=CC=B1?= =?UTF-8?q?=CC=9F=CC=AA=CC=9DH=CC=B6=CD=80=CC=AE=CC=97=CC=A3=CC=A8=CC=AA?= =?UTF-8?q?=CC=A8=CD=93=CC=BA=CD=99=CD=88=CD=99i=CC=B6=CC=94=CC=90=CC=87?= =?UTF-8?q?=CC=89=CD=83=CD=92=CD=98=CD=9B=CC=85=CC=BF=CC=95=CD=8A=CC=8D?= =?UTF-8?q?=CD=86=CC=B0=CD=87=CC=B9=CC=A7=CD=99=CC=A9=CD=8D=CD=8E=CC=A1?= =?UTF-8?q?=CC=AE=CC=A4=CC=A6=CC=9C=CC=BB=CD=8E=CC=9Eg=CC=B7=CC=91=CC=91?= =?UTF-8?q?=CD=8B=CD=84=CD=8C=CD=9D=CD=90=CD=A0=CC=8A=CD=9D=CD=80=CD=96?= =?UTF-8?q?=CD=99=CD=8D=CD=93=CC=AF=CC=AA=CC=A9h=CC=B4=CC=82=CD=9D=CD=8A?= =?UTF-8?q?=CD=91=CD=9B=CC=86=CC=AB=CC=AA=CC=9F=CC=9E=CC=AD=CC=9F=CC=A2?= =?UTF-8?q?=CC=A1=CD=95=CC=96=CD=8Ee=CC=B4=CD=86=CC=92=CC=BE=CC=BE=CD=83?= =?UTF-8?q?=CC=88=CD=8A=CD=83=CC=A1=CC=97=CC=A8=CC=B1=CC=B1=CD=99=CD=94?= =?UTF-8?q?=CC=BB=CD=85=CC=A4=CD=8Er=CC=B5=CC=94=CC=8C=CC=9B=CC=83=CC=87?= =?UTF-8?q?=CD=8A=CC=BD=CD=80=CC=89=CC=BD=CC=8A=CD=8C=CC=BF=CC=81=CD=88?= =?UTF-8?q?=CC=A9=CD=8D=20=CC=B7=CC=87=CC=9B=CC=87=CD=84=CC=91=CC=8D=CC=8A?= =?UTF-8?q?=CD=92=CC=84=CD=81=CD=9B=CC=A9=CC=A8=CC=B9=CC=A1=CC=B9H=CC=B7?= =?UTF-8?q?=CD=8B=CD=81=CC=9A=CD=98=CC=86=CD=A0=CD=8B=CC=82=CD=98=CC=AA?= =?UTF-8?q?=CC=A8=CC=9C=CD=9C=CC=A4=CD=8D=CC=BB=CD=8E=CC=B2=CC=9Ca=CC=B7?= =?UTF-8?q?=CD=81=CC=81=CC=BD=CC=89=CC=92=CD=8C=CD=81=CC=93=CC=A8=CC=A0?= =?UTF-8?q?=CD=93=CC=AB=CD=85=CC=B2l=CC=B4=CC=86=CC=8E=CC=84=CC=95=CC=8A?= =?UTF-8?q?=CD=84=CC=90=CC=BE=CC=8F=CC=BF=CC=9B=CD=88=CC=A4=CC=BA=CC=A2?= =?UTF-8?q?=CC=B1=CC=99=CC=ACf=CC=B8=CC=82=CC=B0=CD=93=CC=A6=CC=BA=CC=B0?= =?UTF-8?q?=CC=AF=CD=9A=CD=9C=CC=A2=CC=A3=CC=99=CD=9C=CD=94=CC=BA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- GNUmakefile | 2 +- kernel/src/arch/x86_64/idt.c | 17 +++--- kernel/src/arch/x86_64/idt.h | 4 +- kernel/src/arch/x86_64/msr.h | 26 +++------ kernel/src/arch/x86_64/pit.c | 13 ++--- kernel/src/arch/x86_64/pit.h | 3 +- kernel/src/arch/x86_64/smp.c | 53 ++++++++++--------- kernel/src/arch/x86_64/sse.c | 2 +- kernel/src/arch/x86_64/syscall.c | 3 +- kernel/src/arch/x86_64/syscall.h | 2 +- kernel/src/dev/ioapic.c | 62 ++++++++++++---------- kernel/src/dev/ioapic.h | 18 +++---- kernel/src/dev/lapic.c | 14 ++--- kernel/src/fs/vfs.c | 26 ++++----- kernel/src/fs/vfs.h | 40 +++++++------- kernel/src/lib/spinlock.h | 34 ++++++------ kernel/src/lib/string.c | 1 - kernel/src/main.c | 31 ++++++----- kernel/src/mm/vmm.c | 6 +-- kernel/src/sched/sched.c | 7 ++- kernel/src/sched/sched.h | 2 +- kernel/src/sys/acpi.c | 6 +-- kernel/src/sys/acpi/madt.c | 46 ++++++++-------- kernel/src/sys/acpi/madt.h | 6 +-- kernel/src/sys/errhnd/panic.c | 88 ++++++++++++++++--------------- kernel/src/sys/log.c | 10 ++-- kernel/src/sys/syscall.c | 2 +- kernel/src/sys/syscall.h | 2 +- testing/sk-hello.elf | Bin 4312 -> 4320 bytes testing/test.asm | 1 + testing/test.o | Bin 608 -> 608 bytes 32 files changed, 265 insertions(+), 265 deletions(-) mode change 100755 => 100644 kernel/src/arch/x86_64/pit.h diff --git a/.gitignore b/.gitignore index 31c65c9..bda1078 100755 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /.cache *.iso *.hdd -/compile_commands.json \ No newline at end of file +/compile_commands.json +/.idea \ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile index 5745a01..3adffb8 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR ARCH := x86_64 # Default user QEMU flags. These are appended to the QEMU command calls. -QEMUFLAGS := -m 2G -debugcon stdio -no-reboot -no-shutdown +QEMUFLAGS := -m 2G -debugcon stdio -no-reboot -no-shutdown override IMAGE_NAME := sild-live-$(ARCH) diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index 2e7ab3f..39ce4ce 100644 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -1,11 +1,11 @@ // #include "sys/log.h" +#include "arch/x86_64/smp.h" #include "dev/ioapic.h" #include "dev/lapic.h" #include "mm/vmm.h" -#include "arch/x86_64/smp.h" #include "sys/errhnd/panic.h" +#include #include -#include #include __attribute__((aligned(0x10))) static idt_entry_t idt[256]; @@ -50,9 +50,9 @@ void idt_init() { } // Do not use the legacy PIC. - //pic_init(); - //pic_unmask_irq(1); - //pic_unmask_irq(8); + // pic_init(); + // pic_unmask_irq(1); + // pic_unmask_irq(8); __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("sti"); // set the interrupt flag @@ -60,11 +60,10 @@ void idt_init() { log("idt - initialized\n"); } - void idt_int_handler(registers_t *regs) { vmm_load_pagemap(vmm_kernel_pm); - //log("kernel - Interrupt %d\n", regs->int_no); - + // log("kernel - Interrupt %d\n", regs->int_no); + if (regs->int_no < 32) { panic_ctx("A CPU exception occured.", regs); } @@ -79,5 +78,5 @@ void idt_int_handler(registers_t *regs) { } lapic_eoi(); - //pic_ack(regs->int_no - 32); + // pic_ack(regs->int_no - 32); } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h index 32569f2..3bf8d94 100644 --- a/kernel/src/arch/x86_64/idt.h +++ b/kernel/src/arch/x86_64/idt.h @@ -5,7 +5,7 @@ // VT = Vector type #define IDT_VT_UNDEFINED 0 #define IDT_VT_EXCEPTION 1 -#define IDT_VT_IRQ 2 +#define IDT_VT_IRQ 2 typedef struct { uint64_t r15; @@ -55,7 +55,7 @@ typedef struct { uint64_t base; } __attribute__((packed)) idtr_t; -typedef void(*idt_irq_handler_t)(registers_t *regs); +typedef void (*idt_irq_handler_t)(registers_t *regs); void idt_register_irq(uint8_t vector, void *isr); void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags); diff --git a/kernel/src/arch/x86_64/msr.h b/kernel/src/arch/x86_64/msr.h index 1761298..5354f78 100644 --- a/kernel/src/arch/x86_64/msr.h +++ b/kernel/src/arch/x86_64/msr.h @@ -5,24 +5,14 @@ #define IA32_GS_MSR 0xC0000101 #define IA32_GS_KERNEL_MSR 0xC0000102 -static inline void wrmsr(uint64_t msr, uint64_t value) -{ - uint32_t low = value & 0xFFFFFFFF; - uint32_t high = value >> 32; - asm volatile ( - "wrmsr" - : - : "c"(msr), "a"(low), "d"(high) - ); +static inline void wrmsr(uint64_t msr, uint64_t value) { + uint32_t low = value & 0xFFFFFFFF; + uint32_t high = value >> 32; + asm volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high)); } -static inline uint64_t rdmsr(uint64_t msr) -{ - uint32_t low, high; - asm volatile ( - "rdmsr" - : "=a"(low), "=d"(high) - : "c"(msr) - ); - return ((uint64_t)high << 32) | low; +static inline uint64_t rdmsr(uint64_t msr) { + uint32_t low, high; + asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); + return ((uint64_t)high << 32) | low; } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c index bc64f81..2818395 100644 --- a/kernel/src/arch/x86_64/pit.c +++ b/kernel/src/arch/x86_64/pit.c @@ -1,14 +1,14 @@ -#include "arch//x86_64/idt.h" +#include "arch/x86_64/idt.h" #include "sched/sched.h" +#include +#include #include #include -#include -#include uint32_t tick = 0; void pit_handler(registers_t *regs) { - //log("PIT"); + // log("PIT"); tick++; schedule(regs); } @@ -18,12 +18,13 @@ void pit_init() { uint16_t div = (uint16_t)(1193180 / 1000); outb(0x40, (uint8_t)div); outb(0x40, (uint8_t)(div >> 8)); - idt_register_irq(0, pit_handler); } +void pit_enable() { idt_register_irq(0, pit_handler); } + void pit_sleep(uint32_t ms) { uint64_t start = tick; while (tick - start < ms) { - __asm__ volatile ("nop"); + __asm__ volatile("nop"); } } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.h b/kernel/src/arch/x86_64/pit.h old mode 100755 new mode 100644 index 1884a1e..92c7bde --- a/kernel/src/arch/x86_64/pit.h +++ b/kernel/src/arch/x86_64/pit.h @@ -1,12 +1,13 @@ #ifndef PIT_H #define PIT_H +#include #include -#include extern uint32_t tick; void pit_init(); void pit_sleep(uint32_t ms); +void pit_enable(); #endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c index 2355478..d913504 100644 --- a/kernel/src/arch/x86_64/smp.c +++ b/kernel/src/arch/x86_64/smp.c @@ -1,49 +1,52 @@ -#include "arch//x86_64/smp.h" +#include "arch/x86_64/smp.h" #include "lib/spinlock.h" -#include "sys/log.h" #include "limine.h" +#include "sys/log.h" #include __attribute__(( - used, - section(".limine_requests"))) static volatile struct limine_mp_request + used, section(".limine_requests"))) static volatile struct limine_mp_request smp_request = {.id = LIMINE_MP_REQUEST, .revision = 0}; uint32_t bootstrap_lapic_id = 0; uint32_t smp_cpu_count = 0; // Number of processors -spinlock_t smp_lock = { 0 }; +spinlock_t smp_lock = {0}; uint32_t ctr = 0; -void smp_entry(struct limine_mp_info* smp_info) { - //spinlock_acquire(&smp_lock); +void smp_entry(struct limine_mp_info *smp_info) { + // spinlock_acquire(&smp_lock); - log("smp - CPU %d started (LAPIC ID: %d)\n", smp_info->processor_id, smp_info->lapic_id); - __atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST); + log("smp - CPU %d started (LAPIC ID: %d)\n", smp_info->processor_id, + smp_info->lapic_id); + __atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST); - while (1) - ;; - //spinlock_release(&smp_lock); + while (1) + ; + ; + // spinlock_release(&smp_lock); } void smp_init() { - bootstrap_lapic_id = smp_request.response->bsp_lapic_id; - smp_cpu_count = smp_request.response->cpu_count; + bootstrap_lapic_id = smp_request.response->bsp_lapic_id; + smp_cpu_count = smp_request.response->cpu_count; - log("smp - detected %d CPUs\n", smp_cpu_count); + log("smp - detected %d CPUs\n", smp_cpu_count); - for (uint64_t i = 0; i < smp_cpu_count; i++) { - if (smp_request.response->cpus[i]->lapic_id != bootstrap_lapic_id) { - uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST); + for (uint64_t i = 0; i < smp_cpu_count; i++) { + if (smp_request.response->cpus[i]->lapic_id != bootstrap_lapic_id) { + uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST); - __atomic_store_n(&smp_request.response->cpus[i]->goto_address, smp_entry, __ATOMIC_SEQ_CST); + __atomic_store_n(&smp_request.response->cpus[i]->goto_address, smp_entry, + __ATOMIC_SEQ_CST); - while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr) - ; - } else { - log("smp - CPU %d is the bootstrap processor (LAPIC ID: %d)\n", i, smp_request.response->cpus[i]->lapic_id); - } + while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr) + ; + } else { + log("smp - CPU %d is the bootstrap processor (LAPIC ID: %d)\n", i, + smp_request.response->cpus[i]->lapic_id); } + } - log("smp - initialized\n"); + log("smp - initialized\n"); } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/sse.c b/kernel/src/arch/x86_64/sse.c index 1fe79ce..84339f0 100644 --- a/kernel/src/arch/x86_64/sse.c +++ b/kernel/src/arch/x86_64/sse.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index 34e7df3..8d6a97d 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -10,7 +10,8 @@ void __x86_64_syscall_init() { wrmsr(IA32_EFER, efer); uint64_t star = 0; star |= ((uint64_t)0x28 << 32); // kernel cs - star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + star |= ((uint64_t)0x30 + << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) wrmsr(IA32_STAR, star); wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); wrmsr(IA32_CSTAR, 0x0); diff --git a/kernel/src/arch/x86_64/syscall.h b/kernel/src/arch/x86_64/syscall.h index c64911c..479d406 100644 --- a/kernel/src/arch/x86_64/syscall.h +++ b/kernel/src/arch/x86_64/syscall.h @@ -1,6 +1,6 @@ #pragma once -#define IA32_EFER 0xC0000080 +#define IA32_EFER 0xC0000080 #define IA32_STAR 0xC0000081 #define IA32_LSTAR 0xC0000082 #define IA32_CSTAR 0xC0000083 diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c index 8c216ce..5803024 100644 --- a/kernel/src/dev/ioapic.c +++ b/kernel/src/dev/ioapic.c @@ -1,11 +1,11 @@ #include "sys/acpi/madt.h" #include -#include #include +#include void ioapic_init() { - madt_ioapic* ioapic = acpi_madt_ioapic_list[0]; - + madt_ioapic *ioapic = acpi_madt_ioapic_list[0]; + uint32_t val = ioapic_read(ioapic, IOAPIC_VER); uint32_t count = ((val >> 16) & 0xFF); @@ -14,44 +14,49 @@ void ioapic_init() { } for (uint8_t i = 0; i <= count; ++i) { - ioapic_write(ioapic, IOAPIC_REDTBL+2*i, 0x00010000 | (32 + i)); - ioapic_write(ioapic, IOAPIC_REDTBL+2*i+1, 0); + ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i, 0x00010000 | (32 + i)); + ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i + 1, 0); } - + log("ioapic - initialized\n"); } -void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val) { - *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; - *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)) = val; +void ioapic_write(madt_ioapic *ioapic, uint8_t reg, uint32_t val) { + *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = + reg; + *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)) = val; } -uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg) { - *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = reg; - return *((volatile uint32_t*)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)); +uint32_t ioapic_read(madt_ioapic *ioapic, uint8_t reg) { + *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = + reg; + return *( + (volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)); } -void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data) { +void ioapic_set_entry(madt_ioapic *ioapic, uint8_t idx, uint64_t data) { ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2), (uint32_t)data); - ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), (uint32_t)(data >> 32)); + ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), + (uint32_t)(data >> 32)); } - -uint64_t ioapic_gsi_count(madt_ioapic* ioapic) { +uint64_t ioapic_gsi_count(madt_ioapic *ioapic) { return (ioapic_read(ioapic, 1) & 0xff0000) >> 16; } -madt_ioapic* ioapic_get_gsi(uint32_t gsi) { +madt_ioapic *ioapic_get_gsi(uint32_t gsi) { for (uint64_t i = 0; i < acpi_madt_ioapic_length; i++) { - madt_ioapic* ioapic = acpi_madt_ioapic_list[i]; - if (ioapic->gsi_base <= gsi && ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) + madt_ioapic *ioapic = acpi_madt_ioapic_list[i]; + if (ioapic->gsi_base <= gsi && + ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) return ioapic; } - return (madt_ioapic*)0; + return (madt_ioapic *)0; } -void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t flags, bool mask) { - madt_ioapic* ioapic = ioapic_get_gsi(gsi); +void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, + uint16_t flags, bool mask) { + madt_ioapic *ioapic = ioapic_get_gsi(gsi); uint64_t redirect = vec; @@ -63,8 +68,10 @@ void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t redirect |= (1 << 15); } - if (mask) redirect |= (1 << 16); - else redirect &= ~(1 << 16); + if (mask) + redirect |= (1 << 16); + else + redirect &= ~(1 << 16); redirect |= (uint64_t)lapic_id << 56; @@ -73,9 +80,10 @@ void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); } -void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) { +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, + bool mask) { uint8_t idx = 0; - madt_iso* iso = (madt_iso*)0; + madt_iso *iso = (madt_iso *)0; while (idx < acpi_madt_iso_length) { iso = acpi_madt_iso_list[idx]; @@ -91,7 +99,7 @@ void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) uint32_t ioapic_get_redirect_irq(uint8_t irq) { uint8_t idx = 0; - madt_iso* iso; + madt_iso *iso; while (idx < acpi_madt_iso_length) { iso = acpi_madt_iso_list[idx]; diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h index a5c1793..86f7c6f 100644 --- a/kernel/src/dev/ioapic.h +++ b/kernel/src/dev/ioapic.h @@ -5,20 +5,20 @@ #include #define IOAPIC_REGSEL 0x0 -#define IOAPIC_IOWIN 0x10 +#define IOAPIC_IOWIN 0x10 -#define IOAPIC_ID 0x0 -#define IOAPIC_VER 0x01 -#define IOAPIC_ARB 0x02 +#define IOAPIC_ID 0x0 +#define IOAPIC_VER 0x01 +#define IOAPIC_ARB 0x02 #define IOAPIC_REDTBL 0x10 +void ioapic_write(madt_ioapic *ioapic, uint8_t reg, uint32_t val); +uint32_t ioapic_read(madt_ioapic *ioapic, uint8_t reg); -void ioapic_write(madt_ioapic* ioapic, uint8_t reg, uint32_t val); -uint32_t ioapic_read(madt_ioapic* ioapic, uint8_t reg); - -void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask); +void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, + bool mask); uint32_t ioapic_get_redirect_irq(uint8_t irq); -void ioapic_set_entry(madt_ioapic* ioapic, uint8_t idx, uint64_t data); +void ioapic_set_entry(madt_ioapic *ioapic, uint8_t idx, uint64_t data); void ioapic_init(); \ No newline at end of file diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c index 8b3c83f..b83c3c4 100644 --- a/kernel/src/dev/lapic.c +++ b/kernel/src/dev/lapic.c @@ -27,7 +27,7 @@ void lapic_calibrate_timer() { lapic_write(LAPIC_TIMER_DIV, 0); lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff); lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF); - //pit_sleep(1); // 1 ms + // pit_sleep(1); // 1 ms lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT); apic_ticks = ticks; @@ -35,16 +35,14 @@ void lapic_calibrate_timer() { } void lapic_write(uint32_t reg, uint32_t val) { - *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)) = val; + *((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg)) = val; } uint32_t lapic_read(uint32_t reg) { - return *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)); + return *((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg)); } -void lapic_eoi() { - lapic_write((uint8_t)0xb0, 0x0); -} +void lapic_eoi() { lapic_write((uint8_t)0xb0, 0x0); } void lapic_ipi(uint32_t id, uint8_t dat) { lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT); @@ -59,6 +57,4 @@ void lapic_send_others_int(uint32_t id, uint32_t vec) { lapic_ipi(id, vec | LAPIC_ICRAES); } -uint32_t lapic_get_id() { - return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; -} \ No newline at end of file +uint32_t lapic_get_id() { return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; } \ No newline at end of file diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c index 72cd25d..bcbf98f 100644 --- a/kernel/src/fs/vfs.c +++ b/kernel/src/fs/vfs.c @@ -1,19 +1,19 @@ #include "fs/vfs.h" +#include "lib/string.h" #include "mm/liballoc/liballoc.h" #include "mm/memop.h" -#include "lib/string.h" vnode_t *vfs_create_node(char *name, vnode_type_t type) { - vnode_t *node = (vnode_t *)malloc(sizeof(vnode_t)); - if (!node) { - return NULL; - } - memset(node, 0, sizeof(vnode_t)); - strncpy(node->name, name, sizeof(node->name) - 1); - node->type = type; - node->ops = NULL; - //node->parent = NULL; - //node->child = NULL; - //node->next = NULL; - return node; + vnode_t *node = (vnode_t *)malloc(sizeof(vnode_t)); + if (!node) { + return NULL; + } + memset(node, 0, sizeof(vnode_t)); + strncpy(node->name, name, sizeof(node->name) - 1); + node->type = type; + node->ops = NULL; + // node->parent = NULL; + // node->child = NULL; + // node->next = NULL; + return node; } \ No newline at end of file diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h index 6a1c4c2..a85c826 100644 --- a/kernel/src/fs/vfs.h +++ b/kernel/src/fs/vfs.h @@ -6,41 +6,41 @@ struct vnode; #define VN_FILE 1 -#define VN_DIR 2 +#define VN_DIR 2 typedef uint32_t vnode_type_t; typedef struct vnode_ops { - int (*read)(struct vnode* vn, void* buf, size_t off, size_t size); - struct vnode* (*lookup)(struct vnode* vn, const char* name); + int (*read)(struct vnode *vn, void *buf, size_t off, size_t size); + struct vnode *(*lookup)(struct vnode *vn, const char *name); } vnode_ops_t; typedef struct vnode { - char name[256]; - vnode_type_t type; - uint32_t refcount; - //struct vnode* parent; - //struct vnode* child; - //struct vnode* next; + char name[256]; + vnode_type_t type; + uint32_t refcount; + // struct vnode* parent; + // struct vnode* child; + // struct vnode* next; - struct vnode_ops* ops; - void* internal; + struct vnode_ops *ops; + void *internal; } vnode_t; typedef struct mountpoint { - char name[32]; - struct fs* fs; - vnode_t* mountpoint; + char name[32]; + struct fs *fs; + vnode_t *mountpoint; } mountpoint_t; typedef struct fs { - char name[32]; - struct vnode* root; - int (*mount)(struct vnode* mountpoint); + char name[32]; + struct vnode *root; + int (*mount)(struct vnode *mountpoint); } fs_t; void vfs_init(void); -int vfs_mount(char *path, fs_t* fs); +int vfs_mount(char *path, fs_t *fs); int vfs_unmount(char *path); -int vfs_open(const char* path, vnode_t** result); -int vfs_read(vnode_t* vn, void* buf, size_t off, size_t size); +int vfs_open(const char *path, vnode_t **result); +int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size); diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h index 49229f7..bf54abe 100644 --- a/kernel/src/lib/spinlock.h +++ b/kernel/src/lib/spinlock.h @@ -4,28 +4,28 @@ #include typedef struct spinlock { - volatile int locked; + volatile int locked; } spinlock_t; static inline void spinlock_acquire(spinlock_t *lock) { - //uint64_t timeout = 1000000; // Adjust this value based on your needs - - for (;;) { - if (__atomic_exchange_n(&lock->locked, 1, __ATOMIC_ACQUIRE) == 0) { - return; - } - - while (__atomic_load_n(&lock->locked, __ATOMIC_RELAXED)) { - /**if (--timeout == 0) { - // Force unlock after too many attempts - __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); - continue; - }**/ - __asm__ volatile("pause" ::: "memory"); - } + // uint64_t timeout = 1000000; // Adjust this value based on your needs + + for (;;) { + if (__atomic_exchange_n(&lock->locked, 1, __ATOMIC_ACQUIRE) == 0) { + return; } + + while (__atomic_load_n(&lock->locked, __ATOMIC_RELAXED)) { + /**if (--timeout == 0) { + // Force unlock after too many attempts + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); + continue; + }**/ + __asm__ volatile("pause" ::: "memory"); + } + } } static inline void spinlock_release(spinlock_t *lock) { - __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); + __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); } \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index 35caf14..71eb5a9 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -78,4 +78,3 @@ char *strncpy(char *dest, const char *src, size_t n) { dest[i] = '\0'; return dest; } - diff --git a/kernel/src/main.c b/kernel/src/main.c index 746aab4..e1dde83 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,3 +1,6 @@ +#include "arch/x86_64/pit.h" +#include "arch/x86_64/smp.h" +#include "arch/x86_64/sse.h" #include "dev/ioapic.h" #include "dev/lapic.h" #include "exec/elf.h" @@ -9,25 +12,22 @@ #include "sched/sched.h" #include "sys/acpi.h" #include "sys/acpi/madt.h" -#include "arch//x86_64/pit.h" -#include "arch//x86_64/smp.h" -#include "arch//x86_64/sse.h" #include "sys/syscall.h" +#include +#include +#include #include +#include #include #include #include #include #include -#include -#include -#include #include #include #include #include #include -#include __attribute__(( used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); @@ -79,7 +79,7 @@ void kmain(void) { idt_init(); pmm_init(); vmm_init(); - + kernel_vma_context = vma_create_context(vmm_kernel_pm); if (!kernel_vma_context) { log("kernel - vma ctx creation failed. halting\n"); @@ -87,7 +87,7 @@ void kmain(void) { while (1) asm("hlt"); } - + acpi_init(); madt_init(); ioapic_init(); @@ -97,21 +97,20 @@ void kmain(void) { syscall_init(); sched_init(); - - //vfs_init(); + // vfs_init(); - - //panic("No working initialization program found. (This is normal due to " - // "Soaplin's current state, so please do not report this as a bug)"); + // panic("No working initialization program found. (This is normal due to " + // "Soaplin's current state, so please do not report this as a bug)"); program_t *p = elf_load(module_request.response->modules[0]->address, 1); - sched_process *proc = sched_create("Test", p->entry, p->pm, - SCHED_USER_PROCESS); + sched_process *proc = + sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS); log("kernel - Soaplin initialized sucessfully.\n"); + pit_enable(); while (1) ; ; diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index cc246f0..f84bf9b 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -49,7 +49,7 @@ void vmm_release_pm(pagemap_t *pm) { } void vmm_sanity_check() { - uint64_t *my_memory = pmm_request_page(); + uint64_t *my_memory = HIGHER_HALF(pmm_request_page()); *my_memory = 0x40; pagemap_t *pm = vmm_alloc_pm(); @@ -113,14 +113,14 @@ void vmm_init() { log("vmm - mapping address from 0x0 to 0x100000000...\n"); for (uint64_t gb4 = 0; gb4 < 0x100000000; gb4 += PMM_PAGE_SIZE) { - vmm_map(vmm_kernel_pm, gb4, gb4, VMM_PRESENT | VMM_WRITABLE); + //vmm_map(vmm_kernel_pm, gb4, gb4, VMM_PRESENT | VMM_WRITABLE); vmm_map(vmm_kernel_pm, (uint64_t)HIGHER_HALF(gb4), gb4, VMM_PRESENT | VMM_WRITABLE); } vmm_load_pagemap(vmm_kernel_pm); - vmm_sanity_check(); + //vmm_sanity_check(); log("vmm - initialized!\n"); } diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index 3ebb371..69e0abf 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -1,13 +1,13 @@ #include "sched/sched.h" +#include "arch/x86_64/idt.h" #include "arch/x86_64/msr.h" #include "mm/memop.h" #include "mm/pmm.h" #include "mm/vmm.h" -#include "arch//x86_64/idt.h" #include "sys/log.h" #include -#include #include +#include sched_process *proc_list; sched_process *curr_proc; @@ -114,7 +114,6 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, "disabled.\n"); } - log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip); return proc; @@ -158,6 +157,6 @@ void schedule(registers_t *regs) { memcpy(regs, &curr_proc->regs, sizeof(registers_t)); wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); - //log("sched - proc %d\n", curr_proc->pid); + // log("sched - proc %d\n", curr_proc->pid); vmm_load_pagemap(curr_proc->pm); } \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index 4a05629..971b651 100644 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -1,7 +1,7 @@ #pragma once -#include "mm/vmm.h" #include "arch/x86_64/idt.h" +#include "mm/vmm.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. #define SCHED_USER_PROCESS \ diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c index aee1d31..f284c67 100644 --- a/kernel/src/sys/acpi.c +++ b/kernel/src/sys/acpi.c @@ -42,7 +42,7 @@ void *acpi_find_table(const char *name) { } void acpi_init() { - acpi_rsdp *rsdp = (acpi_rsdp *)rsdp_req.response->address; + acpi_rsdp *rsdp = (acpi_rsdp *)HIGHER_HALF(rsdp_req.response->address); if (memcmp(rsdp->sign, "RSD PTR", 7)) panic("acpi: Invalid RSDP signature!"); @@ -50,9 +50,9 @@ void acpi_init() { if (rsdp->revision != 0) { __acpi_uses_xsdt = 1; acpi_xsdp *xsdp = (acpi_xsdp *)rsdp; - __acpi_rsdt_ptr = (acpi_xsdt *)HIGHER_HALF((uint64_t)xsdp->xsdt_addr); + __acpi_rsdt_ptr = (void *)HIGHER_HALF(xsdp->xsdt_addr); return; } - __acpi_rsdt_ptr = (acpi_rsdt *)HIGHER_HALF((uint64_t)rsdp->rsdt_addr); + __acpi_rsdt_ptr = (void *)HIGHER_HALF(rsdp->rsdt_addr); } \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.c b/kernel/src/sys/acpi/madt.c index f41dc04..e73b668 100644 --- a/kernel/src/sys/acpi/madt.c +++ b/kernel/src/sys/acpi/madt.c @@ -4,39 +4,39 @@ #include #include -madt_ioapic* acpi_madt_ioapic_list[256] = {0}; -madt_iso* acpi_madt_iso_list[256] = {0}; +madt_ioapic *acpi_madt_ioapic_list[256] = {0}; +madt_iso *acpi_madt_iso_list[256] = {0}; uint32_t acpi_madt_ioapic_length = 0; uint32_t acpi_madt_iso_length = 0; -uint64_t* acpi_lapic_addr = 0; +uint64_t *acpi_lapic_addr = 0; void madt_init() { - void *addr = acpi_find_table("APIC"); - if (!addr) - panic("madt: Failed to find MADT table!"); + void *addr = acpi_find_table("APIC"); + if (!addr) + panic("madt: Failed to find MADT table!"); - acpi_madt *madt = (acpi_madt *)addr; + acpi_madt *madt = (acpi_madt *)addr; - uint64_t offset = 0; - int i = 0; + uint64_t offset = 0; + int i = 0; - while (1) { - if (offset > madt->sdt.len - sizeof(acpi_madt)) - break; + while (1) { + if (offset > madt->sdt.len - sizeof(acpi_madt)) + break; - madt_entry* entry = (madt_entry*)(madt->table + offset); + madt_entry *entry = (madt_entry *)(madt->table + offset); - if (entry->type == 0) - i++; - else if (entry->type == 1) - acpi_madt_ioapic_list[acpi_madt_ioapic_length++] = (madt_ioapic*)entry; - else if (entry->type == 2) - acpi_madt_iso_list[acpi_madt_iso_length++] = (madt_iso*)entry; - else if (entry->type == 5) - acpi_lapic_addr = (uint64_t*)((madt_lapic_addr*)entry)->phys_lapic; + if (entry->type == 0) + i++; + else if (entry->type == 1) + acpi_madt_ioapic_list[acpi_madt_ioapic_length++] = (madt_ioapic *)entry; + else if (entry->type == 2) + acpi_madt_iso_list[acpi_madt_iso_length++] = (madt_iso *)entry; + else if (entry->type == 5) + acpi_lapic_addr = (uint64_t *)((madt_lapic_addr *)entry)->phys_lapic; - offset += entry->length; - } + offset += entry->length; + } } \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.h b/kernel/src/sys/acpi/madt.h index 1ce1138..444c3fd 100644 --- a/kernel/src/sys/acpi/madt.h +++ b/kernel/src/sys/acpi/madt.h @@ -45,12 +45,12 @@ typedef struct { uint64_t phys_lapic; } madt_lapic_addr; -extern madt_ioapic* acpi_madt_ioapic_list[256]; -extern madt_iso* acpi_madt_iso_list[256]; +extern madt_ioapic *acpi_madt_ioapic_list[256]; +extern madt_iso *acpi_madt_iso_list[256]; extern uint32_t acpi_madt_ioapic_length; extern uint32_t acpi_madt_iso_length; -extern uint64_t* acpi_lapic_addr; +extern uint64_t *acpi_lapic_addr; void madt_init(); \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index dd71a1b..b4d8274 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,8 +1,10 @@ -#include "arch//x86_64/idt.h" +#include "arch/x86_64/idt.h" #include "lib/spinlock.h" #include #include +#include "sched/sched.h" + static registers_t __panic_regdump; static void __panic_dump_regs() { @@ -51,53 +53,50 @@ static void __panic_dump_regs() { } static void __panic_display_page_fault(registers_t *regs) { - if (regs->int_no != 14) // 14 is the page fault interrupt number - return; + if (regs->int_no != 14) // 14 is the page fault interrupt number + return; - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2)); - - log("Page Fault Details:\n"); - log("Faulting Address (CR2): 0x%lx\n", cr2); - log("Error Code: %d\n", regs->err_code); - log("Flags:\n"); - if (!(regs->err_code & (1 << 0))) - log(" - Page Not Present\n"); - else - log(" - Protection Violation\n"); - - if (regs->err_code & (1 << 1)) - log(" - Write Access\n"); - else - log(" - Read Access\n"); - - if (regs->err_code & (1 << 2)) - log(" - User-Mode Access\n"); - else - log(" - Kernel-Mode Access\n"); - - if (regs->err_code & (1 << 3)) - log(" - Reserved Bits Set\n"); - - if (regs->err_code & (1 << 4)) - log(" - Instruction Fetch\n"); + uint64_t cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2)); + + log("Page Fault Details:\n"); + log("Faulting Address (CR2): 0x%lx\n", cr2); + log("Error Code: %d\n", regs->err_code); + log("Flags:\n"); + if (!(regs->err_code & (1 << 0))) + log(" - Page Not Present\n"); + else + log(" - Protection Violation\n"); + + if (regs->err_code & (1 << 1)) + log(" - Write Access\n"); + else + log(" - Read Access\n"); + + if (regs->err_code & (1 << 2)) + log(" - User-Mode Access\n"); + else + log(" - Kernel-Mode Access\n"); + + if (regs->err_code & (1 << 3)) + log(" - Reserved Bits Set\n"); + + if (regs->err_code & (1 << 4)) + log(" - Instruction Fetch\n"); } static void __panic_display_regs(registers_t *regs) { log("-- REGISTER DUMP --\n"); - log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", - regs->rdi, regs->rsi, regs->rdx, - regs->rcx, regs->r8, regs->r9); - log("RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p\n", - regs->rax, regs->rbp, regs->rbx, - regs->r10, regs->r11, regs->r12); - log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, - regs->r15); + log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", regs->rdi, + regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); + log("RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p\n", regs->rax, + regs->rbp, regs->rbx, regs->r10, regs->r11, regs->r12); + log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, regs->r15); log("RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", - regs->rip, regs->cs, regs->ss, - regs->rflags, regs->int_no, regs->err_code); + regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, + regs->err_code); log("RSP: %p\n", regs->rsp); - + if (regs->int_no == 14) // If it's a page fault __panic_display_page_fault(regs); } @@ -135,14 +134,17 @@ void panic_ctx(char *msg, registers_t *regs) { log("\n"); log("%s\n", msg); log("\n"); + + if (curr_proc) { + log("Current process: %s (PID: %d)\n", curr_proc->name, curr_proc->pid); + log("\n"); + } if (regs) __panic_display_regs(regs); else log("No register context provided.\n"); - - log("System halted: Please restart your computer manually.\n"); asm("cli"); diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c index e6f3988..4f3c313 100644 --- a/kernel/src/sys/log.c +++ b/kernel/src/sys/log.c @@ -1,4 +1,4 @@ -#include "arch//x86_64/io.h" +#include "arch/x86_64/io.h" #include "sys/gfx/flanterm/flanterm.h" #include #include @@ -12,8 +12,8 @@ static spinlock_t log_lock = {0}; void log(char *format, ...) { // TODO: replace this call with a call to printf() when the RTC is // implemented. - - //spinlock_acquire(&log_lock); + + // spinlock_acquire(&log_lock); char *date = "1970-01-01 00:00:00 | "; if (ft_ctx) @@ -41,6 +41,6 @@ void log(char *format, ...) { outb(0xE9, buf[i]); } - - //spinlock_release(&log_lock); + + // spinlock_release(&log_lock); } \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index c132998..9340143 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -52,7 +52,7 @@ void syscall_register(int id, syscall handler) { extern void syscall_exit(int exit_code); -void syscall_init() { +void syscall_init() { for (int i = 0; i < 1024; i++) syscall_table[i] = (syscall)__syscall_undefined; diff --git a/kernel/src/sys/syscall.h b/kernel/src/sys/syscall.h index 1d0f3f0..d428af6 100644 --- a/kernel/src/sys/syscall.h +++ b/kernel/src/sys/syscall.h @@ -1,6 +1,6 @@ #pragma once -#include "arch//x86_64/idt.h" +#include "arch/x86_64/idt.h" #include /// A function that defines a system call. diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index 257f986d7fe37189320b805fea11bfba94db923b..f22be1c771bdd953f1f38c7cde5b0e4d328a78c7 100755 GIT binary patch delta 56 zcmcbi_&{-j2BX46O><681_<5b1_)r;m^qz)GOIwu3-5F8U}Rxn;AegPZ*nJNJ0tsKK_-6yx&{h( delta 31 lcmaFB@_=Q+0!EgJ3-5FCv%dbv00NUc8QU3|CJQq80|2#X39$eG From ca489e986aebfbff7338413c90eacde9af90557a Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Fri, 16 May 2025 08:48:15 +0200 Subject: [PATCH 13/30] gdt - swap usermode CS & SS --- kernel/src/arch/x86_64/gdt.c | 4 ++-- kernel/src/arch/x86_64/syscall.c | 3 +-- kernel/src/sched/sched.c | 4 ++-- kernel/src/sys/syscall.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c index 5f18fb0..0612961 100644 --- a/kernel/src/arch/x86_64/gdt.c +++ b/kernel/src/arch/x86_64/gdt.c @@ -16,8 +16,8 @@ gdt_table def_table = {{ 0x00af9b000000ffff, // 0x28 64 bit code cs 0x00af93000000ffff, // 0x30 64 bit data ss - 0x00affb000000ffff, // 0x38 user mode code cs - 0x00aff3000000ffff, // 0x40 user mode data ss + 0x00aff3000000ffff, // 0x38 user mode data ss + 0x00affb000000ffff, // 0x40 user mode code cs }, {}}; diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index 8d6a97d..34e7df3 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -10,8 +10,7 @@ void __x86_64_syscall_init() { wrmsr(IA32_EFER, efer); uint64_t star = 0; star |= ((uint64_t)0x28 << 32); // kernel cs - star |= ((uint64_t)0x30 - << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) wrmsr(IA32_STAR, star); wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); wrmsr(IA32_CSTAR, 0x0); diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index 69e0abf..d822096 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -87,8 +87,8 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, proc->regs.cs = 0x28; // Run in kernel mode proc->regs.ss = 0x30; } else if (flags == SCHED_USER_PROCESS) { - proc->regs.cs = 0x38 | 3; // Run in user mode - proc->regs.ss = 0x40 | 3; + proc->regs.cs = 0x40 | 3; // Run in user mode + proc->regs.ss = 0x38 | 3; } proc->regs.rflags = 0x202; // Enable interrupts proc->regs.rsp = (uint64_t)proc->stack_end; diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 9340143..1abefe6 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -20,7 +20,7 @@ void syscall_handle(registers_t *regs) { return; } - if (curr_proc == NULL || curr_proc->regs.cs != 0x3B) { + if (curr_proc == NULL || curr_proc->regs.cs != 0x43) { log("syscall - syscall_handle was called by the kernel. is this wanted?\n"); return; } From cfc9159ad9419d121ae4d9ba7673aab8c727cb7b Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Fri, 16 May 2025 15:58:51 +0200 Subject: [PATCH 14/30] kernel: try some shit to get the compiler to put a backtrace --- README.md | 10 +++--- kernel/GNUmakefile | 4 ++- kernel/src/arch/x86_64/syscall.c | 2 +- kernel/src/main.c | 11 ++++-- kernel/src/premain.asm | 10 ++++++ kernel/src/sys/errhnd/panic.c | 57 +++++++++++++++++++++++++++++++- kernel/src/sys/errhnd/panic.h | 6 ++++ 7 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 kernel/src/premain.asm diff --git a/README.md b/README.md index f6fbc5b..fa0230d 100755 --- a/README.md +++ b/README.md @@ -3,11 +3,12 @@ The Soaplin kernel is a new Unix-like operating system kernel. ## Features * x86_64 support (kinda) -* Memory management (VMM/PMM) +* Memory management (VMM/PMM/VMA/kmalloc) * Simple pre-emptive scheduler * Ring 3 (user mode) support * ELF loader * ACPI +* Symetric Multiprocessing (It runs code, but the scheduler is running on 1 processor.) ## In the works * Virtual File System @@ -17,7 +18,7 @@ The Soaplin kernel is a new Unix-like operating system kernel. * RTC support * EXT2 driver * FAT32 driver -* CPIO-based init ram disk +* TAR-based init ram disk * Video driver for Bochs graphics adapter, and the VMware display adapter. ## Known bugs @@ -26,12 +27,13 @@ The Soaplin kernel is a new Unix-like operating system kernel. ## Building To build Soaplin, you must ensure you have these: * The Netwide Assembler (nasm) -* A compiler (In the future, a custom toolchain would be built.) -* A linker +* A compiler (both GCC & Clang works!) (In the future, a custom toolchain would be built.) +* A linker (both GNU LD & LLVM linker works too!) Clone the repo, and run "make" in it! ## Acknowledgements Thanks to all these people :heart: +* Limine contributors: The Limine bootloader, used for kicking up Soaplin * Kevin Alavik (kevinalavik): VMAs implementation * Astrido (asterd-og): IOAPIC/LAPIC (from ZanOS) \ No newline at end of file diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index 7350da5..84475d5 100755 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -58,7 +58,9 @@ override CFLAGS += \ -fno-stack-check \ -fno-PIC \ -ffunction-sections \ - -fdata-sections + -fdata-sections \ + -fno-omit-frame-pointer \ + -fno-optimize-sibling-calls # Internal C preprocessor flags that should not be changed by the user. override CPPFLAGS := \ diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c index 34e7df3..0839c78 100644 --- a/kernel/src/arch/x86_64/syscall.c +++ b/kernel/src/arch/x86_64/syscall.c @@ -10,7 +10,7 @@ void __x86_64_syscall_init() { wrmsr(IA32_EFER, efer); uint64_t star = 0; star |= ((uint64_t)0x28 << 32); // kernel cs - star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40) + star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x40, 24 for SS=0x38) wrmsr(IA32_STAR, star); wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); wrmsr(IA32_CSTAR, 0x0); diff --git a/kernel/src/main.c b/kernel/src/main.c index e1dde83..c4c4935 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -57,7 +57,11 @@ struct flanterm_context *ft_ctx; char kstack[8192]; -void kmain(void) { +void test3() { *((uint8_t*)0x0) = (uint8_t)0xFF; } +void test2() { test3();} +void test1() { test2(); } + +void __kmain(void) { if (framebuffer_request.response != NULL) { struct limine_framebuffer *framebuffer = @@ -97,6 +101,7 @@ void kmain(void) { syscall_init(); sched_init(); + test1(); // vfs_init(); @@ -105,6 +110,7 @@ void kmain(void) { program_t *p = elf_load(module_request.response->modules[0]->address, 1); + sched_process *proc = sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS); @@ -112,6 +118,5 @@ void kmain(void) { pit_enable(); while (1) - ; - ; + ;; } diff --git a/kernel/src/premain.asm b/kernel/src/premain.asm new file mode 100644 index 0000000..b06f99b --- /dev/null +++ b/kernel/src/premain.asm @@ -0,0 +1,10 @@ +bits 64 +section .text + global kmain + extern __kmain + extern kstack + +kmain: + mov rsp, kstack+0x2000 ; supposons 16 KiB de stack + xor rbp, rbp ; Set %ebp to NULL + call __kmain \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c index b4d8274..1a82fd8 100644 --- a/kernel/src/sys/errhnd/panic.c +++ b/kernel/src/sys/errhnd/panic.c @@ -1,3 +1,4 @@ +#include "sys/errhnd/panic.h" #include "arch/x86_64/idt.h" #include "lib/spinlock.h" #include @@ -59,7 +60,9 @@ static void __panic_display_page_fault(registers_t *regs) { uint64_t cr2; asm volatile("mov %%cr2, %0" : "=r"(cr2)); - log("Page Fault Details:\n"); + log("-- PAGE FAULT DETAILS --\n"); + log("This appears to be a page fault.\n"); + log("\n"); log("Faulting Address (CR2): 0x%lx\n", cr2); log("Error Code: %d\n", regs->err_code); log("Flags:\n"); @@ -83,6 +86,7 @@ static void __panic_display_page_fault(registers_t *regs) { if (regs->err_code & (1 << 4)) log(" - Instruction Fetch\n"); + log("\n"); } static void __panic_display_regs(registers_t *regs) { @@ -96,11 +100,60 @@ static void __panic_display_regs(registers_t *regs) { regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, regs->err_code); log("RSP: %p\n", regs->rsp); + log("\n"); if (regs->int_no == 14) // If it's a page fault __panic_display_page_fault(regs); } +static void __panic_display_bt(registers_t *regs) { + if (regs->cs == 0x43 || regs->cs == 0x3B) { + log("The backtrace can't be dumped from a userspace process.\n"); + return; // Don't try to backtrace userspace + } + + log("-- BACKTRACE --\n"); + + // First print the current instruction pointer from the interrupt frame + if (regs->rip) { + log("* %p (current)\n", regs->rip); + } + + uint64_t *frame = (uint64_t*)regs->rbp; + if (!frame || (uint64_t)frame < 0xffffffff80000000) { + log("No further stack frames available\n"); + return; + } + + // Frame format in x86_64: + // [rbp] -> previous rbp + // [rbp+8] -> return address + int depth = 0; + while (frame && depth < 16) { // Limit depth to avoid infinite loops + // Validate both frame and return address pointers + uint64_t *ret_addr_ptr = frame + 1; + if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) { + break; + } + + uint64_t ret_addr = *ret_addr_ptr; + if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) { + break; + } + + log("* %p\n", ret_addr); + + uint64_t next_rbp = *frame; + if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) { + break; + } + + frame = (uint64_t*)next_rbp; + depth++; + } + log("\n"); +} + void __panic_display_ascii_art() { log(" _ __ _ ___ _ \n"); log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n"); @@ -145,6 +198,8 @@ void panic_ctx(char *msg, registers_t *regs) { else log("No register context provided.\n"); + __panic_display_bt(regs); + log("System halted: Please restart your computer manually.\n"); asm("cli"); diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h index 147263b..4794b32 100644 --- a/kernel/src/sys/errhnd/panic.h +++ b/kernel/src/sys/errhnd/panic.h @@ -1,5 +1,11 @@ #pragma once #include "arch/x86_64/idt.h" + +typedef struct __panic_backtrace { + struct Idt_StackFrame* rbp; + uint64_t rip; +} __attribute__((packed)) panic_backtrace_t; + void panic(char *msg); void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file From 1e84bcedc9aaca3b1efd8009cfb4e22d19d1dc78 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Fri, 16 May 2025 20:53:35 +0200 Subject: [PATCH 15/30] vfs - kinda good vfs implementation --- kernel/src/dbg/sym.c | 56 + kernel/src/dbg/sym.h | 12 + kernel/src/exec/elf.h | 30 +- kernel/src/fs/hellofs.c | 101 ++ kernel/src/fs/hellofs.h | 5 + kernel/src/fs/vfs.c | 93 ++ kernel/src/fs/vfs.h | 9 +- kernel/src/lib/string.c | 54 + kernel/src/lib/string.h | 3 +- kernel/src/main.c | 29 +- kernel/src/mm/vmm.c | 2 +- strings.txt | 2709 +++++++++++++++++++++++++++++++++++++++ txt.txt | 559 ++++++++ 13 files changed, 3650 insertions(+), 12 deletions(-) create mode 100644 kernel/src/dbg/sym.c create mode 100644 kernel/src/dbg/sym.h create mode 100644 kernel/src/fs/hellofs.c create mode 100644 kernel/src/fs/hellofs.h create mode 100644 strings.txt create mode 100644 txt.txt diff --git a/kernel/src/dbg/sym.c b/kernel/src/dbg/sym.c new file mode 100644 index 0000000..2d03766 --- /dev/null +++ b/kernel/src/dbg/sym.c @@ -0,0 +1,56 @@ +#include "dbg/sym.h" +#include "exec/elf.h" +#include "limine.h" +#include "sys/errhnd/panic.h" +#include "sys/log.h" +#include +#include + +static Elf64_Sym *__ksym_symtab; +static char *__ksym_strtab; +static int __ksym_symcount = 0; + +__attribute__((used, section(".limine_requests"))) static volatile struct + limine_executable_file_request exec_file_rq = { + .id = LIMINE_EXECUTABLE_FILE_REQUEST, .revision = 3}; + +void ksym_init() { + char *img = exec_file_rq.response->executable_file->address; + Elf64_Ehdr *ehdr = (Elf64_Ehdr *)img; + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 || + ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) { + panic("kernel - how did i even boot? *starts galaxy brain meme*"); + } + + Elf64_Shdr *shdr = (Elf64_Shdr *)(img + ehdr->e_shoff); + const char *shstrtab = (char *)img + shdr[ehdr->e_shstrndx].sh_offset; + + for (int j = 0; j < ehdr->e_shnum; j++) { + if (shdr[j].sh_type == SHT_SYMTAB) { + __ksym_symtab = (Elf64_Sym *)(img + shdr[j].sh_offset); + __ksym_symcount = shdr[j].sh_size / shdr[j].sh_entsize; + } else if (shdr[j].sh_type == SHT_STRTAB && + strcmp(shstrtab + shdr[j].sh_name, ".strtab") == 0) { + __ksym_strtab = (char *)(img + shdr[j].sh_offset); + } + } + + log("kernel - loaded %d symbols\n", __ksym_symcount); +} + +func *ksym_fromip(uint64_t ip) { + for (int i = 0; i < __ksym_symcount; i++) { + uint64_t value = __ksym_symtab[i].st_value; + uint64_t size = __ksym_symtab[i].st_size; + + if (value <= ip && ip < (value + size)) { + func *f = malloc(sizeof(func)); + f->base = value; + f->ip = ip; + f->name = (__ksym_strtab + __ksym_symtab[i].st_name); + return f; + } + } + + return NULL; +} \ No newline at end of file diff --git a/kernel/src/dbg/sym.h b/kernel/src/dbg/sym.h new file mode 100644 index 0000000..9419994 --- /dev/null +++ b/kernel/src/dbg/sym.h @@ -0,0 +1,12 @@ +#pragma once + +#include "mm/vmm.h" + +typedef struct func { + uint64_t base; + uint64_t ip; + char *name; +} func; + +void ksym_init(); +func *ksym_fromip(uint64_t ip); \ No newline at end of file diff --git a/kernel/src/exec/elf.h b/kernel/src/exec/elf.h index 8180a8e..a680291 100644 --- a/kernel/src/exec/elf.h +++ b/kernel/src/exec/elf.h @@ -122,4 +122,32 @@ typedef struct { Elf64_Ehdr *ehdr; } elf_program_t; -program_t *elf_load(char *data, int user); \ No newline at end of file +program_t *elf_load(char *data, int user); + +// Those aren't used for loading, but used by +// the kernel to resolve symbols from an instruction +// pointer. +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 + +typedef struct { + uint32_t st_name; + unsigned char st_info; + unsigned char st_other; + uint16_t st_shndx; + Elf64_Addr st_value; + uint64_t st_size; +} Elf64_Sym; + +typedef struct { + uint32_t sh_name; + uint32_t sh_type; + uint64_t sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + uint64_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint64_t sh_addralign; + uint64_t sh_entsize; +} Elf64_Shdr; diff --git a/kernel/src/fs/hellofs.c b/kernel/src/fs/hellofs.c new file mode 100644 index 0000000..6addd24 --- /dev/null +++ b/kernel/src/fs/hellofs.c @@ -0,0 +1,101 @@ +#include "fs/hellofs.h" +#include "fs/vfs.h" +#include +#include +#include + +static int hellofs_read(vnode_t *vn, void *buf, size_t off, size_t size) { + if (!vn || !buf || size <= 0) { + return -1; + } + + const char *hello = "hello"; + const size_t hello_len = 5; // strlen("hello") + char *cbuf = (char *)buf; + size_t bytes_written = 0; + + while (bytes_written < size) { + size_t pos = off % hello_len; // Position within "hello" + size_t remaining = hello_len - pos; // Remaining bytes in current "hello" + size_t to_copy = (size - bytes_written < remaining) ? + (size - bytes_written) : remaining; + + memcpy(cbuf + bytes_written, hello + pos, to_copy); + bytes_written += to_copy; + off += to_copy; + } + + return bytes_written; +} + +vnode_ops_t hellofs_hello_ops = { + .read = hellofs_read, + .lookup = NULL, +}; + +static int hellofs_lookup(vnode_t *vn, const char *name, vnode_t **out) { + if (!vn || !name || !out) { + return -1; + } + + if (strcmp(name, "hello") == 0) { + *out = vfs_create_node("hello", VN_FILE); + if (*out) { + (*out)->ops = &hellofs_hello_ops; + return 0; + } + + return -1; + } else { + *out = NULL; // Not found + return -1; + } +} + +vnode_ops_t hellofs_root_ops = { + .read = NULL, + .lookup = hellofs_lookup, +}; + +static int hellofs_mount(fs_t *fs, vnode_t *mountpoint) { + if (!fs || !mountpoint) { + return -1; + } + + // mountpoint list isn't implemented. + + /*mountpoint_t *mp = (mountpoint_t *)malloc(sizeof(mountpoint_t)); + if (!mp) { + return -1; + } + + memset(mp, 0, sizeof(mountpoint_t)); + strncpy(mp->name, fs->name, sizeof(mp->name) - 1); + mp->fs = fs; + mp->mountpoint = mountpoint;*/ + + // Mounting is essentially just putting the file system's root directory operations + // on the mountpoint vnode. + mountpoint->ops = &hellofs_root_ops; + + return 0; +} + +fs_t *hellofs_init() { + fs_t *fs = (fs_t *)malloc(sizeof(fs_t)); + if (!fs) { + return NULL; + } + + memset(fs, 0, sizeof(fs_t)); + strncpy(fs->name, "hellofs", sizeof(fs->name) - 1); + + fs->mount = hellofs_mount; + fs->root = vfs_create_node("/", VN_DIR); + if (!fs->root) { + free(fs); + return NULL; + } + + return fs; +} \ No newline at end of file diff --git a/kernel/src/fs/hellofs.h b/kernel/src/fs/hellofs.h new file mode 100644 index 0000000..5e35108 --- /dev/null +++ b/kernel/src/fs/hellofs.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +fs_t *hellofs_init(void); \ No newline at end of file diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c index bcbf98f..c8e966e 100644 --- a/kernel/src/fs/vfs.c +++ b/kernel/src/fs/vfs.c @@ -2,6 +2,99 @@ #include "lib/string.h" #include "mm/liballoc/liballoc.h" #include "mm/memop.h" +#include "sys/errhnd/panic.h" + +vnode_t *root = NULL; + +void vfs_init() { + root = vfs_create_node("/", VN_DIR); + if (!root) { + panic("vfs - failed to create root node"); + } + root->parent = root; // Root's parent is itself +} + +// Not worth adding to the header, since it should only lookup +// for files/directories in dir, without going deeper. +int vfs_lookup(vnode_t *dir, const char *name, vnode_t **out) { + if (!dir || !name) + return -1; + + if (dir->ops && dir->ops->lookup) { + return dir->ops->lookup(dir, name, out); + } + return -1; +} + +int vfs_open(vnode_t *curdir, const char *path, vnode_t **out) { + if (strcmp(path, ".") == 0) { + *out = curdir; + return 0; + } + if (strcmp(path, "..") == 0) { + *out = curdir->parent; + return 0; + } + + char *path_copy = strdup(path); + if (!path_copy) { + *out = NULL; + return -1; + } + + vnode_t *cur_node = path[0] == '/' ? root : curdir; + char *token = strtok(path_copy, "/"); + + while (token) { + vnode_t *next; + vfs_lookup(cur_node, token, &next); + if (!next) { + free(path_copy); + *out = NULL; + return -1; + } + cur_node = next; + token = strtok(NULL, "/"); + } + + free(path_copy); + *out = cur_node; + return 0; +} + +int vfs_mount(char *path, fs_t *fs) { + if (!fs || !path) { + return -1; + } + + vnode_t *mp; + if (strcmp(path, "/") == 0) { + mp = root; + } else { + vfs_open(root, path, &mp); + } + + if (fs->mount == NULL) + return -1; // why allocating a fs without the capability to mount to a node? lmao + + return fs->mount(fs, mp); +} + +int vfs_unmount(char *path) { + (void)path; + return -1; +} + +int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size) { + if (!vn || !buf || off < 0 || size <= 0) { + return -1; + } + + if (vn->ops && vn->ops->read) { + return vn->ops->read(vn, buf, off, size); + } + return -1; +} vnode_t *vfs_create_node(char *name, vnode_type_t type) { vnode_t *node = (vnode_t *)malloc(sizeof(vnode_t)); diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h index a85c826..03282b3 100644 --- a/kernel/src/fs/vfs.h +++ b/kernel/src/fs/vfs.h @@ -12,14 +12,14 @@ typedef uint32_t vnode_type_t; typedef struct vnode_ops { int (*read)(struct vnode *vn, void *buf, size_t off, size_t size); - struct vnode *(*lookup)(struct vnode *vn, const char *name); + int (*lookup)(struct vnode *vn, const char *name, struct vnode **out); } vnode_ops_t; typedef struct vnode { char name[256]; vnode_type_t type; uint32_t refcount; - // struct vnode* parent; + struct vnode* parent; // If this vnode exists, then it's parent too. // struct vnode* child; // struct vnode* next; @@ -36,11 +36,12 @@ typedef struct mountpoint { typedef struct fs { char name[32]; struct vnode *root; - int (*mount)(struct vnode *mountpoint); + int (*mount)(struct fs *fs, struct vnode *mountpoint); } fs_t; void vfs_init(void); int vfs_mount(char *path, fs_t *fs); int vfs_unmount(char *path); -int vfs_open(const char *path, vnode_t **result); +int vfs_open(vnode_t *curdir, const char *path, vnode_t **out); int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size); +vnode_t *vfs_create_node(char *name, vnode_type_t type); \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index 71eb5a9..945bece 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -1,7 +1,10 @@ #include #include +#include #include +static char *olds; + int strlen(const char *str) { int len = 0; while (str[len]) @@ -78,3 +81,54 @@ char *strncpy(char *dest, const char *src, size_t n) { dest[i] = '\0'; return dest; } + +#define DICT_LEN 256 + +static int *create_delim_dict(char *delim) { + int *d = (int *)malloc(sizeof(int) * DICT_LEN); + memset((void *)d, 0, sizeof(int) * DICT_LEN); + + int i; + for (i = 0; i < strlen(delim); i++) { + d[delim[i]] = 1; + } + return d; +} + +char *strtok(char *str, char *delim) { + + static char *last, *to_free; + int *deli_dict = create_delim_dict(delim); + + if (!deli_dict) { + return NULL; + } + + if (str) { + last = (char *)malloc(strlen(str) + 1); + if (!last) { + free(deli_dict); + } + to_free = last; + strcpy(last, str); + } + + while (deli_dict[*last] && *last != '\0') { + last++; + } + str = last; + if (*last == '\0') { + free(deli_dict); + free(to_free); + return NULL; + } + while (*last != '\0' && !deli_dict[*last]) { + last++; + } + + *last = '\0'; + last++; + + free(deli_dict); + return str; +} diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h index 3f4be59..c80bf30 100644 --- a/kernel/src/lib/string.h +++ b/kernel/src/lib/string.h @@ -8,4 +8,5 @@ char *strcpy(char *dest, const char *src); char *strrchr(const char *s, int c); int oct2bin(unsigned char *str, int size); char *strdup(const char *str); -char *strncpy(char *dest, const char *src, size_t n); \ No newline at end of file +char *strncpy(char *dest, const char *src, size_t n); +char *strtok(char *str, char *delim); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index c4c4935..cedbcbe 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,10 +1,12 @@ #include "arch/x86_64/pit.h" #include "arch/x86_64/smp.h" #include "arch/x86_64/sse.h" +#include "dbg/sym.h" #include "dev/ioapic.h" #include "dev/lapic.h" #include "exec/elf.h" #include "exec/exec.h" +#include "fs/hellofs.h" #include "mm/liballoc/liballoc.h" #include "mm/pmm.h" #include "mm/vma.h" @@ -57,10 +59,6 @@ struct flanterm_context *ft_ctx; char kstack[8192]; -void test3() { *((uint8_t*)0x0) = (uint8_t)0xFF; } -void test2() { test3();} -void test1() { test2(); } - void __kmain(void) { if (framebuffer_request.response != NULL) { @@ -92,6 +90,14 @@ void __kmain(void) { asm("hlt"); } + ksym_init(); + func *f = ksym_fromip((uint64_t)__kmain); + if (f) { + log("ksym: found %s at %p\n", f->name, f->ip); + } else { + log("ksym: not found\n"); + } + acpi_init(); madt_init(); ioapic_init(); @@ -99,9 +105,22 @@ void __kmain(void) { pit_init(); smp_init(); + vfs_init(); + fs_t *hellofs = hellofs_init(); + vfs_mount("/", hellofs); + + vnode_t *vn; + vfs_open(NULL, "/hello", &vn); + if (vn) { + char buf[100]; + vfs_read(vn, buf, 2, sizeof(buf)); + log("Read from /hello: %s\n", buf); + } else { + log("Failed to open /hello\n"); + } + syscall_init(); sched_init(); - test1(); // vfs_init(); diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index f84bf9b..b724f57 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -15,7 +15,7 @@ __attribute__(( .revision = 3, .mode = LIMINE_PAGING_MODE_X86_64_4LVL}; -__attribute__((used, section(".limine_requests"))) static volatile struct +__attribute__((used, section(".limine_requests"))) volatile struct limine_executable_address_request karq = { .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, .revision = 0, diff --git a/strings.txt b/strings.txt new file mode 100644 index 0000000..843bc51 --- /dev/null +++ b/strings.txt @@ -0,0 +1,2709 @@ +[A\] +AVAUATSH +E>E1 +[A\A]A^] +[A\A]] +AWAVAUATSH +\$ I +8f;X8 +_AXL9 +[A\A]A^A_] +@ff. +P#RH + AVAUATSH +T$ H +[A\A]A^A_] +D$(I +D$ I +\$HA +\$`A +d$8E +|$DL +D$(H +T$0I +D$ A + ff. +[A\] +H+= +AWAVAUATSH +tGE1 +[A\A]A^A_] +[A\A]A^A_] +[A\A]] +AWAVAUATSH +s6ff. +8[A\A]A^A_] +[A\A]A^] +AWAVI +[A\A]A^A_] +AVAUI +[A\A]A^] +[A\A]A^] +AXAYH +AUATI +s1H; +AUATSH +r%M9 +t&ff. +[A\A]] +AVAUATSH +[A\A]A^] +AVAUATSH +[A\A]A^] +AWAVAUATSH +tLff. +[A\A]A^A_] +[A\A]A^A_] +[A\] +AWAVAUATSH +P[A\A]A^A_] +AWAVAUATSL +[A\A]A^A_] +AWAVAUATSD +[A\A]A^A_] +[A\A]A^A_] +AWAVAUATSH + [A\A]A^A_] +AWAVAUA +ATSL +> tVI +[A\A]A^A_] +ATSH +UHE1 +UPE1 +[A\A]A^A_] +AWAVL +AUATI +E@<7 +([A\A]A^A_] +S@< +H9Ch +<5w2 +SxH9 +SxE1 +CpH9 +s H9 +KxE1 +KxI9 +kxI9 +sxH9 +KxH9 +KhH9 +spH9 +r H9 +SxH9 +8ff. +AWAVAUI +ATSH +x[A\A]A^A_] +<-t`H + ff. +tMHc +/v:H +ATSH +[A\] +[A\D +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j!PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j"PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j#PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j$PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j%PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j&PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j'PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j(PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j)PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j*PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j+PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j,PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j-PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j.PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j/PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j0PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j1PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j2PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j3PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j4PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j5PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j6PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j7PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j8PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j9PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j:PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j;PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j?PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j@PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jAPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jBPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jCPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jDPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jEPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jFPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jGPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jHPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jIPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jJPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jKPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jLPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jMPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jNPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jOPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jPPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jQPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jRPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jSPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jTPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jUPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jVPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jWPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jXPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jYPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jZPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j[PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j\PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j]PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j^PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j_PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j`PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jaPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jbPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jcPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jdPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jePQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jfPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jgPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jhPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jiPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jjPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jkPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jlPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jmPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jnPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +joPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jpPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jqPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jrPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jsPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jtPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +juPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jvPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jwPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jxPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jyPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +jzPQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j{PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j|PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j}PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +j~PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +PQRSUVWAPAQARASATAUAVAWH +A_A^A]A\A[AZAYAX_^][ZYXH +sj;r +\-+V +kSDI8{j +C{~9k{ +Exc' +bLv1 +gdt - initialized. +idt - initialized +A CPU exception occured. +smp - detected %d CPUs +smp - initialized +.strtab +kernel - loaded %d symbols +ioapic - initialized +lapic - initialized +elf - e_ident[EI_DATA]: %d +elf - e_ident[EI_CLASS]: %d +elf - e_ident[EI_OSABI]: %d +elf - e_machine: %d +elf - e_entry: %p +elf - e_type: %p +elf - e_phnum: %p +elf - ELF segment type: %d +elf - memset(%p, 0, 0x1000) +elf - memcpy(%p, %p, %d) +ksym: found %s at %p +ksym: not found +Test +pmm - out of memory. +vmm - initialized! +RSD PTR +acpi: Invalid RSDP signature! +APIC +-- REGISTER DUMP -- +R13: %p, R14: %p, R15: %p +RSP: %p +-- PAGE FAULT DETAILS -- +Error Code: %d +Flags: + - Page Not Present + - Protection Violation + - Write Access + - Read Access + - User-Mode Access + - Kernel-Mode Access + - Reserved Bits Set + - Instruction Fetch +-- BACKTRACE -- +* %p (current) +* %p +1970-01-01 00:00:00 | +Hello! +smp - CPU %d started (LAPIC ID: %d) +smp - CPU %d is the bootstrap processor (LAPIC ID: %d) +kernel - how did i even boot? *starts galaxy brain meme* +elf - loading failed: magic is incorrect +elf - loading failed: is the file built for amd64? +elf - loading failed: ELF type isn't ET_EXEC +elf - loaded ELF program in memory. +elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset 0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx +elf - pmm page alloc failed. out of memory? +elf - vmm_map_user(%p, %p, %p, %d) +elf - vmm_map(%p, %p, %p, %d) + Soaplin 0.7-sild is booting up your computer... +kernel - vma ctx creation failed. halting +kernel - Soaplin initialized sucessfully. +pmm - %dmb is available to us. +pmm - could not free the page: stack overflow. +vma - creating VMA context with pagemap: 0x%.16llx +vma - failed to allocate VMA context +vma - allocated VMA context at 0x%.16llx +vma - zeroed out VMA context at 0x%.16llx +vma - failed to allocate root region +vma - allocated root region at 0x%.16llx +vma - VMA context created at 0x%.16llx with root region at 0x%.16llx +vma - invalid context or root passed to vma_alloc +vma - failed to allocate new VMA region +vma - failed to allocate physical memory for VMA region +vmm - Soaplin only supports 4-level paging! +vmm - mapping .requests section... +vmm - mapping .text section... +vmm - mapping .rodata section... +vmm - mapping .data section... +vmm - mapping address from 0x0 to 0x100000000... +sched - As there's nothing to schedule, the scheduler entered standbymode. +sched - Standby mode has beendisabled. +sched - created process '%s' (pid: %d, rip: %p) +sched - Process %d exited with code %d! +madt: Failed to find MADT table! +RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p +RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p +RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d +This appears to be a page fault. +Faulting Address (CR2): 0x%lx + _ __ _ ___ _ +| |/ /___ _ _ _ _ ___| | | _ \__ _ _ _ (_)__ +| ' +8ll8 +6666666 +66666666 +66666666 +66666 +666666666666666666666666 +6666666666666 +6666666 +66666667666666666666670? +?076666666666666 +666666666666670766666666 +66666 +66666666 +6666666 +666666666666666? +?666666666666666 +66666666 +lllllll +fffff|`` +ffff< +0``|```0 +8ll8 +lllll +||||||| + rsp +$ ist +#log +&isr +(isr + low + low +%log +%log ++log +2msr +3low +!log +(cr2 +/bpp +/map +8$3% +U)bg +U)fg +U)bg +U)fg + ctx + ctx + ctx + ctx + ctx + ctx +Fret +$osc +$rrr +!ctx +!ctx +!ctx + ctx + ucs + ucs + max + ctx + ctx + ctx + ctx + ctx + ctx + ctx + ctx + ctx +6sgr +'ctx +8def +9out +)ctx +)buf +'ctx + 'buf +o'lst + #val + #val +!cur +src/arch/x86_64/idt.asm +/home/raphm/Projets/sild/soaplin/kernel/src/arch/x86_64/ +NASM 2.16.03 +src/arch/x86_64/syscall.asm +/home/raphm/Projets/sild/soaplin/kernel/src/arch/x86_64/ +NASM 2.16.03 +src/premain.asm +/home/raphm/Projets/sild/soaplin/kernel/src/ +NASM 2.16.03 +:! ; +!(:! +9!1I +Y!*W! + &3$ + &4$ + &4$ + &4$ + &4$ +U#P<% + $0."@ +U#P<% + $0." +*P s +Tk s +*k s +*k s + O s +Sl s + l s + l s +;t s +Yt s +;t s +Yt s +.. X +.] X + * x +.i=I +& +flanterm.h +src/sys/printf.c +src/sys/syscall.c +src/sys/syscalls/syscalls_proc.c +src/sys/syscalls +GCC: (GNU) 15.1.1 20250425 +gdt.c +idt.c +vectors +idtr +io.c +pit.c +smp.c +smp_request +syscall.c +sym.c +exec_file_rq +__ksym_symtab +__ksym_symcount +__ksym_strtab +ioapic.c +lapic.c +elf.c +string.c +main.c +framebuffer_request +module_request +limine_requests_end_marker +limine_requests_start_marker +limine_base_revision +liballoc.c +allocate_new_page +l_allocated +l_warningCount +l_memRoot +l_bestBet +l_inuse +liballoc_soaplin.c +liballoc_lock_var +memop.c +pmm.c +vma.c +vmm.c +__vmm_get_next_lvl +pmrq +sched.c +schedule.part.0 +acpi.c +__acpi_rsdt_ptr +__acpi_uses_xsdt +rsdp_req +madt.c +panic.c +__panic_display_regs +__panic_regdump +fb.c +bump_alloc +base_offset_added.0 +bump_alloc_ptr +bump_alloc_pool +flanterm_fb_save_state +flanterm_fb_restore_state +flanterm_fb_swap_palette +push_to_queue +flanterm_fb_revscroll +flanterm_fb_scroll +flanterm_fb_set_cursor_pos +flanterm_fb_get_cursor_pos +flanterm_fb_move_character +flanterm_fb_set_text_fg +flanterm_fb_set_text_bg +flanterm_fb_set_text_fg_bright +flanterm_fb_set_text_bg_bright +flanterm_fb_set_text_fg_rgb +flanterm_fb_set_text_bg_rgb +flanterm_fb_set_text_fg_default +flanterm_fb_set_text_bg_default +flanterm_fb_set_text_fg_default_bright +flanterm_fb_set_text_bg_default_bright +draw_cursor +flanterm_fb_double_buffer_flush +flanterm_fb_full_refresh +flanterm_fb_deinit +bump_allocated_instance +plot_char_scaled_canvas +plot_char_unscaled_canvas +plot_char_unscaled_uncanvas +plot_char_scaled_uncanvas +flanterm_fb_clear +flanterm_fb_raw_putchar +builtin_font +flanterm.c +combining.0 +col256 +log.c +printf.c +npf_utoa_rev +npf_bufputc +npf_bufputc_nop +__syscall_undefined +syscall_table +syscalls_proc.c +src/arch/x86_64/idt.asm +isr_stub_0 +isr_stub_1 +isr_stub_2 +isr_stub_3 +isr_stub_4 +isr_stub_5 +isr_stub_6 +isr_stub_7 +isr_stub_8 +isr_stub_9 +isr_stub_10 +isr_stub_11 +isr_stub_12 +isr_stub_13 +isr_stub_14 +isr_stub_15 +isr_stub_16 +isr_stub_17 +isr_stub_18 +isr_stub_19 +isr_stub_20 +isr_stub_21 +isr_stub_22 +isr_stub_23 +isr_stub_24 +isr_stub_25 +isr_stub_26 +isr_stub_27 +isr_stub_28 +isr_stub_29 +isr_stub_30 +isr_stub_31 +isr_stub_32 +isr_stub_33 +isr_stub_34 +isr_stub_35 +isr_stub_36 +isr_stub_37 +isr_stub_38 +isr_stub_39 +isr_stub_40 +isr_stub_41 +isr_stub_42 +isr_stub_43 +isr_stub_44 +isr_stub_45 +isr_stub_46 +isr_stub_47 +isr_stub_48 +isr_stub_49 +isr_stub_50 +isr_stub_51 +isr_stub_52 +isr_stub_53 +isr_stub_54 +isr_stub_55 +isr_stub_56 +isr_stub_57 +isr_stub_58 +isr_stub_59 +isr_stub_60 +isr_stub_61 +isr_stub_62 +isr_stub_63 +isr_stub_64 +isr_stub_65 +isr_stub_66 +isr_stub_67 +isr_stub_68 +isr_stub_69 +isr_stub_70 +isr_stub_71 +isr_stub_72 +isr_stub_73 +isr_stub_74 +isr_stub_75 +isr_stub_76 +isr_stub_77 +isr_stub_78 +isr_stub_79 +isr_stub_80 +isr_stub_81 +isr_stub_82 +isr_stub_83 +isr_stub_84 +isr_stub_85 +isr_stub_86 +isr_stub_87 +isr_stub_88 +isr_stub_89 +isr_stub_90 +isr_stub_91 +isr_stub_92 +isr_stub_93 +isr_stub_94 +isr_stub_95 +isr_stub_96 +isr_stub_97 +isr_stub_98 +isr_stub_99 +isr_stub_100 +isr_stub_101 +isr_stub_102 +isr_stub_103 +isr_stub_104 +isr_stub_105 +isr_stub_106 +isr_stub_107 +isr_stub_108 +isr_stub_109 +isr_stub_110 +isr_stub_111 +isr_stub_112 +isr_stub_113 +isr_stub_114 +isr_stub_115 +isr_stub_116 +isr_stub_117 +isr_stub_118 +isr_stub_119 +isr_stub_120 +isr_stub_121 +isr_stub_122 +isr_stub_123 +isr_stub_124 +isr_stub_125 +isr_stub_126 +isr_stub_127 +isr_stub_128 +isr_stub_129 +isr_stub_130 +isr_stub_131 +isr_stub_132 +isr_stub_133 +isr_stub_134 +isr_stub_135 +isr_stub_136 +isr_stub_137 +isr_stub_138 +isr_stub_139 +isr_stub_140 +isr_stub_141 +isr_stub_142 +isr_stub_143 +isr_stub_144 +isr_stub_145 +isr_stub_146 +isr_stub_147 +isr_stub_148 +isr_stub_149 +isr_stub_150 +isr_stub_151 +isr_stub_152 +isr_stub_153 +isr_stub_154 +isr_stub_155 +isr_stub_156 +isr_stub_157 +isr_stub_158 +isr_stub_159 +isr_stub_160 +isr_stub_161 +isr_stub_162 +isr_stub_163 +isr_stub_164 +isr_stub_165 +isr_stub_166 +isr_stub_167 +isr_stub_168 +isr_stub_169 +isr_stub_170 +isr_stub_171 +isr_stub_172 +isr_stub_173 +isr_stub_174 +isr_stub_175 +isr_stub_176 +isr_stub_177 +isr_stub_178 +isr_stub_179 +isr_stub_180 +isr_stub_181 +isr_stub_182 +isr_stub_183 +isr_stub_184 +isr_stub_185 +isr_stub_186 +isr_stub_187 +isr_stub_188 +isr_stub_189 +isr_stub_190 +isr_stub_191 +isr_stub_192 +isr_stub_193 +isr_stub_194 +isr_stub_195 +isr_stub_196 +isr_stub_197 +isr_stub_198 +isr_stub_199 +isr_stub_200 +isr_stub_201 +isr_stub_202 +isr_stub_203 +isr_stub_204 +isr_stub_205 +isr_stub_206 +isr_stub_207 +isr_stub_208 +isr_stub_209 +isr_stub_210 +isr_stub_211 +isr_stub_212 +isr_stub_213 +isr_stub_214 +isr_stub_215 +isr_stub_216 +isr_stub_217 +isr_stub_218 +isr_stub_219 +isr_stub_220 +isr_stub_221 +isr_stub_222 +isr_stub_223 +isr_stub_224 +isr_stub_225 +isr_stub_226 +isr_stub_227 +isr_stub_228 +isr_stub_229 +isr_stub_230 +isr_stub_231 +isr_stub_232 +isr_stub_233 +isr_stub_234 +isr_stub_235 +isr_stub_236 +isr_stub_237 +isr_stub_238 +isr_stub_239 +isr_stub_240 +isr_stub_241 +isr_stub_242 +isr_stub_243 +isr_stub_244 +isr_stub_245 +isr_stub_246 +isr_stub_247 +isr_stub_248 +isr_stub_249 +isr_stub_250 +isr_stub_251 +isr_stub_252 +isr_stub_253 +isr_stub_254 +isr_stub_255 +src/arch/x86_64/syscall.asm +src/premain.asm +font.c +smp_init +acpi_madt_iso_length +flanterm_fb_init +rodata_end_ld +syscall_handle +sched_exit +kernel_vma_context +liballoc_unlock +lapic_eoi +proc_list +hhdm_offset +acpi_madt_ioapic_list +vmm_init +memcpy +acpi_init +ioapic_get_gsi +malloc +lapic_init +vma_create_context +standby +karq +reqs_end_ld +vmm_alloc_pm +gdt_init +rodata_start_ld +ioapic_init +__kmain +curr_proc +ksym_init +ioapic_redirect_irq +schedule +bootstrap_lapic_id +pit_enable +virt_to_phys +liballoc_lock +pit_init +npf_vsnprintf +vma_alloc +idt_init +smp_entry +pmm_request_page +vmm_map +acpi_madt_ioapic_length +hhdm_req +acpi_madt_iso_list +panic_ctx +current_pid +flanterm_write +vmm_release_pm +irq_handler_table +liballoc_alloc +__x86_64_syscall_init +__panic_display_ascii_art +syscall_exit +npf_vpprintf +panic +vmm_kernel_pm_exists +memcmp +sched_create +tick +vmm_kernel_pm +ksym_fromip +outb +def_table +ft_ctx +memset +pmm_free_page +idt_int_handler +acpi_lapic_addr +flanterm_context_reinit +strcmp +vmm_map_user +acpi_find_table +idt_register_irq +VGA8 +text_end_ld +pmm_init +ioapic_redirect_gsi +reqs_start_ld +pit_handler +smp_cpu_count +vmm_current_pm +tss_list +isr_stub_table +vmm_load_pagemap +mk_wcwidth +sched_init +strlen +madt_init +text_start_ld +mm_req +syscall_entry +elf_load +kstack +_memmap +.symtab +.strtab +.shstrtab +.text +.limine_requests +.rodata +.data +.bss +.debug_info +.debug_abbrev +.debug_loclists +.debug_aranges +.debug_rnglists +.debug_line +.debug_str +.debug_line_str +.comment diff --git a/txt.txt b/txt.txt new file mode 100644 index 0000000..3e59680 --- /dev/null +++ b/txt.txt @@ -0,0 +1,559 @@ +En-tête ELF: + Magique: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 + Classe: ELF64 + Données: complément à 2, système à octets de poids faible d'abord (little endian) + Version: 1 (actuelle) + OS/ABI: UNIX - System V + Version ABI: 0 + Type: EXEC (fichier exécutable) + Machine: Advanced Micro Devices X86-64 + Version: 0x1 + Adresse du point d'entrée: 0xffffffff8000d040 + Début des en-têtes de programme : 64 (octets dans le fichier) + Début des en-têtes de section : 308160 (octets dans le fichier) + Fanions: 0x0 + Taille de cet en-tête: 64 (octets) + Taille de l'en-tête du programme: 56 (octets) + Nombre d'en-tête du programme: 4 + Taille des en-têtes de section: 64 (octets) + Nombre d'en-têtes de section: 18 + Table d'index des chaînes d'en-tête de section: 17 + +En-têtes de section : + [Nr] Nom Type Adresse Décalage + Taille TaillEntrée Fanion Lien Info Alignement + [ 0] NULL 0000000000000000 00000000 + 0000000000000000 0000000000000000 0 0 0 + [ 1] .text PROGBITS ffffffff80000000 00001000 + 000000000000d052 0000000000000000 AX 0 0 64 + [ 2] .limine_requests PROGBITS ffffffff8000e000 0000f000 + 00000000000002a0 0000000000000000 WA 0 0 32 + [ 3] .rodata PROGBITS ffffffff8000f000 00010000 + 0000000000004de0 0000000000000000 A 0 0 32 + [ 4] .data PROGBITS ffffffff80014000 00015000 + 0000000000001060 0000000000000000 WA 0 0 32 + [ 5] .bss NOBITS ffffffff80015060 00016060 + 00000000000e2f00 0000000000000000 WA 0 0 32 + [ 6] .debug_info PROGBITS 0000000000000000 00016060 + 0000000000010054 0000000000000000 0 0 1 + [ 7] .debug_abbrev PROGBITS 0000000000000000 000260b4 + 0000000000003d55 0000000000000000 0 0 1 + [ 8] .debug_loclists PROGBITS 0000000000000000 00029e09 + 000000000000b554 0000000000000000 0 0 1 + [ 9] .debug_aranges PROGBITS 0000000000000000 0003535d + 0000000000000d70 0000000000000000 0 0 1 + [10] .debug_rnglists PROGBITS 0000000000000000 000360cd + 00000000000017ea 0000000000000000 0 0 1 + [11] .debug_line PROGBITS 0000000000000000 000378b7 + 000000000000ce27 0000000000000000 0 0 1 + [12] .debug_str PROGBITS 0000000000000000 000446de + 0000000000002468 0000000000000001 MS 0 0 1 + [13] .debug_line_str PROGBITS 0000000000000000 00046b46 + 0000000000000474 0000000000000001 MS 0 0 1 + [14] .comment PROGBITS 0000000000000000 00046fba + 000000000000001b 0000000000000001 MS 0 0 1 + [15] .symtab SYMTAB 0000000000000000 00046fd8 + 0000000000002b68 0000000000000018 16 359 8 + [16] .strtab STRTAB 0000000000000000 00049b40 + 00000000000017bc 0000000000000000 0 0 1 + [17] .shstrtab STRTAB 0000000000000000 0004b2fc + 00000000000000be 0000000000000000 0 0 1 +Clé des fanions : + W (écriture), A (allocation), X (exécution), M (fusion), S (chaînes), I (info), + L (ordre des liens), O (traitement supplémentaire par l'OS requis), G (groupe), + T (TLS), C (compressé), x (inconnu), o (spécifique à l'OS), E (exclu), + D (mbind), l (grand), p (processor specific) + +Il n'y a pas de groupe de section dans ce fichier. + +En-têtes de programme : + Type Décalage Adr.virt Adr.phys. + Taille fichier Taille mémoire Fanion Alignement + LOAD 0x000000000000f000 0xffffffff8000e000 0xffffffff8000e000 + 0x00000000000002a0 0x00000000000002a0 RW 0x1000 + LOAD 0x0000000000001000 0xffffffff80000000 0xffffffff80000000 + 0x000000000000d052 0x000000000000d052 R E 0x1000 + LOAD 0x0000000000010000 0xffffffff8000f000 0xffffffff8000f000 + 0x0000000000004de0 0x0000000000004de0 R 0x1000 + LOAD 0x0000000000015000 0xffffffff80014000 0xffffffff80014000 + 0x0000000000001060 0x00000000000e3f60 RW 0x1000 + + Correspondance section/segment : + Sections de segment... + 00 .limine_requests + 01 .text + 02 .rodata + 03 .data .bss + +Il n'y a pas de section dynamique dans ce fichier. + +Il n'y a pas de réadressages dans ce fichier. +Pas d'information de déroulement spécifique au processeur à décoder + +La table de symboles « .symtab » contient 463 entrées : + Num: Valeur Tail Type Lien Vis Ndx Nom + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND + 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS gdt.c + 2: 0000000000000000 0 FILE LOCAL DEFAULT ABS idt.c + 3: ffffffff8001cb70 4096 OBJECT LOCAL DEFAULT 5 idt + 4: ffffffff8001c760 1024 OBJECT LOCAL DEFAULT 5 vectors + 5: ffffffff8001cb60 10 OBJECT LOCAL DEFAULT 5 idtr + 6: 0000000000000000 0 FILE LOCAL DEFAULT ABS io.c + 7: 0000000000000000 0 FILE LOCAL DEFAULT ABS pit.c + 8: 0000000000000000 0 FILE LOCAL DEFAULT ABS smp.c + 9: ffffffff8000e020 56 OBJECT LOCAL DEFAULT 2 smp_request + 10: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscall.c + 11: 0000000000000000 0 FILE LOCAL DEFAULT ABS sym.c + 12: ffffffff8000e060 48 OBJECT LOCAL DEFAULT 2 exec_file_rq + 13: ffffffff8001db90 8 OBJECT LOCAL DEFAULT 5 __ksym_symtab + 14: ffffffff8001db80 4 OBJECT LOCAL DEFAULT 5 __ksym_symcount + 15: ffffffff8001db88 8 OBJECT LOCAL DEFAULT 5 __ksym_strtab + 16: 0000000000000000 0 FILE LOCAL DEFAULT ABS ioapic.c + 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS lapic.c + 18: 0000000000000000 0 FILE LOCAL DEFAULT ABS elf.c + 19: 0000000000000000 0 FILE LOCAL DEFAULT ABS string.c + 20: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c + 21: ffffffff8000e0e0 48 OBJECT LOCAL DEFAULT 2 framebuffer_request + 22: ffffffff8000e0a0 64 OBJECT LOCAL DEFAULT 2 module_request + 23: ffffffff8000e290 16 OBJECT LOCAL DEFAULT 2 limine_requests_[...] + 24: ffffffff8000e000 32 OBJECT LOCAL DEFAULT 2 limine_requests_[...] + 25: ffffffff8000e110 24 OBJECT LOCAL DEFAULT 2 limine_base_revision + 26: 0000000000000000 0 FILE LOCAL DEFAULT ABS liballoc.c + 27: ffffffff80000fb0 129 FUNC LOCAL DEFAULT 1 allocate_new_page + 28: ffffffff8001fbc0 8 OBJECT LOCAL DEFAULT 5 l_allocated + 29: ffffffff8001fbb0 8 OBJECT LOCAL DEFAULT 5 l_warningCount + 30: ffffffff8001fbd0 8 OBJECT LOCAL DEFAULT 5 l_memRoot + 31: ffffffff8001fbc8 8 OBJECT LOCAL DEFAULT 5 l_bestBet + 32: ffffffff8001fbb8 8 OBJECT LOCAL DEFAULT 5 l_inuse + 33: 0000000000000000 0 FILE LOCAL DEFAULT ABS liballoc_soaplin.c + 34: ffffffff8001fbd8 4 OBJECT LOCAL DEFAULT 5 liballoc_lock_var + 35: 0000000000000000 0 FILE LOCAL DEFAULT ABS memop.c + 36: 0000000000000000 0 FILE LOCAL DEFAULT ABS pmm.c + 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS vma.c + 38: 0000000000000000 0 FILE LOCAL DEFAULT ABS vmm.c + 39: ffffffff80001a20 144 FUNC LOCAL DEFAULT 1 __vmm_get_next_lvl + 40: ffffffff8000e200 72 OBJECT LOCAL DEFAULT 2 pmrq + 41: 0000000000000000 0 FILE LOCAL DEFAULT ABS sched.c + 42: ffffffff80002050 254 FUNC LOCAL DEFAULT 1 schedule.part.0 + 43: 0000000000000000 0 FILE LOCAL DEFAULT ABS acpi.c + 44: ffffffff8001fc40 8 OBJECT LOCAL DEFAULT 5 __acpi_rsdt_ptr + 45: ffffffff8001fc48 4 OBJECT LOCAL DEFAULT 5 __acpi_uses_xsdt + 46: ffffffff8000e260 48 OBJECT LOCAL DEFAULT 2 rsdp_req + 47: 0000000000000000 0 FILE LOCAL DEFAULT ABS madt.c + 48: 0000000000000000 0 FILE LOCAL DEFAULT ABS panic.c + 49: ffffffff80002790 527 FUNC LOCAL DEFAULT 1 __panic_display_regs + 50: ffffffff80020c60 176 OBJECT LOCAL DEFAULT 5 __panic_regdump + 51: 0000000000000000 0 FILE LOCAL DEFAULT ABS fb.c + 52: ffffffff80002cd0 75 FUNC LOCAL DEFAULT 1 bump_alloc + 53: ffffffff80020d10 1 OBJECT LOCAL DEFAULT 5 base_offset_added.0 + 54: ffffffff80020d18 8 OBJECT LOCAL DEFAULT 5 bump_alloc_ptr + 55: ffffffff80020d20 0xd5228 OBJECT LOCAL DEFAULT 5 bump_alloc_pool + 56: ffffffff80002d20 43 FUNC LOCAL DEFAULT 1 flanterm_fb_save[...] + 57: ffffffff80002d50 43 FUNC LOCAL DEFAULT 1 flanterm_fb_rest[...] + 58: ffffffff80002d80 27 FUNC LOCAL DEFAULT 1 flanterm_fb_swap[...] + 59: ffffffff80002da0 163 FUNC LOCAL DEFAULT 1 push_to_queue + 60: ffffffff80002e50 211 FUNC LOCAL DEFAULT 1 flanterm_fb_revscroll + 61: ffffffff80002f30 213 FUNC LOCAL DEFAULT 1 flanterm_fb_scroll + 62: ffffffff80003010 69 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 63: ffffffff80003060 60 FUNC LOCAL DEFAULT 1 flanterm_fb_get_[...] + 64: ffffffff800030a0 113 FUNC LOCAL DEFAULT 1 flanterm_fb_move[...] + 65: ffffffff80003120 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 66: ffffffff80003130 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 67: ffffffff80003140 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 68: ffffffff80003150 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 69: ffffffff80003160 55 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 70: ffffffff800031a0 55 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 71: ffffffff800031e0 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 72: ffffffff800031f0 11 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 73: ffffffff80003200 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 74: ffffffff80003210 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] + 75: ffffffff80003220 238 FUNC LOCAL DEFAULT 1 draw_cursor + 76: ffffffff80003310 346 FUNC LOCAL DEFAULT 1 flanterm_fb_doub[...] + 77: ffffffff80003480 368 FUNC LOCAL DEFAULT 1 flanterm_fb_full[...] + 78: ffffffff800035f0 185 FUNC LOCAL DEFAULT 1 flanterm_fb_deinit + 79: ffffffff80020d11 1 OBJECT LOCAL DEFAULT 5 bump_allocated_i[...] + 80: ffffffff800036b0 469 FUNC LOCAL DEFAULT 1 plot_char_scaled[...] + 81: ffffffff80003890 289 FUNC LOCAL DEFAULT 1 plot_char_unscal[...] + 82: ffffffff800039c0 311 FUNC LOCAL DEFAULT 1 plot_char_unscal[...] + 83: ffffffff80003b00 416 FUNC LOCAL DEFAULT 1 plot_char_scaled[...] + 84: ffffffff80003ca0 256 FUNC LOCAL DEFAULT 1 flanterm_fb_clear + 85: ffffffff80003da0 395 FUNC LOCAL DEFAULT 1 flanterm_fb_raw_[...] + 86: ffffffff8000ffa0 4096 OBJECT LOCAL DEFAULT 3 builtin_font + 87: 0000000000000000 0 FILE LOCAL DEFAULT ABS flanterm.c + 88: ffffffff80013100 1136 OBJECT LOCAL DEFAULT 3 combining.0 + 89: ffffffff80013580 960 OBJECT LOCAL DEFAULT 3 col256 + 90: 0000000000000000 0 FILE LOCAL DEFAULT ABS log.c + 91: 0000000000000000 0 FILE LOCAL DEFAULT ABS printf.c + 92: ffffffff80006c40 113 FUNC LOCAL DEFAULT 1 npf_utoa_rev + 93: ffffffff80006cc0 26 FUNC LOCAL DEFAULT 1 npf_bufputc + 94: ffffffff80006ce0 1 FUNC LOCAL DEFAULT 1 npf_bufputc_nop + 95: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscall.c + 96: ffffffff800084e0 3 FUNC LOCAL DEFAULT 1 __syscall_undefined + 97: ffffffff800f5f60 8192 OBJECT LOCAL DEFAULT 5 syscall_table + 98: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscalls_proc.c + 99: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/arch/x86_64/[...] + 100: ffffffff80008660 0 NOTYPE LOCAL DEFAULT 1 isr_stub_0 + 101: ffffffff800086a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_1 + 102: ffffffff800086e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_2 + 103: ffffffff80008720 0 NOTYPE LOCAL DEFAULT 1 isr_stub_3 + 104: ffffffff80008760 0 NOTYPE LOCAL DEFAULT 1 isr_stub_4 + 105: ffffffff800087a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_5 + 106: ffffffff800087e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_6 + 107: ffffffff80008820 0 NOTYPE LOCAL DEFAULT 1 isr_stub_7 + 108: ffffffff80008860 0 NOTYPE LOCAL DEFAULT 1 isr_stub_8 + 109: ffffffff8000889e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_9 + 110: ffffffff800088de 0 NOTYPE LOCAL DEFAULT 1 isr_stub_10 + 111: ffffffff8000891c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_11 + 112: ffffffff8000895a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_12 + 113: ffffffff80008998 0 NOTYPE LOCAL DEFAULT 1 isr_stub_13 + 114: ffffffff800089d6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_14 + 115: ffffffff80008a14 0 NOTYPE LOCAL DEFAULT 1 isr_stub_15 + 116: ffffffff80008a54 0 NOTYPE LOCAL DEFAULT 1 isr_stub_16 + 117: ffffffff80008a94 0 NOTYPE LOCAL DEFAULT 1 isr_stub_17 + 118: ffffffff80008ad2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_18 + 119: ffffffff80008b12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_19 + 120: ffffffff80008b52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_20 + 121: ffffffff80008b92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_21 + 122: ffffffff80008bd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_22 + 123: ffffffff80008c12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_23 + 124: ffffffff80008c52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_24 + 125: ffffffff80008c92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_25 + 126: ffffffff80008cd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_26 + 127: ffffffff80008d12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_27 + 128: ffffffff80008d52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_28 + 129: ffffffff80008d92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_29 + 130: ffffffff80008dd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_30 + 131: ffffffff80008e10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_31 + 132: ffffffff80008e50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_32 + 133: ffffffff80008e90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_33 + 134: ffffffff80008ed0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_34 + 135: ffffffff80008f10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_35 + 136: ffffffff80008f50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_36 + 137: ffffffff80008f90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_37 + 138: ffffffff80008fd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_38 + 139: ffffffff80009010 0 NOTYPE LOCAL DEFAULT 1 isr_stub_39 + 140: ffffffff80009050 0 NOTYPE LOCAL DEFAULT 1 isr_stub_40 + 141: ffffffff80009090 0 NOTYPE LOCAL DEFAULT 1 isr_stub_41 + 142: ffffffff800090d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_42 + 143: ffffffff80009110 0 NOTYPE LOCAL DEFAULT 1 isr_stub_43 + 144: ffffffff80009150 0 NOTYPE LOCAL DEFAULT 1 isr_stub_44 + 145: ffffffff80009190 0 NOTYPE LOCAL DEFAULT 1 isr_stub_45 + 146: ffffffff800091d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_46 + 147: ffffffff80009210 0 NOTYPE LOCAL DEFAULT 1 isr_stub_47 + 148: ffffffff80009250 0 NOTYPE LOCAL DEFAULT 1 isr_stub_48 + 149: ffffffff80009290 0 NOTYPE LOCAL DEFAULT 1 isr_stub_49 + 150: ffffffff800092d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_50 + 151: ffffffff80009310 0 NOTYPE LOCAL DEFAULT 1 isr_stub_51 + 152: ffffffff80009350 0 NOTYPE LOCAL DEFAULT 1 isr_stub_52 + 153: ffffffff80009390 0 NOTYPE LOCAL DEFAULT 1 isr_stub_53 + 154: ffffffff800093d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_54 + 155: ffffffff80009410 0 NOTYPE LOCAL DEFAULT 1 isr_stub_55 + 156: ffffffff80009450 0 NOTYPE LOCAL DEFAULT 1 isr_stub_56 + 157: ffffffff80009490 0 NOTYPE LOCAL DEFAULT 1 isr_stub_57 + 158: ffffffff800094d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_58 + 159: ffffffff80009510 0 NOTYPE LOCAL DEFAULT 1 isr_stub_59 + 160: ffffffff80009550 0 NOTYPE LOCAL DEFAULT 1 isr_stub_60 + 161: ffffffff80009590 0 NOTYPE LOCAL DEFAULT 1 isr_stub_61 + 162: ffffffff800095d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_62 + 163: ffffffff80009610 0 NOTYPE LOCAL DEFAULT 1 isr_stub_63 + 164: ffffffff80009650 0 NOTYPE LOCAL DEFAULT 1 isr_stub_64 + 165: ffffffff80009690 0 NOTYPE LOCAL DEFAULT 1 isr_stub_65 + 166: ffffffff800096d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_66 + 167: ffffffff80009710 0 NOTYPE LOCAL DEFAULT 1 isr_stub_67 + 168: ffffffff80009750 0 NOTYPE LOCAL DEFAULT 1 isr_stub_68 + 169: ffffffff80009790 0 NOTYPE LOCAL DEFAULT 1 isr_stub_69 + 170: ffffffff800097d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_70 + 171: ffffffff80009810 0 NOTYPE LOCAL DEFAULT 1 isr_stub_71 + 172: ffffffff80009850 0 NOTYPE LOCAL DEFAULT 1 isr_stub_72 + 173: ffffffff80009890 0 NOTYPE LOCAL DEFAULT 1 isr_stub_73 + 174: ffffffff800098d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_74 + 175: ffffffff80009910 0 NOTYPE LOCAL DEFAULT 1 isr_stub_75 + 176: ffffffff80009950 0 NOTYPE LOCAL DEFAULT 1 isr_stub_76 + 177: ffffffff80009990 0 NOTYPE LOCAL DEFAULT 1 isr_stub_77 + 178: ffffffff800099d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_78 + 179: ffffffff80009a10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_79 + 180: ffffffff80009a50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_80 + 181: ffffffff80009a90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_81 + 182: ffffffff80009ad0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_82 + 183: ffffffff80009b10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_83 + 184: ffffffff80009b50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_84 + 185: ffffffff80009b90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_85 + 186: ffffffff80009bd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_86 + 187: ffffffff80009c10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_87 + 188: ffffffff80009c50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_88 + 189: ffffffff80009c90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_89 + 190: ffffffff80009cd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_90 + 191: ffffffff80009d10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_91 + 192: ffffffff80009d50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_92 + 193: ffffffff80009d90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_93 + 194: ffffffff80009dd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_94 + 195: ffffffff80009e10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_95 + 196: ffffffff80009e50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_96 + 197: ffffffff80009e90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_97 + 198: ffffffff80009ed0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_98 + 199: ffffffff80009f10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_99 + 200: ffffffff80009f50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_100 + 201: ffffffff80009f90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_101 + 202: ffffffff80009fd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_102 + 203: ffffffff8000a010 0 NOTYPE LOCAL DEFAULT 1 isr_stub_103 + 204: ffffffff8000a050 0 NOTYPE LOCAL DEFAULT 1 isr_stub_104 + 205: ffffffff8000a090 0 NOTYPE LOCAL DEFAULT 1 isr_stub_105 + 206: ffffffff8000a0d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_106 + 207: ffffffff8000a110 0 NOTYPE LOCAL DEFAULT 1 isr_stub_107 + 208: ffffffff8000a150 0 NOTYPE LOCAL DEFAULT 1 isr_stub_108 + 209: ffffffff8000a190 0 NOTYPE LOCAL DEFAULT 1 isr_stub_109 + 210: ffffffff8000a1d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_110 + 211: ffffffff8000a210 0 NOTYPE LOCAL DEFAULT 1 isr_stub_111 + 212: ffffffff8000a250 0 NOTYPE LOCAL DEFAULT 1 isr_stub_112 + 213: ffffffff8000a290 0 NOTYPE LOCAL DEFAULT 1 isr_stub_113 + 214: ffffffff8000a2d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_114 + 215: ffffffff8000a310 0 NOTYPE LOCAL DEFAULT 1 isr_stub_115 + 216: ffffffff8000a350 0 NOTYPE LOCAL DEFAULT 1 isr_stub_116 + 217: ffffffff8000a390 0 NOTYPE LOCAL DEFAULT 1 isr_stub_117 + 218: ffffffff8000a3d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_118 + 219: ffffffff8000a410 0 NOTYPE LOCAL DEFAULT 1 isr_stub_119 + 220: ffffffff8000a450 0 NOTYPE LOCAL DEFAULT 1 isr_stub_120 + 221: ffffffff8000a490 0 NOTYPE LOCAL DEFAULT 1 isr_stub_121 + 222: ffffffff8000a4d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_122 + 223: ffffffff8000a510 0 NOTYPE LOCAL DEFAULT 1 isr_stub_123 + 224: ffffffff8000a550 0 NOTYPE LOCAL DEFAULT 1 isr_stub_124 + 225: ffffffff8000a590 0 NOTYPE LOCAL DEFAULT 1 isr_stub_125 + 226: ffffffff8000a5d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_126 + 227: ffffffff8000a610 0 NOTYPE LOCAL DEFAULT 1 isr_stub_127 + 228: ffffffff8000a650 0 NOTYPE LOCAL DEFAULT 1 isr_stub_128 + 229: ffffffff8000a693 0 NOTYPE LOCAL DEFAULT 1 isr_stub_129 + 230: ffffffff8000a6d6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_130 + 231: ffffffff8000a719 0 NOTYPE LOCAL DEFAULT 1 isr_stub_131 + 232: ffffffff8000a75c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_132 + 233: ffffffff8000a79f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_133 + 234: ffffffff8000a7e2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_134 + 235: ffffffff8000a825 0 NOTYPE LOCAL DEFAULT 1 isr_stub_135 + 236: ffffffff8000a868 0 NOTYPE LOCAL DEFAULT 1 isr_stub_136 + 237: ffffffff8000a8ab 0 NOTYPE LOCAL DEFAULT 1 isr_stub_137 + 238: ffffffff8000a8ee 0 NOTYPE LOCAL DEFAULT 1 isr_stub_138 + 239: ffffffff8000a931 0 NOTYPE LOCAL DEFAULT 1 isr_stub_139 + 240: ffffffff8000a974 0 NOTYPE LOCAL DEFAULT 1 isr_stub_140 + 241: ffffffff8000a9b7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_141 + 242: ffffffff8000a9fa 0 NOTYPE LOCAL DEFAULT 1 isr_stub_142 + 243: ffffffff8000aa3d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_143 + 244: ffffffff8000aa80 0 NOTYPE LOCAL DEFAULT 1 isr_stub_144 + 245: ffffffff8000aac3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_145 + 246: ffffffff8000ab06 0 NOTYPE LOCAL DEFAULT 1 isr_stub_146 + 247: ffffffff8000ab49 0 NOTYPE LOCAL DEFAULT 1 isr_stub_147 + 248: ffffffff8000ab8c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_148 + 249: ffffffff8000abcf 0 NOTYPE LOCAL DEFAULT 1 isr_stub_149 + 250: ffffffff8000ac12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_150 + 251: ffffffff8000ac55 0 NOTYPE LOCAL DEFAULT 1 isr_stub_151 + 252: ffffffff8000ac98 0 NOTYPE LOCAL DEFAULT 1 isr_stub_152 + 253: ffffffff8000acdb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_153 + 254: ffffffff8000ad1e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_154 + 255: ffffffff8000ad61 0 NOTYPE LOCAL DEFAULT 1 isr_stub_155 + 256: ffffffff8000ada4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_156 + 257: ffffffff8000ade7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_157 + 258: ffffffff8000ae2a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_158 + 259: ffffffff8000ae6d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_159 + 260: ffffffff8000aeb0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_160 + 261: ffffffff8000aef3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_161 + 262: ffffffff8000af36 0 NOTYPE LOCAL DEFAULT 1 isr_stub_162 + 263: ffffffff8000af79 0 NOTYPE LOCAL DEFAULT 1 isr_stub_163 + 264: ffffffff8000afbc 0 NOTYPE LOCAL DEFAULT 1 isr_stub_164 + 265: ffffffff8000afff 0 NOTYPE LOCAL DEFAULT 1 isr_stub_165 + 266: ffffffff8000b042 0 NOTYPE LOCAL DEFAULT 1 isr_stub_166 + 267: ffffffff8000b085 0 NOTYPE LOCAL DEFAULT 1 isr_stub_167 + 268: ffffffff8000b0c8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_168 + 269: ffffffff8000b10b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_169 + 270: ffffffff8000b14e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_170 + 271: ffffffff8000b191 0 NOTYPE LOCAL DEFAULT 1 isr_stub_171 + 272: ffffffff8000b1d4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_172 + 273: ffffffff8000b217 0 NOTYPE LOCAL DEFAULT 1 isr_stub_173 + 274: ffffffff8000b25a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_174 + 275: ffffffff8000b29d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_175 + 276: ffffffff8000b2e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_176 + 277: ffffffff8000b323 0 NOTYPE LOCAL DEFAULT 1 isr_stub_177 + 278: ffffffff8000b366 0 NOTYPE LOCAL DEFAULT 1 isr_stub_178 + 279: ffffffff8000b3a9 0 NOTYPE LOCAL DEFAULT 1 isr_stub_179 + 280: ffffffff8000b3ec 0 NOTYPE LOCAL DEFAULT 1 isr_stub_180 + 281: ffffffff8000b42f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_181 + 282: ffffffff8000b472 0 NOTYPE LOCAL DEFAULT 1 isr_stub_182 + 283: ffffffff8000b4b5 0 NOTYPE LOCAL DEFAULT 1 isr_stub_183 + 284: ffffffff8000b4f8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_184 + 285: ffffffff8000b53b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_185 + 286: ffffffff8000b57e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_186 + 287: ffffffff8000b5c1 0 NOTYPE LOCAL DEFAULT 1 isr_stub_187 + 288: ffffffff8000b604 0 NOTYPE LOCAL DEFAULT 1 isr_stub_188 + 289: ffffffff8000b647 0 NOTYPE LOCAL DEFAULT 1 isr_stub_189 + 290: ffffffff8000b68a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_190 + 291: ffffffff8000b6cd 0 NOTYPE LOCAL DEFAULT 1 isr_stub_191 + 292: ffffffff8000b710 0 NOTYPE LOCAL DEFAULT 1 isr_stub_192 + 293: ffffffff8000b753 0 NOTYPE LOCAL DEFAULT 1 isr_stub_193 + 294: ffffffff8000b796 0 NOTYPE LOCAL DEFAULT 1 isr_stub_194 + 295: ffffffff8000b7d9 0 NOTYPE LOCAL DEFAULT 1 isr_stub_195 + 296: ffffffff8000b81c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_196 + 297: ffffffff8000b85f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_197 + 298: ffffffff8000b8a2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_198 + 299: ffffffff8000b8e5 0 NOTYPE LOCAL DEFAULT 1 isr_stub_199 + 300: ffffffff8000b928 0 NOTYPE LOCAL DEFAULT 1 isr_stub_200 + 301: ffffffff8000b96b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_201 + 302: ffffffff8000b9ae 0 NOTYPE LOCAL DEFAULT 1 isr_stub_202 + 303: ffffffff8000b9f1 0 NOTYPE LOCAL DEFAULT 1 isr_stub_203 + 304: ffffffff8000ba34 0 NOTYPE LOCAL DEFAULT 1 isr_stub_204 + 305: ffffffff8000ba77 0 NOTYPE LOCAL DEFAULT 1 isr_stub_205 + 306: ffffffff8000baba 0 NOTYPE LOCAL DEFAULT 1 isr_stub_206 + 307: ffffffff8000bafd 0 NOTYPE LOCAL DEFAULT 1 isr_stub_207 + 308: ffffffff8000bb40 0 NOTYPE LOCAL DEFAULT 1 isr_stub_208 + 309: ffffffff8000bb83 0 NOTYPE LOCAL DEFAULT 1 isr_stub_209 + 310: ffffffff8000bbc6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_210 + 311: ffffffff8000bc09 0 NOTYPE LOCAL DEFAULT 1 isr_stub_211 + 312: ffffffff8000bc4c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_212 + 313: ffffffff8000bc8f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_213 + 314: ffffffff8000bcd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_214 + 315: ffffffff8000bd15 0 NOTYPE LOCAL DEFAULT 1 isr_stub_215 + 316: ffffffff8000bd58 0 NOTYPE LOCAL DEFAULT 1 isr_stub_216 + 317: ffffffff8000bd9b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_217 + 318: ffffffff8000bdde 0 NOTYPE LOCAL DEFAULT 1 isr_stub_218 + 319: ffffffff8000be21 0 NOTYPE LOCAL DEFAULT 1 isr_stub_219 + 320: ffffffff8000be64 0 NOTYPE LOCAL DEFAULT 1 isr_stub_220 + 321: ffffffff8000bea7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_221 + 322: ffffffff8000beea 0 NOTYPE LOCAL DEFAULT 1 isr_stub_222 + 323: ffffffff8000bf2d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_223 + 324: ffffffff8000bf70 0 NOTYPE LOCAL DEFAULT 1 isr_stub_224 + 325: ffffffff8000bfb3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_225 + 326: ffffffff8000bff6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_226 + 327: ffffffff8000c039 0 NOTYPE LOCAL DEFAULT 1 isr_stub_227 + 328: ffffffff8000c07c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_228 + 329: ffffffff8000c0bf 0 NOTYPE LOCAL DEFAULT 1 isr_stub_229 + 330: ffffffff8000c102 0 NOTYPE LOCAL DEFAULT 1 isr_stub_230 + 331: ffffffff8000c145 0 NOTYPE LOCAL DEFAULT 1 isr_stub_231 + 332: ffffffff8000c188 0 NOTYPE LOCAL DEFAULT 1 isr_stub_232 + 333: ffffffff8000c1cb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_233 + 334: ffffffff8000c20e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_234 + 335: ffffffff8000c251 0 NOTYPE LOCAL DEFAULT 1 isr_stub_235 + 336: ffffffff8000c294 0 NOTYPE LOCAL DEFAULT 1 isr_stub_236 + 337: ffffffff8000c2d7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_237 + 338: ffffffff8000c31a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_238 + 339: ffffffff8000c35d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_239 + 340: ffffffff8000c3a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_240 + 341: ffffffff8000c3e3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_241 + 342: ffffffff8000c426 0 NOTYPE LOCAL DEFAULT 1 isr_stub_242 + 343: ffffffff8000c469 0 NOTYPE LOCAL DEFAULT 1 isr_stub_243 + 344: ffffffff8000c4ac 0 NOTYPE LOCAL DEFAULT 1 isr_stub_244 + 345: ffffffff8000c4ef 0 NOTYPE LOCAL DEFAULT 1 isr_stub_245 + 346: ffffffff8000c532 0 NOTYPE LOCAL DEFAULT 1 isr_stub_246 + 347: ffffffff8000c575 0 NOTYPE LOCAL DEFAULT 1 isr_stub_247 + 348: ffffffff8000c5b8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_248 + 349: ffffffff8000c5fb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_249 + 350: ffffffff8000c63e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_250 + 351: ffffffff8000c681 0 NOTYPE LOCAL DEFAULT 1 isr_stub_251 + 352: ffffffff8000c6c4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_252 + 353: ffffffff8000c707 0 NOTYPE LOCAL DEFAULT 1 isr_stub_253 + 354: ffffffff8000c74a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_254 + 355: ffffffff8000c78d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_255 + 356: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/arch/x86_64/[...] + 357: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/premain.asm + 358: 0000000000000000 0 FILE LOCAL DEFAULT ABS font.c + 359: ffffffff80000350 236 FUNC GLOBAL DEFAULT 1 smp_init + 360: ffffffff80006af0 285 FUNC GLOBAL DEFAULT 1 log + 361: ffffffff80008420 189 FUNC GLOBAL DEFAULT 1 printf + 362: ffffffff8001fc58 4 OBJECT GLOBAL DEFAULT 5 acpi_madt_iso_length + 363: ffffffff80003f40 3011 FUNC GLOBAL DEFAULT 1 flanterm_fb_init + 364: ffffffff80013de0 0 NOTYPE GLOBAL DEFAULT 3 rodata_end_ld + 365: ffffffff800084f0 184 FUNC GLOBAL DEFAULT 1 syscall_handle + 366: ffffffff800024c0 78 FUNC GLOBAL DEFAULT 1 sched_exit + 367: ffffffff8001fc08 8 OBJECT GLOBAL DEFAULT 5 kernel_vma_context + 368: ffffffff80001400 13 FUNC GLOBAL DEFAULT 1 liballoc_unlock + 369: ffffffff80000920 19 FUNC GLOBAL DEFAULT 1 lapic_eoi + 370: ffffffff8001fc38 8 OBJECT GLOBAL DEFAULT 5 proc_list + 371: ffffffff8001fbe0 8 OBJECT GLOBAL DEFAULT 5 hhdm_offset + 372: ffffffff80020460 2048 OBJECT GLOBAL DEFAULT 5 acpi_madt_ioapic_list + 373: ffffffff80001ce0 721 FUNC GLOBAL DEFAULT 1 vmm_init + 374: ffffffff80001430 36 FUNC GLOBAL DEFAULT 1 memcpy + 375: ffffffff8001db74 4 OBJECT GLOBAL DEFAULT 5 ctr + 376: ffffffff80002600 134 FUNC GLOBAL DEFAULT 1 acpi_init + 377: ffffffff80000760 102 FUNC GLOBAL DEFAULT 1 ioapic_get_gsi + 378: ffffffff80001040 904 FUNC GLOBAL DEFAULT 1 malloc + 379: ffffffff800008f0 38 FUNC GLOBAL DEFAULT 1 lapic_init + 380: ffffffff800017d0 249 FUNC GLOBAL DEFAULT 1 vma_create_context + 381: ffffffff8001fc28 4 OBJECT GLOBAL DEFAULT 5 standby + 382: ffffffff8000e1c0 48 OBJECT GLOBAL DEFAULT 2 karq + 383: ffffffff8000e2a0 0 NOTYPE GLOBAL DEFAULT 2 reqs_end_ld + 384: ffffffff80001ac0 157 FUNC GLOBAL DEFAULT 1 vmm_alloc_pm + 385: ffffffff80000000 183 FUNC GLOBAL DEFAULT 1 gdt_init + 386: ffffffff8000f000 0 NOTYPE GLOBAL DEFAULT 3 rodata_start_ld + 387: ffffffff80000650 257 FUNC GLOBAL DEFAULT 1 ioapic_init + 388: ffffffff80000df0 435 FUNC GLOBAL DEFAULT 1 __kmain + 389: ffffffff8001fc30 8 OBJECT GLOBAL DEFAULT 5 curr_proc + 390: ffffffff800004a0 283 FUNC GLOBAL DEFAULT 1 ksym_init + 391: ffffffff80000880 111 FUNC GLOBAL DEFAULT 1 ioapic_redirect_irq + 392: ffffffff8001fbf0 24 OBJECT GLOBAL DEFAULT 5 stack + 393: ffffffff80002510 27 FUNC GLOBAL DEFAULT 1 schedule + 394: ffffffff8001db7c 4 OBJECT GLOBAL DEFAULT 5 bootstrap_lapic_id + 395: ffffffff8001fba8 8 OBJECT GLOBAL DEFAULT 5 fb + 396: ffffffff80000300 20 FUNC GLOBAL DEFAULT 1 pit_enable + 397: ffffffff80001bc0 144 FUNC GLOBAL DEFAULT 1 virt_to_phys + 398: ffffffff800013d0 35 FUNC GLOBAL DEFAULT 1 liballoc_lock + 399: ffffffff800002c0 51 FUNC GLOBAL DEFAULT 1 pit_init + 400: ffffffff800083a0 127 FUNC GLOBAL DEFAULT 1 npf_vsnprintf + 401: ffffffff800018e0 316 FUNC GLOBAL DEFAULT 1 vma_alloc + 402: ffffffff80000120 246 FUNC GLOBAL DEFAULT 1 idt_init + 403: ffffffff80000320 33 FUNC GLOBAL DEFAULT 1 smp_entry + 404: ffffffff80001710 104 FUNC GLOBAL DEFAULT 1 pmm_request_page + 405: ffffffff80001c50 140 FUNC GLOBAL DEFAULT 1 vmm_map + 406: ffffffff8001fc5c 4 OBJECT GLOBAL DEFAULT 5 acpi_madt_ioapic[...] + 407: ffffffff8000e140 48 OBJECT GLOBAL DEFAULT 2 hhdm_req + 408: ffffffff8001fc60 2048 OBJECT GLOBAL DEFAULT 5 acpi_madt_iso_list + 409: ffffffff80002b40 393 FUNC GLOBAL DEFAULT 1 panic_ctx + 410: ffffffff8001fc2c 4 OBJECT GLOBAL DEFAULT 5 current_pid + 411: ffffffff80004d00 7649 FUNC GLOBAL DEFAULT 1 flanterm_write + 412: ffffffff80001b60 64 FUNC GLOBAL DEFAULT 1 vmm_release_pm + 413: ffffffff8001c060 1792 OBJECT GLOBAL DEFAULT 5 irq_handler_table + 414: ffffffff80001410 26 FUNC GLOBAL DEFAULT 1 liballoc_alloc + 415: ffffffff80000440 84 FUNC GLOBAL DEFAULT 1 __x86_64_syscall_init + 416: ffffffff800029a0 90 FUNC GLOBAL DEFAULT 1 __panic_display_[...] + 417: ffffffff80008650 13 FUNC GLOBAL DEFAULT 1 syscall_exit + 418: ffffffff80006d00 5792 FUNC GLOBAL DEFAULT 1 npf_vpprintf + 419: ffffffff80002a00 307 FUNC GLOBAL DEFAULT 1 panic + 420: ffffffff8001fc10 4 OBJECT GLOBAL DEFAULT 5 vmm_kernel_pm_exists + 421: ffffffff800014c0 67 FUNC GLOBAL DEFAULT 1 memcmp + 422: ffffffff800021d0 752 FUNC GLOBAL DEFAULT 1 sched_create + 423: ffffffff8001db70 4 OBJECT GLOBAL DEFAULT 5 tick + 424: ffffffff8001fc20 8 OBJECT GLOBAL DEFAULT 5 vmm_kernel_pm + 425: ffffffff800005c0 144 FUNC GLOBAL DEFAULT 1 ksym_fromip + 426: ffffffff800085c0 138 FUNC GLOBAL DEFAULT 1 syscall_init + 427: ffffffff80000290 6 FUNC GLOBAL DEFAULT 1 outb + 428: ffffffff80014000 88 OBJECT GLOBAL DEFAULT 4 def_table + 429: ffffffff8001fba0 8 OBJECT GLOBAL DEFAULT 5 ft_ctx + 430: ffffffff80001460 68 FUNC GLOBAL DEFAULT 1 memset + 431: ffffffff80001780 76 FUNC GLOBAL DEFAULT 1 pmm_free_page + 432: ffffffff80000220 101 FUNC GLOBAL DEFAULT 1 idt_int_handler + 433: ffffffff8001fc50 8 OBJECT GLOBAL DEFAULT 5 acpi_lapic_addr + 434: ffffffff80004b10 136 FUNC GLOBAL DEFAULT 1 flanterm_context[...] + 435: ffffffff80000da0 80 FUNC GLOBAL DEFAULT 1 strcmp + 436: ffffffff80001fc0 137 FUNC GLOBAL DEFAULT 1 vmm_map_user + 437: ffffffff80002530 206 FUNC GLOBAL DEFAULT 1 acpi_find_table + 438: ffffffff800000c0 88 FUNC GLOBAL DEFAULT 1 idt_register_irq + 439: ffffffff80014060 4096 OBJECT GLOBAL DEFAULT 4 VGA8 + 440: ffffffff8000d052 0 NOTYPE GLOBAL DEFAULT 1 text_end_ld + 441: ffffffff80001540 451 FUNC GLOBAL DEFAULT 1 pmm_init + 442: ffffffff800007d0 156 FUNC GLOBAL DEFAULT 1 ioapic_redirect_gsi + 443: ffffffff8000e000 0 NOTYPE GLOBAL DEFAULT 2 reqs_start_ld + 444: ffffffff800002a0 18 FUNC GLOBAL DEFAULT 1 pit_handler + 445: ffffffff8001db78 4 OBJECT GLOBAL DEFAULT 5 smp_cpu_count + 446: ffffffff8001fc18 8 OBJECT GLOBAL DEFAULT 5 vmm_current_pm + 447: ffffffff80015060 28672 OBJECT GLOBAL DEFAULT 5 tss_list + 448: ffffffff8000c7d0 0 NOTYPE GLOBAL DEFAULT 1 isr_stub_table + 449: ffffffff80014000 0 NOTYPE GLOBAL DEFAULT 4 data_start_ld + 450: ffffffff80001ba0 31 FUNC GLOBAL DEFAULT 1 vmm_load_pagemap + 451: ffffffff80004ba0 331 FUNC GLOBAL DEFAULT 1 mk_wcwidth + 452: ffffffff800f7f60 0 NOTYPE GLOBAL DEFAULT 5 data_end_ld + 453: ffffffff8000d040 0 NOTYPE GLOBAL DEFAULT 1 kmain + 454: ffffffff80002150 123 FUNC GLOBAL DEFAULT 1 sched_init + 455: ffffffff80000d60 35 FUNC GLOBAL DEFAULT 1 strlen + 456: ffffffff800026a0 233 FUNC GLOBAL DEFAULT 1 madt_init + 457: ffffffff80000000 0 NOTYPE GLOBAL DEFAULT 1 text_start_ld + 458: ffffffff8000e180 48 OBJECT GLOBAL DEFAULT 2 mm_req + 459: ffffffff8000cfd0 0 NOTYPE GLOBAL DEFAULT 1 syscall_entry + 460: ffffffff80000940 1050 FUNC GLOBAL DEFAULT 1 elf_load + 461: ffffffff8001dba0 8192 OBJECT GLOBAL DEFAULT 5 kstack + 462: ffffffff8001fbe8 8 OBJECT GLOBAL DEFAULT 5 _memmap + +Aucune information de version repérée dans ce fichier. From 0652010b1cf7f61e3af652b3319ba7bd0c817583 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sat, 17 May 2025 01:26:38 +0200 Subject: [PATCH 16/30] kernel: Various changes + elf: Prevent dynamically linked programs from running on Soaplin. + sched: Support creating a process from a program_t structure. + syscall: Fix a bug where using syscall number 1024 would crash the OS. + syscall: Added a write syscall. It can only be used for writing to the standard output (FD: 1) --- kernel/src/exec/elf.c | 10 +++++++++- kernel/src/main.c | 2 +- kernel/src/sched/sched.c | 4 ++++ kernel/src/sched/sched.h | 4 ++++ kernel/src/sys/syscall.c | 6 ++++-- kernel/src/sys/syscalls/syscalls_fs.c | 11 +++++++++++ testing/sk-hello.elf | Bin 4320 -> 4480 bytes testing/test.asm | 13 +++++++++++-- testing/test.o | Bin 608 -> 960 bytes 9 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 kernel/src/sys/syscalls/syscalls_fs.c diff --git a/kernel/src/exec/elf.c b/kernel/src/exec/elf.c index 5cd8d9c..de0a3a4 100644 --- a/kernel/src/exec/elf.c +++ b/kernel/src/exec/elf.c @@ -47,6 +47,12 @@ program_t *elf_load(char *data, int user) { for (uint16_t i = 0; i < ehdr->e_phnum; i++) { log("elf - ELF segment type: %d\n", phdr[i].p_type); + + if (phdr[i].p_type == PT_INTERP) { + log("elf - A PT_INTERP program header was found. This was meant to be a dynamically-linked program, which Soaplin doesn't supports.\n"); + return NULL; + } + if (phdr[i].p_type != PT_LOAD) continue; @@ -58,7 +64,9 @@ program_t *elf_load(char *data, int user) { uint64_t flags = VMM_PRESENT; if (phdr[i].p_flags & PF_W) flags |= VMM_WRITABLE; - if (!(phdr[i].p_flags & PF_X)) + if (phdr[i].p_flags & PF_X) + flags &= ~VMM_NX; + else flags |= VMM_NX; if (user) diff --git a/kernel/src/main.c b/kernel/src/main.c index cedbcbe..3bfcb04 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -131,7 +131,7 @@ void __kmain(void) { sched_process *proc = - sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS); + sched_from_program(p); log("kernel - Soaplin initialized sucessfully.\n"); diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index d822096..9a998de 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -119,6 +119,10 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, return proc; } +sched_process *sched_from_program(program_t *prog) { + // D̶̽̃̿ÍÍ̀̑Í̡͖̼̪̩̑ǫ̴͚̘̩̗̠̣̗͇̳̀̅̈͌͆͆ ̸̑͋Í̢̢̯͎̳̟N̷̹͛̋͗ö̴͇̼̖́̀̾̿̾̓̔̌Ì̼t̵̯̘͇̙̬̤̫͚͓̠͔̭̚ͅ ̵͔̲͈̭͛̆̈UÌ·ÍÍ„ÍÍ‘Í̱̇̀̈́̔͠s̴̀̓̎Í̢͇̳̯̬͔̦̗̯̜̆̅̈́̈́̑̾͆͌̆eÌ´Ì‚Í̊̈͋̆̂̌͘͘Ì̛͎̪̩̙͕̖͖̂̚ÍÍ“ ̵̂͒͌͌̈́Í̇Ì̢̢͖̦̬͔̻͇̠̺͑͋̓̔̅̓͂S̴͋͊Ì̋̑Ì̡͇͎̠̯͙̖̲̮͓͂͆̿C̵̈̂Ì̤̲͉̫̜͓͇̙͇̪̥̈́͋̃̿̕H̶͓̠͋͋̎̃Ì̡͉E̶͉̬̞̖̮͚̙͗̔̋͆Ḑ̴̛͎̙̥̱̱͎͊͊͋̈́̆̎̓͑̚̚_̷̈͗Ì͚̯̻̖͈̳̺̖̽͠KÌ´Ì̆̿͂͂̀̂͆̀ÍÌ̮͓̲̠̫͈̔ͅEÌ·Ì’Ì’Ì͆Ì̡̭͔̘̀R̵ÌÍÍ̾̈́̈́̋͗̎̉Í̭̰N̴̰͆̂͛̂̈́̄̊͌̓͆̕͘͠͠Ě̴̀͌̓͑͘Ì̥͙̼̳̩̠͓͕̫͔̘̠̻̓̂̋̌͜L̴̙͓̣̭̙͙͈̺̩̄̈͆͆͒͗͛̈́̎̉̈́͘͘͜͠_̵͌̿͂͊͘̕Ì̭̱͇Í̩̬ͅP̵̡̪̹̀͂̀̋̇̓͘͜R̸Ì̇ÌÍ̭͌͌̋Í̮̼̙͓͕̳̫͜Ở̵̈̈́̊̕̕Į͎̭̱͈̫̮̘͉͔̪̟̺̥́͠ͅC̵͕̱̠̑̽̔̑͠Ì̡̡̭͓̗̜͇̼̳̲͓Ȇ̷̛̈̒̃̊̈́̓̚̚͠Į̦́͜S̴̿͗̀͌͊̽Ì̧̥͇̬̱̠̟͙̳̖͒̃͜SÌ´Ì͉͖͉͎͎̱͑͊̒͆̃͗̂͌̽͑̓Ì͔̙̜̭ͅ ̶̈́̑͆̂Í̼̥̜͙͈̦̲̰̞H̸̩̭̹̘̩̊͗̔̉̓̈́e̷̓̀̅̊ÍÌ̧̩̓̈́͗̇̔̓͛Í͚̮̰̭̘Í͇͈̺͇̻͜ṙ̶̆͠Í̩̜̜̭͗̉͜Ì̡̪͔͙̟̣͉ͅe̷̿͌ÍÍ̃̃͂̾ÍÌŠĮ̡̦̘̰͖̲͉̤̼͈̺̺̦̯̀.̶̽̊̈̕Í͈Í̡͈̟̠͙̘̤͜Ì̧̪ + return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS); +} void sched_exit(int exit_code) { log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); curr_proc->type = SCHED_DIED; diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index 971b651..ee8089a 100644 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -1,6 +1,7 @@ #pragma once #include "arch/x86_64/idt.h" +#include "exec/exec.h" #include "mm/vmm.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. @@ -38,5 +39,8 @@ extern sched_process *proc_list; void sched_init(); sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); + +sched_process *sched_from_program(program_t *prog); + void sched_exit(int exit_code); void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 1abefe6..61febba 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -14,7 +14,7 @@ extern void __x86_64_syscall_init(); static uint64_t __syscall_undefined() { return 0; } void syscall_handle(registers_t *regs) { - if (regs->rax > 1024) { + if (regs->rax >= 1024) { log("syscall - syscall_handle was called with rax better than what Soaplin " "supports (1024). did you forget to set rax?\n"); return; @@ -50,13 +50,15 @@ void syscall_register(int id, syscall handler) { log("syscall - System call %d has been set to %p\n", id, handler); } +extern void syscall_write(int fd, const char *buf, size_t count); extern void syscall_exit(int exit_code); void syscall_init() { for (int i = 0; i < 1024; i++) syscall_table[i] = (syscall)__syscall_undefined; - syscall_register(0, (syscall)syscall_exit); + syscall_register(1, (syscall)syscall_write); + syscall_register(60, (syscall)syscall_exit); __x86_64_syscall_init(); } \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_fs.c b/kernel/src/sys/syscalls/syscalls_fs.c new file mode 100644 index 0000000..a89b106 --- /dev/null +++ b/kernel/src/sys/syscalls/syscalls_fs.c @@ -0,0 +1,11 @@ +#include +#include + +int syscall_write(int fd, const char *buf, size_t count) { + if (fd == 1) { + printf("%s", buf); // Prevent the buffer from being formatted. + return count; + } + + return 0; +} \ No newline at end of file diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index f22be1c771bdd953f1f38c7cde5b0e4d328a78c7..bf354260e7f44c3fae04d68af34159fba80d210f 100755 GIT binary patch literal 4480 zcmeI0y>7xV5Xa58REEODgmhCU zt8RCL@9uvevVNO=PM7m`tHpw~*&C~~(L+kG@L8v*y}F)+by?@pJMd~#4?*oE&IkY7 zhXry(fCvx)B0vO)01+SpM1Tko0U|&Ih`_%S`0|hai$4}WfRFR<)TPh8>&>fDYcqq5 zDRstSEqAKOcS7rr8CaE9P$_fJ85~Wy2UEb-SOqI1-gREU3oP^EaNKnKgx`rEk6qyBJ17JOfQ=qSY~46%7p*IDOC2bdXG2JYi6x)-p;v;wz59<4P z>I+yi-C0`4^0MQV0E!X7C9I+X1!%8a^4rjW>Kgh#7jxm<;POfi z95KAf;)ah=&u=0~-(mb3i+4)2NJ&Y5!T9`b_WeFle=wg3{2;XME#7sL;sdhB-txQS zR!ZPG@e0H9pZN`56LOzOU*tg!YI*(_1mAJ#zWHT2Uh&a(>z`lVbVIF8OWc}FkEFN> zhfxv_mDaPCa8Yc9jm$)k#DmH1g-OJ~xJXq6_KvSa95r!q%IYGYCu+dG_n9VSKkZE~=_vOf6+Ou0yk delta 173 zcmX@W{(xnI4KphP(?m!6iFHz(4U7z6z&UZD@?;i95zYxv0maFRjPjEOm{}&fFp6j% zfQnW?R5P#uX%Oas@+F|O Date: Sat, 17 May 2025 11:36:36 +0200 Subject: [PATCH 17/30] sched, interrupts: Now recovers from a userspace exception. --- kernel/src/arch/x86_64/idt.c | 12 +++++ kernel/src/sched/sched.c | 82 +++++++++++++++++++++++++---------- testing/sk-hello.elf | Bin 4480 -> 4480 bytes testing/test.asm | 1 + testing/test.o | Bin 960 -> 960 bytes 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index 39ce4ce..529c49d 100644 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -7,6 +7,7 @@ #include #include #include +#include __attribute__((aligned(0x10))) static idt_entry_t idt[256]; @@ -65,6 +66,17 @@ void idt_int_handler(registers_t *regs) { // log("kernel - Interrupt %d\n", regs->int_no); if (regs->int_no < 32) { + if (regs->cs == 0x43) { + log("ints - Process \"%s\" (pid: %d) caused a CPU fault: %d (err: %d, IP: %p)\n", + curr_proc->name, curr_proc->pid, regs->int_no, regs->err_code, regs->rip); + + sched_exit(-144); + return; + //asm("cli"); + //while (1) + // asm("hlt"); + } + panic_ctx("A CPU exception occured.", regs); } diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index 9a998de..707e8c7 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -4,6 +4,7 @@ #include "mm/memop.h" #include "mm/pmm.h" #include "mm/vmm.h" +#include "sys/errhnd/panic.h" #include "sys/log.h" #include #include @@ -28,6 +29,18 @@ void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap, } } +static void __sched_enter_standby() { + standby = 1; + log("sched - As there's nothing " + "to schedule, the scheduler entered standby" + "mode.\n"); +} + +static void __sched_exit_standby() { + standby = 0; + log("sched - The scheduler exited standby mode.\n"); +} + void sched_init() { // TODO: It may be good to implement heap memory to save space. @@ -41,11 +54,7 @@ void sched_init() { proc_list->pm = vmm_kernel_pm; curr_proc = proc_list; - - standby = 1; - log("sched - As there's nothing " - "to schedule, the scheduler entered standby" - "mode.\n"); + __sched_enter_standby(); } sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, @@ -107,11 +116,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, VMM_PRESENT | VMM_WRITABLE); if (standby) { - // Disable standby mode as there's actually something to - // run, now. - standby = 0; - log("sched - Standby mode has been" - "disabled.\n"); + __sched_exit_standby(); } log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, @@ -124,7 +129,7 @@ sched_process *sched_from_program(program_t *prog) { return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS); } void sched_exit(int exit_code) { - log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); + log("sched - Process %d exited with code %d!\n", curr_proc->pid, exit_code); curr_proc->type = SCHED_DIED; schedule(&curr_proc->regs); } @@ -135,30 +140,63 @@ void schedule(registers_t *regs) { return; } - memcpy(&curr_proc->regs, regs, sizeof(registers_t)); + if (curr_proc->type != SCHED_DIED) { + memcpy(&curr_proc->regs, regs, sizeof(registers_t)); + } if (curr_proc->type == SCHED_DIED) { sched_process *prev_proc = proc_list; + sched_process *next = curr_proc->next; + if (next == NULL) { + next = proc_list; + } + + if (proc_list == curr_proc) { + goto kill_process; + } + while (prev_proc->next != curr_proc) { prev_proc = prev_proc->next; } - prev_proc->next = curr_proc->next; +kill_process: + if (next == NULL) { + next = proc_list; + } + + if (proc_list == curr_proc) { + vmm_release_pm(curr_proc->pm); + pmm_free_page(curr_proc->stack_base_physical); + free(curr_proc); + + __sched_enter_standby(); + return; + } + + prev_proc->next = next; vmm_release_pm(curr_proc->pm); pmm_free_page(curr_proc->stack_base_physical); + free(curr_proc); - // R.I.P. process - pmm_free_page(curr_proc); - - return; + curr_proc = next; + } else { + curr_proc = curr_proc->next; + if (curr_proc == NULL) + curr_proc = proc_list; } - curr_proc = curr_proc->next; - if (curr_proc == NULL) - curr_proc = proc_list; - - memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + if (curr_proc->type == SCHED_RUNNING) { + memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + } else if (curr_proc->type == SCHED_EMPTY) { + memset(regs, 0, sizeof(registers_t)); + regs->cs = 0x28; + regs->ss = 0x30; + regs->rflags = 0x202; + regs->rip = 0; + } else { + panic("sched - Tried to schedule a dead process.\n"); + } wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); // log("sched - proc %d\n", curr_proc->pid); diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index bf354260e7f44c3fae04d68af34159fba80d210f..cff52868face31f7facb3cb71fb5d455a1ac0fff 100755 GIT binary patch delta 23 fcmZorZcyGJDZu)LpY`>>$#MdR8098E6qpYHWH<=h delta 23 fcmZorZcyGJDZt9l`uZQkWI2IDjIxs-3d{!pSL6rg diff --git a/testing/test.asm b/testing/test.asm index 762f01f..f32900d 100644 --- a/testing/test.asm +++ b/testing/test.asm @@ -8,6 +8,7 @@ _start: mov rdi, 1 ; stdout file descriptor mov rsi, msg ; pointer to message mov rdx, msg_len ; message length + hlt syscall .loop: diff --git a/testing/test.o b/testing/test.o index 2e97fc6475431c9600f8a41ac557cc9c2953d143..eb32f78ff72f0661eb69bd13a3fee4566a502930 100644 GIT binary patch delta 28 kcmX@Wet><#0!F!w3o95|zwooZ{x?~U=@+BSWJ%`b0HNUuzW@LL delta 28 kcmX@Wet><#0!G=53o95|`B`88W0)+*^ovn?vLy3z0F`(N$p8QV From d017412af5ebec7438fbc09d07ca2a560c273b6f Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sat, 17 May 2025 11:51:28 +0200 Subject: [PATCH 18/30] kmod: prepare for kernel module loading --- README.md | 8 ++++---- kernel/linker-x86_64.ld | 5 +++++ kernel/src/dbg/export.h | 22 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 kernel/src/dbg/export.h diff --git a/README.md b/README.md index fa0230d..29cc83b 100755 --- a/README.md +++ b/README.md @@ -9,9 +9,12 @@ The Soaplin kernel is a new Unix-like operating system kernel. * ELF loader * ACPI * Symetric Multiprocessing (It runs code, but the scheduler is running on 1 processor.) +* Recovers from a faulty userspace process. + +## Nearly done +* Virtual File System ## In the works -* Virtual File System * FPU support ## To come @@ -21,9 +24,6 @@ The Soaplin kernel is a new Unix-like operating system kernel. * TAR-based init ram disk * Video driver for Bochs graphics adapter, and the VMware display adapter. -## Known bugs -* If a user process calls the syscall handler by using interrupts, the system may crash due to a Page Fault. - ## Building To build Soaplin, you must ensure you have these: * The Netwide Assembler (nasm) diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld index 8fe5465..41c5989 100755 --- a/kernel/linker-x86_64.ld +++ b/kernel/linker-x86_64.ld @@ -57,6 +57,11 @@ SECTIONS .data : { data_start_ld = .; *(.data .data.*) + + /* Exported kernel symbols */ + __start_ksyms = .; + KEEP(*(.ksyms)) + __stop_ksyms = .; } :data /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ diff --git a/kernel/src/dbg/export.h b/kernel/src/dbg/export.h new file mode 100644 index 0000000..39b9fa9 --- /dev/null +++ b/kernel/src/dbg/export.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +// At Soaplin, we aren't doing module racism based on the license. (Ḭ̸̛̌͋̋̆͛̉͆Í̡̢͚̙̺̦̩͕̮̙̙̳̮͉Į̧̨̙̜͓̪͇̠̪̣̻̰͕̲̲̘̖̦͖͕͎̲̹͖̮̳̻̞̀ ̸̨͕͎̣̥͖͔̳̫̳͚̯̬̙̘͓̹̼̻̼̈̓̉ͅͅs̶̃͛̽͛Í̆͌̆̒̔̈́̎̿͠ÍÌÍ„Í̟͉̠̣̞͎̓̓͒͌̈̀̓͗̋̕͜͠Í̘̟͜ͅÌ̱̩è̸̈́̈́͂̈́ÌÌ̆̆̔͗Í̆̀͑̀̔͆̄͠ÍÍ̛͔̦̲̦̼̹̙̲͖͎̼̆Ì̯̦̞̜Í̧̡e̸̛̛͂̾̒͋̀͂ÌÌšÍÍ̂̋̅̆̋̈̔̈́̀̔̈́̊̓͂͌̋̂͘ÌĮ͕̱̯̲̦͕͖̦̀̀͒͊͊̓͌̃͠Į̢̢̧̯̮̤̫͙͔̲̬̯̗̗͈̬̳̙͙̼͉̩͚̼̮͚̖̰̗̤͓̘̀͜ ̸̈͗͆͌Í̊̽Í̾Í̼̹͇̞̘͇̯̞̣Ì̧̲̳̦̟̱͇̥͈̟ͅÌ̡̧̹̳̫͕̜̬̥̯̬̟̤̖̹̙̩̰y̵̌ÌÌÌ„ÌÌ̡̞̭͔̰͔͔̖̥͕̙̳̯̈́̓ͅÍ͉̦̦͓̥̞Ì̡̢͖͕̰̼͖̲̮͚̲̜̰̱̘̯̤õ̵̑͊̃̃̒ÌÍ Í̆̎̋̿Í̋̉̇̾͆̿̌̃Ì̽̚Í̛̊̀͒̇Ì̓Í̾Ì̈́̓̿Ì̖̠͉̖̺̻̣̜̬̮͓̫͎͖͎̤̪ͅÌ̢̢̗̰͕Í̢͖̖̟͙ÍÌ»u̸̅̒̅̂̑Ì͕̟͉͉͖̰Ì̧͕̞̪̖͙͙,̶Ì̄̆Ì̂̈̊̄͆̽̑̑̊̓̋͘Í̔̉ÌÍŒÌ̢̡̛̲̬̞̘̻̗̩̫̗͓̪̬͚̗̖͕̰̣͙̀̿͜͜ͅÍ̡̯͇̩̭͎̖Ì̧̬̻͖̟̩̙̩͜Ì͓̤ͅ Ì´Í̈́̽̄͌̾̒Í̔̌Ì̛̽͋̓̄̉̆̑̃̕͠ÍÌ̉̔̓̂̽̊͆̽̎Ì̈͑͘͘Í̛̌͑Ì̢͈͚̳̣̮̬̲̲͈̮͓̭̗ͅL̵̙̯̦̬̱̓̒Ị̹̱́Ìi̵ÌÌ›Ì͊̒͑̊͌̽̂̕Í̉͊̈́̌͒̆̕ÌÍÍ͒̉̀ÌÌ‘ÍÌ…Í›Í̢̗̲Į̨̧̨͇̖̥̯͔̙̪̱͓́ͅÌ̦̼̭̬̟̞̩̭͙ͅn̵͆Ì̃̊̒̇̑̑̾̽͊̃͌̔̕̚̕Í̌̈́̈́͛͆̒̀̿̎͒̑̃̈́̈́͂͘͠͠Í̧̛͓̲͂͜u̸̽ÌÌšÍ̈Í̄̀͒Ì̧̛̯̤̲͚͖̯͖͈̠̅̽̋̓̂̑̋̽͒̄̑̇̈́̆̈͛͆̿̈̉͆͗͊̎͂̇̽̋̅͊̀̚s̶Ì͆̀̅̓̓͆͆̕ÌÌ̄͛̃Í̛͑̔̑̒͒Í͋͂̂Ì͋͂ÌÍ—Ì͆͠Ì̗̥͇̖̠͓) + +typedef struct { + const char* name; + uint64_t addr; + uint64_t size; +} kernel_symbol_t; + +#define EXPORT_SYMBOL(sym) \ + static const kernel_symbol_t __ksym_##sym \ + __attribute__((section(".ksyms"), used)) = { \ + .name = #sym, \ + .addr = (uint64_t)&sym, \ + .size = sizeof(sym) \ + } + +extern const kernel_symbol_t __start_ksyms[]; +extern const kernel_symbol_t __stop_ksyms[]; From a1e27c27304867189463af21bb9dda8703e57a61 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 09:04:25 +0200 Subject: [PATCH 19/30] kernel: Rewrite from scratch since the current thing is held by duct tape (lmao) --- .gitignore | 3 +- CONTRIBUTING.MD | 9 - GNUmakefile | 100 +- LICENSE | 2 +- README.md | 42 +- initramfs.tar | Bin 10240 -> 0 bytes initramfs/dir/subtest.txt | 1 - initramfs/test.txt | 1 - kernel/.gitignore | 6 +- kernel/GNUmakefile | 45 +- kernel/get-deps | 50 +- kernel/linker-aarch64.ld | 0 kernel/linker-loongarch64.ld | 0 kernel/linker-riscv64.ld | 0 kernel/linker-x86_64.ld | 28 +- kernel/src/arch/aarch64/cpu.c | 11 + kernel/src/arch/arch.h | 5 - kernel/src/arch/cpu.h | 4 + kernel/src/arch/la64/cpu.c | 11 + kernel/src/arch/riscv/cpu.c | 11 + kernel/src/arch/x86_64/cpu.c | 12 + kernel/src/arch/x86_64/cpuid.h | 647 ---- kernel/src/arch/x86_64/fpu.c | 12 - kernel/src/arch/x86_64/fpu.h | 6 - kernel/src/arch/x86_64/gdt.c | 51 - kernel/src/arch/x86_64/gdt.h | 36 - kernel/src/arch/x86_64/idt.asm | 335 -- kernel/src/arch/x86_64/idt.c | 94 - kernel/src/arch/x86_64/idt.h | 62 - kernel/src/arch/x86_64/io.c | 17 - kernel/src/arch/x86_64/io.h | 19 - kernel/src/arch/x86_64/msr.h | 18 - kernel/src/arch/x86_64/pit.c | 30 - kernel/src/arch/x86_64/pit.h | 13 - kernel/src/arch/x86_64/rtc.c | 43 - kernel/src/arch/x86_64/rtc.h | 18 - kernel/src/arch/x86_64/smp.c | 52 - kernel/src/arch/x86_64/smp.h | 7 - kernel/src/arch/x86_64/sse.c | 59 - kernel/src/arch/x86_64/sse.h | 4 - kernel/src/arch/x86_64/syscall.asm | 53 - kernel/src/arch/x86_64/syscall.c | 18 - kernel/src/arch/x86_64/syscall.h | 7 - kernel/src/boot/limine.c | 30 + kernel/src/boot/limine.h | 12 + kernel/src/dbg/export.h | 22 - kernel/src/dbg/sym.c | 56 - kernel/src/dbg/sym.h | 12 - kernel/src/dev/ioapic.c | 113 - kernel/src/dev/ioapic.h | 24 - kernel/src/dev/lapic.c | 60 - kernel/src/dev/lapic.h | 52 - kernel/src/dev/tty.c | 31 + kernel/src/dev/tty.h | 4 + kernel/src/exec/elf.c | 135 - kernel/src/exec/elf.h | 153 - kernel/src/exec/exec.h | 28 - kernel/src/font.c | 343 --- kernel/src/font.h | 3 - kernel/src/fs/hellofs.c | 101 - kernel/src/fs/hellofs.h | 5 - kernel/src/fs/vfs.c | 112 - kernel/src/fs/vfs.h | 47 - kernel/src/fs/vnodes.md | 2 - kernel/src/lib/gcc.c | 18 - kernel/src/lib/spinlock.h | 31 - kernel/src/lib/string.c | 138 +- kernel/src/lib/string.h | 11 +- kernel/src/main.c | 146 +- kernel/src/mm/liballoc/liballoc.c | 586 ---- kernel/src/mm/liballoc/liballoc.h | 25 - kernel/src/mm/liballoc/liballoc_soaplin.c | 34 - kernel/src/mm/memop.c | 79 +- kernel/src/mm/memop.h | 7 +- kernel/src/mm/pmm.c | 97 - kernel/src/mm/pmm.h | 28 - kernel/src/mm/vma.c | 181 -- kernel/src/mm/vma.h | 29 - kernel/src/mm/vmm.c | 244 -- kernel/src/mm/vmm.h | 46 - kernel/src/premain.asm | 10 - kernel/src/sched/sched.c | 204 -- kernel/src/sched/sched.h | 46 - kernel/src/sys/acpi.c | 58 - kernel/src/sys/acpi.h | 52 - kernel/src/sys/acpi/madt.c | 42 - kernel/src/sys/acpi/madt.h | 56 - kernel/src/sys/errhnd/panic.c | 208 -- kernel/src/sys/errhnd/panic.h | 11 - kernel/src/sys/gfx/flanterm/.gitignore | 2 - kernel/src/sys/gfx/flanterm/LICENSE | 22 - kernel/src/sys/gfx/flanterm/README.md | 43 - kernel/src/sys/gfx/flanterm/backends/fb.c | 1296 -------- kernel/src/sys/gfx/flanterm/backends/fb.h | 69 - .../sys/gfx/flanterm/backends/fb_private.h | 122 - kernel/src/sys/gfx/flanterm/flanterm.c | 1611 ---------- kernel/src/sys/gfx/flanterm/flanterm.h | 85 - .../src/sys/gfx/flanterm/flanterm_private.h | 125 - kernel/src/sys/log.c | 46 - kernel/src/sys/log.h | 3 - kernel/src/sys/printf.c | 31 - kernel/src/sys/printf.h | 1320 -------- kernel/src/sys/syscall.c | 64 - kernel/src/sys/syscall.h | 20 - kernel/src/sys/syscalls/syscalls_fs.c | 11 - kernel/src/sys/syscalls/syscalls_proc.c | 6 - kernel/src/sys/uname.h | 13 - limine.conf | 11 +- strings.txt | 2709 ----------------- testing/build.sh | 3 - testing/link.ld | 23 - testing/sk-hello.elf | Bin 4480 -> 0 bytes testing/test.asm | 19 - testing/test.bin | 1 - testing/test.o | Bin 960 -> 0 bytes txt.txt | 559 ---- util/get_vaddr_info.py | 19 - 117 files changed, 285 insertions(+), 13622 deletions(-) mode change 100755 => 100644 .gitignore delete mode 100644 CONTRIBUTING.MD mode change 100755 => 100644 GNUmakefile mode change 100755 => 100644 LICENSE mode change 100755 => 100644 README.md delete mode 100644 initramfs.tar delete mode 100644 initramfs/dir/subtest.txt delete mode 100644 initramfs/test.txt mode change 100755 => 100644 kernel/.gitignore mode change 100755 => 100644 kernel/GNUmakefile mode change 100755 => 100644 kernel/linker-aarch64.ld mode change 100755 => 100644 kernel/linker-loongarch64.ld mode change 100755 => 100644 kernel/linker-riscv64.ld mode change 100755 => 100644 kernel/linker-x86_64.ld create mode 100644 kernel/src/arch/aarch64/cpu.c delete mode 100755 kernel/src/arch/arch.h create mode 100644 kernel/src/arch/cpu.h create mode 100644 kernel/src/arch/la64/cpu.c create mode 100644 kernel/src/arch/riscv/cpu.c create mode 100644 kernel/src/arch/x86_64/cpu.c delete mode 100644 kernel/src/arch/x86_64/cpuid.h delete mode 100644 kernel/src/arch/x86_64/fpu.c delete mode 100644 kernel/src/arch/x86_64/fpu.h delete mode 100644 kernel/src/arch/x86_64/gdt.c delete mode 100644 kernel/src/arch/x86_64/gdt.h delete mode 100755 kernel/src/arch/x86_64/idt.asm delete mode 100644 kernel/src/arch/x86_64/idt.c delete mode 100644 kernel/src/arch/x86_64/idt.h delete mode 100755 kernel/src/arch/x86_64/io.c delete mode 100755 kernel/src/arch/x86_64/io.h delete mode 100644 kernel/src/arch/x86_64/msr.h delete mode 100644 kernel/src/arch/x86_64/pit.c delete mode 100644 kernel/src/arch/x86_64/pit.h delete mode 100644 kernel/src/arch/x86_64/rtc.c delete mode 100644 kernel/src/arch/x86_64/rtc.h delete mode 100644 kernel/src/arch/x86_64/smp.c delete mode 100644 kernel/src/arch/x86_64/smp.h delete mode 100644 kernel/src/arch/x86_64/sse.c delete mode 100755 kernel/src/arch/x86_64/sse.h delete mode 100644 kernel/src/arch/x86_64/syscall.asm delete mode 100644 kernel/src/arch/x86_64/syscall.c delete mode 100644 kernel/src/arch/x86_64/syscall.h create mode 100644 kernel/src/boot/limine.c create mode 100644 kernel/src/boot/limine.h delete mode 100644 kernel/src/dbg/export.h delete mode 100644 kernel/src/dbg/sym.c delete mode 100644 kernel/src/dbg/sym.h delete mode 100644 kernel/src/dev/ioapic.c delete mode 100644 kernel/src/dev/ioapic.h delete mode 100644 kernel/src/dev/lapic.c delete mode 100644 kernel/src/dev/lapic.h create mode 100644 kernel/src/dev/tty.c create mode 100644 kernel/src/dev/tty.h delete mode 100644 kernel/src/exec/elf.c delete mode 100644 kernel/src/exec/elf.h delete mode 100644 kernel/src/exec/exec.h delete mode 100644 kernel/src/font.c delete mode 100755 kernel/src/font.h delete mode 100644 kernel/src/fs/hellofs.c delete mode 100644 kernel/src/fs/hellofs.h delete mode 100644 kernel/src/fs/vfs.c delete mode 100644 kernel/src/fs/vfs.h delete mode 100644 kernel/src/fs/vnodes.md delete mode 100644 kernel/src/lib/gcc.c delete mode 100644 kernel/src/lib/spinlock.h delete mode 100644 kernel/src/mm/liballoc/liballoc.c delete mode 100644 kernel/src/mm/liballoc/liballoc.h delete mode 100644 kernel/src/mm/liballoc/liballoc_soaplin.c mode change 100755 => 100644 kernel/src/mm/memop.h delete mode 100644 kernel/src/mm/pmm.c delete mode 100644 kernel/src/mm/pmm.h delete mode 100644 kernel/src/mm/vma.c delete mode 100644 kernel/src/mm/vma.h delete mode 100644 kernel/src/mm/vmm.c delete mode 100644 kernel/src/mm/vmm.h delete mode 100644 kernel/src/premain.asm delete mode 100644 kernel/src/sched/sched.c delete mode 100644 kernel/src/sched/sched.h delete mode 100644 kernel/src/sys/acpi.c delete mode 100644 kernel/src/sys/acpi.h delete mode 100644 kernel/src/sys/acpi/madt.c delete mode 100644 kernel/src/sys/acpi/madt.h delete mode 100644 kernel/src/sys/errhnd/panic.c delete mode 100644 kernel/src/sys/errhnd/panic.h delete mode 100644 kernel/src/sys/gfx/flanterm/.gitignore delete mode 100644 kernel/src/sys/gfx/flanterm/LICENSE delete mode 100644 kernel/src/sys/gfx/flanterm/README.md delete mode 100644 kernel/src/sys/gfx/flanterm/backends/fb.c delete mode 100644 kernel/src/sys/gfx/flanterm/backends/fb.h delete mode 100644 kernel/src/sys/gfx/flanterm/backends/fb_private.h delete mode 100644 kernel/src/sys/gfx/flanterm/flanterm.c delete mode 100644 kernel/src/sys/gfx/flanterm/flanterm.h delete mode 100644 kernel/src/sys/gfx/flanterm/flanterm_private.h delete mode 100644 kernel/src/sys/log.c delete mode 100755 kernel/src/sys/log.h delete mode 100644 kernel/src/sys/printf.c delete mode 100755 kernel/src/sys/printf.h delete mode 100644 kernel/src/sys/syscall.c delete mode 100644 kernel/src/sys/syscall.h delete mode 100644 kernel/src/sys/syscalls/syscalls_fs.c delete mode 100644 kernel/src/sys/syscalls/syscalls_proc.c delete mode 100644 kernel/src/sys/uname.h mode change 100755 => 100644 limine.conf delete mode 100644 strings.txt delete mode 100755 testing/build.sh delete mode 100644 testing/link.ld delete mode 100755 testing/sk-hello.elf delete mode 100644 testing/test.asm delete mode 100644 testing/test.bin delete mode 100644 testing/test.o delete mode 100644 txt.txt delete mode 100755 util/get_vaddr_info.py diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index bda1078..d1c54fd --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ /.cache *.iso *.hdd -/compile_commands.json -/.idea \ No newline at end of file +compile_commands.json \ No newline at end of file diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD deleted file mode 100644 index 4b8e29d..0000000 --- a/CONTRIBUTING.MD +++ /dev/null @@ -1,9 +0,0 @@ -# Contribute to Soaplin! -Do you want to improve Soaplin? You can by contributing to the project! - -## Contributing guidelines -* Before making a commit, please run `make format`. This will run clang-format over all the C source files in kernel/src. -* Large language model-generated code is **allowed**, with the condition that you do extensive testing over that code. - You must also know how to make the LLM-generated code by yourself. - - Note: Even if LLM-generated code is allowed, please try to not use it. \ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile old mode 100755 new mode 100644 index 3adffb8..4621bab --- a/GNUmakefile +++ b/GNUmakefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR ARCH := x86_64 # Default user QEMU flags. These are appended to the QEMU command calls. -QEMUFLAGS := -m 2G -debugcon stdio -no-reboot -no-shutdown +QEMUFLAGS := -m 2G -override IMAGE_NAME := sild-live-$(ARCH) +override IMAGE_NAME := soaplin-$(ARCH) # Toolchain for building the 'limine' executable for the host. HOST_CC := cc @@ -29,29 +29,8 @@ run: run-$(ARCH) .PHONY: run-hdd run-hdd: run-hdd-$(ARCH) -.PHONY: ints -ints: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" - @qemu-system-$(ARCH) \ - -M q35 \ - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ - -cdrom $(IMAGE_NAME).iso \ - -d int \ - $(QEMUFLAGS) - -.PHONY: run-x86_64 -gdb-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" - @qemu-system-$(ARCH) \ - -M q35 \ - -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ - -cdrom $(IMAGE_NAME).iso \ - $(QEMUFLAGS) \ - -S -s - .PHONY: run-x86_64 run-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" @qemu-system-$(ARCH) \ -M q35 \ -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ @@ -60,7 +39,6 @@ run-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso .PHONY: run-hdd-x86_64 run-hdd-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd - @echo " Starting QEMU with $(IMAGE_NAME).hdd" @qemu-system-$(ARCH) \ -M q35 \ -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ @@ -69,7 +47,6 @@ run-hdd-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd .PHONY: run-aarch64 run-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" @qemu-system-$(ARCH) \ -M virt \ -cpu cortex-a72 \ @@ -96,7 +73,6 @@ run-hdd-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd .PHONY: run-riscv64 run-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" @qemu-system-$(ARCH) \ -M virt \ -cpu rv64 \ @@ -110,7 +86,6 @@ run-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso .PHONY: run-hdd-riscv64 run-hdd-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd - @echo " Starting QEMU with $(IMAGE_NAME).hdd" @qemu-system-$(ARCH) \ -M virt \ -cpu rv64 \ @@ -124,7 +99,6 @@ run-hdd-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd .PHONY: run-loongarch64 run-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" @qemu-system-$(ARCH) \ -M virt \ -cpu la464 \ @@ -138,7 +112,6 @@ run-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso .PHONY: run-hdd-loongarch64 run-hdd-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd - @echo " Starting QEMU with $(IMAGE_NAME).hdd" @qemu-system-$(ARCH) \ -M virt \ -cpu la464 \ @@ -153,7 +126,6 @@ run-hdd-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd .PHONY: run-bios run-bios: $(IMAGE_NAME).iso - @echo " Starting QEMU with $(IMAGE_NAME).iso" @qemu-system-$(ARCH) \ -M q35 \ -cdrom $(IMAGE_NAME).iso \ @@ -162,77 +134,75 @@ run-bios: $(IMAGE_NAME).iso .PHONY: run-hdd-bios run-hdd-bios: $(IMAGE_NAME).hdd - @echo " Starting QEMU with $(IMAGE_NAME).hdd" @qemu-system-$(ARCH) \ -M q35 \ -hda $(IMAGE_NAME).hdd \ $(QEMUFLAGS) ovmf/ovmf-code-$(ARCH).fd: + @echo " DEPS Downloading OVMF for $(ARCH)..." @mkdir -p ovmf - @curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-code-$(ARCH).fd + @curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-code-$(ARCH).fd > /dev/null 2>&1 @case "$(ARCH)" in \ aarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=67108864 2>/dev/null;; \ riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ - @esac + esac limine/limine: + @echo " DEPS Downloading Limine binaries..." @rm -rf limine - @git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 + @git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 > /dev/null 2>&1 @$(MAKE) -C limine \ CC="$(HOST_CC)" \ CFLAGS="$(HOST_CFLAGS)" \ CPPFLAGS="$(HOST_CPPFLAGS)" \ LDFLAGS="$(HOST_LDFLAGS)" \ - LIBS="$(HOST_LIBS)" - @echo " Limine installer has been built" + LIBS="$(HOST_LIBS)" > /dev/null 2>&1 kernel-deps: @./kernel/get-deps @touch kernel-deps - @echo " Kernel dependencies have been downloaded" .PHONY: kernel kernel: kernel-deps - $(MAKE) -C kernel + @$(MAKE) -C kernel + @echo "Soaplin $(ARCH) has been compiled successfully." $(IMAGE_NAME).iso: limine/limine kernel @rm -rf iso_root @mkdir -p iso_root/boot - @cp -v kernel/bin-$(ARCH)/soaplin iso_root/boot/ + @cp kernel/bin-$(ARCH)/kernel iso_root/boot/ @mkdir -p iso_root/boot/limine - @cp -v limine.conf iso_root/boot/limine/ + @cp limine.conf iso_root/boot/limine/ @mkdir -p iso_root/EFI/BOOT - @cp -v testing/sk-hello.elf iso_root/ -# @cp -v initramfs.tar iso_root/ ifeq ($(ARCH),x86_64) - @cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ - @cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ - @cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ + @cp limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ + @cp limine/BOOTX64.EFI iso_root/EFI/BOOT/ + @cp limine/BOOTIA32.EFI iso_root/EFI/BOOT/ @xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \ -apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ - iso_root -o $(IMAGE_NAME).iso - @./limine/limine bios-install $(IMAGE_NAME).iso + iso_root -o $(IMAGE_NAME).iso > /dev/null 2>&1 + @./limine/limine bios-install $(IMAGE_NAME).iso > /dev/null 2>&1 endif ifeq ($(ARCH),aarch64) - @cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ - @cp -v limine/BOOTAA64.EFI iso_root/EFI/BOOT/ + @cp limine/limine-uefi-cd.bin iso_root/boot/limine/ + @cp limine/BOOTAA64.EFI iso_root/EFI/BOOT/ @xorriso -as mkisofs -R -r -J \ -hfsplus -apm-block-size 2048 \ --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ - iso_root -o $(IMAGE_NAME).iso + iso_root -o $(IMAGE_NAME).iso > /dev/null 2>&1 endif ifeq ($(ARCH),riscv64) - @cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ - @cp -v limine/BOOTRISCV64.EFI iso_root/EFI/BOOT/ + @cp limine/limine-uefi-cd.bin iso_root/boot/limine/ + @cp limine/BOOTRISCV64.EFI iso_root/EFI/BOOT/ @xorriso -as mkisofs -R -r -J \ -hfsplus -apm-block-size 2048 \ --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ - iso_root -o $(IMAGE_NAME).iso + iso_root -o $(IMAGE_NAME).iso > /dev/null 2>&1 endif ifeq ($(ARCH),loongarch64) @cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ @@ -241,19 +211,19 @@ ifeq ($(ARCH),loongarch64) -hfsplus -apm-block-size 2048 \ --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ - iso_root -o $(IMAGE_NAME).iso + iso_root -o $(IMAGE_NAME).iso > /dev/null 2>&1 endif @rm -rf iso_root - @echo " The final ISO image has been created: $(IMAGE_NAME).iso" + @echo "Soaplin $(ARCH) test disc has been built successfully." $(IMAGE_NAME).hdd: limine/limine kernel @rm -f $(IMAGE_NAME).hdd @dd if=/dev/zero bs=1M count=0 seek=64 of=$(IMAGE_NAME).hdd - @echo " Creating $(IMAGE_NAME).hdd" - @PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 - @echo " Creating partition table" ifeq ($(ARCH),x86_64) - @./limine/limine bios-install $(IMAGE_NAME).hdd + @PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 -m 1 + @./limine/limine bios-install $(IMAGE_NAME).hdd > /dev/null 2>&1 +else + @PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 endif @mformat -i $(IMAGE_NAME).hdd@@1M @mmd -i $(IMAGE_NAME).hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine @@ -273,22 +243,16 @@ endif ifeq ($(ARCH),loongarch64) @mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTLOONGARCH64.EFI ::/EFI/BOOT endif - @echo " Installed Limine bootloader" + @echo "Soaplin $(ARCH) test drive has been built successfully." .PHONY: clean clean: @$(MAKE) -C kernel clean @rm -rf iso_root $(IMAGE_NAME).iso $(IMAGE_NAME).hdd - @echo " The output files have been removed." + @echo "Soaplin output files has been deleted." .PHONY: distclean distclean: @$(MAKE) -C kernel distclean @rm -rf iso_root *.iso *.hdd kernel-deps limine ovmf - @echo " The output & downloaded files have been removed." - -# Make some function to run clang-format all over the kernel -.PHONY: format -format: - @clang-format -i -style=file $(shell find kernel/src -name '*.c' -or -name '*.h') - @echo " Kernel source code formatted" \ No newline at end of file + @echo "Soaplin output files & downloaded dependencies has been deleted." diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 index 6dd09b4..e24565f --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2025 Raphaël M. +Copyright (C) 2025 The SILD Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 29cc83b..80a7dd1 --- a/README.md +++ b/README.md @@ -1,39 +1,3 @@ -# Soaplin -The Soaplin kernel is a new Unix-like operating system kernel. - -## Features -* x86_64 support (kinda) -* Memory management (VMM/PMM/VMA/kmalloc) -* Simple pre-emptive scheduler -* Ring 3 (user mode) support -* ELF loader -* ACPI -* Symetric Multiprocessing (It runs code, but the scheduler is running on 1 processor.) -* Recovers from a faulty userspace process. - -## Nearly done -* Virtual File System - -## In the works -* FPU support - -## To come -* RTC support -* EXT2 driver -* FAT32 driver -* TAR-based init ram disk -* Video driver for Bochs graphics adapter, and the VMware display adapter. - -## Building -To build Soaplin, you must ensure you have these: -* The Netwide Assembler (nasm) -* A compiler (both GCC & Clang works!) (In the future, a custom toolchain would be built.) -* A linker (both GNU LD & LLVM linker works too!) - -Clone the repo, and run "make" in it! - -## Acknowledgements -Thanks to all these people :heart: -* Limine contributors: The Limine bootloader, used for kicking up Soaplin -* Kevin Alavik (kevinalavik): VMAs implementation -* Astrido (asterd-og): IOAPIC/LAPIC (from ZanOS) \ No newline at end of file +# Soaplin (rewrite) +This is a carefully rewritten version of Soaplin, that should be held with super glue instead of +0.99$ duct tape bought on TEMU. \ No newline at end of file diff --git a/initramfs.tar b/initramfs.tar deleted file mode 100644 index d5c2b82cb86e10a48a277e0de24648a33f8137ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10240 zcmeIzO%8%E5Cve4QZG>2(w{4M1J@`RO&~R;CVG3PF$ybmVTlQ^8%PSY`CggfWs!Xd z8qS!4F47q>y{4%&3TcECN@#28Il42dU?%&{Xo2ex>p)uy_2tyhEcj`D=GA|m;$>`y z$m1>M+hq#aYCX;Ubq>-LoeKTV-|33-m(EiDBHxzAFRwiRZQFI8?R@B(&4_}#wFvOC zIfu+WApPQB*MFzd|1Xq9{a@k?KJy>0`;2WM12tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa J0SNp+-~mP@UY`H} diff --git a/initramfs/dir/subtest.txt b/initramfs/dir/subtest.txt deleted file mode 100644 index 0688709..0000000 --- a/initramfs/dir/subtest.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World from a subdirectory! \ No newline at end of file diff --git a/initramfs/test.txt b/initramfs/test.txt deleted file mode 100644 index c57eff5..0000000 --- a/initramfs/test.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World! \ No newline at end of file diff --git a/kernel/.gitignore b/kernel/.gitignore old mode 100755 new mode 100644 index 4eeb3d0..27ac932 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -1,5 +1,5 @@ -/freestnd-c-hdrs -/cc-runtime* -/src/limine.h +/compile_commands.json +/.cache +/src/deps /bin-* /obj-* diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile old mode 100755 new mode 100644 index 84475d5..0d7f9ff --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -4,7 +4,7 @@ MAKEFLAGS += -rR # This is the name that our final executable will have. # Change as needed. -override OUTPUT := soaplin +override OUTPUT := kernel # Target architecture to build for. Default to x86_64. ARCH := x86_64 @@ -20,9 +20,6 @@ endif # User controllable C compiler command. CC := cc -# User controllable archiver command. -AR := ar - # User controllable C flags. CFLAGS := -g -O2 -pipe @@ -39,7 +36,7 @@ LDFLAGS := # Ensure the dependencies have been obtained. ifneq ($(shell ( test '$(MAKECMDGOALS)' = clean || test '$(MAKECMDGOALS)' = distclean ); echo $$?),0) - ifeq ($(shell ( ! test -d freestnd-c-hdrs || ! test -d cc-runtime || ! test -f src/limine.h ); echo $$?),0) + ifeq ($(shell ( ! test -d src/deps/freestnd-c-hdrs || ! test -f src/deps/cc-runtime.c || ! test -f src/deps/limine.h || ! test -d src/deps/flanterm ); echo $$?),0) $(error Please run the ./get-deps script first) endif endif @@ -58,14 +55,12 @@ override CFLAGS += \ -fno-stack-check \ -fno-PIC \ -ffunction-sections \ - -fdata-sections \ - -fno-omit-frame-pointer \ - -fno-optimize-sibling-calls + -fdata-sections # Internal C preprocessor flags that should not be changed by the user. override CPPFLAGS := \ -I src \ - -isystem freestnd-c-hdrs \ + -isystem src/deps/freestnd-c-hdrs \ $(CPPFLAGS) \ -DLIMINE_API_REVISION=3 \ -MMD \ @@ -167,62 +162,52 @@ all: bin-$(ARCH)/$(OUTPUT) # Include header dependencies. -include $(HEADER_DEPS) -# Link rules for building the C compiler runtime. -cc-runtime-$(ARCH)/cc-runtime.a: GNUmakefile cc-runtime/* - @rm -rf cc-runtime-$(ARCH) - @cp -r cc-runtime cc-runtime-$(ARCH) - @$(MAKE) -C cc-runtime-$(ARCH) -f cc-runtime.mk \ - CC="$(CC)" \ - AR="$(AR)" \ - CFLAGS="$(CFLAGS)" \ - CPPFLAGS='-isystem ../freestnd-c-hdrs -DCC_RUNTIME_NO_FLOAT' - @echo " C runtime built" - # Link rules for the final executable. -bin-$(ARCH)/$(OUTPUT): GNUmakefile linker-$(ARCH).ld $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a - @mkdir -p "$$(dirname $@)" +bin-$(ARCH)/$(OUTPUT): GNUmakefile linker-$(ARCH).ld $(OBJ) @echo " LD $@" - @$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a -o $@ + @mkdir -p "$$(dirname $@)" + @$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $@ # Compilation rules for *.c files. obj-$(ARCH)/%.c.o: src/%.c GNUmakefile - @mkdir -p "$$(dirname $@)" @echo " CC $@" + @mkdir -p "$$(dirname $@)" @$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ # Compilation rules for *.S files. obj-$(ARCH)/%.S.o: src/%.S GNUmakefile + @echo " CC $@" @mkdir -p "$$(dirname $@)" - @echo " AS $@" @$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ ifeq ($(ARCH),x86_64) # Compilation rules for *.asm (nasm) files. obj-$(ARCH)/%.asm.o: src/%.asm GNUmakefile + @echo " NASM $@" @mkdir -p "$$(dirname $@)" - @echo " NASM $@" @nasm $(NASMFLAGS) $< -o $@ endif # Remove object files and the final executable. .PHONY: clean clean: - @rm -rf bin-$(ARCH) obj-$(ARCH) cc-runtime-$(ARCH) - @echo " The kernel output files have been removed." + @rm -rf bin-$(ARCH) obj-$(ARCH) + # Remove everything built and generated including downloaded dependencies. .PHONY: distclean distclean: - @rm -rf bin-* obj-* freestnd-c-hdrs cc-runtime* src/limine.h - @echo " The kernel output & downloaded files have been removed." + @rm -rf bin-* obj-* src/deps # Install the final built executable to its final on-root location. .PHONY: install install: all @install -d "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" @install -m 644 bin-$(ARCH)/$(OUTPUT) "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" + @echo "A new copy of Soaplin has been installed to $(DESTDIR)$(PREFIX)/share/$(OUTPUT)." # Try to undo whatever the "install" target did. .PHONY: uninstall uninstall: @rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" @-rmdir "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" + @echo "The copy of Soaplin at $(DESTDIR)$(PREFIX)/share/$(OUTPUT) has been deleted." diff --git a/kernel/get-deps b/kernel/get-deps index 97cf290..25d927b 100755 --- a/kernel/get-deps +++ b/kernel/get-deps @@ -1,16 +1,15 @@ #! /bin/sh -set -ex - srcdir="$(dirname "$0")" test -z "$srcdir" && srcdir=. cd "$srcdir" clone_repo_commit() { + echo " DEPS Cloning $1 to $2 (commit: $3)" if test -d "$2/.git"; then - git -C "$2" reset --hard - git -C "$2" clean -fd + git -C "$2" reset --hard > /dev/null 2>&1 + git -C "$2" clean -fd > /dev/null 2>&1 if ! git -C "$2" checkout $3; then rm -rf "$2" fi @@ -22,8 +21,8 @@ clone_repo_commit() { fi fi if ! test -d "$2"; then - git clone $1 "$2" - if ! git -C "$2" checkout $3; then + git clone $1 "$2" > /dev/null 2>&1 + if ! git -C "$2" checkout $3 > /dev/null 2>&1; then rm -rf "$2" exit 1 fi @@ -32,27 +31,28 @@ clone_repo_commit() { download_by_hash() { DOWNLOAD_COMMAND="curl -Lo" - if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then + if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then DOWNLOAD_COMMAND="wget -O" - if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then + if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then set +x echo "error: Neither curl nor wget found" exit 1 fi fi SHA256_COMMAND="sha256sum" - if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then + if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then SHA256_COMMAND="sha256" - if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then + if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then set +x echo "error: Cannot find sha256(sum) command" exit 1 fi fi + echo " DEPS Downloading $1 to $2" if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then rm -f "$2" mkdir -p "$2" && rm -rf "$2" - $DOWNLOAD_COMMAND "$2" $1 + $DOWNLOAD_COMMAND "$2" $1 > /dev/null 2>&1 if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then set +x echo "error: Cannot download file '$2' by hash" @@ -64,17 +64,29 @@ download_by_hash() { fi } -clone_repo_commit \ - https://github.com/osdev0/freestnd-c-hdrs-0bsd.git \ - freestnd-c-hdrs \ - a87c192f3eb66b0806740dc67325f9ad23fc2d0b +mkdir src/deps clone_repo_commit \ - https://github.com/osdev0/cc-runtime.git \ - cc-runtime \ - 576a01179f3298a4795b92f42c088f9f8800b56b + https://codeberg.org/mintsuki/flanterm \ + src/deps/flanterm \ + bdecdcb1b7dad05ab5249e2c3e4d2c27a661e864 + +clone_repo_commit \ + https://codeberg.org/osdev/freestnd-c-hdrs-0bsd.git \ + src/deps/freestnd-c-hdrs \ + a87c192f3eb66b0806740dc67325f9ad23fc2d0b + +download_by_hash \ + https://codeberg.org/osdev/cc-runtime/raw/commit/d5425655388977fa12ff9b903e554a20b20c426e/cc-runtime.c \ + src/deps/cc-runtime.c \ + 60bb1af4f6541077b736f19bf0f5a22b5dd8a2f3bed0d9d9d89846a33ef24b74 download_by_hash \ https://github.com/limine-bootloader/limine/raw/4687a182be23939c2d9f15db970382dc353ed956/limine.h \ - src/limine.h \ + src/deps/limine.h \ 6879e626f34c1be25ac2f72bf43b083fc2b53887280bb0fcdaee790e258c6974 + +download_by_hash \ + https://github.com/charlesnicholson/nanoprintf/raw/49628bd79977478dbd7c9a1b5277c44e5d49b118/nanoprintf.h \ + src/deps/npf.h \ + ef496c71868b3942695f63e0215da9d25ebdfa21569c854950e8f91adb9e0bea \ No newline at end of file diff --git a/kernel/linker-aarch64.ld b/kernel/linker-aarch64.ld old mode 100755 new mode 100644 diff --git a/kernel/linker-loongarch64.ld b/kernel/linker-loongarch64.ld old mode 100755 new mode 100644 diff --git a/kernel/linker-riscv64.ld b/kernel/linker-riscv64.ld old mode 100755 new mode 100644 diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld old mode 100755 new mode 100644 index 41c5989..b8e1485 --- a/kernel/linker-x86_64.ld +++ b/kernel/linker-x86_64.ld @@ -23,45 +23,32 @@ SECTIONS /* that is the beginning of the region. */ . = 0xffffffff80000000; - - .text : { - text_start_ld = .; - *(.text .text.*) - text_end_ld = .; - } :text - - /* Move to the next memory page for .limine_requests */ - . = ALIGN(CONSTANT(MAXPAGESIZE)); - /* Define a section to contain the Limine requests and assign it to its own PHDR */ .limine_requests : { - reqs_start_ld = .; KEEP(*(.limine_requests_start)) KEEP(*(.limine_requests)) KEEP(*(.limine_requests_end)) - reqs_end_ld = .; } :limine_requests + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + /* Move to the next memory page for .rodata */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { - rodata_start_ld = .; *(.rodata .rodata.*) - rodata_end_ld = .; } :rodata /* Move to the next memory page for .data */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .data : { - data_start_ld = .; *(.data .data.*) - - /* Exported kernel symbols */ - __start_ksyms = .; - KEEP(*(.ksyms)) - __stop_ksyms = .; } :data /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ @@ -71,7 +58,6 @@ SECTIONS .bss : { *(.bss .bss.*) *(COMMON) - data_end_ld = .; } :data /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ diff --git a/kernel/src/arch/aarch64/cpu.c b/kernel/src/arch/aarch64/cpu.c new file mode 100644 index 0000000..d7f43b1 --- /dev/null +++ b/kernel/src/arch/aarch64/cpu.c @@ -0,0 +1,11 @@ +#if defined (__aarch64__) + +#include + +void hcf() { + for (;;) { + asm ("wfi"); + } +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/arch.h b/kernel/src/arch/arch.h deleted file mode 100755 index 284f561..0000000 --- a/kernel/src/arch/arch.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define ENSURE_X86_64 #ifdef __x86_64__ - -#define ENDENSURE \ No newline at end of file diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h new file mode 100644 index 0000000..5d30628 --- /dev/null +++ b/kernel/src/arch/cpu.h @@ -0,0 +1,4 @@ +#pragma once + +// Disable interrupts and halt the system. +void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/la64/cpu.c b/kernel/src/arch/la64/cpu.c new file mode 100644 index 0000000..cf58c4d --- /dev/null +++ b/kernel/src/arch/la64/cpu.c @@ -0,0 +1,11 @@ +#if defined (__loongarch64) + +#include + +void hcf() { + for (;;) { + asm ("idle 0"); + } +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/riscv/cpu.c b/kernel/src/arch/riscv/cpu.c new file mode 100644 index 0000000..4717e48 --- /dev/null +++ b/kernel/src/arch/riscv/cpu.c @@ -0,0 +1,11 @@ +#if defined (__riscv) + +#include + +void hcf() { + for (;;) { + asm ("wfi"); + } +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c new file mode 100644 index 0000000..688812b --- /dev/null +++ b/kernel/src/arch/x86_64/cpu.c @@ -0,0 +1,12 @@ +#if defined (__x86_64__) + +#include + +void hcf() { + asm ("cli"); + for (;;) { + asm ("hlt"); + } +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpuid.h b/kernel/src/arch/x86_64/cpuid.h deleted file mode 100644 index 45a8d5f..0000000 --- a/kernel/src/arch/x86_64/cpuid.h +++ /dev/null @@ -1,647 +0,0 @@ -#ifndef __CPUID_H__ -#define __CPUID_H__ - -#include - -//=================CPUID_VENDOR================= -#define CPUID_VENDOR_INTEL "GenuineIntel" -#define CPUID_VENDOR_AMD "AuthenticAMD" - -//================CPUID_CPU_INFO================ -#define CPUID_CPU_INFO_EAX_STEPPING_MASK 0xF -#define CPUID_CPU_INFO_EAX_MODEL_MASK 0xF << 4 -#define CPUID_CPU_INFO_EAX_FAMILY_MASK 0xF << 8 -#define CPUID_CPU_INFO_EAX_TYPE_MASK 0x3 << 12 -#define CPUID_CPU_INFO_EAX_EXT_MODEL_MASK 0xF << 16 -#define CPUID_CPU_INFO_EAX_EXT_FAMILY_MASK 0xFF << 20 - -#define CPUID_CPU_INFO_EBX_BRAND_INDEX 0xFF -#define CPUID_CPU_INFO_EBX_CFLUSH_SIZE 0xFF << 8 -#define CPUID_CPU_INFO_EBX_MAX_LOGPROC 0xFF << 16 -#define CPUID_CPU_INFO_EBX_INIT_APIC_ID 0xFF << 25 - -#define CPUID_CPU_INFO_ECX_SSE3 1 << 0 -#define CPUID_CPU_INFO_ECX_PCLMULQDQ 1 << 1 -#define CPUID_CPU_INFO_ECX_DTES64 1 << 2 -#define CPUID_CPU_INFO_ECX_MONITOR 1 << 3 -#define CPUID_CPU_INFO_ECX_DS_CPL 1 << 4 -#define CPUID_CPU_INFO_ECX_VMX 1 << 5 -#define CPUID_CPU_INFO_ECX_SMX 1 << 6 -#define CPUID_CPU_INFO_ECX_EIST 1 << 7 -#define CPUID_CPU_INFO_ECX_TM2 1 << 8 -#define CPUID_CPU_INFO_ECX_SSSE3 1 << 9 -#define CPUID_CPU_INFO_ECX_CNXT_ID 1 << 10 -#define CPUID_CPU_INFO_ECX_SDBG 1 << 11 -#define CPUID_CPU_INFO_ECX_FMA 1 << 12 -#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13 -#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14 -#define CPUID_CPU_INFO_ECX_PDCM 1 << 15 -// bit 16 is reserved -#define CPUID_CPU_INFO_ECX_PCID 1 << 17 -#define CPUID_CPU_INFO_ECX_DCA 1 << 18 -#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19 -#define CPUID_CPU_INFO_ECX_SSE4_2 1 << 20 -#define CPUID_CPU_INFO_ECX_X2APIC 1 << 21 -#define CPUID_CPU_INFO_ECX_MOVBE 1 << 22 -#define CPUID_CPU_INFO_ECX_POPCNT 1 << 23 -#define CPUID_CPU_INFO_ECX_TSC_DEADLINE 1 << 24 -#define CPUID_CPU_INFO_ECX_AESNI 1 << 25 -#define CPUID_CPU_INFO_ECX_XSAVE 1 << 26 -#define CPUID_CPU_INFO_ECX_OSXSAVE 1 << 27 -#define CPUID_CPU_INFO_ECX_AVX 1 << 28 -#define CPUID_CPU_INFO_ECX_F16C 1 << 29 -#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30 -// bit 31 is unused - -#define CPUID_CPU_INFO_EDX_FPU 1 << 0 -#define CPUID_CPU_INFO_EDX_VME 1 << 1 -#define CPUID_CPU_INFO_EDX_DE 1 << 2 -#define CPUID_CPU_INFO_EDX_PSE 1 << 3 -#define CPUID_CPU_INFO_EDX_TSC 1 << 4 -#define CPUID_CPU_INFO_EDX_MSR 1 << 5 -#define CPUID_CPU_INFO_EDX_PAE 1 << 6 -#define CPUID_CPU_INFO_EDX_MCE 1 << 7 -#define CPUID_CPU_INFO_EDX_CX8 1 << 8 -#define CPUID_CPU_INFO_EDX_APIC 1 << 9 -// bit 10 is reserved -#define CPUID_CPU_INFO_EDX_SEP 1 << 11 -#define CPUID_CPU_INFO_EDX_MTRR 1 << 12 -#define CPUID_CPU_INFO_EDX_PGE 1 << 13 -#define CPUID_CPU_INFO_EDX_MCA 1 << 14 -#define CPUID_CPU_INFO_EDX_CMOV 1 << 15 -#define CPUID_CPU_INFO_EDX_PAT 1 << 16 -#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17 -#define CPUID_CPU_INFO_EDX_PSN 1 << 18 -#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19 -// bit 20 is reserved -#define CPUID_CPU_INFO_EDX_DS 1 << 21 -#define CPUID_CPU_INFO_EDX_ACPI 1 << 22 -#define CPUID_CPU_INFO_EDX_MMX 1 << 23 -#define CPUID_CPU_INFO_EDX_FXSR 1 << 24 -#define CPUID_CPU_INFO_EDX_SSE 1 << 25 -#define CPUID_CPU_INFO_EDX_SSE2 1 << 26 -#define CPUID_CPU_INFO_EDX_SS 1 << 27 -#define CPUID_CPU_INFO_EDX_HTT 1 << 28 -#define CPUID_CPU_INFO_EDX_TM 1 << 29 -// bit 30 is reserved -#define CPUID_CPU_INFO_EDX_PBE 1 << 31 - -//===============CPUID_CACHE_TLB=============== -// WARNING: I gave up and used ChatGPT for these -#define CPUID_CACHE_TLB_DESC_NULL 0x00 -#define CPUID_CACHE_TLB_DESC_TLB_4_KBYTE_4WAY_32E 0x01 -#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02 -#define CPUID_CACHE_TLB_DESC_DTLB_4_KBYTE_4WAY_64E 0x03 -#define CPUID_CACHE_TLB_DESC_DTLB_4_MBYTE_4WAY_8E 0x04 -#define CPUID_CACHE_TLB_DESC_DTLB1_4_MBYTE_4WAY_32E 0x05 -#define CPUID_CACHE_TLB_DESC_L1_INST_8K_4WAY_32B 0x06 -#define CPUID_CACHE_TLB_DESC_L1_INST_16K_4WAY_32B 0x08 -#define CPUID_CACHE_TLB_DESC_L1_INST_32K_4WAY_64B 0x09 -#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_2WAY_32B 0x0A -#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_4WAY_4E 0x0B -#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_32B 0x0C -#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B 0x0D -#define CPUID_CACHE_TLB_DESC_L1_DATA_24K_6WAY_64B 0x0E -#define CPUID_CACHE_TLB_DESC_L2_128K_2WAY_64B 0x1D -#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B 0x21 -#define CPUID_CACHE_TLB_DESC_L3_512K_4WAY_64B_2LPS 0x22 -#define CPUID_CACHE_TLB_DESC_L3_1M_8WAY_64B_2LPS 0x23 -#define CPUID_CACHE_TLB_DESC_L2_1M_16WAY_64B 0x24 -#define CPUID_CACHE_TLB_DESC_L3_2M_8WAY_64B_2LPS 0x25 -#define CPUID_CACHE_TLB_DESC_L3_4M_8WAY_64B_2LPS 0x29 -#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_8WAY_64B 0x2C -#define CPUID_CACHE_TLB_DESC_L1_INST_32K_8WAY_64B 0x30 -#define CPUID_CACHE_TLB_DESC_NO_L2_OR_L3 0x40 -#define CPUID_CACHE_TLB_DESC_L2_128K_4WAY_32B 0x41 -#define CPUID_CACHE_TLB_DESC_L2_256K_4WAY_32B 0x42 -#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_32B 0x43 -#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_32B 0x44 -#define CPUID_CACHE_TLB_DESC_L2_2M_4WAY_32B 0x45 -#define CPUID_CACHE_TLB_DESC_L3_4M_4WAY_64B 0x46 -#define CPUID_CACHE_TLB_DESC_L3_8M_8WAY_64B 0x47 -#define CPUID_CACHE_TLB_DESC_L2_3M_12WAY_64B 0x48 -#define CPUID_CACHE_TLB_DESC_L3_4M_16WAY_64B 0x49 -#define CPUID_CACHE_TLB_DESC_L3_6M_12WAY_64B 0x4A -#define CPUID_CACHE_TLB_DESC_L3_8M_16WAY_64B 0x4B -#define CPUID_CACHE_TLB_DESC_L3_12M_12WAY_64B 0x4C -#define CPUID_CACHE_TLB_DESC_L3_16M_16WAY_64B 0x4D -#define CPUID_CACHE_TLB_DESC_L2_6M_24WAY_64B 0x4E -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_32E 0x4F -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_64E 0x50 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_128E 0x51 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_256E 0x52 -#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_7E 0x55 -#define CPUID_CACHE_TLB_DESC_DTLB0_4M_4WAY_16E 0x56 -#define CPUID_CACHE_TLB_DESC_DTLB0_4K_4WAY_16E 0x57 -#define CPUID_CACHE_TLB_DESC_DTLB0_4K_FULLY_16E 0x59 -#define CPUID_CACHE_TLB_DESC_DTLB0_2M_4M_4WAY_32E 0x5A -#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_64E 0x5B -#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_128E 0x5C -#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_256E 0x5D -#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_8WAY_64B 0x60 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_FULLY_48E 0x61 -#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_32E_1G_4WAY_4E 0x63 -#define CPUID_CACHE_TLB_DESC_DTLB_4K_4WAY_512E 0x64 -#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_4WAY_64B 0x66 -#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B_DUPLICATE 0x67 //???????????? -#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_4WAY_64B 0x68 -#define CPUID_CACHE_TLB_DESC_UTLB_4K_8WAY_64E 0x6A -#define CPUID_CACHE_TLB_DESC_DTLB_4K_8WAY_256E 0x6B -#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_8WAY_128E 0x6C -#define CPUID_CACHE_TLB_DESC_DTLB_1G_FULLY_16E 0x6D -#define CPUID_CACHE_TLB_DESC_TRACE_12K_8WAY 0x70 -#define CPUID_CACHE_TLB_DESC_TRACE_16K_8WAY 0x71 -#define CPUID_CACHE_TLB_DESC_TRACE_32K_8WAY 0x72 -#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_8E 0x76 -#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_64B 0x78 -#define CPUID_CACHE_TLB_DESC_L2_128K_8WAY_64B_2LPS 0x79 -#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B_2LPS 0x7A -#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B_2LPS 0x7B -#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B_2LPS 0x7C -#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_64B 0x7D -#define CPUID_CACHE_TLB_DESC_L2_512K_2WAY_64B 0x7F -#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B 0x80 -#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_32B 0x82 -#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_32B 0x83 -#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_32B 0x84 -#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_32B 0x85 -#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_64B 0x86 -#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B 0x87 -#define CPUID_CACHE_TLB_DESC_DTLB_4K_FULLY_ASSOC_32E 0xA0 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_128E 0xB0 -#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4WAY_8E_4M_4WAY_4E 0xB1 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_64E 0xB2 -#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_128E 0xB3 -#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_256E 0xB4 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_64E 0xB5 -#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_128E 0xB6 -#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_64E 0xBA -#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4M_4WAY_8E 0xC0 -#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_8WAY_1024E 0xC1 -#define CPUID_CACHE_TLB_DESC_DTLB_4K_2M_4WAY_16E 0xC2 -#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_6WAY_1536E_1GB_4WAY_16E 0xC3 -#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_4WAY_32E 0xC4 -#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_4WAY_512E 0xCA -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_512KB_4WAY_64B_LINE 0xD0 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_4WAY_64B_LINE 0xD1 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_4WAY_64B_LINE 0xD2 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_8WAY_64B_LINE 0xD6 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_8WAY_64B_LINE 0xD7 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_8WAY_64B_LINE 0xD8 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1_5MB_12WAY_64B_LINE 0xDC -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_3MB_12WAY_64B_LINE 0xDD -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_6MB_12WAY_64B_LINE 0xDE -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_16WAY_64B_LINE 0xE2 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_16WAY_64B_LINE 0xE3 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_8MB_16WAY_64B_LINE 0xE4 -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_12MB_24WAY_64B_LINE 0xEA -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_18MB_24WAY_64B_LINE 0xEB -#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_24MB_24WAY_64B_LINE 0xEC -#define CPUID_CACHE_TLB_DESC_PREFETCH_64_BYTE 0xF0 -#define CPUID_CACHE_TLB_DESC_PREFETCH_128_BYTE 0xF1 -#define CPUID_CACHE_TLB_DESC_NO_TLB_INFO_CPUID_LEAF_18H 0xFE -#define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF - -//=============CPUID_SERIAL_NUMBER============= -#define CPUID_SERIAL_NUMBER_STITCH(ECX, EDX) (uint64_t)((EDX << 32) | ECX) - -//=============CPUID_CACHE_PARAMS============== -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF -#define CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL 0x7 << 4 -#define CPUID_CACHE_PARAMS_EAX_IS_SELF_INIT 1 << 8 -#define CPUID_CACHE_PARAMS_EAX_IS_FULLY_ASSOCIATIVE 1 << 9 -// bits 10-13 are reserved -#define CPUID_CACHE_PARAMS_EAX_MAX_PROC_SHARING 0xFFF << 14 - -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_NULL 0x0 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_DATA 0x1 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_INSTRUCTION 0x2 -#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_UNIFIED 0x3 - -#define CPUID_CACHE_PARAMS_EBX_COHERENCY_LINE_SIZE 0xFFF -#define CPUID_CACHE_PARAMS_EBX_PHYS_LINE_PARTITIONS 0x3FF << 12 -#define CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIVITY 0x3FF - -#define CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVENESS 1 -#define CPUID_CACHE_PARAMS_EDX_COMPLEX_CACHE_INDEXING 1 << 1 - -//=============CPUID_MONITOR_MWAIT============= -#define CPUID_MONITOR_MWAIT_ECX_ENUM_EXTENSIONS 1 -#define CPUID_MONITOR_MWAIT_ECX_BREAK_EVENTS 1 << 1 - -#define CPUID_MONITOR_MWAIT_EDX_C0_SUBC_STATES 0xF -#define CPUID_MONITOR_MWAIT_EDX_C1_SUBC_STATES 0xF << 4 -#define CPUID_MONITOR_MWAIT_EDX_C2_SUBC_STATES 0xF << 8 -#define CPUID_MONITOR_MWAIT_EDX_C3_SUBC_STATES 0xF << 12 -#define CPUID_MONITOR_MWAIT_EDX_C4_SUBC_STATES 0xF << 16 -#define CPUID_MONITOR_MWAIT_EDX_C5_SUBC_STATES 0xF << 20 -#define CPUID_MONITOR_MWAIT_EDX_C6_SUBC_STATES 0xF << 24 -#define CPUID_MONITOR_MWAIT_EDX_C7_SUBC_STATES 0xF << 28 - -//===========CPUID_THERMAL_AND_POWER=========== -#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1 -#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST 1 << 1 -#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2 -// Bit 3 is reserved -#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3 -#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5 -#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6 -#define CPUID_THERMAL_AND_POWER_EAX_HWP 1 << 7 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_NOTIFICATION 1 << 8 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PERF_PREF 1 << 10 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11 -// Bit 12 is reserved -#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13 -#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST_MAX 1 << 14 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15 -#define CPUID_THERMAL_AND_POWER_EAX_HWP_PECI 1 << 16 -#define CPUID_THERMAL_AND_POWER_EAX_FLEXIBLE_HWP 1 << 17 -#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18 -#define CPUID_THERMAL_AND_POWER_EAX_HW_FEEDBACK 1 << 19 -#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20 -// Bits 21 and 22 are reserved -#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23 -#define CPUID_THERMAL_AND_POWER_EAX_THERM_INTERRUPT 1 << 24 - -#define CPUID_THERMAL_AND_POWER_EBX_INT_TRESHOLD 0xf - -#define CPUID_THERMAL_AND_POWER_ECX_HW_COORD_FEEDBACK 1 -#define CPUID_THERMAL_AND_POWER_ECX_ENERGY_PERF_BIAS 1 << 3 -#define CPUID_THERMAL_AND_POWER_ECX_TD_CLASSES 0xff << 8 - -#define CPUID_THERMAL_AND_POWER_EDX_PERF_REPORT 1 -#define CPUID_THERMAL_AND_POWER_EDX_EFFICIENCY_REPORT 1 << 1 -#define CPUID_THERMAL_AND_POWER_EDX_HW_FEEDBACK_SIZE 0xf << 8 -#define CPUID_THERMAL_AND_POWER_EDX_THIS_PROC_HW_FB 0xffff << 16 - -//===========CPUID_EXTENDED_FEATURES=========== -#define CPUID_EXTENDED_FEATURES_EBX_FSGSBASE 1 -#define CPUID_EXTENDED_FEATURES_EBX_TSC_ADJUST 1 << 1 -#define CPUID_EXTENDED_FEATURES_EBX_SGX 1 << 2 -#define CPUID_EXTENDED_FEATURES_EBX_BMI1 1 << 3 -#define CPUID_EXTENDED_FEATURES_EBX_HLE 1 << 4 -#define CPUID_EXTENDED_FEATURES_EBX_AVX2 1 << 5 -#define CPUID_EXTENDED_FEATURES_EBX_FDP_EXCPTN_ONLY 1 << 6 -#define CPUID_EXTENDED_FEATURES_EBX_SMEP 1 << 7 -#define CPUID_EXTENDED_FEATURES_EBX_BMI2 1 << 8 -#define CPUID_EXTENDED_FEATURES_EBX_ENHANCED_REP 1 << 9 -#define CPUID_EXTENDED_FEATURES_EBX_INVCIP 1 << 10 -#define CPUID_EXTENDED_FEATURES_EBX_RTM 1 << 11 -#define CPUID_EXTENDED_FEATURES_EBX_RDT_M 1 << 12 -#define CPUID_EXTENDED_FEATURES_EBX_NO_FPU_CS 1 << 13 -#define CPUID_EXTENDED_FEATURES_EBX_MPX 1 << 14 -#define CPUID_EXTENDED_FEATURES_EBX_RDT_A 1 << 15 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512F 1 << 16 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512DQ 1 << 17 -#define CPUID_EXTENDED_FEATURES_EBX_RDSEED 1 << 18 -#define CPUID_EXTENDED_FEATURES_EBX_ADX 1 << 19 -#define CPUID_EXTENDED_FEATURES_EBX_SMAP 1 << 20 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512_IFMA 1 << 21 -// Bit 22 is reserved -#define CPUID_EXTENDED_FEATURES_EBX_CLFLUSHOPT 1 << 23 -#define CPUID_EXTENDED_FEATURES_EBX_CLWB 1 << 24 -#define CPUID_EXTENDED_FEATURES_EBX_TRACE 1 << 25 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512PF 1 << 26 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512ER 1 << 27 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512CD 1 << 28 -#define CPUID_EXTENDED_FEATURES_EBX_SHA 1 << 29 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512BW 1 << 30 -#define CPUID_EXTENDED_FEATURES_EBX_AVX512VL 1 << 31 - -#define CPUID_EXTENDED_FEATURES_ECX_PREFETCHWT1 1 -#define CPUID_EXTENDED_FEATURES_ECX_AFX512_VBMI 1 << 1 -#define CPUID_EXTENDED_FEATURES_ECX_UMIP 1 << 2 -#define CPUID_EXTENDED_FEATURES_ECX_PKU 1 << 3 -#define CPUID_EXTENDED_FEATURES_ECX_OSPKE 1 << 4 -#define CPUID_EXTENDED_FEATURES_ECX_WAITPKG 1 << 5 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VBMI2 1 << 6 -#define CPUID_EXTENDED_FEATURES_ECX_CET_SS 1 << 7 -#define CPUID_EXTENDED_FEATURES_ECX_GFNI 1 << 8 -#define CPUID_EXTENDED_FEATURES_ECX_VAES 1 << 9 -#define CPUID_EXTENDED_FEATURES_ECX_VPCLMULQDQ 1 << 10 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VNNI 1 << 11 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12 -#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13 -#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14 -// bit 15 is reserved -#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16 -#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17 -#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22 -#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23 -#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24 -#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25 -// bit 26 is reserved -#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27 -#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28 -#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29 -#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30 -#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31 - -// bit 0 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3 -#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4 -#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5 -// bits 6 and 7 are reserved -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_VPINTERSECT \ - 1 << 8 // intel you son of a bitch -#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9 -#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10 -#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11 -// bit 12 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13 -#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14 -#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15 -#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16 -// bit 17 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18 -#define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19 -#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20 -// bit 21 is reserved -#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22 -#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23 -#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24 -#define CPUID_EXTENDED_FEATURES_EDX_AMX_INT8 1 << 25 -#define CPUID_EXTENDED_FEATURES_EDX_IBRS 1 << 26 -#define CPUID_EXTENDED_FEATURES_EDX_STIBP 1 << 27 -#define CPUID_EXTENDED_FEATURES_EDX_L1D_FLUSH 1 << 28 -#define CPUID_EXTENDED_FEATURES_EDX_ARCH_CAPABS_MSR 1 << 29 -#define CPUID_EXTENDED_FEATURES_EDX_CORE_CAPABS_MSR 1 << 30 -#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31 - -//=========CPUID_EXTENDED_FEATURES_SL1========= -// bits 0-3 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5 -// bits 6-9 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_STOSB 1 << 11 -#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12 -// bits 13-21 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22 -// bits 23-19 are reserved -#define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30 -// bit 31 is reserved - -#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1 - -#define CPUID_EXTENDED_FEATURES_SL1_EDX_CET_SSS 1 << 18 - -//=========CPUID_EXTENDED_FEATURES_SL2========= -#define CPUID_EXTENDED_FEATURES_SL2_EDX_PSFD 1 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_IPRED_CTRL 1 << 1 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_DDPD_U 1 << 3 -#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4 -// The rest of the bits are reserved - -enum leaves { - /* @ Basic CPU info - * @ Returned EAX: Highest basic CPUID leaf present - * @ Returned EBX: First 4 letters of the vendor identifier string - * @ Returned ECX: Third 4 letters of the vendor identifier string - * @ Retruned EDX: Second 4 letters of the vendor identifier string - */ - CPUID_VENDOR = 0x00000000, - /* @ CPU Version information - * @ Returned EAX: Family,Model,Stepping - * @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical - * processors - * @ Returned ECX: Featrue information - * @ Retruned EDX: More feature information - */ - CPUID_CPU_INFO = 0x00000001, - /* @ CPU Cache and TLB information - * @ Returned EAX: 4 Cache, prefetch or TLB descriptors - * @ Returned EBX: 4 Cache, prefetch or TLB descriptors - * @ Returned ECX: 4 Cache, prefetch or TLB descriptors - * @ Retruned EDX: 4 Cache, prefetch or TLB descriptors - */ - CPUID_CACHE_TLB = 0x00000002, - /* @ CPU Serial Number !!! PENTIUM 3 ONLY !!! - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: bits 0-31 of the serial number - * @ Retruned EDX: bits 32-63 of the serial number - */ - CPUID_SERIAL_NUMBER = 0x00000003, - /* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!! - * @ Returned EAX: Cache level,Is self init,Is fully associative,Maximum - * number of addressable IDs for logical processors sharing this cache - * @ Returned EBX: L, P and W - * @ Returned ECX: S - * @ Retruned EDX: Cache inclusiveness and Complex Cache indexing - */ - CPUID_CACHE_PARAMS = 0x00000004, - /* @ MONITOR/MWAIT params - * @ Returned EAX: Smallest monitor-line size - * @ Returned EBX: Largest monitor-line size - * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating - * interrupts as break-event for MWAIT - * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C - * number thingy IDK - */ - CPUID_MONITOR_MWAIT = 0x00000005, - /* @ Thermal and power managment - * @ Returned EAX: Thermal and power info - * @ Returned EBX: Thermal and power info - * @ Returned ECX: Thermal and power info - * @ Retruned EDX: Thermal and power info - */ - CPUID_THERMAL_AND_POWER = 0x00000006, - /* @ Extended features - * @ Returned EAX: Number of subleaves supported - * @ Returned EBX: Features - * @ Returned ECX: Features - * @ Retruned EDX: Features - */ - CPUID_EXTENDED_FEATURES = 0x00000007, - /* @ Direct Cache Access Information - * @ Returned EAX: Value of the MSR "IA32_PLATFORM_DCA_CAP" - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_CACHE_ACCESS_INFO = 0x00000009, - CPUID_PERFORMANCE_MONITORING = 0x0000000A, - CPUID_EXTENDENDED_TOPOLOGY = 0x0000000B, - CPUID_EXTENDENDED_TOPOLOGY2 = 0x0000000D, - CPUID_INTEL_RDT = 0x0000000F, - CPUID_INTEL_RDT2 = 0x00000010, - CPUID_INTEL_SGX = 0x00000012, - CPUID_CPU_TRACE_ENUM = 0x00000014, - CPUID_TSC = 0x00000015, - CPUID_CPU_FREQ_INFO = 0x00000016, - CPUID_SOC_VENDOR = 0x00000017, - CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS = 0x00000018, - CPUID_KEY_LOCKER = 0x000000019, - CPUID_NATIVE_MODEL_ID = 0x0000001A, - CPUID_PCONFIG_INFO = 0x0000001B, - CPUID_LAST_BRACH = 0x00000001C, - CPUID_TILE_INFO = 0x00000001D, - CPUID_TMUL_INFO = 0x00000001E, - CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F, - CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020, - // TODO: add the bitmasks for these Microsoft ones - /* @ Hypervisor CPUID Leaf Range - * @ Returned EAX: Highest hypervisor CPUID leaf present - * @ Returned EBX: Largest monitor-line size - * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating - * interrupts as break-event for MWAIT - * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C - * number thingy IDK - */ - CPUID_HYPERV_IDENT = 0x40000000, - /* @ Hypervisor Vendor-Neutral Interface Identification - * @ Returned EAX: Hypervisor interface signature - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_INTERFCE_IDENT = 0x40000001, - /* @ Hypervisor System Identity - * @ Returned EAX: Build number - * @ Returned EBX: Major and minor version - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_SYSTEM_IDENT = 0x40000002, - /* @ Hypervisor Feature Identification - * @ Returned EAX: bits 0-31 of HV_PARTITION_PRIVILEGE_MASK - * @ Returned EBX: bits 31-63 of HV_PARTITION_PRIVILEGE_MASK - * @ Returned ECX: Hyper-V features - * @ Retruned EDX: Hyper-V features - */ - CPUID_MS_HYPERV_FEATURE_IDENT = 0x40000003, - /* @ Implementation Recommendations - * @ Returned EAX: Hyper-V feature recommendations - * @ Returned EBX: Hyper-V feature recommendations - * @ Returned ECX: Hyper-V feature recommendations - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_RECOMMENDATIONS = 0x40000004, - /* @ Hypervisor Implementation Limits - * @ Returned EAX: The maximum number of virtual processors supported - * @ Returned EBX: The maximum number of logical processors supported - * @ Returned ECX: The maximum number of physical interrupt vectors available - * for interrupt remapping. - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005, - /* @ Implementation Hardware Features - * @ Returned EAX: Hardware features - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_HARDWARE_FEATURES = 0x40000006, - /* @ Nested Hypervisor Feature Identification - * @ Returned EAX: Nested Hypervisor features - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Nested Hypervisor features - */ - CPUID_MS_HYPERV_NESTED_FEATURES = 0x40000009, - /* @ Nested Hypervisor Nested Virtualization Features - * @ Returned EAX: Nested Hypervisor features - * @ Returned EBX: Nested Hypervisor features - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_MS_HYPERV_NESTED_OPTIMISATIONS = 0x4000000A, - /* @ Extended processor signature - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Extended feature bits - * @ Retruned EDX: Extended feature bits - */ - CPUID_EXTENDED_SIGNATURE = 0x800000001, - /* @ Full CPU name - * @ Returned EAX: First 4 characters of the full CPU name - * @ Returned EBX: Second 4 characters of the full CPU name - * @ Returned ECX: Third 4 characters of the full CPU name - * @ Retruned EDX: Fourth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING1 = 0x800000002, - /* @ Full CPU name 2 - * @ Returned EAX: Fifth 4 characters of the full CPU name - * @ Returned EBX: Sexth 4 characters of the full CPU name - * @ Returned ECX: Seventh 4 characters of the full CPU name - * @ Retruned EDX: Eightth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING2 = 0x800000003, - /* @ Full CPU name 3 - * @ Returned EAX: Nineth 4 characters of the full CPU name - * @ Returned EBX: Tenth 4 characters of the full CPU name - * @ Returned ECX: Eleventh 4 characters of the full CPU name - * @ Retruned EDX: Twelveth 4 characters of the full CPU name - */ - CPUID_BRAND_STRING3 = 0x800000004, - /* @ Cache line size and associativity - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Bits 0-7 = Cache line size in bytes, Bits 12-15 = L2 - * Associativity, Bits 16-31 = Cache size in 1K blocks - * @ Retruned EDX: Reserved - */ - CPUID_MORE_CACHE = 0x800000006, - /* @ Invariant TSC available - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Bit 8 = Invariant TSC available - * @ Retruned EDX: Reserved - */ - CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007, - /* @ Physical adress size - * @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear - * Address bits - * @ Returned EBX: Bit 9 = WBNOINVD available - * @ Returned ECX: Reserved - * @ Retruned EDX: Reserved - */ - CPUID_PHYS_ADDR_SIZE = 0x800000008, -}; - -enum sub_leaves { - /* @ Extended features available subleaf 1 !!! All fields return 0 is info not - * available !!! - * @ Returned EAX: Features - * @ Returned EBX: PPIN - * @ Returned ECX: Reserved - * @ Retruned EDX: CET_SSS - */ - CPUID_EXTENDED_FEATURES_SL1 = 0x00000001, - /* @ Extended features available subleaf 2 !!! All fields return 0 is info not - * available !!! - * @ Returned EAX: Reserved - * @ Returned EBX: Reserved - * @ Returned ECX: Reserved - * @ Retruned EDX: Features - */ - CPUID_EXTENDED_FEATURES_SL2 = 0x00000002, - CPUID_INTEL_RDT_CAPABILITY = 0x00000001, - CPUID_INTEL_RDT2_ALLOCATION = 0x00000000, - CPUID_INTEL_RDT2_RESID1 = 0x00000001, - CPUID_INTEL_RDT2_RESID2 = 0x00000002, - CPUID_INTEL_RDT2_RESID3 = 0x00000003, - CPUID_INTEL_SGX_SL1 = 0x00000001, - CPUID_INTEL_SGX_SL2 = 0x00000002, - CPUID_CPU_TRACE_ENUM_SL = 0x00000001, - CPUID_SOC_VENDOR_SL1 = 0x00000001, - CPUID_SOC_VENDOR_SL2 = 0x00000002, - CPUID_SOC_VENDOR_SL3 = 0x00000003, - // NOTE: goes higher than 1 - CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001, - CPUID_TILE_INFO_PALETTE1 = 0x000000001, -}; - -static inline void cpuid(int leaf, int subleaf, int *a, int *b, int *c, - int *d) { - __asm__ __volatile__("cpuid" - : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) - : "a"(leaf), "c"(subleaf)); -} - -#endif // __CPUID_H__ \ No newline at end of file diff --git a/kernel/src/arch/x86_64/fpu.c b/kernel/src/arch/x86_64/fpu.c deleted file mode 100644 index b569c2c..0000000 --- a/kernel/src/arch/x86_64/fpu.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -void fpu_set_cw(const uint16_t cw) { asm volatile("fldcw %0" ::"m"(cw)); } - -void fpu_activate() { - size_t cr4; - asm volatile("mov %%cr4, %0" : "=r"(cr4)); - cr4 |= 0x200; - asm volatile("mov %0, %%cr4" ::"r"(cr4)); - fpu_set_cw(0x37F); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/fpu.h b/kernel/src/arch/x86_64/fpu.h deleted file mode 100644 index e4107e6..0000000 --- a/kernel/src/arch/x86_64/fpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include - -void fpu_set_cw(const uint16_t cw); -void fpu_activate(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c deleted file mode 100644 index 0612961..0000000 --- a/kernel/src/arch/x86_64/gdt.c +++ /dev/null @@ -1,51 +0,0 @@ -// #include "sys/log.h" -#include -#include -#include -#include - -gdt_table def_table = {{ - 0x0000000000000000, // 0x00 - - 0x00009a000000ffff, // 0x08 16 bit code - 0x000093000000ffff, // 0x10 16 bit data - - 0x00cf9a000000ffff, // 0x18 32 bit code - 0x00cf93000000ffff, // 0x20 32 bit data - - 0x00af9b000000ffff, // 0x28 64 bit code cs - 0x00af93000000ffff, // 0x30 64 bit data ss - - 0x00aff3000000ffff, // 0x38 user mode data ss - 0x00affb000000ffff, // 0x40 user mode code cs - }, - {}}; - -tssr tss_list[256]; // One tssr per CPU - -void gdt_init(char *kstack) { - - // TODO: adapt for multiprocessor kernel - memset(&tss_list[0], 0, sizeof(tssr)); - tss_list[0].rsp[0] = (uint64_t)kstack; - tss_list[0].iopb = sizeof(tssr); - uintptr_t tss = (uintptr_t)&tss_list[0]; - - def_table.tss_entry.length = sizeof(tss_entry); - def_table.tss_entry.base = (uint16_t)(tss & 0xffff); - def_table.tss_entry.base1 = (uint8_t)((tss >> 16) & 0xff); - def_table.tss_entry.flags = 0x89; - def_table.tss_entry.flags1 = 0; - def_table.tss_entry.base2 = (uint8_t)((tss >> 24) & 0xff); - def_table.tss_entry.base3 = (uint32_t)(tss >> 32); - def_table.tss_entry.resv = 0; - - gdtr gdt = - (gdtr){.size = (sizeof(gdt_table)) - 1, .address = (uint64_t)&def_table}; - - __asm__ volatile("lgdt %0\n\t" : : "m"(gdt) : "memory"); - __asm__ volatile("ltr %0\n\t" : : "r"((uint16_t)0x48)); - - // logln(progress, "kinit stage 1", "GDT initialized\n"); - log("gdt - initialized.\n"); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.h b/kernel/src/arch/x86_64/gdt.h deleted file mode 100644 index be55cd9..0000000 --- a/kernel/src/arch/x86_64/gdt.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -typedef struct { - uint16_t length; - uint16_t base; - uint8_t base1; - uint8_t flags; - uint8_t flags1; - uint8_t base2; - uint32_t base3; - uint32_t resv; -} __attribute__((packed)) tss_entry; - -typedef struct { - uint64_t gdt_entries[9]; - tss_entry tss_entry; -} __attribute__((packed)) gdt_table; - -typedef struct { - uint16_t size; - uint64_t address; -} __attribute__((packed)) gdtr; - -typedef struct { - uint32_t resv; - uint64_t rsp[4]; - uint64_t resv1; - uint64_t ist[7]; - uint64_t resv2; - uint16_t resv3; - uint16_t iopb; -} __attribute__((packed)) tssr; // Per CPU - -void gdt_init(char *kstack); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.asm b/kernel/src/arch/x86_64/idt.asm deleted file mode 100755 index c7b8f8e..0000000 --- a/kernel/src/arch/x86_64/idt.asm +++ /dev/null @@ -1,335 +0,0 @@ -%macro pushall 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 -%endmacro - -%macro popall 0 - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax -%endmacro - -%macro isr_err_stub 1 -isr_stub_%+%1: - - push %1 - pushall - - mov rdi, rsp - - call idt_int_handler - - popall - - add rsp, 16 - iretq -%endmacro - -%macro isr_no_err_stub 1 -isr_stub_%+%1: - push 0 - push %1 - pushall - - mov rdi, rsp - - call idt_int_handler - - popall - - add rsp, 16 - iretq -%endmacro - -extern idt_int_handler -isr_no_err_stub 0 -isr_no_err_stub 1 -isr_no_err_stub 2 -isr_no_err_stub 3 -isr_no_err_stub 4 -isr_no_err_stub 5 -isr_no_err_stub 6 -isr_no_err_stub 7 -isr_err_stub 8 -isr_no_err_stub 9 -isr_err_stub 10 -isr_err_stub 11 -isr_err_stub 12 -isr_err_stub 13 -isr_err_stub 14 -isr_no_err_stub 15 -isr_no_err_stub 16 -isr_err_stub 17 -isr_no_err_stub 18 -isr_no_err_stub 19 -isr_no_err_stub 20 -isr_no_err_stub 21 -isr_no_err_stub 22 -isr_no_err_stub 23 -isr_no_err_stub 24 -isr_no_err_stub 25 -isr_no_err_stub 26 -isr_no_err_stub 27 -isr_no_err_stub 28 -isr_no_err_stub 29 -isr_err_stub 30 -isr_no_err_stub 31 - - -isr_no_err_stub 32 -isr_no_err_stub 33 -isr_no_err_stub 34 -isr_no_err_stub 35 -isr_no_err_stub 36 -isr_no_err_stub 37 -isr_no_err_stub 38 -isr_no_err_stub 39 -isr_no_err_stub 40 -isr_no_err_stub 41 -isr_no_err_stub 42 -isr_no_err_stub 43 -isr_no_err_stub 44 -isr_no_err_stub 45 -isr_no_err_stub 46 -isr_no_err_stub 47 -isr_no_err_stub 48 -isr_no_err_stub 49 -isr_no_err_stub 50 -isr_no_err_stub 51 -isr_no_err_stub 52 -isr_no_err_stub 53 -isr_no_err_stub 54 -isr_no_err_stub 55 -isr_no_err_stub 56 -isr_no_err_stub 57 -isr_no_err_stub 58 -isr_no_err_stub 59 -isr_no_err_stub 60 -isr_no_err_stub 61 -isr_no_err_stub 62 -isr_no_err_stub 63 -isr_no_err_stub 64 -isr_no_err_stub 65 -isr_no_err_stub 66 -isr_no_err_stub 67 -isr_no_err_stub 68 -isr_no_err_stub 69 -isr_no_err_stub 70 -isr_no_err_stub 71 -isr_no_err_stub 72 -isr_no_err_stub 73 -isr_no_err_stub 74 -isr_no_err_stub 75 -isr_no_err_stub 76 -isr_no_err_stub 77 -isr_no_err_stub 78 -isr_no_err_stub 79 -isr_no_err_stub 80 -isr_no_err_stub 81 -isr_no_err_stub 82 -isr_no_err_stub 83 -isr_no_err_stub 84 -isr_no_err_stub 85 -isr_no_err_stub 86 -isr_no_err_stub 87 -isr_no_err_stub 88 -isr_no_err_stub 89 -isr_no_err_stub 90 -isr_no_err_stub 91 -isr_no_err_stub 92 -isr_no_err_stub 93 -isr_no_err_stub 94 -isr_no_err_stub 95 -isr_no_err_stub 96 -isr_no_err_stub 97 -isr_no_err_stub 98 -isr_no_err_stub 99 -isr_no_err_stub 100 -isr_no_err_stub 101 -isr_no_err_stub 102 -isr_no_err_stub 103 -isr_no_err_stub 104 -isr_no_err_stub 105 -isr_no_err_stub 106 -isr_no_err_stub 107 -isr_no_err_stub 108 -isr_no_err_stub 109 -isr_no_err_stub 110 -isr_no_err_stub 111 -isr_no_err_stub 112 -isr_no_err_stub 113 -isr_no_err_stub 114 -isr_no_err_stub 115 -isr_no_err_stub 116 -isr_no_err_stub 117 -isr_no_err_stub 118 -isr_no_err_stub 119 -isr_no_err_stub 120 -isr_no_err_stub 121 -isr_no_err_stub 122 -isr_no_err_stub 123 -isr_no_err_stub 124 -isr_no_err_stub 125 -isr_no_err_stub 126 -isr_no_err_stub 127 -isr_no_err_stub 128 -isr_no_err_stub 129 -isr_no_err_stub 130 -isr_no_err_stub 131 -isr_no_err_stub 132 -isr_no_err_stub 133 -isr_no_err_stub 134 -isr_no_err_stub 135 -isr_no_err_stub 136 -isr_no_err_stub 137 -isr_no_err_stub 138 -isr_no_err_stub 139 -isr_no_err_stub 140 -isr_no_err_stub 141 -isr_no_err_stub 142 -isr_no_err_stub 143 -isr_no_err_stub 144 -isr_no_err_stub 145 -isr_no_err_stub 146 -isr_no_err_stub 147 -isr_no_err_stub 148 -isr_no_err_stub 149 -isr_no_err_stub 150 -isr_no_err_stub 151 -isr_no_err_stub 152 -isr_no_err_stub 153 -isr_no_err_stub 154 -isr_no_err_stub 155 -isr_no_err_stub 156 -isr_no_err_stub 157 -isr_no_err_stub 158 -isr_no_err_stub 159 -isr_no_err_stub 160 -isr_no_err_stub 161 -isr_no_err_stub 162 -isr_no_err_stub 163 -isr_no_err_stub 164 -isr_no_err_stub 165 -isr_no_err_stub 166 -isr_no_err_stub 167 -isr_no_err_stub 168 -isr_no_err_stub 169 -isr_no_err_stub 170 -isr_no_err_stub 171 -isr_no_err_stub 172 -isr_no_err_stub 173 -isr_no_err_stub 174 -isr_no_err_stub 175 -isr_no_err_stub 176 -isr_no_err_stub 177 -isr_no_err_stub 178 -isr_no_err_stub 179 -isr_no_err_stub 180 -isr_no_err_stub 181 -isr_no_err_stub 182 -isr_no_err_stub 183 -isr_no_err_stub 184 -isr_no_err_stub 185 -isr_no_err_stub 186 -isr_no_err_stub 187 -isr_no_err_stub 188 -isr_no_err_stub 189 -isr_no_err_stub 190 -isr_no_err_stub 191 -isr_no_err_stub 192 -isr_no_err_stub 193 -isr_no_err_stub 194 -isr_no_err_stub 195 -isr_no_err_stub 196 -isr_no_err_stub 197 -isr_no_err_stub 198 -isr_no_err_stub 199 -isr_no_err_stub 200 -isr_no_err_stub 201 -isr_no_err_stub 202 -isr_no_err_stub 203 -isr_no_err_stub 204 -isr_no_err_stub 205 -isr_no_err_stub 206 -isr_no_err_stub 207 -isr_no_err_stub 208 -isr_no_err_stub 209 -isr_no_err_stub 210 -isr_no_err_stub 211 -isr_no_err_stub 212 -isr_no_err_stub 213 -isr_no_err_stub 214 -isr_no_err_stub 215 -isr_no_err_stub 216 -isr_no_err_stub 217 -isr_no_err_stub 218 -isr_no_err_stub 219 -isr_no_err_stub 220 -isr_no_err_stub 221 -isr_no_err_stub 222 -isr_no_err_stub 223 -isr_no_err_stub 224 -isr_no_err_stub 225 -isr_no_err_stub 226 -isr_no_err_stub 227 -isr_no_err_stub 228 -isr_no_err_stub 229 -isr_no_err_stub 230 -isr_no_err_stub 231 -isr_no_err_stub 232 -isr_no_err_stub 233 -isr_no_err_stub 234 -isr_no_err_stub 235 -isr_no_err_stub 236 -isr_no_err_stub 237 -isr_no_err_stub 238 -isr_no_err_stub 239 -isr_no_err_stub 240 -isr_no_err_stub 241 -isr_no_err_stub 242 -isr_no_err_stub 243 -isr_no_err_stub 244 -isr_no_err_stub 245 -isr_no_err_stub 246 -isr_no_err_stub 247 -isr_no_err_stub 248 -isr_no_err_stub 249 -isr_no_err_stub 250 -isr_no_err_stub 251 -isr_no_err_stub 252 -isr_no_err_stub 253 -isr_no_err_stub 254 -isr_no_err_stub 255 - -global isr_stub_table -isr_stub_table: -%assign i 0 -%rep 256 - dq isr_stub_%+i ; use DQ instead if targeting 64-bit -%assign i i+1 -%endrep \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c deleted file mode 100644 index 529c49d..0000000 --- a/kernel/src/arch/x86_64/idt.c +++ /dev/null @@ -1,94 +0,0 @@ -// #include "sys/log.h" -#include "arch/x86_64/smp.h" -#include "dev/ioapic.h" -#include "dev/lapic.h" -#include "mm/vmm.h" -#include "sys/errhnd/panic.h" -#include -#include -#include -#include - -__attribute__((aligned(0x10))) static idt_entry_t idt[256]; - -static idtr_t idtr; -static int vectors[256]; -extern void *isr_stub_table[]; -idt_irq_handler_t irq_handler_table[256 - 32]; - -void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) { - idt_entry_t *descriptor = &idt[vector]; - - descriptor->isr_low = (uint64_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x28; - descriptor->ist = 0; - descriptor->attributes = flags; - descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; - descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; - descriptor->reserved = 0; -} - -void idt_register_irq(uint8_t vector, void *isr) { - if (vector <= 14) - ioapic_redirect_irq(bootstrap_lapic_id, vector + 32, vector, false); - - irq_handler_table[vector] = isr; - vectors[vector <= 14 ? vector + 32 : vector] = IDT_VT_IRQ; -} - -void idt_init() { - idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - - for (uint16_t vector = 0; vector < 32; vector++) { - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = IDT_VT_EXCEPTION; - } - - for (uint16_t vector = 32; vector < 256; vector++) { - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = IDT_VT_UNDEFINED; - } - - // Do not use the legacy PIC. - // pic_init(); - // pic_unmask_irq(1); - // pic_unmask_irq(8); - - __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT - __asm__ volatile("sti"); // set the interrupt flag - - log("idt - initialized\n"); -} - -void idt_int_handler(registers_t *regs) { - vmm_load_pagemap(vmm_kernel_pm); - // log("kernel - Interrupt %d\n", regs->int_no); - - if (regs->int_no < 32) { - if (regs->cs == 0x43) { - log("ints - Process \"%s\" (pid: %d) caused a CPU fault: %d (err: %d, IP: %p)\n", - curr_proc->name, curr_proc->pid, regs->int_no, regs->err_code, regs->rip); - - sched_exit(-144); - return; - //asm("cli"); - //while (1) - // asm("hlt"); - } - - panic_ctx("A CPU exception occured.", regs); - } - - int vec = regs->int_no; - if (vec >= 32 && vec < 47) - vec -= 32; - - if (vectors[regs->int_no] == IDT_VT_IRQ) { - idt_irq_handler_t i = irq_handler_table[vec]; - i(regs); - } - - lapic_eoi(); - // pic_ack(regs->int_no - 32); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h deleted file mode 100644 index 3bf8d94..0000000 --- a/kernel/src/arch/x86_64/idt.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include - -// VT = Vector type -#define IDT_VT_UNDEFINED 0 -#define IDT_VT_EXCEPTION 1 -#define IDT_VT_IRQ 2 - -typedef struct { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rdi; - uint64_t rsi; - uint64_t rbp; - uint64_t rbx; - uint64_t rdx; - uint64_t rcx; - uint64_t rax; - uint64_t int_no; - uint64_t err_code; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; -} __attribute__((packed)) registers_t; - -typedef struct stackframe { - struct stackframe *rbp; - uint64_t rip; -} stackframe_t; - -typedef struct { - uint16_t isr_low; // The lower 16 bits of the ISR's address - uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS - // before calling the ISR - uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to - // zero for now - uint8_t attributes; // Type and attributes; see the IDT page - uint16_t - isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address - uint32_t isr_high; // The higher 32 bits of the ISR's address - uint32_t reserved; // Set to zero -} __attribute__((packed)) idt_entry_t; - -typedef struct { - uint16_t limit; - uint64_t base; -} __attribute__((packed)) idtr_t; - -typedef void (*idt_irq_handler_t)(registers_t *regs); - -void idt_register_irq(uint8_t vector, void *isr); -void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags); -void idt_init(void); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/io.c b/kernel/src/arch/x86_64/io.c deleted file mode 100755 index 80b1919..0000000 --- a/kernel/src/arch/x86_64/io.c +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - -#include - -uint8_t inb(uint16_t port) { - uint8_t ret; - __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port) : "memory"); - return ret; -} - -void outb(uint16_t port, uint8_t val) { - __asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory"); -} - -void io_wait(void) { outb(0x80, 0); } \ No newline at end of file diff --git a/kernel/src/arch/x86_64/io.h b/kernel/src/arch/x86_64/io.h deleted file mode 100755 index 3e41421..0000000 --- a/kernel/src/arch/x86_64/io.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -uint8_t inb(uint16_t port); -void outb(uint16_t port, uint8_t val); -void io_wait(void); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/msr.h b/kernel/src/arch/x86_64/msr.h deleted file mode 100644 index 5354f78..0000000 --- a/kernel/src/arch/x86_64/msr.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#define IA32_GS_MSR 0xC0000101 -#define IA32_GS_KERNEL_MSR 0xC0000102 - -static inline void wrmsr(uint64_t msr, uint64_t value) { - uint32_t low = value & 0xFFFFFFFF; - uint32_t high = value >> 32; - asm volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high)); -} - -static inline uint64_t rdmsr(uint64_t msr) { - uint32_t low, high; - asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); - return ((uint64_t)high << 32) | low; -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c deleted file mode 100644 index 2818395..0000000 --- a/kernel/src/arch/x86_64/pit.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "arch/x86_64/idt.h" -#include "sched/sched.h" -#include -#include -#include -#include - -uint32_t tick = 0; - -void pit_handler(registers_t *regs) { - // log("PIT"); - tick++; - schedule(regs); -} - -void pit_init() { - outb(0x43, 0x36); - uint16_t div = (uint16_t)(1193180 / 1000); - outb(0x40, (uint8_t)div); - outb(0x40, (uint8_t)(div >> 8)); -} - -void pit_enable() { idt_register_irq(0, pit_handler); } - -void pit_sleep(uint32_t ms) { - uint64_t start = tick; - while (tick - start < ms) { - __asm__ volatile("nop"); - } -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.h b/kernel/src/arch/x86_64/pit.h deleted file mode 100644 index 92c7bde..0000000 --- a/kernel/src/arch/x86_64/pit.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PIT_H -#define PIT_H - -#include -#include - -extern uint32_t tick; - -void pit_init(); -void pit_sleep(uint32_t ms); -void pit_enable(); - -#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/rtc.c b/kernel/src/arch/x86_64/rtc.c deleted file mode 100644 index 7836045..0000000 --- a/kernel/src/arch/x86_64/rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "rtc.h" -#include "io.h" - -char bcd; - -unsigned char read_register(unsigned char reg) { - __asm__ volatile("cli"); - outb(RTC_COMMAND, reg); - return inb(RTC_DATA); - __asm__ volatile("sti"); -} - -void write_register(unsigned char reg, unsigned char value) { - __asm__ volatile("cli"); - outb(RTC_COMMAND, reg); - outb(RTC_DATA, value); - __asm__ volatile("sti"); -} - -unsigned char bcd2bin(unsigned char in_bcd) { - return (bcd) ? ((in_bcd >> 4) * 10) + (in_bcd & 0x0F) : in_bcd; -} - -int rtc_init() { - __asm__ volatile("cli"); - unsigned char status; - status = read_register(RTC_STATUS); - status |= 0x02; // 24 hour clock - status |= 0x10; // update ended interrupts - status &= ~0x20; // no alarm interrupts - status &= ~0x40; // no periodic interrupt - bcd = !(status & 0x04); // check if data type is BCD - write_register(RTC_STATUS, status); - - outb(0x70, 0x8B); // select register B, and disable NMI - char prev = inb(0x71); // read the current value of register B - outb(0x70, - 0x8B); // set the index again (a read will reset the index to register D) - outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This - // turns on bit 6 of register B - __asm__ volatile("sti"); - return 0; -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/rtc.h b/kernel/src/arch/x86_64/rtc.h deleted file mode 100644 index 51fb46c..0000000 --- a/kernel/src/arch/x86_64/rtc.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __TIME_H -#define __TIME_H - -#define RTC_COMMAND 0x70 -#define RTC_DATA 0x71 -#define RTC_STATUS 0x0B - -#define RTC_SECONDS 0x00 -#define RTC_MINUTES 0x02 -#define RTC_HOURS 0x04 -#define RTC_DAY_OF_WEEK 0x06 -#define RTC_DAY 0x07 -#define RTC_MONTH 0x08 -#define RTC_YEAR 0x09 - -int rtc_init(); - -#endif // __TIME_H__ \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c deleted file mode 100644 index d913504..0000000 --- a/kernel/src/arch/x86_64/smp.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "arch/x86_64/smp.h" -#include "lib/spinlock.h" -#include "limine.h" -#include "sys/log.h" -#include - -__attribute__(( - used, section(".limine_requests"))) static volatile struct limine_mp_request - smp_request = {.id = LIMINE_MP_REQUEST, .revision = 0}; - -uint32_t bootstrap_lapic_id = 0; -uint32_t smp_cpu_count = 0; // Number of processors -spinlock_t smp_lock = {0}; - -uint32_t ctr = 0; - -void smp_entry(struct limine_mp_info *smp_info) { - // spinlock_acquire(&smp_lock); - - log("smp - CPU %d started (LAPIC ID: %d)\n", smp_info->processor_id, - smp_info->lapic_id); - __atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST); - - while (1) - ; - ; - // spinlock_release(&smp_lock); -} - -void smp_init() { - bootstrap_lapic_id = smp_request.response->bsp_lapic_id; - smp_cpu_count = smp_request.response->cpu_count; - - log("smp - detected %d CPUs\n", smp_cpu_count); - - for (uint64_t i = 0; i < smp_cpu_count; i++) { - if (smp_request.response->cpus[i]->lapic_id != bootstrap_lapic_id) { - uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST); - - __atomic_store_n(&smp_request.response->cpus[i]->goto_address, smp_entry, - __ATOMIC_SEQ_CST); - - while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr) - ; - } else { - log("smp - CPU %d is the bootstrap processor (LAPIC ID: %d)\n", i, - smp_request.response->cpus[i]->lapic_id); - } - } - - log("smp - initialized\n"); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.h b/kernel/src/arch/x86_64/smp.h deleted file mode 100644 index b375f5f..0000000 --- a/kernel/src/arch/x86_64/smp.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -extern uint32_t bootstrap_lapic_id; - -void smp_init(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/sse.c b/kernel/src/arch/x86_64/sse.c deleted file mode 100644 index 84339f0..0000000 --- a/kernel/src/arch/x86_64/sse.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -int cpuid_check_bit(int reg, int bit) { - int eax, ebx, ecx, edx; - - // Minimal inline assembly to execute CPUID - __asm__ volatile("cpuid" // Execute CPUID instruction - : "=a"(eax), "=b"(ebx), "=c"(ecx), - "=d"(edx) // Output registers - : "a"(0x1) // Input: EAX = 0x1 (query feature flags) - : // No clobbered registers - ); - - // Check bit 25 of EDX (SSE support) in plain C - if (reg == 0) { - if (edx & (1 << bit)) { - return 1; // SSE is supported - } else { - return 0; // SSE is not supported - } - } else if (reg == 1) { - if (ecx & (1 << bit)) { - return 1; // SSE is supported - } else { - return 0; // SSE is not supported - } - } - - return 0; -} - -void sse_init() { - int sse = cpuid_check_bit(0, 25); - int sse2 = cpuid_check_bit(0, 26); - int sse3 = cpuid_check_bit(1, 0); - int ssse3 = cpuid_check_bit(1, 9); - - if (sse) - log("sse - sse is supported!\n"); - else - log("sse - sse isn't supported!\n"); - - if (sse2) - log("sse - sse2 is supported!\n"); - else - log("sse - sse2 isn't supported!\n"); - - if (sse3) - log("sse - sse3 is supported!\n"); - else - log("sse - sse3 isn't supported!\n"); - - if (ssse3) - log("sse - ssse3 is supported!\n"); - else - log("sse - ssse3 isn't supported!\n"); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/sse.h b/kernel/src/arch/x86_64/sse.h deleted file mode 100755 index b4500fa..0000000 --- a/kernel/src/arch/x86_64/sse.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -int sse_is_supported(); -void sse_init(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscall.asm b/kernel/src/arch/x86_64/syscall.asm deleted file mode 100644 index de88abe..0000000 --- a/kernel/src/arch/x86_64/syscall.asm +++ /dev/null @@ -1,53 +0,0 @@ -bits 64 - -section .text - global syscall_entry - extern syscall_handle - -syscall_entry: - swapgs ; switch - mov [gs:0], rsp - mov rsp, [gs:8] - - push 0 - push 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - - mov rdi, rsp - call syscall_handle - - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax - add rsp, 16 - - mov [gs:8], rsp - mov rsp, [gs:0] - swapgs - o64 sysret diff --git a/kernel/src/arch/x86_64/syscall.c b/kernel/src/arch/x86_64/syscall.c deleted file mode 100644 index 0839c78..0000000 --- a/kernel/src/arch/x86_64/syscall.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include - -extern void syscall_entry(); - -void __x86_64_syscall_init() { - uint64_t efer = rdmsr(IA32_EFER); - efer |= (1 << 0); - wrmsr(IA32_EFER, efer); - uint64_t star = 0; - star |= ((uint64_t)0x28 << 32); // kernel cs - star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x40, 24 for SS=0x38) - wrmsr(IA32_STAR, star); - wrmsr(IA32_LSTAR, (uint64_t)syscall_entry); - wrmsr(IA32_CSTAR, 0x0); - wrmsr(IA32_CSTAR + 1, 0x200); -} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscall.h b/kernel/src/arch/x86_64/syscall.h deleted file mode 100644 index 479d406..0000000 --- a/kernel/src/arch/x86_64/syscall.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#define IA32_EFER 0xC0000080 -#define IA32_STAR 0xC0000081 -#define IA32_LSTAR 0xC0000082 -#define IA32_CSTAR 0xC0000083 -#define IA32_SFMASK 0xC0000084 diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c new file mode 100644 index 0000000..67178c1 --- /dev/null +++ b/kernel/src/boot/limine.c @@ -0,0 +1,30 @@ +#include "deps/limine.h" +#include +#include +#include + +__attribute__((used, section(".limine_requests"))) +static volatile LIMINE_BASE_REVISION(3); + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0 +}; + +__attribute__((used, section(".limine_requests_start"))) +static volatile LIMINE_REQUESTS_START_MARKER; + +__attribute__((used, section(".limine_requests_end"))) +static volatile LIMINE_REQUESTS_END_MARKER; + +bool limine_ensure_baserev() { return LIMINE_BASE_REVISION_SUPPORTED; } + +limine_fb_t *limine_get_fb(int id) { + if (!framebuffer_request.response) + return NULL; + + if (id >= (int32_t)framebuffer_request.response->framebuffer_count) // Limine, WHY putting the FB count as a 64-bit integer??? I never seen someone with 0xFFFFFFFFFFFFFFFF screens + return NULL; + return framebuffer_request.response->framebuffers[id]; +} \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h new file mode 100644 index 0000000..9173039 --- /dev/null +++ b/kernel/src/boot/limine.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +typedef struct limine_framebuffer limine_fb_t; + +// Ensure that the used boot loader supports the kernel's LBP revision +bool limine_ensure_baserev(); + +// Get a framebuffer +limine_fb_t *limine_get_fb(int id); \ No newline at end of file diff --git a/kernel/src/dbg/export.h b/kernel/src/dbg/export.h deleted file mode 100644 index 39b9fa9..0000000 --- a/kernel/src/dbg/export.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -// At Soaplin, we aren't doing module racism based on the license. (Ḭ̸̛̌͋̋̆͛̉͆Í̡̢͚̙̺̦̩͕̮̙̙̳̮͉Į̧̨̙̜͓̪͇̠̪̣̻̰͕̲̲̘̖̦͖͕͎̲̹͖̮̳̻̞̀ ̸̨͕͎̣̥͖͔̳̫̳͚̯̬̙̘͓̹̼̻̼̈̓̉ͅͅs̶̃͛̽͛Í̆͌̆̒̔̈́̎̿͠ÍÌÍ„Í̟͉̠̣̞͎̓̓͒͌̈̀̓͗̋̕͜͠Í̘̟͜ͅÌ̱̩è̸̈́̈́͂̈́ÌÌ̆̆̔͗Í̆̀͑̀̔͆̄͠ÍÍ̛͔̦̲̦̼̹̙̲͖͎̼̆Ì̯̦̞̜Í̧̡e̸̛̛͂̾̒͋̀͂ÌÌšÍÍ̂̋̅̆̋̈̔̈́̀̔̈́̊̓͂͌̋̂͘ÌĮ͕̱̯̲̦͕͖̦̀̀͒͊͊̓͌̃͠Į̢̢̧̯̮̤̫͙͔̲̬̯̗̗͈̬̳̙͙̼͉̩͚̼̮͚̖̰̗̤͓̘̀͜ ̸̈͗͆͌Í̊̽Í̾Í̼̹͇̞̘͇̯̞̣Ì̧̲̳̦̟̱͇̥͈̟ͅÌ̡̧̹̳̫͕̜̬̥̯̬̟̤̖̹̙̩̰y̵̌ÌÌÌ„ÌÌ̡̞̭͔̰͔͔̖̥͕̙̳̯̈́̓ͅÍ͉̦̦͓̥̞Ì̡̢͖͕̰̼͖̲̮͚̲̜̰̱̘̯̤õ̵̑͊̃̃̒ÌÍ Í̆̎̋̿Í̋̉̇̾͆̿̌̃Ì̽̚Í̛̊̀͒̇Ì̓Í̾Ì̈́̓̿Ì̖̠͉̖̺̻̣̜̬̮͓̫͎͖͎̤̪ͅÌ̢̢̗̰͕Í̢͖̖̟͙ÍÌ»u̸̅̒̅̂̑Ì͕̟͉͉͖̰Ì̧͕̞̪̖͙͙,̶Ì̄̆Ì̂̈̊̄͆̽̑̑̊̓̋͘Í̔̉ÌÍŒÌ̢̡̛̲̬̞̘̻̗̩̫̗͓̪̬͚̗̖͕̰̣͙̀̿͜͜ͅÍ̡̯͇̩̭͎̖Ì̧̬̻͖̟̩̙̩͜Ì͓̤ͅ Ì´Í̈́̽̄͌̾̒Í̔̌Ì̛̽͋̓̄̉̆̑̃̕͠ÍÌ̉̔̓̂̽̊͆̽̎Ì̈͑͘͘Í̛̌͑Ì̢͈͚̳̣̮̬̲̲͈̮͓̭̗ͅL̵̙̯̦̬̱̓̒Ị̹̱́Ìi̵ÌÌ›Ì͊̒͑̊͌̽̂̕Í̉͊̈́̌͒̆̕ÌÍÍ͒̉̀ÌÌ‘ÍÌ…Í›Í̢̗̲Į̨̧̨͇̖̥̯͔̙̪̱͓́ͅÌ̦̼̭̬̟̞̩̭͙ͅn̵͆Ì̃̊̒̇̑̑̾̽͊̃͌̔̕̚̕Í̌̈́̈́͛͆̒̀̿̎͒̑̃̈́̈́͂͘͠͠Í̧̛͓̲͂͜u̸̽ÌÌšÍ̈Í̄̀͒Ì̧̛̯̤̲͚͖̯͖͈̠̅̽̋̓̂̑̋̽͒̄̑̇̈́̆̈͛͆̿̈̉͆͗͊̎͂̇̽̋̅͊̀̚s̶Ì͆̀̅̓̓͆͆̕ÌÌ̄͛̃Í̛͑̔̑̒͒Í͋͂̂Ì͋͂ÌÍ—Ì͆͠Ì̗̥͇̖̠͓) - -typedef struct { - const char* name; - uint64_t addr; - uint64_t size; -} kernel_symbol_t; - -#define EXPORT_SYMBOL(sym) \ - static const kernel_symbol_t __ksym_##sym \ - __attribute__((section(".ksyms"), used)) = { \ - .name = #sym, \ - .addr = (uint64_t)&sym, \ - .size = sizeof(sym) \ - } - -extern const kernel_symbol_t __start_ksyms[]; -extern const kernel_symbol_t __stop_ksyms[]; diff --git a/kernel/src/dbg/sym.c b/kernel/src/dbg/sym.c deleted file mode 100644 index 2d03766..0000000 --- a/kernel/src/dbg/sym.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "dbg/sym.h" -#include "exec/elf.h" -#include "limine.h" -#include "sys/errhnd/panic.h" -#include "sys/log.h" -#include -#include - -static Elf64_Sym *__ksym_symtab; -static char *__ksym_strtab; -static int __ksym_symcount = 0; - -__attribute__((used, section(".limine_requests"))) static volatile struct - limine_executable_file_request exec_file_rq = { - .id = LIMINE_EXECUTABLE_FILE_REQUEST, .revision = 3}; - -void ksym_init() { - char *img = exec_file_rq.response->executable_file->address; - Elf64_Ehdr *ehdr = (Elf64_Ehdr *)img; - if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 || - ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) { - panic("kernel - how did i even boot? *starts galaxy brain meme*"); - } - - Elf64_Shdr *shdr = (Elf64_Shdr *)(img + ehdr->e_shoff); - const char *shstrtab = (char *)img + shdr[ehdr->e_shstrndx].sh_offset; - - for (int j = 0; j < ehdr->e_shnum; j++) { - if (shdr[j].sh_type == SHT_SYMTAB) { - __ksym_symtab = (Elf64_Sym *)(img + shdr[j].sh_offset); - __ksym_symcount = shdr[j].sh_size / shdr[j].sh_entsize; - } else if (shdr[j].sh_type == SHT_STRTAB && - strcmp(shstrtab + shdr[j].sh_name, ".strtab") == 0) { - __ksym_strtab = (char *)(img + shdr[j].sh_offset); - } - } - - log("kernel - loaded %d symbols\n", __ksym_symcount); -} - -func *ksym_fromip(uint64_t ip) { - for (int i = 0; i < __ksym_symcount; i++) { - uint64_t value = __ksym_symtab[i].st_value; - uint64_t size = __ksym_symtab[i].st_size; - - if (value <= ip && ip < (value + size)) { - func *f = malloc(sizeof(func)); - f->base = value; - f->ip = ip; - f->name = (__ksym_strtab + __ksym_symtab[i].st_name); - return f; - } - } - - return NULL; -} \ No newline at end of file diff --git a/kernel/src/dbg/sym.h b/kernel/src/dbg/sym.h deleted file mode 100644 index 9419994..0000000 --- a/kernel/src/dbg/sym.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "mm/vmm.h" - -typedef struct func { - uint64_t base; - uint64_t ip; - char *name; -} func; - -void ksym_init(); -func *ksym_fromip(uint64_t ip); \ No newline at end of file diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c deleted file mode 100644 index 5803024..0000000 --- a/kernel/src/dev/ioapic.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "sys/acpi/madt.h" -#include -#include -#include - -void ioapic_init() { - madt_ioapic *ioapic = acpi_madt_ioapic_list[0]; - - uint32_t val = ioapic_read(ioapic, IOAPIC_VER); - uint32_t count = ((val >> 16) & 0xFF); - - if ((ioapic_read(ioapic, 0) >> 24) != ioapic->apic_id) { - return; - } - - for (uint8_t i = 0; i <= count; ++i) { - ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i, 0x00010000 | (32 + i)); - ioapic_write(ioapic, IOAPIC_REDTBL + 2 * i + 1, 0); - } - - log("ioapic - initialized\n"); -} - -void ioapic_write(madt_ioapic *ioapic, uint8_t reg, uint32_t val) { - *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = - reg; - *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)) = val; -} - -uint32_t ioapic_read(madt_ioapic *ioapic, uint8_t reg) { - *((volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_REGSEL)) = - reg; - return *( - (volatile uint32_t *)(HIGHER_HALF(ioapic->apic_addr) + IOAPIC_IOWIN)); -} - -void ioapic_set_entry(madt_ioapic *ioapic, uint8_t idx, uint64_t data) { - ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2), (uint32_t)data); - ioapic_write(ioapic, (uint8_t)(IOAPIC_REDTBL + idx * 2 + 1), - (uint32_t)(data >> 32)); -} - -uint64_t ioapic_gsi_count(madt_ioapic *ioapic) { - return (ioapic_read(ioapic, 1) & 0xff0000) >> 16; -} - -madt_ioapic *ioapic_get_gsi(uint32_t gsi) { - for (uint64_t i = 0; i < acpi_madt_ioapic_length; i++) { - madt_ioapic *ioapic = acpi_madt_ioapic_list[i]; - if (ioapic->gsi_base <= gsi && - ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) - return ioapic; - } - return (madt_ioapic *)0; -} - -void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, - uint16_t flags, bool mask) { - madt_ioapic *ioapic = ioapic_get_gsi(gsi); - - uint64_t redirect = vec; - - if ((flags & (1 << 1)) != 0) { - redirect |= (1 << 13); - } - - if ((flags & (1 << 3)) != 0) { - redirect |= (1 << 15); - } - - if (mask) - redirect |= (1 << 16); - else - redirect &= ~(1 << 16); - - redirect |= (uint64_t)lapic_id << 56; - - uint32_t redir_table = (gsi - ioapic->gsi_base) * 2 + 16; - ioapic_write(ioapic, redir_table, (uint32_t)redirect); - ioapic_write(ioapic, redir_table + 1, (uint32_t)(redirect >> 32)); -} - -void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, - bool mask) { - uint8_t idx = 0; - madt_iso *iso = (madt_iso *)0; - - while (idx < acpi_madt_iso_length) { - iso = acpi_madt_iso_list[idx]; - if (iso->irq_src == irq) { - ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); - return; - } - idx++; - } - - ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); -} - -uint32_t ioapic_get_redirect_irq(uint8_t irq) { - uint8_t idx = 0; - madt_iso *iso; - - while (idx < acpi_madt_iso_length) { - iso = acpi_madt_iso_list[idx]; - if (iso->irq_src == irq) { - return iso->gsi; - } - idx++; - } - - return irq; -} \ No newline at end of file diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h deleted file mode 100644 index 86f7c6f..0000000 --- a/kernel/src/dev/ioapic.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#define IOAPIC_REGSEL 0x0 -#define IOAPIC_IOWIN 0x10 - -#define IOAPIC_ID 0x0 -#define IOAPIC_VER 0x01 -#define IOAPIC_ARB 0x02 -#define IOAPIC_REDTBL 0x10 - -void ioapic_write(madt_ioapic *ioapic, uint8_t reg, uint32_t val); -uint32_t ioapic_read(madt_ioapic *ioapic, uint8_t reg); - -void ioapic_redirect_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, - bool mask); -uint32_t ioapic_get_redirect_irq(uint8_t irq); - -void ioapic_set_entry(madt_ioapic *ioapic, uint8_t idx, uint64_t data); - -void ioapic_init(); \ No newline at end of file diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c deleted file mode 100644 index b83c3c4..0000000 --- a/kernel/src/dev/lapic.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "mm/pmm.h" -#include -#include - -uint64_t apic_ticks = 0; - -void lapic_init() { - lapic_write(0xf0, 0x1ff); - log("lapic - initialized\n"); -} - -void lapic_stop_timer() { - // We do this to avoid overlapping oneshots - lapic_write(LAPIC_TIMER_INITCNT, 0); - lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); -} - -void lapic_oneshot(uint8_t vec, uint64_t ms) { - lapic_stop_timer(); - lapic_write(LAPIC_TIMER_DIV, 0); - lapic_write(LAPIC_TIMER_LVT, vec); - lapic_write(LAPIC_TIMER_INITCNT, apic_ticks * ms); -} - -void lapic_calibrate_timer() { - lapic_stop_timer(); - lapic_write(LAPIC_TIMER_DIV, 0); - lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff); - lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF); - // pit_sleep(1); // 1 ms - lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE); - uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT); - apic_ticks = ticks; - lapic_stop_timer(); -} - -void lapic_write(uint32_t reg, uint32_t val) { - *((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg)) = val; -} - -uint32_t lapic_read(uint32_t reg) { - return *((volatile uint32_t *)(HIGHER_HALF(0xfee00000) + reg)); -} - -void lapic_eoi() { lapic_write((uint8_t)0xb0, 0x0); } - -void lapic_ipi(uint32_t id, uint8_t dat) { - lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT); - lapic_write(LAPIC_ICRLO, dat); -} - -void lapic_send_all_int(uint32_t id, uint32_t vec) { - lapic_ipi(id, vec | LAPIC_ICRAIS); -} - -void lapic_send_others_int(uint32_t id, uint32_t vec) { - lapic_ipi(id, vec | LAPIC_ICRAES); -} - -uint32_t lapic_get_id() { return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT; } \ No newline at end of file diff --git a/kernel/src/dev/lapic.h b/kernel/src/dev/lapic.h deleted file mode 100644 index a4b5fed..0000000 --- a/kernel/src/dev/lapic.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include -#include - -#define LAPIC_PPR 0x00a0 - -#define LAPIC_ICRLO 0x0300 -#define LAPIC_ICRHI 0x0310 - -#define LAPIC_ICINI 0x0500 -#define LAPIC_ICSTR 0x0600 - -#define LAPIC_ICEDGE 0x0000 - -#define LAPIC_ICPEND 0x00001000 -#define LAPIC_ICPHYS 0x00000000 -#define LAPIC_ICASSR 0x00004000 -#define LAPIC_ICSHRTHND 0x00000000 -#define LAPIC_ICDESTSHIFT 24 - -#define LAPIC_ICRAIS 0x00080000 -#define LAPIC_ICRAES 0x000c0000 - -// Timer - -#define LAPIC_TIMER_DIV 0x3E0 -#define LAPIC_TIMER_INITCNT 0x380 -#define LAPIC_TIMER_LVT 0x320 -#define LAPIC_TIMER_DISABLE 0x10000 -#define LAPIC_TIMER_CURCNT 0x390 -#define LAPIC_TIMER_PERIODIC 0x20000 - -void lapic_init(); - -void lapic_stop_timer(); -void lapic_oneshot(uint8_t vec, uint64_t ms); -void lapic_calibrate_timer(); - -void lapic_write(uint32_t reg, uint32_t val); -uint32_t lapic_read(uint32_t reg); - -void lapic_eoi(); - -void lapic_ipi(uint32_t id, uint8_t dat); - -void lapic_send_all_int(uint32_t id, uint32_t vec); -void lapic_send_others_int(uint32_t id, uint32_t vec); - -void lapic_init_cpu(uint32_t id); -void lapic_start_cpu(uint32_t id, uint32_t vec); -uint32_t lapic_get_id(); \ No newline at end of file diff --git a/kernel/src/dev/tty.c b/kernel/src/dev/tty.c new file mode 100644 index 0000000..3ddccfb --- /dev/null +++ b/kernel/src/dev/tty.c @@ -0,0 +1,31 @@ + +#include +#include +#include +#include + +struct flanterm_context *tty0_ctx; + +void tty_init() { + limine_fb_t *fb0 = limine_get_fb(0); + + tty0_ctx = flanterm_fb_init( + NULL, + NULL, + fb0->address, fb0->width, fb0->height, fb0->pitch, + fb0->red_mask_size, fb0->red_mask_shift, + fb0->green_mask_size, fb0->green_mask_shift, + fb0->blue_mask_size, fb0->blue_mask_shift, + NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, 0, 1, + 0, 0, + 0 + ); +} + +void tty_write_raw(char *str) { + flanterm_write(tty0_ctx, str, strlen(str)); +} \ No newline at end of file diff --git a/kernel/src/dev/tty.h b/kernel/src/dev/tty.h new file mode 100644 index 0000000..14fc734 --- /dev/null +++ b/kernel/src/dev/tty.h @@ -0,0 +1,4 @@ +#pragma once + +void tty_init(); +void tty_write_raw(char *str); \ No newline at end of file diff --git a/kernel/src/exec/elf.c b/kernel/src/exec/elf.c deleted file mode 100644 index de0a3a4..0000000 --- a/kernel/src/exec/elf.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "exec/exec.h" -#include "mm/memop.h" -#include "mm/pmm.h" -#include "mm/vmm.h" -#include -#include -#include -#include - -program_t *elf_load(char *data, int user) { - Elf64_Ehdr *ehdr = (Elf64_Ehdr *)data; - if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 || - ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) { - log("elf - loading failed: magic is incorrect\n"); - return NULL; - } - - log("elf - e_ident[EI_DATA]: %d\n", ehdr->e_ident[EI_DATA]); - log("elf - e_ident[EI_CLASS]: %d\n", ehdr->e_ident[EI_CLASS]); - log("elf - e_ident[EI_OSABI]: %d\n", ehdr->e_ident[EI_OSABI]); - log("elf - e_machine: %d\n", ehdr->e_machine); - log("elf - e_entry: %p\n", ehdr->e_entry); - log("elf - e_type: %p\n", ehdr->e_type); - log("elf - e_phnum: %p\n", ehdr->e_phnum); - - if (ehdr->e_ident[EI_CLASS] != ELFCLASS64 || ehdr->e_machine != EM_X86_64) { - log("elf - loading failed: is the file built for amd64?\n"); - return NULL; - } - - if (ehdr->e_type != ET_EXEC) { - log("elf - loading failed: ELF type isn't ET_EXEC\n"); - return NULL; - } - - // There's the interesing part - elf_program_t *ret = - malloc(sizeof(elf_program_t)); // Allocate memory for the program. - - pagemap_t *pm = vmm_alloc_pm(); // Allocate a pagemap, so that we can map the - // program inside. - ret->program.pm = pm; - ret->program.entry = ehdr->e_entry; - ret->ehdr = ehdr; - - Elf64_Phdr *phdr = (Elf64_Phdr *)((uint8_t *)data + ehdr->e_phoff); - - for (uint16_t i = 0; i < ehdr->e_phnum; i++) { - log("elf - ELF segment type: %d\n", phdr[i].p_type); - - if (phdr[i].p_type == PT_INTERP) { - log("elf - A PT_INTERP program header was found. This was meant to be a dynamically-linked program, which Soaplin doesn't supports.\n"); - return NULL; - } - - if (phdr[i].p_type != PT_LOAD) - continue; - - uint64_t vaddr_start = ALIGN_DOWN(phdr[i].p_vaddr, PMM_PAGE_SIZE); - uint64_t vaddr_end = - ALIGN_UP(phdr[i].p_vaddr + phdr[i].p_memsz, PMM_PAGE_SIZE); - uint64_t offset = phdr[i].p_offset; - - uint64_t flags = VMM_PRESENT; - if (phdr[i].p_flags & PF_W) - flags |= VMM_WRITABLE; - if (phdr[i].p_flags & PF_X) - flags &= ~VMM_NX; - else - flags |= VMM_NX; - - if (user) - flags |= VMM_USER; - - log("elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset " - "0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx\n", - i, vaddr_start, vaddr_end, offset, phdr[i].p_filesz, phdr[i].p_memsz, - flags); - - uint64_t page_offset = phdr[i].p_vaddr & (PMM_PAGE_SIZE - 1); - - for (uint64_t vaddr = vaddr_start; vaddr < vaddr_end; - vaddr += PMM_PAGE_SIZE) { - uint64_t phys = (uint64_t)pmm_request_page(); - if (!phys) { - log("elf - pmm page alloc failed. out of memory?\n"); - return 0; - } - - if (user) { - log("elf - vmm_map_user(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); - vmm_map_user(pm, vaddr, phys, flags); - } else { - log("elf - vmm_map(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); - vmm_map(pm, vaddr, phys, flags); - } - log("elf - memset(%p, 0, 0x1000)\n", HIGHER_HALF(phys)); - memset((void *)HIGHER_HALF(phys), 0, PMM_PAGE_SIZE); - - uint64_t file_page_offset = offset + (vaddr - vaddr_start); - uint64_t file_data_end = offset + phdr[i].p_filesz; - - if (file_page_offset < file_data_end) { - uint64_t bytes_from_start = vaddr - vaddr_start; - uint64_t page_data_offset = 0; - - if (bytes_from_start == 0 && page_offset > 0) { - page_data_offset = page_offset; - } - - uint64_t copy_offset = file_page_offset; - uint64_t copy_size = PMM_PAGE_SIZE - page_data_offset; - - if (copy_offset + copy_size > file_data_end) { - copy_size = file_data_end - copy_offset; - } - - if (copy_size > 0) { - void *dest = (void *)(HIGHER_HALF(phys) + page_data_offset); - void *src = (uint8_t *)data + copy_offset; - log("elf - memcpy(%p, %p, %d)\n", dest, src, copy_size); - memcpy(dest, src, copy_size); - - // log("elf - copied 0x%llx bytes from ELF file offset 0x%llx to vaddr - // 0x%llx (phys 0x%llx)\n", - // copy_size, copy_offset, vaddr + page_data_offset, phys + - // page_data_offset); - } - } - } - } - - log("elf - loaded ELF program in memory.\n"); - return (program_t *)ret; -} \ No newline at end of file diff --git a/kernel/src/exec/elf.h b/kernel/src/exec/elf.h deleted file mode 100644 index a680291..0000000 --- a/kernel/src/exec/elf.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once - -#include "exec/exec.h" -#include - -// ELF magic. -#define EI_MAG0 0 -#define ELFMAG0 0x7f - -#define EI_MAG1 1 -#define ELFMAG1 'E' - -#define EI_MAG2 2 -#define ELFMAG2 'L' - -#define EI_MAG3 3 -#define ELFMAG3 'F' - -// ELF class -#define EI_CLASS 4 -#define ELFCLASSNONE 0 -#define ELFCLASS32 1 -#define ELFCLASS64 2 - -// Is processor-specific data little-endian or big-endian? -#define EI_DATA 5 -#define ELFDATANONE 0 -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -// ELF version -#define EI_VERSION 6 -#define EV_NONE 0 -#define EV_CURRENT 1 - -// ELF ABI -#define EI_OSABI 7 -#define ELFOSABI_NONE 0 -#define ELFOSABI_SYSV 0 -#define ELFOSABI_HPUX 1 -#define ELFOSABI_NETBSD 2 -#define ELFOSABI_LINUX 3 -#define ELFOSABI_SOLARIS 6 -#define ELFOSABI_IRIX 8 -#define ELFOSABI_FREEBSD 9 -#define ELFOSABI_TRU64 10 -#define ELFOSABI_ARM 97 -#define ELFOSABI_STANDALONE 255 - -// ABI version -#define EI_ABIVERSION 8 - -// Unused bytes. -#define EI_PAD 9 - -// Magic size. -#define EI_NIDENT 16 - -// e_type -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 - -// e_machine (we only included machines supported by Soaplin.) -#define EM_X86_64 62 - -typedef uint64_t Elf64_Addr; -typedef uint64_t Elf64_Off; -typedef uint16_t Elf64_Section; -typedef uint16_t Elf64_Versym; -typedef uint8_t Elf_Byte; -typedef uint16_t Elf64_Half; -typedef int32_t Elf64_Sword; -typedef uint32_t Elf64_Word; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Xword; - -typedef struct { - unsigned char e_ident[EI_NIDENT]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -} Elf64_Ehdr; - -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 - -#define PF_X (1 << 0) -#define PF_W (1 << 1) -#define PF_R (1 << 2) - -typedef struct { - uint32_t p_type; - uint32_t p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - uint64_t p_filesz; - uint64_t p_memsz; - uint64_t p_align; -} Elf64_Phdr; - -typedef struct { - program_t program; - - Elf64_Ehdr *ehdr; -} elf_program_t; - -program_t *elf_load(char *data, int user); - -// Those aren't used for loading, but used by -// the kernel to resolve symbols from an instruction -// pointer. -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 - -typedef struct { - uint32_t st_name; - unsigned char st_info; - unsigned char st_other; - uint16_t st_shndx; - Elf64_Addr st_value; - uint64_t st_size; -} Elf64_Sym; - -typedef struct { - uint32_t sh_name; - uint32_t sh_type; - uint64_t sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - uint64_t sh_size; - uint32_t sh_link; - uint32_t sh_info; - uint64_t sh_addralign; - uint64_t sh_entsize; -} Elf64_Shdr; diff --git a/kernel/src/exec/exec.h b/kernel/src/exec/exec.h deleted file mode 100644 index 2ac1776..0000000 --- a/kernel/src/exec/exec.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -/* - * A program (or a script, if a shebang is found inside), literally. - */ -#include "mm/vmm.h" - -#define EXEC_TYPE_ELF 0 - -typedef struct { - // The path to the program/script that will be executed. - char *path; - - // The pagemap where the program's code is loaded. - pagemap_t *pm; - - // The path to the first instruction. This will be passed to the new process's - // rip register. - uint64_t entry; - - // The program type. Used to get additional, unneeded information out of a - // program - int type; - - // That is what Soaplin needs to know. Executable file loaders are encouraged - // to extend this structure to include info such as the EHDR for the ELF - // loader... -} program_t; \ No newline at end of file diff --git a/kernel/src/font.c b/kernel/src/font.c deleted file mode 100644 index 0c8c3ba..0000000 --- a/kernel/src/font.c +++ /dev/null @@ -1,343 +0,0 @@ -unsigned char VGA8[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, - 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, - 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, - 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, - 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, - 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, - 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, - 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, - 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, - 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, - 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, - 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, - 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, - 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, - 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, - 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, - 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, - 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, - 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, - 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, - 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, - 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, - 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, - 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, - 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, - 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, - 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, - 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, - 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, - 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, - 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, - 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, - 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, - 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, - 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, - 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, - 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, - 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, - 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, - 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, - 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, - 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, - 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, - 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, - 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, - 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, - 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, - 0x18, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, - 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, - 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, - 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, - 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, - 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, - 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, - 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; \ No newline at end of file diff --git a/kernel/src/font.h b/kernel/src/font.h deleted file mode 100755 index 2ab685a..0000000 --- a/kernel/src/font.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -extern unsigned char VGA8[]; \ No newline at end of file diff --git a/kernel/src/fs/hellofs.c b/kernel/src/fs/hellofs.c deleted file mode 100644 index 6addd24..0000000 --- a/kernel/src/fs/hellofs.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "fs/hellofs.h" -#include "fs/vfs.h" -#include -#include -#include - -static int hellofs_read(vnode_t *vn, void *buf, size_t off, size_t size) { - if (!vn || !buf || size <= 0) { - return -1; - } - - const char *hello = "hello"; - const size_t hello_len = 5; // strlen("hello") - char *cbuf = (char *)buf; - size_t bytes_written = 0; - - while (bytes_written < size) { - size_t pos = off % hello_len; // Position within "hello" - size_t remaining = hello_len - pos; // Remaining bytes in current "hello" - size_t to_copy = (size - bytes_written < remaining) ? - (size - bytes_written) : remaining; - - memcpy(cbuf + bytes_written, hello + pos, to_copy); - bytes_written += to_copy; - off += to_copy; - } - - return bytes_written; -} - -vnode_ops_t hellofs_hello_ops = { - .read = hellofs_read, - .lookup = NULL, -}; - -static int hellofs_lookup(vnode_t *vn, const char *name, vnode_t **out) { - if (!vn || !name || !out) { - return -1; - } - - if (strcmp(name, "hello") == 0) { - *out = vfs_create_node("hello", VN_FILE); - if (*out) { - (*out)->ops = &hellofs_hello_ops; - return 0; - } - - return -1; - } else { - *out = NULL; // Not found - return -1; - } -} - -vnode_ops_t hellofs_root_ops = { - .read = NULL, - .lookup = hellofs_lookup, -}; - -static int hellofs_mount(fs_t *fs, vnode_t *mountpoint) { - if (!fs || !mountpoint) { - return -1; - } - - // mountpoint list isn't implemented. - - /*mountpoint_t *mp = (mountpoint_t *)malloc(sizeof(mountpoint_t)); - if (!mp) { - return -1; - } - - memset(mp, 0, sizeof(mountpoint_t)); - strncpy(mp->name, fs->name, sizeof(mp->name) - 1); - mp->fs = fs; - mp->mountpoint = mountpoint;*/ - - // Mounting is essentially just putting the file system's root directory operations - // on the mountpoint vnode. - mountpoint->ops = &hellofs_root_ops; - - return 0; -} - -fs_t *hellofs_init() { - fs_t *fs = (fs_t *)malloc(sizeof(fs_t)); - if (!fs) { - return NULL; - } - - memset(fs, 0, sizeof(fs_t)); - strncpy(fs->name, "hellofs", sizeof(fs->name) - 1); - - fs->mount = hellofs_mount; - fs->root = vfs_create_node("/", VN_DIR); - if (!fs->root) { - free(fs); - return NULL; - } - - return fs; -} \ No newline at end of file diff --git a/kernel/src/fs/hellofs.h b/kernel/src/fs/hellofs.h deleted file mode 100644 index 5e35108..0000000 --- a/kernel/src/fs/hellofs.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -fs_t *hellofs_init(void); \ No newline at end of file diff --git a/kernel/src/fs/vfs.c b/kernel/src/fs/vfs.c deleted file mode 100644 index c8e966e..0000000 --- a/kernel/src/fs/vfs.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "fs/vfs.h" -#include "lib/string.h" -#include "mm/liballoc/liballoc.h" -#include "mm/memop.h" -#include "sys/errhnd/panic.h" - -vnode_t *root = NULL; - -void vfs_init() { - root = vfs_create_node("/", VN_DIR); - if (!root) { - panic("vfs - failed to create root node"); - } - root->parent = root; // Root's parent is itself -} - -// Not worth adding to the header, since it should only lookup -// for files/directories in dir, without going deeper. -int vfs_lookup(vnode_t *dir, const char *name, vnode_t **out) { - if (!dir || !name) - return -1; - - if (dir->ops && dir->ops->lookup) { - return dir->ops->lookup(dir, name, out); - } - return -1; -} - -int vfs_open(vnode_t *curdir, const char *path, vnode_t **out) { - if (strcmp(path, ".") == 0) { - *out = curdir; - return 0; - } - if (strcmp(path, "..") == 0) { - *out = curdir->parent; - return 0; - } - - char *path_copy = strdup(path); - if (!path_copy) { - *out = NULL; - return -1; - } - - vnode_t *cur_node = path[0] == '/' ? root : curdir; - char *token = strtok(path_copy, "/"); - - while (token) { - vnode_t *next; - vfs_lookup(cur_node, token, &next); - if (!next) { - free(path_copy); - *out = NULL; - return -1; - } - cur_node = next; - token = strtok(NULL, "/"); - } - - free(path_copy); - *out = cur_node; - return 0; -} - -int vfs_mount(char *path, fs_t *fs) { - if (!fs || !path) { - return -1; - } - - vnode_t *mp; - if (strcmp(path, "/") == 0) { - mp = root; - } else { - vfs_open(root, path, &mp); - } - - if (fs->mount == NULL) - return -1; // why allocating a fs without the capability to mount to a node? lmao - - return fs->mount(fs, mp); -} - -int vfs_unmount(char *path) { - (void)path; - return -1; -} - -int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size) { - if (!vn || !buf || off < 0 || size <= 0) { - return -1; - } - - if (vn->ops && vn->ops->read) { - return vn->ops->read(vn, buf, off, size); - } - return -1; -} - -vnode_t *vfs_create_node(char *name, vnode_type_t type) { - vnode_t *node = (vnode_t *)malloc(sizeof(vnode_t)); - if (!node) { - return NULL; - } - memset(node, 0, sizeof(vnode_t)); - strncpy(node->name, name, sizeof(node->name) - 1); - node->type = type; - node->ops = NULL; - // node->parent = NULL; - // node->child = NULL; - // node->next = NULL; - return node; -} \ No newline at end of file diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h deleted file mode 100644 index 03282b3..0000000 --- a/kernel/src/fs/vfs.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include - -struct vnode; - -#define VN_FILE 1 -#define VN_DIR 2 - -typedef uint32_t vnode_type_t; - -typedef struct vnode_ops { - int (*read)(struct vnode *vn, void *buf, size_t off, size_t size); - int (*lookup)(struct vnode *vn, const char *name, struct vnode **out); -} vnode_ops_t; - -typedef struct vnode { - char name[256]; - vnode_type_t type; - uint32_t refcount; - struct vnode* parent; // If this vnode exists, then it's parent too. - // struct vnode* child; - // struct vnode* next; - - struct vnode_ops *ops; - void *internal; -} vnode_t; - -typedef struct mountpoint { - char name[32]; - struct fs *fs; - vnode_t *mountpoint; -} mountpoint_t; - -typedef struct fs { - char name[32]; - struct vnode *root; - int (*mount)(struct fs *fs, struct vnode *mountpoint); -} fs_t; - -void vfs_init(void); -int vfs_mount(char *path, fs_t *fs); -int vfs_unmount(char *path); -int vfs_open(vnode_t *curdir, const char *path, vnode_t **out); -int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size); -vnode_t *vfs_create_node(char *name, vnode_type_t type); \ No newline at end of file diff --git a/kernel/src/fs/vnodes.md b/kernel/src/fs/vnodes.md deleted file mode 100644 index e33911c..0000000 --- a/kernel/src/fs/vnodes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Soaplin vnodes -... \ No newline at end of file diff --git a/kernel/src/lib/gcc.c b/kernel/src/lib/gcc.c deleted file mode 100644 index 197ca84..0000000 --- a/kernel/src/lib/gcc.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -/*int __eqdf2(double a, double b) { - union { double f; uint64_t i; } ua = { a }, ub = { b }; - return ua.i == ub.i; -} -int __ltdf2(double a, double b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; -} -double __truncxfdf2(double x) { - return (double)x; -} -int __gtdf2(double a, double b) { - if (a > b) return 1; - if (a < b) return -1; - return 0; -}**/ diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h deleted file mode 100644 index bf54abe..0000000 --- a/kernel/src/lib/spinlock.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include - -typedef struct spinlock { - volatile int locked; -} spinlock_t; - -static inline void spinlock_acquire(spinlock_t *lock) { - // uint64_t timeout = 1000000; // Adjust this value based on your needs - - for (;;) { - if (__atomic_exchange_n(&lock->locked, 1, __ATOMIC_ACQUIRE) == 0) { - return; - } - - while (__atomic_load_n(&lock->locked, __ATOMIC_RELAXED)) { - /**if (--timeout == 0) { - // Force unlock after too many attempts - __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); - continue; - }**/ - __asm__ volatile("pause" ::: "memory"); - } - } -} - -static inline void spinlock_release(spinlock_t *lock) { - __atomic_store_n(&lock->locked, 0, __ATOMIC_RELEASE); -} \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index 945bece..a345e2d 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -1,134 +1,8 @@ #include -#include -#include -#include -static char *olds; - -int strlen(const char *str) { - int len = 0; - while (str[len]) - len++; - return len; -} - -int strcmp(const char *s1, const char *s2) { - while (*s1 && *s1 == *s2) { - s1++; - s2++; - } - return *s1 - *s2; -} - -char *strcpy(char *dest, const char *src) { - if (dest == NULL || src == NULL) - return NULL; - - char *temp = dest; - while ((*dest++ = *src++) != '\0') - ; - return temp; -} - -char *strchr(const char *s, int c) { - while (*s++) { - if (*s == c) - return (char *)s; - } - return NULL; -} - -char *strrchr(const char *s, int c) { - const char *p = NULL; - - for (;;) { - if (*s == (char)c) - p = s; - if (*s++ == '\0') - return (char *)p; - } -} - -int oct2bin(unsigned char *str, int size) { - int n = 0; - unsigned char *c = str; - while (size-- > 0) { - n *= 8; - n += *c - '0'; - c++; - } - return n; -} - -char *strdup(const char *str) { - if (str == NULL) - return NULL; - - int len = strlen(str); - char *dup = (char *)malloc(len + 1); - if (dup == NULL) - return NULL; - - strcpy(dup, str); - return dup; -} - -char *strncpy(char *dest, const char *src, size_t n) { - size_t i; - for (i = 0; i < n && src[i] != '\0'; i++) - dest[i] = src[i]; - for (; i < n; i++) - dest[i] = '\0'; - return dest; -} - -#define DICT_LEN 256 - -static int *create_delim_dict(char *delim) { - int *d = (int *)malloc(sizeof(int) * DICT_LEN); - memset((void *)d, 0, sizeof(int) * DICT_LEN); - - int i; - for (i = 0; i < strlen(delim); i++) { - d[delim[i]] = 1; - } - return d; -} - -char *strtok(char *str, char *delim) { - - static char *last, *to_free; - int *deli_dict = create_delim_dict(delim); - - if (!deli_dict) { - return NULL; - } - - if (str) { - last = (char *)malloc(strlen(str) + 1); - if (!last) { - free(deli_dict); - } - to_free = last; - strcpy(last, str); - } - - while (deli_dict[*last] && *last != '\0') { - last++; - } - str = last; - if (*last == '\0') { - free(deli_dict); - free(to_free); - return NULL; - } - while (*last != '\0' && !deli_dict[*last]) { - last++; - } - - *last = '\0'; - last++; - - free(deli_dict); - return str; -} +size_t strlen(char *str) { + size_t i = 0; + while (str[i] != '\0') + i++; + return i; +} \ No newline at end of file diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h index c80bf30..4e6e619 100644 --- a/kernel/src/lib/string.h +++ b/kernel/src/lib/string.h @@ -1,12 +1,5 @@ #pragma once + #include -int strlen(const char *str); -int strcmp(const char *s1, const char *s2); -char *strchr(const char *s, int c); -char *strcpy(char *dest, const char *src); -char *strrchr(const char *s, int c); -int oct2bin(unsigned char *str, int size); -char *strdup(const char *str); -char *strncpy(char *dest, const char *src, size_t n); -char *strtok(char *str, char *delim); \ No newline at end of file +size_t strlen(char *str); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 3bfcb04..b4c2057 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,141 +1,15 @@ -#include "arch/x86_64/pit.h" -#include "arch/x86_64/smp.h" -#include "arch/x86_64/sse.h" -#include "dbg/sym.h" -#include "dev/ioapic.h" -#include "dev/lapic.h" -#include "exec/elf.h" -#include "exec/exec.h" -#include "fs/hellofs.h" -#include "mm/liballoc/liballoc.h" -#include "mm/pmm.h" -#include "mm/vma.h" -#include "mm/vmm.h" -#include "sched/sched.h" -#include "sys/acpi.h" -#include "sys/acpi/madt.h" -#include "sys/syscall.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -__attribute__(( - used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); +void kmain(void) { + tty_init(); -__attribute__(( - used, - section( - ".limine_requests"))) static volatile struct limine_framebuffer_request - framebuffer_request = {.id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0}; + tty_write_raw("Hello, World!\n"); -__attribute__(( - used, - section(".limine_requests"))) static volatile struct limine_module_request - module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0}; - -__attribute__((used, - section(".limine_requests_" - "start"))) static volatile LIMINE_REQUESTS_START_MARKER; - -__attribute__(( - used, - section( - ".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; - -struct limine_framebuffer *fb; -struct flanterm_context *ft_ctx; - -char kstack[8192]; - -void __kmain(void) { - if (framebuffer_request.response != NULL) { - - struct limine_framebuffer *framebuffer = - framebuffer_request.response->framebuffers[0]; - fb = framebuffer; - - ft_ctx = flanterm_fb_init( - NULL, NULL, framebuffer->address, framebuffer->width, - framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size, - framebuffer->red_mask_shift, framebuffer->green_mask_size, - framebuffer->green_mask_shift, framebuffer->blue_mask_size, - framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - VGA8, 8, 16, 0, 0, 0, 0); - } - - printf("\n Soaplin 0.7-sild is booting up your computer...\n\n"); - - gdt_init(&kstack[8192]); - idt_init(); - pmm_init(); - vmm_init(); - - kernel_vma_context = vma_create_context(vmm_kernel_pm); - if (!kernel_vma_context) { - log("kernel - vma ctx creation failed. halting\n"); - asm("cli"); - while (1) - asm("hlt"); - } - - ksym_init(); - func *f = ksym_fromip((uint64_t)__kmain); - if (f) { - log("ksym: found %s at %p\n", f->name, f->ip); - } else { - log("ksym: not found\n"); - } - - acpi_init(); - madt_init(); - ioapic_init(); - lapic_init(); - pit_init(); - smp_init(); - - vfs_init(); - fs_t *hellofs = hellofs_init(); - vfs_mount("/", hellofs); - - vnode_t *vn; - vfs_open(NULL, "/hello", &vn); - if (vn) { - char buf[100]; - vfs_read(vn, buf, 2, sizeof(buf)); - log("Read from /hello: %s\n", buf); - } else { - log("Failed to open /hello\n"); - } - - syscall_init(); - sched_init(); - - // vfs_init(); - - // panic("No working initialization program found. (This is normal due to " - // "Soaplin's current state, so please do not report this as a bug)"); - - program_t *p = elf_load(module_request.response->modules[0]->address, 1); - - - sched_process *proc = - sched_from_program(p); - - log("kernel - Soaplin initialized sucessfully.\n"); - - pit_enable(); - while (1) - ;; + // We're done, just hang... + hcf(); } diff --git a/kernel/src/mm/liballoc/liballoc.c b/kernel/src/mm/liballoc/liballoc.c deleted file mode 100644 index 00d961a..0000000 --- a/kernel/src/mm/liballoc/liballoc.c +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright: Durand Miller -#include - -// very dirty way of disabling logging in liballoc -#define log(...) (void)0 - -#define VERSION "1.1" -#define ALIGNMENT 16ul - -#define ALIGN_TYPE char -#define ALIGN_INFO sizeof(ALIGN_TYPE) * 16 - -#define USE_CASE1 -#define USE_CASE2 -#define USE_CASE3 -#define USE_CASE4 -#define USE_CASE5 - -#define ALIGN(ptr) \ - if (ALIGNMENT > 1) { \ - uintptr_t diff; \ - ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \ - diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ - if (diff != 0) { \ - diff = ALIGNMENT - diff; \ - ptr = (void *)((uintptr_t)ptr + diff); \ - } \ - *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \ - } - -#define UNALIGN(ptr) \ - if (ALIGNMENT > 1) { \ - uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \ - if (diff < (ALIGNMENT + ALIGN_INFO)) { \ - ptr = (void *)((uintptr_t)ptr - diff); \ - } \ - } - -#define LIBALLOC_MAGIC 0xc001c0de -#define LIBALLOC_DEAD 0xdeaddead - -struct liballoc_major { - struct liballoc_major *prev; - struct liballoc_major *next; - unsigned int pages; - unsigned int size; - unsigned int usage; - struct liballoc_minor *first; -}; - -struct liballoc_minor { - struct liballoc_minor *prev; - struct liballoc_minor *next; - struct liballoc_major *block; - unsigned int magic; - unsigned int size; - unsigned int req_size; -}; - -static struct liballoc_major *l_memRoot = NULL; -static struct liballoc_major *l_bestBet = NULL; - -static unsigned int l_pageSize = 4096; -static unsigned int l_pageCount = 16; -static unsigned long long l_allocated = 0; -static unsigned long long l_inuse = 0; - -static long long l_warningCount = 0; -static long long l_errorCount = 0; -static long long l_possibleOverruns = 0; - -static void *liballoc_memset(void *s, int c, size_t n) { - unsigned int i; - for (i = 0; i < n; i++) - ((char *)s)[i] = c; - - return s; -} -static void *liballoc_memcpy(void *s1, const void *s2, size_t n) { - char *cdest; - char *csrc; - unsigned int *ldest = (unsigned int *)s1; - unsigned int *lsrc = (unsigned int *)s2; - - while (n >= sizeof(unsigned int)) { - *ldest++ = *lsrc++; - n -= sizeof(unsigned int); - } - - cdest = (char *)ldest; - csrc = (char *)lsrc; - - while (n > 0) { - *cdest++ = *csrc++; - n -= 1; - } - - return s1; -} - -#if _DEBUG -void liballoc_dump() { -#ifdef _DEBUG - struct liballoc_major *maj = l_memRoot; - struct liballoc_minor *min = NULL; -#endif - - info("------ Memory data ---------------"); - info("System memory allocated: %i bytes", l_allocated); - info("Memory in used (malloc'ed): %i bytes", l_inuse); - info("Warning count: %i", l_warningCount); - info("Error count: %i", l_errorCount); - info("Possible overruns: %i", l_possibleOverruns); - -#ifdef _DEBUG - while (maj != NULL) { - info("%x: total = %i, used = %i", maj, maj->size, maj->usage); - - min = maj->first; - while (min != NULL) { - info(" %x: %i bytes", min, min->size); - min = min->next; - } - - maj = maj->next; - } -#endif -} -#else -void liballoc_dump() { return; } -#endif - -static struct liballoc_major *allocate_new_page(unsigned int size) { - unsigned int st; - struct liballoc_major *maj; - - st = size + sizeof(struct liballoc_major); - st += sizeof(struct liballoc_minor); - - if ((st % l_pageSize) == 0) - st = st / (l_pageSize); - else - st = st / (l_pageSize) + 1; - - if (st < l_pageCount) - st = l_pageCount; - - maj = (struct liballoc_major *)liballoc_alloc(st); - - if (maj == NULL) { - l_warningCount += 1; - log("liballoc - (warning) liballoc_alloc( %i ) return NULL", st); - return NULL; - } - - maj->prev = NULL; - maj->next = NULL; - maj->pages = st; - maj->size = st * l_pageSize; - maj->usage = sizeof(struct liballoc_major); - maj->first = NULL; - - l_allocated += maj->size; - - log("liballoc - Resource allocated %x of %i pages (%i bytes) for %i size.", - maj, st, maj->size, size); - log("liballoc - Total memory usage = %i KB", (int)((l_allocated / (1024)))); - - return maj; -} - -void *PREFIX(malloc)(size_t req_size) { - int startedBet = 0; - unsigned long long bestSize = 0; - void *p = NULL; - uintptr_t diff; - struct liballoc_major *maj; - struct liballoc_minor *min; - struct liballoc_minor *new_min; - unsigned long size = req_size; - - if (ALIGNMENT > 1) { - size += ALIGNMENT + ALIGN_INFO; - } - - liballoc_lock(); - - if (size == 0) { - l_warningCount += 1; - log("liballoc - (warning) alloc( 0 ) called from %x", - __builtin_return_address(0)); - - liballoc_unlock(); - return PREFIX(malloc)(1); - } - - if (l_memRoot == NULL) { - log("liballoc - initialization of liballoc " VERSION ""); - l_memRoot = allocate_new_page(size); - if (l_memRoot == NULL) { - liballoc_unlock(); - log("liballoc - initial l_memRoot initialization failed", p); - return NULL; - } - - log("liballoc - set up first memory major %x", l_memRoot); - } - - log("liballoc - %x PREFIX(malloc)( %i ): ", __builtin_return_address(0), - size); - - maj = l_memRoot; - startedBet = 0; - - if (l_bestBet != NULL) { - bestSize = l_bestBet->size - l_bestBet->usage; - - if (bestSize > (size + sizeof(struct liballoc_minor))) { - maj = l_bestBet; - startedBet = 1; - } - } - - while (maj != NULL) { - diff = maj->size - maj->usage; - - if (bestSize < diff) { - - l_bestBet = maj; - bestSize = diff; - } - -#ifdef USE_CASE1 - - if (diff < (size + sizeof(struct liballoc_minor))) { - log("liballoc - (warning) CASE 1: Insufficient space in block %x", maj); - - if (maj->next != NULL) { - maj = maj->next; - continue; - } - - if (startedBet == 1) { - maj = l_memRoot; - startedBet = 0; - continue; - } - - maj->next = allocate_new_page(size); - if (maj->next == NULL) - break; - maj->next->prev = maj; - maj = maj->next; - } - -#endif - -#ifdef USE_CASE2 - - if (maj->first == NULL) { - maj->first = (struct liballoc_minor *)((uintptr_t)maj + - sizeof(struct liballoc_major)); - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->next = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - - ALIGN(p); - - log("liballoc - (warning) CASE 2: returning %x", p); - liballoc_unlock(); - return p; - } - -#endif - -#ifdef USE_CASE3 - - diff = (uintptr_t)(maj->first); - diff -= (uintptr_t)maj; - diff -= sizeof(struct liballoc_major); - - if (diff >= (size + sizeof(struct liballoc_minor))) { - - maj->first->prev = - (struct liballoc_minor *)((uintptr_t)maj + - sizeof(struct liballoc_major)); - maj->first->prev->next = maj->first; - maj->first = maj->first->prev; - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); - - log("liballoc - (warning) CASE 3: returning %x", p); - liballoc_unlock(); - return p; - } - -#endif - -#ifdef USE_CASE4 - - min = maj->first; - - while (min != NULL) { - - if (min->next == NULL) { - - diff = (uintptr_t)(maj) + maj->size; - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - - if (diff >= (size + sizeof(struct liballoc_minor))) { - - min->next = (struct liballoc_minor *)((uintptr_t)min + - sizeof(struct liballoc_minor) + - min->size); - min->next->prev = min; - min = min->next; - min->next = NULL; - min->magic = LIBALLOC_MAGIC; - min->block = maj; - min->size = size; - min->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void *)((uintptr_t)min + sizeof(struct liballoc_minor)); - ALIGN(p); - - log("liballoc - (warning) CASE 4.1: returning %x", p); - liballoc_unlock(); - return p; - } - } - - if (min->next != NULL) { - - diff = (uintptr_t)(min->next); - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - - if (diff >= (size + sizeof(struct liballoc_minor))) { - - new_min = (struct liballoc_minor *)((uintptr_t)min + - sizeof(struct liballoc_minor) + - min->size); - - new_min->magic = LIBALLOC_MAGIC; - new_min->next = min->next; - new_min->prev = min; - new_min->size = size; - new_min->req_size = req_size; - new_min->block = maj; - min->next->prev = new_min; - min->next = new_min; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void *)((uintptr_t)new_min + sizeof(struct liballoc_minor)); - ALIGN(p); - - log("liballoc - (warning) CASE 4.2: returning %x", p); - liballoc_unlock(); - return p; - } - } - - min = min->next; - } - -#endif - -#ifdef USE_CASE5 - - if (maj->next == NULL) { - log("liballoc - (warning) CASE 5: block full"); - - if (startedBet == 1) { - maj = l_memRoot; - startedBet = 0; - continue; - } - - maj->next = allocate_new_page(size); - if (maj->next == NULL) - break; - maj->next->prev = maj; - } - -#endif - - maj = maj->next; - } - - liballoc_unlock(); - - log("liballoc - (warning) All cases exhausted. No memory available."); - log("liballoc - (warning) PREFIX(malloc)( %i ) returning NULL.", size); - liballoc_dump(); - - return NULL; -} - -void PREFIX(free)(void *ptr) { - struct liballoc_minor *min; - struct liballoc_major *maj; - - if (ptr == NULL) { - l_warningCount += 1; - log("liballoc - (warning) PREFIX(free)( NULL ) called from %x", - __builtin_return_address(0)); - - return; - } - - UNALIGN(ptr); - - liballoc_lock(); - - min = - (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) { - l_errorCount += 1; - - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { - l_possibleOverruns += 1; - log("liballoc - (warning) Possible 1-3 byte overrun for magic %x != %x", - min->magic, LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) { - log("liballoc - multiple PREFIX(free)() attempt on %x from %x.", ptr, - __builtin_return_address(0)); - } else { - log("liballoc - Bad PREFIX(free)( %x ) called from %x", ptr, - __builtin_return_address(0)); - } - - liballoc_unlock(); - return; - } - - log("liballoc - %x PREFIX(free)( %x ): ", __builtin_return_address(0), ptr); - - maj = min->block; - - l_inuse -= min->size; - - maj->usage -= (min->size + sizeof(struct liballoc_minor)); - min->magic = LIBALLOC_DEAD; - - if (min->next != NULL) - min->next->prev = min->prev; - if (min->prev != NULL) - min->prev->next = min->next; - - if (min->prev == NULL) - maj->first = min->next; - - if (maj->first == NULL) { - if (l_memRoot == maj) - l_memRoot = maj->next; - if (l_bestBet == maj) - l_bestBet = NULL; - if (maj->prev != NULL) - maj->prev->next = maj->next; - if (maj->next != NULL) - maj->next->prev = maj->prev; - l_allocated -= maj->size; - - liballoc_free(maj, maj->pages); - } else { - if (l_bestBet != NULL) { - int bestSize = l_bestBet->size - l_bestBet->usage; - int majSize = maj->size - maj->usage; - - if (majSize > bestSize) - l_bestBet = maj; - } - } - - log("liballoc - (warning) OK"); - - liballoc_unlock(); -} - -void *PREFIX(calloc)(size_t nobj, size_t size) { - int real_size; - void *p; - - real_size = nobj * size; - - p = PREFIX(malloc)(real_size); - - liballoc_memset(p, 0, real_size); - - return p; -} - -void *PREFIX(realloc)(void *p, size_t size) { - void *ptr; - struct liballoc_minor *min; - unsigned int real_size; - - if (size == 0) { - PREFIX(free) - (p); - return NULL; - } - - if (p == NULL) - return PREFIX(malloc)(size); - - ptr = p; - UNALIGN(ptr); - - liballoc_lock(); - - min = - (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) { - l_errorCount += 1; - - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || - ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) { - l_possibleOverruns += 1; - log("liballoc - Possible 1-3 byte overrun for magic %x != %x", min->magic, - LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) { - log("liballoc - liballoc: multiple PREFIX(free)() attempt on %x from %x.", - ptr, __builtin_return_address(0)); - } else { - log("liballoc - liballoc: Bad PREFIX(free)( %x ) called from %x", ptr, - __builtin_return_address(0)); - } - - liballoc_unlock(); - return NULL; - } - - real_size = min->req_size; - - if (real_size >= size) { - min->req_size = size; - liballoc_unlock(); - return p; - } - - liballoc_unlock(); - - ptr = PREFIX(malloc)(size); - liballoc_memcpy(ptr, p, real_size); - PREFIX(free) - (p); - - return ptr; -} \ No newline at end of file diff --git a/kernel/src/mm/liballoc/liballoc.h b/kernel/src/mm/liballoc/liballoc.h deleted file mode 100644 index 6b0183a..0000000 --- a/kernel/src/mm/liballoc/liballoc.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright: Durand Miller -#ifndef LIBALLOC_H -#define LIBALLOC_H - -#include -#include -#include - -#define PREFIX(func) func - -#ifdef _DEBUG -void liballoc_dump(); -#endif // _DEBUG - -extern int liballoc_lock(); -extern int liballoc_unlock(); -extern void *liballoc_alloc(size_t); -extern int liballoc_free(void *, size_t); - -extern void *PREFIX(malloc)(size_t); -extern void *PREFIX(realloc)(void *, size_t); -extern void *PREFIX(calloc)(size_t, size_t); -extern void PREFIX(free)(void *); - -#endif // LIBALLOC_H \ No newline at end of file diff --git a/kernel/src/mm/liballoc/liballoc_soaplin.c b/kernel/src/mm/liballoc/liballoc_soaplin.c deleted file mode 100644 index 97a94a4..0000000 --- a/kernel/src/mm/liballoc/liballoc_soaplin.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "mm/liballoc/liballoc.h" -#include "mm/vmm.h" -#include -#include -#include - -extern vma_context_t *kernel_vma_context; - -static spinlock_t liballoc_lock_var = {0}; - -int liballoc_lock() { - spinlock_acquire(&liballoc_lock_var); - return 0; -} - -int liballoc_unlock() { - spinlock_release(&liballoc_lock_var); - return 0; -} - -void *liballoc_alloc(size_t pages) { - return vma_alloc(kernel_vma_context, pages, VMM_PRESENT | VMM_WRITABLE); -} - -int liballoc_free(void *ptr, size_t pages) { - (void)pages; - vma_free(kernel_vma_context, ptr); - return 0; -} - -// void *malloc(size_t s) { return PREFIX(malloc)(s); } -// void *realloc(void *v, size_t s) { return PREFIX(realloc)(v, s); } -// void *calloc(size_t s1, size_t s) { return PREFIX(calloc)(s1, s); } -// void free(void *v) { return PREFIX(free)(v); } \ No newline at end of file diff --git a/kernel/src/mm/memop.c b/kernel/src/mm/memop.c index 0fdff0e..8910891 100644 --- a/kernel/src/mm/memop.c +++ b/kernel/src/mm/memop.c @@ -1,58 +1,65 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - -#include "mm/pmm.h" -#include +#include #include -void *memcpy(void *dest, const void *src, size_t n) { - uint8_t *pdest = (uint8_t *)dest; - const uint8_t *psrc = (const uint8_t *)src; +void *memcpy(void *restrict dest, const void *restrict src, size_t n) { +#if defined(__x86_64__) + long d0, d1, d2; + asm volatile( + "rep ; movsq\n\t movq %4,%%rcx\n\t""rep ; movsb\n\t": "=&c" (d0), + "=&D" (d1), + "=&S" (d2): "0" (n >> 3), + "g" (n & 7), + "1" (dest), + "2" (src): "memory" + ); +#else + uint8_t *restrict pdest = (uint8_t *restrict)dest; + const uint8_t *restrict psrc = (const uint8_t *restrict)src; - for (size_t i = 0; i < n; i++) { - pdest[i] = psrc[i]; - } + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } - return dest; + return dest; +#endif } void *memset(void *s, int c, size_t n) { - uint8_t *p = (uint8_t *)s; + uint8_t *p = (uint8_t *)s; - for (size_t i = 0; i < n; i++) { - p[i] = (uint8_t)c; - } + for (size_t i = 0; i < n; i++) { + p[i] = (uint8_t)c; + } - return s; + return s; } void *memmove(void *dest, const void *src, size_t n) { - uint8_t *pdest = (uint8_t *)dest; - const uint8_t *psrc = (const uint8_t *)src; + uint8_t *pdest = (uint8_t *)dest; + const uint8_t *psrc = (const uint8_t *)src; - if (src > dest) { - for (size_t i = 0; i < n; i++) { - pdest[i] = psrc[i]; + if (src > dest) { + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + } else if (src < dest) { + for (size_t i = n; i > 0; i--) { + pdest[i-1] = psrc[i-1]; + } } - } else if (src < dest) { - for (size_t i = n; i > 0; i--) { - pdest[i - 1] = psrc[i - 1]; - } - } - return dest; + return dest; } int memcmp(const void *s1, const void *s2, size_t n) { - const uint8_t *p1 = (const uint8_t *)s1; - const uint8_t *p2 = (const uint8_t *)s2; + const uint8_t *p1 = (const uint8_t *)s1; + const uint8_t *p2 = (const uint8_t *)s2; - for (size_t i = 0; i < n; i++) { - if (p1[i] != p2[i]) { - return p1[i] < p2[i] ? -1 : 1; + for (size_t i = 0; i < n; i++) { + if (p1[i] != p2[i]) { + return p1[i] < p2[i] ? -1 : 1; + } } - } - return 0; + return 0; } \ No newline at end of file diff --git a/kernel/src/mm/memop.h b/kernel/src/mm/memop.h old mode 100755 new mode 100644 index 7a62f7e..1d75ae1 --- a/kernel/src/mm/memop.h +++ b/kernel/src/mm/memop.h @@ -1,13 +1,8 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. - #pragma once #include -#include -void *memcpy(void *dest, const void *src, size_t n); +void *memcpy(void *restrict dest, const void *restrict src, size_t n); void *memset(void *s, int c, size_t n); void *memmove(void *dest, const void *src, size_t n); int memcmp(const void *s1, const void *s2, size_t n); \ No newline at end of file diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c deleted file mode 100644 index 8dcf73a..0000000 --- a/kernel/src/mm/pmm.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "limine.h" -#include -#include -#include -#include -#include - -pmm_stack_t stack; -struct limine_memmap_response *_memmap; - -uint64_t hhdm_offset = 0x0; - -__attribute__(( - used, section(".limine_requests"))) struct limine_memmap_request mm_req = { - .id = LIMINE_MEMMAP_REQUEST, .revision = 3}; - -__attribute__(( - used, section(".limine_requests"))) struct limine_hhdm_request hhdm_req = { - .id = LIMINE_HHDM_REQUEST, .revision = 3}; - -int pmm_init() { - uint64_t free_pages = 0; - hhdm_offset = hhdm_req.response->offset; - - struct limine_memmap_response *memmap = mm_req.response; - _memmap = memmap; - - // DEBUG("mm", "----- PMM //INFO -----"); - int freemem = 0; - for (uint64_t i = 0; i < memmap->entry_count; i++) { - if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) { - // DEBUG("mm", " - USABLE ENTRY\t\t@ 0x%.16llx, size: 0x%.16llx", - // memmap->entries[i]->base, memmap->entries[i]->length); - free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE); - freemem += memmap->entries[i]->length; - } - } - - uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE); - - for (uint64_t i = 0; i < memmap->entry_count; i++) { - struct limine_memmap_entry *entry = memmap->entries[i]; - if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) { - stack.pages = (uintptr_t *)HIGHER_HALF(entry->base); - entry->length -= array_size; - entry->base += array_size; - // DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages); - break; - } - } - - for (uint64_t i = 0; i < memmap->entry_count; i++) { - struct limine_memmap_entry *entry = memmap->entries[i]; - if (entry->type == LIMINE_MEMMAP_USABLE) { - for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE) { - stack.pages[stack.idx++] = entry->base + j; - } - } - } - - stack.max = stack.idx; - // DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max); - // DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx); - // DEBUG("mm", "--------------------"); - - log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024)); - return 0; -} - -void *pmm_request_page() { - if (stack.idx == 0) { - // ERROR("mm", "No more pages available."); - log("pmm - out of memory.\n"); - asm("cli"); - while (1) { - asm("hlt"); - } - return NULL; - } - - uint64_t page_addr = stack.pages[--stack.idx]; - memset(HIGHER_HALF(page_addr), 0, PMM_PAGE_SIZE); - return (void *)page_addr; -} - -void pmm_free_page(void *ptr) { - if (ptr == NULL) - return; - - if (stack.idx >= stack.max) { - // ERROR("mm", "Stack overflow attempt while freeing a page."); - log("pmm - could not free the page: stack overflow.\n"); - return; - } - - stack.pages[stack.idx++] = (uint64_t)ptr; -} \ No newline at end of file diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h deleted file mode 100644 index 533a457..0000000 --- a/kernel/src/mm/pmm.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef PMM_H -#define PMM_H - -#include -#define PMM_PAGE_SIZE 4096 - -typedef struct pmm_stack { - uintptr_t *pages; - uint64_t idx; - uint64_t max; -} pmm_stack_t; - -extern uint64_t hhdm_offset; - -#define DIV_ROUND_UP(x, y) \ - (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) -#define ALIGN_UP(x, y) (DIV_ROUND_UP(x, y) * (uint64_t)(y)) -#define ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y)) - -#define HIGHER_HALF(ptr) ((void *)((uint64_t)ptr) + hhdm_offset) -#define PHYSICAL(ptr) ((void *)((uint64_t)ptr) - hhdm_offset) - -int pmm_init(); -void *pmm_request_page(); -void pmm_free_page(void *ptr); -void pmm_dump(); - -#endif // PMM_H \ No newline at end of file diff --git a/kernel/src/mm/vma.c b/kernel/src/mm/vma.c deleted file mode 100644 index 3412e92..0000000 --- a/kernel/src/mm/vma.c +++ /dev/null @@ -1,181 +0,0 @@ -// credit to kevin for writing the vma -// go check his projects: https://github.com/kevinalavik - -#include "mm/pmm.h" -#include "mm/vmm.h" -#include -#include -#include - -vma_context_t *kernel_vma_context; - -vma_context_t *vma_create_context(pagemap_t *pagemap) { - log("vma - creating VMA context with pagemap: 0x%.16llx\n", - (uint64_t)pagemap); - - vma_context_t *ctx = (vma_context_t *)HIGHER_HALF(pmm_request_page()); - if (ctx == NULL) { - log("vma - failed to allocate VMA context\n"); - return NULL; - } - log("vma - allocated VMA context at 0x%.16llx\n", (uint64_t)ctx); - memset(ctx, 0, sizeof(vma_context_t)); - log("vma - zeroed out VMA context at 0x%.16llx\n", (uint64_t)ctx); - - ctx->root = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (ctx->root == NULL) { - log("vma - failed to allocate root region\n"); - pmm_free_page((void *)PHYSICAL(ctx)); - return NULL; - } - log("vma - allocated root region at 0x%.16llx\n", (uint64_t)ctx->root); - - ctx->pagemap = pagemap; - ctx->root->start = PMM_PAGE_SIZE; - ctx->root->size = 0; - - log("vma - VMA context created at 0x%.16llx with root region at 0x%.16llx\n", - (uint64_t)ctx, (uint64_t)ctx->root); - return ctx; -} - -void vma_destroy_context(vma_context_t *ctx) { - log("vma - destroying VMA context at 0x%.16llx\n", (uint64_t)ctx); - - if (ctx->root == NULL || ctx->pagemap == NULL) { - log("vma - invalid context or root passed to vma_destroy_context\n"); - return; - } - - vma_region_t *region = ctx->root; - while (region != NULL) { - log("vma - freeing region at 0x%.16llx\n", (uint64_t)region); - vma_region_t *next = region->next; - pmm_free_page((void *)PHYSICAL(region)); - region = next; - } - - pmm_free_page((void *)PHYSICAL(ctx)); - log("vma - destroyed VMA context at 0x%.16llx\n", (uint64_t)ctx); -} - -void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags) { - if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL) { - log("vma - invalid context or root passed to vma_alloc\n"); - return NULL; - } - - vma_region_t *region = ctx->root; - vma_region_t *new_region; - vma_region_t *last_region = ctx->root; - - while (region != NULL) { - if (region->next == NULL || - region->start + region->size < region->next->start) { - new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (new_region == NULL) { - log("vma - failed to allocate new VMA region\n"); - return NULL; - } - - memset(new_region, 0, sizeof(vma_region_t)); - new_region->size = size; - new_region->flags = flags; - new_region->start = region->start + region->size; - new_region->next = region->next; - new_region->prev = region; - region->next = new_region; - - for (uint64_t i = 0; i < size; i++) { - uint64_t page = (uint64_t)pmm_request_page(); - if (page == 0) { - log("vma - failed to allocate physical memory for VMA region\n"); - return NULL; - } - - vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, - new_region->flags); - } - - return (void *)new_region->start; - } - region = region->next; - } - - new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); - if (new_region == NULL) { - log("vma - failed to allocate new VMA region\n"); - return NULL; - } - - memset(new_region, 0, sizeof(vma_region_t)); - - last_region->next = new_region; - new_region->prev = last_region; - new_region->start = last_region->start + last_region->size; - new_region->size = size; - new_region->flags = flags; - new_region->next = NULL; - - for (uint64_t i = 0; i < size; i++) { - uint64_t page = (uint64_t)pmm_request_page(); - if (page == 0) { - log("vma - failed to allocate physical memory for VMA region\n"); - return NULL; - } - - vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, - new_region->flags); - } - - return (void *)new_region->start; -} - -void vma_free(vma_context_t *ctx, void *ptr) { - if (ctx == NULL) { - log("vma - invalid context passed to vma_free\n"); - return; - } - - vma_region_t *region = ctx->root; - while (region != NULL) { - if (region->start == (uint64_t)ptr) { - log("vma - found region to free at 0x%.16llx\n", (uint64_t)region); - break; - } - region = region->next; - } - - if (region == NULL) { - log("vma - unable to find region to free at address 0x%.16llx\n", - (uint64_t)ptr); - return; - } - - vma_region_t *prev = region->prev; - vma_region_t *next = region->next; - - for (uint64_t i = 0; i < region->size; i++) { - uint64_t virt = region->start + i * PMM_PAGE_SIZE; - uint64_t phys = virt_to_phys(vmm_kernel_pm, virt); - - if (phys != 0) { - pmm_free_page((void *)phys); - vmm_unmap(ctx->pagemap, virt); - } - } - - if (prev != NULL) { - prev->next = next; - } - - if (next != NULL) { - next->prev = prev; - } - - if (region == ctx->root) { - ctx->root = next; - } - - pmm_free_page((void *)PHYSICAL(region)); -} diff --git a/kernel/src/mm/vma.h b/kernel/src/mm/vma.h deleted file mode 100644 index d77d22e..0000000 --- a/kernel/src/mm/vma.h +++ /dev/null @@ -1,29 +0,0 @@ -// credit to kevin for writing the vma -// go check his projects: https://github.com/kevinalavik - -#pragma once - -#include -#include -#include - -typedef struct vma_region { - uint64_t start; - uint64_t size; - uint64_t flags; - struct vma_region *next; - struct vma_region *prev; -} vma_region_t; - -typedef struct vma_context { - pagemap_t *pagemap; - vma_region_t *root; -} vma_context_t; - -extern vma_context_t *kernel_vma_context; - -vma_context_t *vma_create_context(pagemap_t *pagemap); -void vma_destroy_context(vma_context_t *ctx); -void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags); -void vma_free(vma_context_t *ctx, void *ptr); -void vma_dump_context(vma_context_t *ctx); \ No newline at end of file diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c deleted file mode 100644 index b724f57..0000000 --- a/kernel/src/mm/vmm.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "mm/vmm.h" -#include "limine.h" -#include "mm/memop.h" -#include "mm/pmm.h" -#include "sys/log.h" -#include "vmm.h" -#include -#include - -__attribute__(( - used, - section( - ".limine_requests"))) static volatile struct limine_paging_mode_request - pmrq = {.id = LIMINE_PAGING_MODE_REQUEST, - .revision = 3, - .mode = LIMINE_PAGING_MODE_X86_64_4LVL}; - -__attribute__((used, section(".limine_requests"))) volatile struct - limine_executable_address_request karq = { - .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, - .revision = 0, -}; - -pagemap_t *vmm_kernel_pm = NULL; -pagemap_t *vmm_current_pm = NULL; -int vmm_kernel_pm_exists = 0; - -pagemap_t *vmm_alloc_pm() { - pagemap_t *pm = (pagemap_t *)HIGHER_HALF((uint64_t)pmm_request_page()); - memset(pm, 0, PMM_PAGE_SIZE); - - pm->toplevel = (uint64_t *)HIGHER_HALF((uint64_t)pmm_request_page()); - memset(pm->toplevel, 0, PMM_PAGE_SIZE); - - if (vmm_kernel_pm_exists) { - for (int i = 256; i < 512; i++) { - pm->toplevel[i] = vmm_kernel_pm->toplevel[i]; - } - } - - return pm; -} - -void vmm_release_pm(pagemap_t *pm) { - memset(pm->toplevel, 0, PMM_PAGE_SIZE); - memset(pm, 0, PMM_PAGE_SIZE); - pmm_free_page(pm->toplevel); - pmm_free_page(pm); -} - -void vmm_sanity_check() { - uint64_t *my_memory = HIGHER_HALF(pmm_request_page()); - *my_memory = 0x40; - - pagemap_t *pm = vmm_alloc_pm(); - vmm_map(pm, 0x1000, (uint64_t)my_memory, VMM_PRESENT | VMM_WRITABLE); - - uint64_t *my_ptr = (uint64_t *)0x1000; - uint64_t ptr_val = 0; - vmm_load_pagemap(pm); - ptr_val = *my_ptr; - vmm_load_pagemap(vmm_kernel_pm); - - if (ptr_val != 0x40) { - log("vmm - sanity check failed. system halted.\n"); - asm("cli"); - while (1) - asm("hlt"); - } -} - -void vmm_init() { - if (pmrq.response->mode != LIMINE_PAGING_MODE_X86_64_4LVL) { - log("vmm - Soaplin only supports 4-level paging!\n"); - asm("cli; hlt;"); - } - vmm_kernel_pm = vmm_alloc_pm(); - vmm_kernel_pm_exists = 1; - - uint64_t kphysaddr = karq.response->physical_base; - uint64_t kvirtaddr = karq.response->virtual_base; - - uint64_t reqs_start = ALIGN_DOWN((uint64_t)reqs_start_ld, PMM_PAGE_SIZE); - uint64_t reqs_end = ALIGN_UP((uint64_t)reqs_end_ld, PMM_PAGE_SIZE); - uint64_t text_start = ALIGN_DOWN((uint64_t)text_start_ld, PMM_PAGE_SIZE); - uint64_t text_end = ALIGN_UP((uint64_t)text_end_ld, PMM_PAGE_SIZE); - uint64_t rodata_start = ALIGN_DOWN((uint64_t)rodata_start_ld, PMM_PAGE_SIZE); - uint64_t rodata_end = ALIGN_UP((uint64_t)rodata_end_ld, PMM_PAGE_SIZE); - uint64_t data_start = ALIGN_DOWN((uint64_t)data_start_ld, PMM_PAGE_SIZE); - uint64_t data_end = ALIGN_UP((uint64_t)data_end_ld, PMM_PAGE_SIZE); - - log("vmm - mapping .requests section...\n"); - for (uint64_t req = reqs_start; req < reqs_end; req += PMM_PAGE_SIZE) { - vmm_map(vmm_kernel_pm, req, req - kvirtaddr + kphysaddr, - VMM_PRESENT | VMM_WRITABLE); - } - - log("vmm - mapping .text section...\n"); - for (uint64_t text = text_start; text < text_end; text += PMM_PAGE_SIZE) { - vmm_map(vmm_kernel_pm, text, text - kvirtaddr + kphysaddr, VMM_PRESENT); - } - - log("vmm - mapping .rodata section...\n"); - for (uint64_t roData = rodata_start; roData < rodata_end; - roData += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, roData, roData - kvirtaddr + kphysaddr, - VMM_PRESENT | VMM_NX); - - log("vmm - mapping .data section...\n"); - for (uint64_t data = data_start; data < data_end; data += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, data, data - kvirtaddr + kphysaddr, - VMM_PRESENT | VMM_WRITABLE | VMM_NX); - - log("vmm - mapping address from 0x0 to 0x100000000...\n"); - for (uint64_t gb4 = 0; gb4 < 0x100000000; gb4 += PMM_PAGE_SIZE) { - //vmm_map(vmm_kernel_pm, gb4, gb4, VMM_PRESENT | VMM_WRITABLE); - vmm_map(vmm_kernel_pm, (uint64_t)HIGHER_HALF(gb4), gb4, - VMM_PRESENT | VMM_WRITABLE); - } - - vmm_load_pagemap(vmm_kernel_pm); - - //vmm_sanity_check(); - log("vmm - initialized!\n"); -} - -void vmm_load_pagemap(pagemap_t *pm) { - if (!pm) - return; - - if (!pm->toplevel) - return; - - vmm_current_pm = pm; - __asm__ volatile("mov %0, %%cr3" : : "r"(PHYSICAL(pm->toplevel)) : "memory"); -} - -static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, - uint64_t flags, bool alloc) { - if (level[entry] & VMM_PRESENT) - return HIGHER_HALF(PTE_GET_ADDR(level[entry])); - if (alloc) { - uint64_t *pml = (uint64_t *)HIGHER_HALF(pmm_request_page()); - memset(pml, 0, PMM_PAGE_SIZE); - level[entry] = (uint64_t)PHYSICAL(pml) | flags; - return pml; - } - return NULL; -} - -uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) { - uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; - uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; - uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; - uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false); - if (!pml3) - return 0; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); - if (!pml2) - return 0; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); - if (!pml1) - return 0; - - return pml1[pml1_entry] & 0x7000000000000FFF; -} - -uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt) { - uint64_t pml4_idx = (virt >> 39) & 0x1FF; - uint64_t pml3_idx = (virt >> 30) & 0x1FF; - uint64_t pml2_idx = (virt >> 21) & 0x1FF; - uint64_t pml1_idx = (virt >> 12) & 0x1FF; - - uint64_t *pml3 = __vmm_get_next_lvl(pagemap->toplevel, pml4_idx, 0, false); - if (!pml3) - return 0; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_idx, 0, false); - if (!pml2) - return 0; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_idx, 0, false); - if (!pml1) - return 0; - - uint64_t phys_addr = pml1[pml1_idx] & 0x000FFFFFFFFFF000; - - return phys_addr; -} - -void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { - uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; - uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; - uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; - uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, - VMM_PRESENT | VMM_WRITABLE, true); - uint64_t *pml2 = - __vmm_get_next_lvl(pml3, pml3_entry, VMM_PRESENT | VMM_WRITABLE, true); - uint64_t *pml1 = - __vmm_get_next_lvl(pml2, pml2_entry, VMM_PRESENT | VMM_WRITABLE, true); - - pml1[pml1_entry] = paddr | flags; -} - -void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, - uint64_t flags) { - uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; - uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; - uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; - uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - - uint64_t *pml3 = - __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags | VMM_WRITABLE, - true); // PML3 / Page Directory Pointer Entry - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags | VMM_WRITABLE, - true); // PML2 / Page Directory Entry - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags | VMM_WRITABLE, - true); // PML1 / Page Table Entry - - pml1[pml1_entry] = paddr | flags; -} - -void vmm_unmap(pagemap_t *pm, uint64_t vaddr) { - uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; - uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; - uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; - - uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false); - if (pml3 == NULL) - return; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); - if (pml2 == NULL) - return; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); - if (pml1 == NULL) - return; - - pml1[pml1_entry] = 0; - - __asm__ volatile("invlpg (%0)" : : "b"(vaddr) : "memory"); -} \ No newline at end of file diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h deleted file mode 100644 index 12566bc..0000000 --- a/kernel/src/mm/vmm.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include - -#define PTE_ADDR_MASK 0x000ffffffffff000 -#define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) -#define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) - -#define VMM_PRESENT (1 << 0) -#define VMM_WRITABLE (1 << 1) -#define VMM_USER (1 << 2) -#define VMM_NX (1ULL << 63) - -typedef char sym[]; - -extern sym reqs_start_ld; -extern sym reqs_end_ld; - -extern sym text_start_ld; -extern sym text_end_ld; - -extern sym rodata_start_ld; -extern sym rodata_end_ld; - -extern sym data_start_ld; -extern sym data_end_ld; - -typedef struct pagemap { - uint64_t *toplevel; -} pagemap_t; - -extern pagemap_t *vmm_kernel_pm; -extern pagemap_t *vmm_current_pm; - -pagemap_t *vmm_alloc_pm(); -void vmm_init(); -void vmm_release_pm(pagemap_t *pm); -void vmm_load_pagemap(pagemap_t *pm); -uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr); -uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt); - -// NOTE: for user mode, please use vmm_map_user instead. -void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); -void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, - uint64_t flags); -void vmm_unmap(pagemap_t *pm, uint64_t vaddr); \ No newline at end of file diff --git a/kernel/src/premain.asm b/kernel/src/premain.asm deleted file mode 100644 index b06f99b..0000000 --- a/kernel/src/premain.asm +++ /dev/null @@ -1,10 +0,0 @@ -bits 64 -section .text - global kmain - extern __kmain - extern kstack - -kmain: - mov rsp, kstack+0x2000 ; supposons 16 KiB de stack - xor rbp, rbp ; Set %ebp to NULL - call __kmain \ No newline at end of file diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c deleted file mode 100644 index 707e8c7..0000000 --- a/kernel/src/sched/sched.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "sched/sched.h" -#include "arch/x86_64/idt.h" -#include "arch/x86_64/msr.h" -#include "mm/memop.h" -#include "mm/pmm.h" -#include "mm/vmm.h" -#include "sys/errhnd/panic.h" -#include "sys/log.h" -#include -#include -#include - -sched_process *proc_list; -sched_process *curr_proc; -int current_pid = 0; -int standby = 0; - -void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap, - uint64_t start, uint64_t size, int user, - uint64_t flags) { - for (uint64_t offset = 0; offset < size; offset += PMM_PAGE_SIZE) { - uint64_t phys = virt_to_phys(src_pagemap, start + offset); - if (phys) { - if (user) - vmm_map_user(dest_pagemap, start + offset, phys, flags); - else - vmm_map(dest_pagemap, start + offset, phys, flags); - } - } -} - -static void __sched_enter_standby() { - standby = 1; - log("sched - As there's nothing " - "to schedule, the scheduler entered standby" - "mode.\n"); -} - -static void __sched_exit_standby() { - standby = 0; - log("sched - The scheduler exited standby mode.\n"); -} - -void sched_init() { - // TODO: It may be good to implement heap memory to save space. - - // We must initialize the process list. - // By default, sched_create will append to this list. - proc_list = malloc(sizeof(sched_process)); - memcpy(proc_list->name, "System\0", 7); - proc_list->pid = -1; - proc_list->type = SCHED_EMPTY; - proc_list->flags = SCHED_KERNEL_PROCESS; - proc_list->pm = vmm_kernel_pm; - - curr_proc = proc_list; - __sched_enter_standby(); -} - -sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, - uint32_t flags) { - - sched_process *proc = malloc(sizeof(sched_process)); - memset(proc, 0, sizeof(sched_process)); - - memcpy(proc->name, name, strlen(name) > 128 ? 128 : strlen(name)); - proc->pid = current_pid; - proc->type = SCHED_RUNNING; - proc->flags = flags; - - // We are about to setup the registers ourself. - // If it's broken, it's a boom in the ass of your computer - // (and a CPU exception) - - proc->pm = pm; - - uint64_t *stack_phys = pmm_request_page(); - uint64_t *kstack_phys = pmm_request_page(); - uint64_t *stack_virt = (uint64_t *)0x40000000; - - proc->kernel_stack = HIGHER_HALF(kstack_phys) + PMM_PAGE_SIZE; - if (flags == SCHED_KERNEL_PROCESS) { - proc->stack_base = HIGHER_HALF(stack_phys); - proc->stack_base_physical = stack_phys; - proc->stack_end = proc->stack_base + PMM_PAGE_SIZE; - } else if (flags == SCHED_USER_PROCESS) { - vmm_map_user(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, - VMM_PRESENT | VMM_WRITABLE | VMM_USER); - proc->stack_base = stack_virt; - proc->stack_base_physical = stack_phys; - proc->stack_end = proc->stack_base + PMM_PAGE_SIZE; - } - proc->regs.rip = (uint64_t)entry_point; - - if (flags == SCHED_KERNEL_PROCESS) { - proc->regs.cs = 0x28; // Run in kernel mode - proc->regs.ss = 0x30; - } else if (flags == SCHED_USER_PROCESS) { - proc->regs.cs = 0x40 | 3; // Run in user mode - proc->regs.ss = 0x38 | 3; - } - proc->regs.rflags = 0x202; // Enable interrupts - proc->regs.rsp = (uint64_t)proc->stack_end; - proc->regs.rbp = 0; - - proc->next = curr_proc->next; - curr_proc->next = proc; - - current_pid++; - - if (flags == SCHED_USER_PROCESS) - map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 1, - VMM_PRESENT | VMM_WRITABLE | VMM_USER); - else - map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 0, - VMM_PRESENT | VMM_WRITABLE); - - if (standby) { - __sched_exit_standby(); - } - - log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, - proc->pid, proc->regs.rip); - return proc; -} - -sched_process *sched_from_program(program_t *prog) { - // D̶̽̃̿ÍÍ̀̑Í̡͖̼̪̩̑ǫ̴͚̘̩̗̠̣̗͇̳̀̅̈͌͆͆ ̸̑͋Í̢̢̯͎̳̟N̷̹͛̋͗ö̴͇̼̖́̀̾̿̾̓̔̌Ì̼t̵̯̘͇̙̬̤̫͚͓̠͔̭̚ͅ ̵͔̲͈̭͛̆̈UÌ·ÍÍ„ÍÍ‘Í̱̇̀̈́̔͠s̴̀̓̎Í̢͇̳̯̬͔̦̗̯̜̆̅̈́̈́̑̾͆͌̆eÌ´Ì‚Í̊̈͋̆̂̌͘͘Ì̛͎̪̩̙͕̖͖̂̚ÍÍ“ ̵̂͒͌͌̈́Í̇Ì̢̢͖̦̬͔̻͇̠̺͑͋̓̔̅̓͂S̴͋͊Ì̋̑Ì̡͇͎̠̯͙̖̲̮͓͂͆̿C̵̈̂Ì̤̲͉̫̜͓͇̙͇̪̥̈́͋̃̿̕H̶͓̠͋͋̎̃Ì̡͉E̶͉̬̞̖̮͚̙͗̔̋͆Ḑ̴̛͎̙̥̱̱͎͊͊͋̈́̆̎̓͑̚̚_̷̈͗Ì͚̯̻̖͈̳̺̖̽͠KÌ´Ì̆̿͂͂̀̂͆̀ÍÌ̮͓̲̠̫͈̔ͅEÌ·Ì’Ì’Ì͆Ì̡̭͔̘̀R̵ÌÍÍ̾̈́̈́̋͗̎̉Í̭̰N̴̰͆̂͛̂̈́̄̊͌̓͆̕͘͠͠Ě̴̀͌̓͑͘Ì̥͙̼̳̩̠͓͕̫͔̘̠̻̓̂̋̌͜L̴̙͓̣̭̙͙͈̺̩̄̈͆͆͒͗͛̈́̎̉̈́͘͘͜͠_̵͌̿͂͊͘̕Ì̭̱͇Í̩̬ͅP̵̡̪̹̀͂̀̋̇̓͘͜R̸Ì̇ÌÍ̭͌͌̋Í̮̼̙͓͕̳̫͜Ở̵̈̈́̊̕̕Į͎̭̱͈̫̮̘͉͔̪̟̺̥́͠ͅC̵͕̱̠̑̽̔̑͠Ì̡̡̭͓̗̜͇̼̳̲͓Ȇ̷̛̈̒̃̊̈́̓̚̚͠Į̦́͜S̴̿͗̀͌͊̽Ì̧̥͇̬̱̠̟͙̳̖͒̃͜SÌ´Ì͉͖͉͎͎̱͑͊̒͆̃͗̂͌̽͑̓Ì͔̙̜̭ͅ ̶̈́̑͆̂Í̼̥̜͙͈̦̲̰̞H̸̩̭̹̘̩̊͗̔̉̓̈́e̷̓̀̅̊ÍÌ̧̩̓̈́͗̇̔̓͛Í͚̮̰̭̘Í͇͈̺͇̻͜ṙ̶̆͠Í̩̜̜̭͗̉͜Ì̡̪͔͙̟̣͉ͅe̷̿͌ÍÍ̃̃͂̾ÍÌŠĮ̡̦̘̰͖̲͉̤̼͈̺̺̦̯̀.̶̽̊̈̕Í͈Í̡͈̟̠͙̘̤͜Ì̧̪ - return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS); -} -void sched_exit(int exit_code) { - log("sched - Process %d exited with code %d!\n", curr_proc->pid, exit_code); - curr_proc->type = SCHED_DIED; - schedule(&curr_proc->regs); -} - -void schedule(registers_t *regs) { - if (standby) { - // log("sched - Sched is in standby.\n"); - return; - } - - if (curr_proc->type != SCHED_DIED) { - memcpy(&curr_proc->regs, regs, sizeof(registers_t)); - } - - if (curr_proc->type == SCHED_DIED) { - sched_process *prev_proc = proc_list; - sched_process *next = curr_proc->next; - if (next == NULL) { - next = proc_list; - } - - if (proc_list == curr_proc) { - goto kill_process; - } - - while (prev_proc->next != curr_proc) { - prev_proc = prev_proc->next; - } - -kill_process: - if (next == NULL) { - next = proc_list; - } - - if (proc_list == curr_proc) { - vmm_release_pm(curr_proc->pm); - pmm_free_page(curr_proc->stack_base_physical); - free(curr_proc); - - __sched_enter_standby(); - return; - } - - prev_proc->next = next; - - vmm_release_pm(curr_proc->pm); - pmm_free_page(curr_proc->stack_base_physical); - free(curr_proc); - - curr_proc = next; - } else { - curr_proc = curr_proc->next; - if (curr_proc == NULL) - curr_proc = proc_list; - } - - if (curr_proc->type == SCHED_RUNNING) { - memcpy(regs, &curr_proc->regs, sizeof(registers_t)); - } else if (curr_proc->type == SCHED_EMPTY) { - memset(regs, 0, sizeof(registers_t)); - regs->cs = 0x28; - regs->ss = 0x30; - regs->rflags = 0x202; - regs->rip = 0; - } else { - panic("sched - Tried to schedule a dead process.\n"); - } - - wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); - // log("sched - proc %d\n", curr_proc->pid); - vmm_load_pagemap(curr_proc->pm); -} \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h deleted file mode 100644 index ee8089a..0000000 --- a/kernel/src/sched/sched.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "arch/x86_64/idt.h" -#include "exec/exec.h" -#include "mm/vmm.h" - -#define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. -#define SCHED_USER_PROCESS \ - 1 // A process that runs in userspace. The code MUST be mapped directly after - // creating the process. - -typedef enum { SCHED_RUNNING, SCHED_DIED, SCHED_EMPTY } sched_proc_type; - -typedef struct _sched_process { - uint64_t *stack_base; - uint64_t *kernel_stack; // Kernel-mode stack used for "syscall" - - char name[128]; - int pid; - int type; - int flags; - - registers_t regs; - pagemap_t *pm; - - uint64_t *stack_end; - uint64_t *stack_base_physical; - - struct _sched_process *next; -} sched_process; - -extern sched_process *curr_proc; -extern sched_process *proc_list; - -// The idle process is ditched in favor of standby mode, -// which activates when there's nothing to run. -// extern sched_process *idle_process; - -void sched_init(); -sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, - uint32_t flags); - -sched_process *sched_from_program(program_t *prog); - -void sched_exit(int exit_code); -void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c deleted file mode 100644 index f284c67..0000000 --- a/kernel/src/sys/acpi.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "limine.h" -#include "mm/pmm.h" -#include "sys/log.h" -#include -#include -#include -#include -#include - -__attribute__(( - used, - section(".limine_requests"))) static volatile struct limine_rsdp_request - rsdp_req = {.revision = 0, .id = LIMINE_RSDP_REQUEST}; - -static int __acpi_uses_xsdt = 0; -static void *__acpi_rsdt_ptr; - -void *acpi_find_table(const char *name) { - if (!__acpi_uses_xsdt) { - acpi_rsdt *rsdt = (acpi_rsdt *)__acpi_rsdt_ptr; - uint32_t entries = (rsdt->sdt.len - sizeof(rsdt->sdt)) / 4; - - for (uint32_t i = 0; i < entries; i++) { - acpi_sdt *sdt = (acpi_sdt *)HIGHER_HALF(*((uint32_t *)rsdt->table + i)); - if (!memcmp(sdt->sign, name, 4)) - return (void *)sdt; - } - return NULL; - } - - acpi_xsdt *xsdt = (acpi_xsdt *)__acpi_rsdt_ptr; - uint32_t entries = (xsdt->sdt.len - sizeof(xsdt->sdt)) / 8; - - for (uint32_t i = 0; i < entries; i++) { - acpi_sdt *sdt = (acpi_sdt *)HIGHER_HALF(*((uint64_t *)xsdt->table + i)); - if (!memcmp(sdt->sign, name, 4)) { - return (void *)sdt; - } - } - - return NULL; -} - -void acpi_init() { - acpi_rsdp *rsdp = (acpi_rsdp *)HIGHER_HALF(rsdp_req.response->address); - - if (memcmp(rsdp->sign, "RSD PTR", 7)) - panic("acpi: Invalid RSDP signature!"); - - if (rsdp->revision != 0) { - __acpi_uses_xsdt = 1; - acpi_xsdp *xsdp = (acpi_xsdp *)rsdp; - __acpi_rsdt_ptr = (void *)HIGHER_HALF(xsdp->xsdt_addr); - return; - } - - __acpi_rsdt_ptr = (void *)HIGHER_HALF(rsdp->rsdt_addr); -} \ No newline at end of file diff --git a/kernel/src/sys/acpi.h b/kernel/src/sys/acpi.h deleted file mode 100644 index 1e47f4a..0000000 --- a/kernel/src/sys/acpi.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include - -#define ACPI_RSDP_SIGNATURE "RSD PTR " -#define ACPI_RSDP_SIGNATURE_LEN 7 - -typedef struct { - char sign[8]; - uint8_t checksum; - char oem_id[6]; - uint8_t revision; - uint32_t rsdt_addr; -} __attribute__((packed)) acpi_rsdp; - -typedef struct { - char sign[8]; - uint8_t checksum; - char oem_id[6]; - uint8_t revision; - uint32_t resv; - - uint32_t length; - uint64_t xsdt_addr; - uint8_t extended_checksum; - uint8_t resv1[3]; -} __attribute__((packed)) acpi_xsdp; - -typedef struct { - char sign[4]; - uint32_t len; - uint8_t revision; - uint8_t checksum; - char oem_id[6]; - char oem_table_id[8]; - uint32_t oem_revision; - uint32_t creator_id; - uint32_t creator_revision; -} __attribute__((packed)) acpi_sdt; - -typedef struct { - acpi_sdt sdt; - char table[]; -} acpi_rsdt; - -typedef struct { - acpi_sdt sdt; - char table[]; -} acpi_xsdt; - -void *acpi_find_table(const char *name); -void acpi_init(); \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.c b/kernel/src/sys/acpi/madt.c deleted file mode 100644 index e73b668..0000000 --- a/kernel/src/sys/acpi/madt.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "sys/acpi.h" -#include -#include -#include -#include - -madt_ioapic *acpi_madt_ioapic_list[256] = {0}; -madt_iso *acpi_madt_iso_list[256] = {0}; - -uint32_t acpi_madt_ioapic_length = 0; -uint32_t acpi_madt_iso_length = 0; - -uint64_t *acpi_lapic_addr = 0; - -void madt_init() { - void *addr = acpi_find_table("APIC"); - if (!addr) - panic("madt: Failed to find MADT table!"); - - acpi_madt *madt = (acpi_madt *)addr; - - uint64_t offset = 0; - int i = 0; - - while (1) { - if (offset > madt->sdt.len - sizeof(acpi_madt)) - break; - - madt_entry *entry = (madt_entry *)(madt->table + offset); - - if (entry->type == 0) - i++; - else if (entry->type == 1) - acpi_madt_ioapic_list[acpi_madt_ioapic_length++] = (madt_ioapic *)entry; - else if (entry->type == 2) - acpi_madt_iso_list[acpi_madt_iso_length++] = (madt_iso *)entry; - else if (entry->type == 5) - acpi_lapic_addr = (uint64_t *)((madt_lapic_addr *)entry)->phys_lapic; - - offset += entry->length; - } -} \ No newline at end of file diff --git a/kernel/src/sys/acpi/madt.h b/kernel/src/sys/acpi/madt.h deleted file mode 100644 index 444c3fd..0000000 --- a/kernel/src/sys/acpi/madt.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "sys/acpi.h" -#include -typedef struct { - acpi_sdt sdt; - - uint32_t lapic_address; - uint32_t flags; - - char table[]; -} acpi_madt; - -typedef struct { - uint8_t type; - uint8_t length; -} madt_entry; - -typedef struct { - madt_entry un; - uint8_t cpu_id; - uint8_t apic_id; - uint32_t flags; -} madt_cpu_lapic; - -typedef struct { - madt_entry un; - uint8_t apic_id; - uint8_t reserved; - uint32_t apic_addr; - uint32_t gsi_base; -} madt_ioapic; - -typedef struct { - madt_entry un; - uint8_t bus_src; - uint8_t irq_src; - uint32_t gsi; - uint16_t flags; -} madt_iso; - -typedef struct { - madt_entry un; - uint16_t reserved; - uint64_t phys_lapic; -} madt_lapic_addr; - -extern madt_ioapic *acpi_madt_ioapic_list[256]; -extern madt_iso *acpi_madt_iso_list[256]; - -extern uint32_t acpi_madt_ioapic_length; -extern uint32_t acpi_madt_iso_length; - -extern uint64_t *acpi_lapic_addr; - -void madt_init(); \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.c b/kernel/src/sys/errhnd/panic.c deleted file mode 100644 index 1a82fd8..0000000 --- a/kernel/src/sys/errhnd/panic.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "sys/errhnd/panic.h" -#include "arch/x86_64/idt.h" -#include "lib/spinlock.h" -#include -#include - -#include "sched/sched.h" - -static registers_t __panic_regdump; - -static void __panic_dump_regs() { - memset(&__panic_regdump, 0, sizeof(registers_t)); - - asm volatile( - // Save general purpose registers - "movq %%r15, %0\n\t" - "movq %%r14, %1\n\t" - "movq %%r13, %2\n\t" - "movq %%r12, %3\n\t" - "movq %%r11, %4\n\t" - "movq %%r10, %5\n\t" - "movq %%r9, %6\n\t" - "movq %%r8, %7\n\t" - "movq %%rdi, %8\n\t" - "movq %%rsi, %9\n\t" - "movq %%rbp, %10\n\t" - "movq %%rbx, %11\n\t" - "movq %%rdx, %12\n\t" - "movq %%rcx, %13\n\t" - "movq %%rax, %14\n\t" - - // The rest of the registers (rip, cs, rflags, rsp, ss) would typically - // be captured in the interrupt/exception handler context and passed in - // We'll zero them out here since we don't have direct access - : "=m"(__panic_regdump.r15), "=m"(__panic_regdump.r14), - "=m"(__panic_regdump.r13), "=m"(__panic_regdump.r12), - "=m"(__panic_regdump.r11), "=m"(__panic_regdump.r10), - "=m"(__panic_regdump.r9), "=m"(__panic_regdump.r8), - "=m"(__panic_regdump.rdi), "=m"(__panic_regdump.rsi), - "=m"(__panic_regdump.rbp), "=m"(__panic_regdump.rbx), - "=m"(__panic_regdump.rdx), "=m"(__panic_regdump.rcx), - "=m"(__panic_regdump.rax) - : - : "memory"); - - // Zero out the registers we can't directly access in this context - __panic_regdump.int_no = 0; - __panic_regdump.err_code = 0; - __panic_regdump.rip = 0; - __panic_regdump.cs = 0; - __panic_regdump.rflags = 0; - __panic_regdump.rsp = 0; - __panic_regdump.ss = 0; -} - -static void __panic_display_page_fault(registers_t *regs) { - if (regs->int_no != 14) // 14 is the page fault interrupt number - return; - - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2)); - - log("-- PAGE FAULT DETAILS --\n"); - log("This appears to be a page fault.\n"); - log("\n"); - log("Faulting Address (CR2): 0x%lx\n", cr2); - log("Error Code: %d\n", regs->err_code); - log("Flags:\n"); - if (!(regs->err_code & (1 << 0))) - log(" - Page Not Present\n"); - else - log(" - Protection Violation\n"); - - if (regs->err_code & (1 << 1)) - log(" - Write Access\n"); - else - log(" - Read Access\n"); - - if (regs->err_code & (1 << 2)) - log(" - User-Mode Access\n"); - else - log(" - Kernel-Mode Access\n"); - - if (regs->err_code & (1 << 3)) - log(" - Reserved Bits Set\n"); - - if (regs->err_code & (1 << 4)) - log(" - Instruction Fetch\n"); - log("\n"); -} - -static void __panic_display_regs(registers_t *regs) { - log("-- REGISTER DUMP --\n"); - log("RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p\n", regs->rdi, - regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); - log("RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p\n", regs->rax, - regs->rbp, regs->rbx, regs->r10, regs->r11, regs->r12); - log("R13: %p, R14: %p, R15: %p\n", regs->r13, regs->r14, regs->r15); - log("RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d\n", - regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no, - regs->err_code); - log("RSP: %p\n", regs->rsp); - log("\n"); - - if (regs->int_no == 14) // If it's a page fault - __panic_display_page_fault(regs); -} - -static void __panic_display_bt(registers_t *regs) { - if (regs->cs == 0x43 || regs->cs == 0x3B) { - log("The backtrace can't be dumped from a userspace process.\n"); - return; // Don't try to backtrace userspace - } - - log("-- BACKTRACE --\n"); - - // First print the current instruction pointer from the interrupt frame - if (regs->rip) { - log("* %p (current)\n", regs->rip); - } - - uint64_t *frame = (uint64_t*)regs->rbp; - if (!frame || (uint64_t)frame < 0xffffffff80000000) { - log("No further stack frames available\n"); - return; - } - - // Frame format in x86_64: - // [rbp] -> previous rbp - // [rbp+8] -> return address - int depth = 0; - while (frame && depth < 16) { // Limit depth to avoid infinite loops - // Validate both frame and return address pointers - uint64_t *ret_addr_ptr = frame + 1; - if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) { - break; - } - - uint64_t ret_addr = *ret_addr_ptr; - if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) { - break; - } - - log("* %p\n", ret_addr); - - uint64_t next_rbp = *frame; - if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) { - break; - } - - frame = (uint64_t*)next_rbp; - depth++; - } - log("\n"); -} - -void __panic_display_ascii_art() { - log(" _ __ _ ___ _ \n"); - log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n"); - log("| ' name, curr_proc->pid); - log("\n"); - } - - if (regs) - __panic_display_regs(regs); - else - log("No register context provided.\n"); - - __panic_display_bt(regs); - - log("System halted: Please restart your computer manually.\n"); - - asm("cli"); - for (;;) - asm("hlt"); -} \ No newline at end of file diff --git a/kernel/src/sys/errhnd/panic.h b/kernel/src/sys/errhnd/panic.h deleted file mode 100644 index 4794b32..0000000 --- a/kernel/src/sys/errhnd/panic.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "arch/x86_64/idt.h" - -typedef struct __panic_backtrace { - struct Idt_StackFrame* rbp; - uint64_t rip; -} __attribute__((packed)) panic_backtrace_t; - -void panic(char *msg); -void panic_ctx(char *msg, registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/gfx/flanterm/.gitignore b/kernel/src/sys/gfx/flanterm/.gitignore deleted file mode 100644 index cc62e43..0000000 --- a/kernel/src/sys/gfx/flanterm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.d -*.o \ No newline at end of file diff --git a/kernel/src/sys/gfx/flanterm/LICENSE b/kernel/src/sys/gfx/flanterm/LICENSE deleted file mode 100644 index b3f6075..0000000 --- a/kernel/src/sys/gfx/flanterm/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (C) 2022-2025 mintsuki and contributors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/kernel/src/sys/gfx/flanterm/README.md b/kernel/src/sys/gfx/flanterm/README.md deleted file mode 100644 index 37cae29..0000000 --- a/kernel/src/sys/gfx/flanterm/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Flanterm - -Flanterm is a fast and reasonably complete terminal emulator with support for -multiple output backends. Included is a fast framebuffer backend. - -### Quick usage - -To quickly set up and use a framebuffer Flanterm instance, it is possible to -use the `flanterm_fb_init()` function as such: -```c -#include -#include - -struct flanterm_context *ft_ctx = flanterm_fb_init( - NULL, - NULL, - framebuffer_ptr, width, height, pitch, - red_mask_size, red_mask_shift, - green_mask_size, green_mask_shift, - blue_mask_size, blue_mask_shift, - NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, 0, 0, 1, - 0, 0, - 0 - ); -``` -Where `framebuffer_ptr, width, height, pitch` and `{red,green,blue}_mask_{size,shift}` -represent the corresponding info about the framebuffer to use for this given instance. - -The meaning of the other arguments can be found in `backends/fb.h`. - -To then print to the terminal instance, simply use the `flanterm_write()` -function on the given instance. For example: -```c -#include - -const char msg[] = "Hello world\n"; - -flanterm_write(ft_ctx, msg, sizeof(msg)); -``` diff --git a/kernel/src/sys/gfx/flanterm/backends/fb.c b/kernel/src/sys/gfx/flanterm/backends/fb.c deleted file mode 100644 index e3bac67..0000000 --- a/kernel/src/sys/gfx/flanterm/backends/fb.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef __cplusplus -#error \ - "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." -#endif - -#ifndef __STDC_VERSION__ -#error "Flanterm must be compiled as C99 or newer." -#endif - -#if defined(_MSC_VER) -#define ALWAYS_INLINE __forceinline -#elif defined(__GNUC__) || defined(__clang__) -#define ALWAYS_INLINE __attribute__((always_inline)) inline -#else -#define ALWAYS_INLINE inline -#endif - -#include -#include -#include - -#define FLANTERM_IN_FLANTERM - -#include "../flanterm.h" -#include "fb.h" - -void *memset(void *, int, size_t); -void *memcpy(void *, const void *, size_t); - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - -#ifndef FLANTERM_FB_BUMP_ALLOC_POOL_SIZE -#define FLANTERM_FB_BUMP_ALLOC_POOL_SIZE 873000 - -#define FLANTERM_FB_WIDTH_LIMIT 1920 -#define FLANTERM_FB_HEIGHT_LIMIT 1200 -#endif - -static uint8_t bump_alloc_pool[FLANTERM_FB_BUMP_ALLOC_POOL_SIZE]; -static size_t bump_alloc_ptr = 0; - -static void *bump_alloc(size_t s) { - static bool base_offset_added = false; - if (!base_offset_added) { - if ((uintptr_t)bump_alloc_pool & 0xf) { - bump_alloc_ptr += 0x10 - ((uintptr_t)bump_alloc_pool & 0xf); - } - base_offset_added = true; - } - - if ((s & 0xf) != 0) { - s += 0x10; - s &= ~(size_t)0xf; - } - - size_t next_ptr = bump_alloc_ptr + s; - if (next_ptr > FLANTERM_FB_BUMP_ALLOC_POOL_SIZE) { - return NULL; - } - void *ret = &bump_alloc_pool[bump_alloc_ptr]; - bump_alloc_ptr = next_ptr; - return ret; -} - -static bool bump_allocated_instance = false; - -#endif - -// Builtin font originally taken from: -// https://github.com/viler-int10h/vga-text-mode-fonts/raw/master/FONTS/PC-OTHER/TOSH-SAT.F16 -static const uint8_t builtin_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xa5, 0xa5, 0x81, - 0x81, 0xa5, 0x99, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0xff, - 0xff, 0xdb, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0x7e, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, - 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x3c, 0x3c, 0xdb, 0xff, 0xff, 0xdb, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x66, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x84, 0x84, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, - 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1e, - 0x0e, 0x1e, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x1c, 0x1e, 0x16, 0x12, - 0x10, 0x10, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x2c, - 0x26, 0x32, 0x3a, 0x2e, 0x26, 0x22, 0x62, 0xe2, 0xc6, 0x0e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, - 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, - 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, - 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, - 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x78, 0x30, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0xfe, 0x60, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, - 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0x7c, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x0c, 0x0c, 0x18, 0x38, - 0x30, 0x60, 0x60, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0x6c, 0x38, 0x30, 0x76, 0xde, 0xcc, 0xcc, 0xde, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, - 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x0c, 0x0c, 0x18, 0x38, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, - 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, - 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, - 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, - 0xde, 0xde, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, - 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xda, - 0x6c, 0x06, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, - 0xd8, 0xcc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, - 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0x60, 0x60, 0x30, 0x38, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1e, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xc0, 0xc0, - 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, - 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc6, - 0xc6, 0xc6, 0xe6, 0xdc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, - 0x70, 0x1c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x30, 0xfe, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x30, 0x30, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, - 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, - 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x18, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, - 0x00, 0x7c, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, - 0x7c, 0x18, 0x0c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0xc0, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x3c, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, - 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, - 0x76, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, - 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, - 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, - 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, - 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x30, 0x78, 0xcc, 0xc0, 0xc0, 0xcc, 0x78, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0xe6, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, - 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, - 0x18, 0xd8, 0x70, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x06, - 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, - 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x00, 0xdc, 0xe6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0x6c, 0x00, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, - 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xc6, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, - 0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc6, 0xcc, 0xd8, 0x30, - 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, - 0x00, 0x30, 0x30, 0x30, 0x78, 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, - 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x06, - 0x06, 0xf6, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf6, 0xf6, 0x06, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, - 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, - 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x37, 0x37, 0x30, 0x30, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0xf7, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x30, 0x30, 0x37, 0x37, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0x36, 0xf7, 0xf7, 0x00, 0x00, 0xf7, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, - 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xd6, 0xdc, 0xc8, 0xc8, 0xdc, 0xd6, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xfe, 0x24, 0x24, 0x24, 0x24, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc2, 0xfe, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc8, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x6c, 0x60, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xfc, 0x98, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x30, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x30, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, - 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x60, 0x30, 0x78, 0xcc, - 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x76, 0xbb, 0x99, 0x99, 0xdd, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x3c, 0x6c, 0xce, 0xd6, 0xd6, 0xe6, 0x6c, 0x78, - 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x60, 0xc0, 0xc0, 0xfe, - 0xc0, 0xc0, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, - 0x30, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, - 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c, 0x00, 0x00, - 0x00, 0xd8, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x0c, 0x18, 0x30, 0x60, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; - -static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx, - uint32_t colour) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t r = (colour >> 16) & 0xff; - uint32_t g = (colour >> 8) & 0xff; - uint32_t b = colour & 0xff; - return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) | - (b << ctx->blue_mask_shift); -} - -static void flanterm_fb_save_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->saved_state_text_fg = ctx->text_fg; - ctx->saved_state_text_bg = ctx->text_bg; - ctx->saved_state_cursor_x = ctx->cursor_x; - ctx->saved_state_cursor_y = ctx->cursor_y; -} - -static void flanterm_fb_restore_state(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - ctx->text_fg = ctx->saved_state_text_fg; - ctx->text_bg = ctx->saved_state_text_bg; - ctx->cursor_x = ctx->saved_state_cursor_x; - ctx->cursor_y = ctx->saved_state_cursor_y; -} - -static void flanterm_fb_swap_palette(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - uint32_t tmp = ctx->text_bg; - ctx->text_bg = ctx->text_fg; - ctx->text_fg = tmp; -} - -static void plot_char_scaled_canvas(struct flanterm_context *_ctx, - struct flanterm_fb_char *c, size_t x, - size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = - ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } - } -} - -static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, - struct flanterm_fb_char *c, size_t x, - size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - uint8_t fy = gy / ctx->font_scale_y; - volatile uint32_t *fb_line = - ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (fy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - for (size_t i = 0; i < ctx->font_scale_x; i++) { - size_t gx = ctx->font_scale_x * fx + i; - fb_line[gx] = *glyph_pointer ? fg : bg; - } - glyph_pointer++; - } - } -} - -static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, - struct flanterm_fb_char *c, size_t x, - size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = - ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - uint32_t bg = c->bg == 0xffffffff ? canvas_line[fx] : c->bg; - uint32_t fg = c->fg == 0xffffffff ? canvas_line[fx] : c->fg; - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } - } -} - -static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, - struct flanterm_fb_char *c, size_t x, - size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - uint32_t default_bg = ctx->default_bg; - - uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg; - uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg; - - x = ctx->offset_x + x * ctx->glyph_width; - y = ctx->offset_y + y * ctx->glyph_height; - - bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; - // naming: fx,fy for font coordinates, gx,gy for glyph coordinates - for (size_t gy = 0; gy < ctx->glyph_height; gy++) { - volatile uint32_t *fb_line = - ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); - bool *glyph_pointer = glyph + (gy * ctx->font_width); - for (size_t fx = 0; fx < ctx->font_width; fx++) { - fb_line[fx] = *(glyph_pointer++) ? fg : bg; - } - } -} - -static inline bool compare_char(struct flanterm_fb_char *a, - struct flanterm_fb_char *b) { - return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg); -} - -static void push_to_queue(struct flanterm_context *_ctx, - struct flanterm_fb_char *c, size_t x, size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols || y >= _ctx->rows) { - return; - } - - size_t i = y * _ctx->cols + x; - - struct flanterm_fb_queue_item *q = ctx->map[i]; - - if (q == NULL) { - if (compare_char(&ctx->grid[i], c)) { - return; - } - q = &ctx->queue[ctx->queue_i++]; - q->x = x; - q->y = y; - ctx->map[i] = q; - } - - q->c = *c; -} - -static void flanterm_fb_revscroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - for (size_t i = (_ctx->scroll_bottom_margin - 1) * _ctx->cols - 1; - i >= _ctx->scroll_top_margin * _ctx->cols; i--) { - if (i == (size_t)-1) { - break; - } - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols, - (i + _ctx->cols) / _ctx->cols); - } - - // Clear the first line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_top_margin); - } -} - -static void flanterm_fb_scroll(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols; - i < _ctx->scroll_bottom_margin * _ctx->cols; i++) { - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols, - (i - _ctx->cols) / _ctx->cols); - } - - // Clear the last line of the screen. - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i, _ctx->scroll_bottom_margin - 1); - } -} - -static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - struct flanterm_fb_char empty; - empty.c = ' '; - empty.fg = ctx->text_fg; - empty.bg = ctx->text_bg; - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - push_to_queue(_ctx, &empty, i % _ctx->cols, i / _ctx->cols); - } - - if (move) { - ctx->cursor_x = 0; - ctx->cursor_y = 0; - } -} - -static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, - size_t y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (x >= _ctx->cols) { - if ((int)x < 0) { - x = 0; - } else { - x = _ctx->cols - 1; - } - } - if (y >= _ctx->rows) { - if ((int)y < 0) { - y = 0; - } else { - y = _ctx->rows - 1; - } - } - ctx->cursor_x = x; - ctx->cursor_y = y; -} - -static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, - size_t *y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - *x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x; - *y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y; -} - -static void flanterm_fb_move_character(struct flanterm_context *_ctx, - size_t new_x, size_t new_y, size_t old_x, - size_t old_y) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (old_x >= _ctx->cols || old_y >= _ctx->rows || new_x >= _ctx->cols || - new_y >= _ctx->rows) { - return; - } - - size_t i = old_x + old_y * _ctx->cols; - - struct flanterm_fb_char *c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = &q->c; - } else { - c = &ctx->grid[i]; - } - - push_to_queue(_ctx, c, new_x, new_y); -} - -static void flanterm_fb_set_text_fg(struct flanterm_context *_ctx, size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->ansi_colours[fg]; -} - -static void flanterm_fb_set_text_bg(struct flanterm_context *_ctx, size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->ansi_colours[bg]; -} - -static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, - size_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->ansi_bright_colours[fg]; -} - -static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, - size_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->ansi_bright_colours[bg]; -} - -static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, - uint32_t fg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = convert_colour(_ctx, fg); -} - -static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, - uint32_t bg) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = convert_colour(_ctx, bg); -} - -static void flanterm_fb_set_text_fg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->default_fg; -} - -static void flanterm_fb_set_text_bg_default(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = 0xffffffff; -} - -static void -flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_fg = ctx->default_fg_bright; -} - -static void -flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - ctx->text_bg = ctx->default_bg_bright; -} - -static void draw_cursor(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (ctx->cursor_x >= _ctx->cols || ctx->cursor_y >= _ctx->rows) { - return; - } - - size_t i = ctx->cursor_x + ctx->cursor_y * _ctx->cols; - - struct flanterm_fb_char c; - struct flanterm_fb_queue_item *q = ctx->map[i]; - if (q != NULL) { - c = q->c; - } else { - c = ctx->grid[i]; - } - uint32_t tmp = c.fg; - c.fg = c.bg; - c.bg = tmp; - ctx->plot_char(_ctx, &c, ctx->cursor_x, ctx->cursor_y); - if (q != NULL) { - ctx->grid[i] = q->c; - ctx->map[i] = NULL; - } -} - -static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); - } - - for (size_t i = 0; i < ctx->queue_i; i++) { - struct flanterm_fb_queue_item *q = &ctx->queue[i]; - size_t offset = q->y * _ctx->cols + q->x; - if (ctx->map[offset] == NULL) { - continue; - } - ctx->plot_char(_ctx, &q->c, q->x, q->y); - ctx->grid[offset] = q->c; - ctx->map[offset] = NULL; - } - - if ((ctx->old_cursor_x != ctx->cursor_x || - ctx->old_cursor_y != ctx->cursor_y) || - _ctx->cursor_enabled == false) { - if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) { - ctx->plot_char( - _ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols], - ctx->old_cursor_x, ctx->old_cursor_y); - } - } - - ctx->old_cursor_x = ctx->cursor_x; - ctx->old_cursor_y = ctx->cursor_y; - - ctx->queue_i = 0; -} - -static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (ctx->cursor_x >= _ctx->cols && - (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || - _ctx->scroll_enabled)) { - ctx->cursor_x = 0; - ctx->cursor_y++; - if (ctx->cursor_y == _ctx->scroll_bottom_margin) { - ctx->cursor_y--; - flanterm_fb_scroll(_ctx); - } - if (ctx->cursor_y >= _ctx->cols) { - ctx->cursor_y = _ctx->cols - 1; - } - } - - struct flanterm_fb_char ch; - ch.c = c; - ch.fg = ctx->text_fg; - ch.bg = ctx->text_bg; - push_to_queue(_ctx, &ch, ctx->cursor_x++, ctx->cursor_y); -} - -static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - uint32_t default_bg = ctx->default_bg; - - for (size_t y = 0; y < ctx->height; y++) { - for (size_t x = 0; x < ctx->width; x++) { - if (ctx->canvas != NULL) { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = - ctx->canvas[y * ctx->width + x]; - } else { - ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg; - } - } - } - - for (size_t i = 0; i < (size_t)_ctx->rows * _ctx->cols; i++) { - size_t x = i % _ctx->cols; - size_t y = i / _ctx->cols; - - ctx->plot_char(_ctx, &ctx->grid[i], x, y); - } - - if (_ctx->cursor_enabled) { - draw_cursor(_ctx); - } -} - -static void flanterm_fb_deinit(struct flanterm_context *_ctx, - void (*_free)(void *, size_t)) { - struct flanterm_fb_context *ctx = (void *)_ctx; - - if (_free == NULL) { -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - bump_alloc_ptr = 0; - bump_allocated_instance = false; - } -#endif - return; - } - - _free(ctx->font_bits, ctx->font_bits_size); - _free(ctx->font_bool, ctx->font_bool_size); - _free(ctx->grid, ctx->grid_size); - _free(ctx->queue, ctx->queue_size); - _free(ctx->map, ctx->map_size); - - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } - - _free(ctx, sizeof(struct flanterm_fb_context)); -} - -struct flanterm_context *flanterm_fb_init( - void *(*_malloc)(size_t), void (*_free)(void *, size_t), - uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size, - uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, uint32_t *ansi_colours, uint32_t *ansi_bright_colours, - uint32_t *default_bg, uint32_t *default_fg, uint32_t *default_bg_bright, - uint32_t *default_fg_bright, void *font, size_t font_width, - size_t font_height, size_t font_spacing, size_t font_scale_x, - size_t font_scale_y, size_t margin) { - if (font_scale_x == 0 || font_scale_y == 0) { - font_scale_x = 1; - font_scale_y = 1; - if (width >= (1920 + 1920 / 3) && height >= (1080 + 1080 / 3)) { - font_scale_x = 2; - font_scale_y = 2; - } - if (width >= (3840 + 3840 / 3) && height >= (2160 + 2160 / 3)) { - font_scale_x = 4; - font_scale_y = 4; - } - } - - /*if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size - != blue_mask_size) { return NULL; - }*/ - - if (_malloc == NULL) { -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (bump_allocated_instance == true) { - return NULL; - } - _malloc = bump_alloc; - // Limit terminal size if needed - if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) { - size_t width_limit = - width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width; - size_t height_limit = - height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height; - - framebuffer = - (uint32_t *)((uintptr_t)framebuffer + - ((((height / 2) - (height_limit / 2)) * pitch) + - (((width / 2) - (width_limit / 2)) * 4))); - - width = width_limit; - height = height_limit; - } - - // Force disable canvas - canvas = NULL; -#else - return NULL; -#endif - } - - struct flanterm_fb_context *ctx = NULL; - ctx = _malloc(sizeof(struct flanterm_fb_context)); - if (ctx == NULL) { - goto fail; - } - - struct flanterm_context *_ctx = (void *)ctx; - memset(ctx, 0, sizeof(struct flanterm_fb_context)); - - ctx->red_mask_size = red_mask_size; - ctx->red_mask_shift = red_mask_shift + (red_mask_size - 8); - ctx->green_mask_size = green_mask_size; - ctx->green_mask_shift = green_mask_shift + (green_mask_size - 8); - ctx->blue_mask_size = blue_mask_size; - ctx->blue_mask_shift = blue_mask_shift + (blue_mask_size - 8); - - if (ansi_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_colours[i] = convert_colour(_ctx, ansi_colours[i]); - } - } else { - ctx->ansi_colours[0] = convert_colour(_ctx, 0x00000000); // black - ctx->ansi_colours[1] = convert_colour(_ctx, 0x00aa0000); // red - ctx->ansi_colours[2] = convert_colour(_ctx, 0x0000aa00); // green - ctx->ansi_colours[3] = convert_colour(_ctx, 0x00aa5500); // brown - ctx->ansi_colours[4] = convert_colour(_ctx, 0x000000aa); // blue - ctx->ansi_colours[5] = convert_colour(_ctx, 0x00aa00aa); // magenta - ctx->ansi_colours[6] = convert_colour(_ctx, 0x0000aaaa); // cyan - ctx->ansi_colours[7] = convert_colour(_ctx, 0x00aaaaaa); // grey - } - - if (ansi_bright_colours != NULL) { - for (size_t i = 0; i < 8; i++) { - ctx->ansi_bright_colours[i] = - convert_colour(_ctx, ansi_bright_colours[i]); - } - } else { - ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black - ctx->ansi_bright_colours[1] = convert_colour(_ctx, 0x00ff5555); // red - ctx->ansi_bright_colours[2] = convert_colour(_ctx, 0x0055ff55); // green - ctx->ansi_bright_colours[3] = convert_colour(_ctx, 0x00ffff55); // brown - ctx->ansi_bright_colours[4] = convert_colour(_ctx, 0x005555ff); // blue - ctx->ansi_bright_colours[5] = convert_colour(_ctx, 0x00ff55ff); // magenta - ctx->ansi_bright_colours[6] = convert_colour(_ctx, 0x0055ffff); // cyan - ctx->ansi_bright_colours[7] = convert_colour(_ctx, 0x00ffffff); // grey - } - - if (default_bg != NULL) { - ctx->default_bg = convert_colour(_ctx, *default_bg); - } else { - ctx->default_bg = 0x00000000; // background (black) - } - - if (default_fg != NULL) { - ctx->default_fg = convert_colour(_ctx, *default_fg); - } else { - ctx->default_fg = convert_colour(_ctx, 0x00aaaaaa); // foreground (grey) - } - - if (default_bg_bright != NULL) { - ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright); - } else { - ctx->default_bg_bright = - convert_colour(_ctx, 0x00555555); // background (black) - } - - if (default_fg_bright != NULL) { - ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright); - } else { - ctx->default_fg_bright = - convert_colour(_ctx, 0x00ffffff); // foreground (grey) - } - - ctx->text_fg = ctx->default_fg; - ctx->text_bg = 0xffffffff; - - ctx->framebuffer = (void *)framebuffer; - ctx->width = width; - ctx->height = height; - ctx->pitch = pitch; - -#define FONT_BYTES ((font_width * font_height * FLANTERM_FB_FONT_GLYPHS) / 8) - - if (font != NULL) { - ctx->font_width = font_width; - ctx->font_height = font_height; - ctx->font_bits_size = FONT_BYTES; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, font, ctx->font_bits_size); - } else { - ctx->font_width = font_width = 8; - ctx->font_height = font_height = 16; - ctx->font_bits_size = FONT_BYTES; - font_spacing = 1; - ctx->font_bits = _malloc(ctx->font_bits_size); - if (ctx->font_bits == NULL) { - goto fail; - } - memcpy(ctx->font_bits, builtin_font, ctx->font_bits_size); - } - -#undef FONT_BYTES - - ctx->font_width += font_spacing; - - ctx->font_bool_size = - FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool); - ctx->font_bool = _malloc(ctx->font_bool_size); - if (ctx->font_bool == NULL) { - goto fail; - } - - for (size_t i = 0; i < FLANTERM_FB_FONT_GLYPHS; i++) { - uint8_t *glyph = &ctx->font_bits[i * font_height]; - - for (size_t y = 0; y < font_height; y++) { - // NOTE: the characters in VGA fonts are always one byte wide. - // 9 dot wide fonts have 8 dots and one empty column, except - // characters 0xC0-0xDF replicate column 9. - for (size_t x = 0; x < 8; x++) { - size_t offset = - i * font_height * ctx->font_width + y * ctx->font_width + x; - - if ((glyph[y] & (0x80 >> x))) { - ctx->font_bool[offset] = true; - } else { - ctx->font_bool[offset] = false; - } - } - // fill columns above 8 like VGA Line Graphics Mode does - for (size_t x = 8; x < ctx->font_width; x++) { - size_t offset = - i * font_height * ctx->font_width + y * ctx->font_width + x; - - if (i >= 0xc0 && i <= 0xdf) { - ctx->font_bool[offset] = (glyph[y] & 1); - } else { - ctx->font_bool[offset] = false; - } - } - } - } - - ctx->font_scale_x = font_scale_x; - ctx->font_scale_y = font_scale_y; - - ctx->glyph_width = ctx->font_width * font_scale_x; - ctx->glyph_height = font_height * font_scale_y; - - _ctx->cols = (ctx->width - margin * 2) / ctx->glyph_width; - _ctx->rows = (ctx->height - margin * 2) / ctx->glyph_height; - - ctx->offset_x = margin + ((ctx->width - margin * 2) % ctx->glyph_width) / 2; - ctx->offset_y = margin + ((ctx->height - margin * 2) % ctx->glyph_height) / 2; - - ctx->grid_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_char); - ctx->grid = _malloc(ctx->grid_size); - if (ctx->grid == NULL) { - goto fail; - } - for (size_t i = 0; i < _ctx->rows * _ctx->cols; i++) { - ctx->grid[i].c = ' '; - ctx->grid[i].fg = ctx->text_fg; - ctx->grid[i].bg = ctx->text_bg; - } - - ctx->queue_size = - _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item); - ctx->queue = _malloc(ctx->queue_size); - if (ctx->queue == NULL) { - goto fail; - } - ctx->queue_i = 0; - memset(ctx->queue, 0, ctx->queue_size); - - ctx->map_size = - _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *); - ctx->map = _malloc(ctx->map_size); - if (ctx->map == NULL) { - goto fail; - } - memset(ctx->map, 0, ctx->map_size); - - if (canvas != NULL) { - ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t); - ctx->canvas = _malloc(ctx->canvas_size); - if (ctx->canvas == NULL) { - goto fail; - } - for (size_t i = 0; i < ctx->width * ctx->height; i++) { - ctx->canvas[i] = convert_colour(_ctx, canvas[i]); - } - } - - if (font_scale_x == 1 && font_scale_y == 1) { - if (canvas == NULL) { - ctx->plot_char = plot_char_unscaled_uncanvas; - } else { - ctx->plot_char = plot_char_unscaled_canvas; - } - } else { - if (canvas == NULL) { - ctx->plot_char = plot_char_scaled_uncanvas; - } else { - ctx->plot_char = plot_char_scaled_canvas; - } - } - - _ctx->raw_putchar = flanterm_fb_raw_putchar; - _ctx->clear = flanterm_fb_clear; - _ctx->set_cursor_pos = flanterm_fb_set_cursor_pos; - _ctx->get_cursor_pos = flanterm_fb_get_cursor_pos; - _ctx->set_text_fg = flanterm_fb_set_text_fg; - _ctx->set_text_bg = flanterm_fb_set_text_bg; - _ctx->set_text_fg_bright = flanterm_fb_set_text_fg_bright; - _ctx->set_text_bg_bright = flanterm_fb_set_text_bg_bright; - _ctx->set_text_fg_rgb = flanterm_fb_set_text_fg_rgb; - _ctx->set_text_bg_rgb = flanterm_fb_set_text_bg_rgb; - _ctx->set_text_fg_default = flanterm_fb_set_text_fg_default; - _ctx->set_text_bg_default = flanterm_fb_set_text_bg_default; - _ctx->set_text_fg_default_bright = flanterm_fb_set_text_fg_default_bright; - _ctx->set_text_bg_default_bright = flanterm_fb_set_text_bg_default_bright; - _ctx->move_character = flanterm_fb_move_character; - _ctx->scroll = flanterm_fb_scroll; - _ctx->revscroll = flanterm_fb_revscroll; - _ctx->swap_palette = flanterm_fb_swap_palette; - _ctx->save_state = flanterm_fb_save_state; - _ctx->restore_state = flanterm_fb_restore_state; - _ctx->double_buffer_flush = flanterm_fb_double_buffer_flush; - _ctx->full_refresh = flanterm_fb_full_refresh; - _ctx->deinit = flanterm_fb_deinit; - - flanterm_context_reinit(_ctx); - flanterm_fb_full_refresh(_ctx); - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_allocated_instance = true; - } -#endif - - return _ctx; - -fail: - if (ctx == NULL) { - return NULL; - } - -#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC - if (_malloc == bump_alloc) { - bump_alloc_ptr = 0; - return NULL; - } -#endif - - if (_free == NULL) { - return NULL; - } - - if (ctx->canvas != NULL) { - _free(ctx->canvas, ctx->canvas_size); - } - if (ctx->map != NULL) { - _free(ctx->map, ctx->map_size); - } - if (ctx->queue != NULL) { - _free(ctx->queue, ctx->queue_size); - } - if (ctx->grid != NULL) { - _free(ctx->grid, ctx->grid_size); - } - if (ctx->font_bool != NULL) { - _free(ctx->font_bool, ctx->font_bool_size); - } - if (ctx->font_bits != NULL) { - _free(ctx->font_bits, ctx->font_bits_size); - } - if (ctx != NULL) { - _free(ctx, sizeof(struct flanterm_fb_context)); - } - - return NULL; -} diff --git a/kernel/src/sys/gfx/flanterm/backends/fb.h b/kernel/src/sys/gfx/flanterm/backends/fb.h deleted file mode 100644 index 7f5a6c6..0000000 --- a/kernel/src/sys/gfx/flanterm/backends/fb.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLANTERM_FB_H -#define FLANTERM_FB_H 1 - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../flanterm.h" - -#ifdef FLANTERM_IN_FLANTERM - -#include "fb_private.h" - -#endif - -struct flanterm_context *flanterm_fb_init( - /* If _malloc and _free are nulled, use the bump allocated instance (1 use - only). */ - void *(*_malloc)(size_t size), void (*_free)(void *ptr, size_t size), - uint32_t *framebuffer, size_t width, size_t height, size_t pitch, - uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size, - uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift, - uint32_t *canvas, /* If nulled, no canvas. */ - uint32_t *ansi_colours, - uint32_t *ansi_bright_colours, /* If nulled, default. */ - uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */ - uint32_t *default_bg_bright, - uint32_t *default_fg_bright, /* If nulled, default. */ - /* If font is null, use default font and font_width and font_height ignored. - */ - void *font, size_t font_width, size_t font_height, size_t font_spacing, - /* If scale_x and scale_y are 0, automatically scale font based on - resolution. */ - size_t font_scale_x, size_t font_scale_y, size_t margin); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/sys/gfx/flanterm/backends/fb_private.h b/kernel/src/sys/gfx/flanterm/backends/fb_private.h deleted file mode 100644 index 5985a6a..0000000 --- a/kernel/src/sys/gfx/flanterm/backends/fb_private.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLANTERM_FB_PRIVATE_H -#define FLANTERM_FB_PRIVATE_H 1 - -#ifndef FLANTERM_IN_FLANTERM -#error "Do not use fb_private.h. Use interfaces defined in fb.h only." -#endif - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_FB_FONT_GLYPHS 256 - -struct flanterm_fb_char { - uint32_t c; - uint32_t fg; - uint32_t bg; -}; - -struct flanterm_fb_queue_item { - size_t x, y; - struct flanterm_fb_char c; -}; - -struct flanterm_fb_context { - struct flanterm_context term; - - void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c, - size_t x, size_t y); - - size_t font_width; - size_t font_height; - size_t glyph_width; - size_t glyph_height; - - size_t font_scale_x; - size_t font_scale_y; - - size_t offset_x, offset_y; - - volatile uint32_t *framebuffer; - size_t pitch; - size_t width; - size_t height; - size_t bpp; - - uint8_t red_mask_size, red_mask_shift; - uint8_t green_mask_size, green_mask_shift; - uint8_t blue_mask_size, blue_mask_shift; - - size_t font_bits_size; - uint8_t *font_bits; - size_t font_bool_size; - bool *font_bool; - - uint32_t ansi_colours[8]; - uint32_t ansi_bright_colours[8]; - uint32_t default_fg, default_bg; - uint32_t default_fg_bright, default_bg_bright; - - size_t canvas_size; - uint32_t *canvas; - - size_t grid_size; - size_t queue_size; - size_t map_size; - - struct flanterm_fb_char *grid; - - struct flanterm_fb_queue_item *queue; - size_t queue_i; - - struct flanterm_fb_queue_item **map; - - uint32_t text_fg; - uint32_t text_bg; - size_t cursor_x; - size_t cursor_y; - - uint32_t saved_state_text_fg; - uint32_t saved_state_text_bg; - size_t saved_state_cursor_x; - size_t saved_state_cursor_y; - - size_t old_cursor_x; - size_t old_cursor_y; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/sys/gfx/flanterm/flanterm.c b/kernel/src/sys/gfx/flanterm/flanterm.c deleted file mode 100644 index ae77986..0000000 --- a/kernel/src/sys/gfx/flanterm/flanterm.c +++ /dev/null @@ -1,1611 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef __cplusplus -#error \ - "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." -#endif - -#ifndef __STDC_VERSION__ -#error "Flanterm must be compiled as C99 or newer." -#endif - -#include -#include -#include - -#define FLANTERM_IN_FLANTERM - -#include "flanterm.h" - -// Tries to implement this standard for terminfo -// https://man7.org/linux/man-pages/man4/console_codes.4.html - -static const uint32_t col256[] = { - 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, - 0x005f5f, 0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, - 0x008787, 0x0087af, 0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, - 0x00afaf, 0x00afd7, 0x00afff, 0x00d700, 0x00d75f, 0x00d787, 0x00d7af, - 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, 0x00ff87, 0x00ffaf, 0x00ffd7, - 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af, 0x5f00d7, 0x5f00ff, - 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff, 0x5f8700, - 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f, - 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, - 0x5fd7af, 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, - 0x5fffd7, 0x5fffff, 0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, - 0x8700ff, 0x875f00, 0x875f5f, 0x875f87, 0x875faf, 0x875fd7, 0x875fff, - 0x878700, 0x87875f, 0x878787, 0x8787af, 0x8787d7, 0x8787ff, 0x87af00, - 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff, 0x87d700, 0x87d75f, - 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f, 0x87ff87, - 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af, - 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, - 0xaf5fff, 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, - 0xafaf00, 0xafaf5f, 0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, - 0xafd75f, 0xafd787, 0xafd7af, 0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, - 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, 0xd70000, 0xd7005f, 0xd70087, - 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f, 0xd75f87, 0xd75faf, - 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af, 0xd787d7, - 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff, - 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, - 0xd7ff5f, 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, - 0xff0087, 0xff00af, 0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, - 0xff5faf, 0xff5fd7, 0xff5fff, 0xff8700, 0xff875f, 0xff8787, 0xff87af, - 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, 0xffaf87, 0xffafaf, 0xffafd7, - 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af, 0xffd7d7, 0xffd7ff, - 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff, 0x080808, - 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, - 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, - 0x9e9e9e, 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, - 0xe4e4e4, 0xeeeeee}; - -#define CHARSET_DEFAULT 0 -#define CHARSET_DEC_SPECIAL 1 - -void flanterm_context_reinit(struct flanterm_context *ctx) { - ctx->tab_size = 8; - ctx->autoflush = true; - ctx->cursor_enabled = true; - ctx->scroll_enabled = true; - ctx->control_sequence = false; - ctx->escape = false; - ctx->osc = false; - ctx->osc_escape = false; - ctx->rrr = false; - ctx->discard_next = false; - ctx->bold = false; - ctx->bg_bold = false; - ctx->reverse_video = false; - ctx->dec_private = false; - ctx->insert_mode = false; - ctx->unicode_remaining = 0; - ctx->g_select = 0; - ctx->charsets[0] = CHARSET_DEFAULT; - ctx->charsets[1] = CHARSET_DEC_SPECIAL; - ctx->current_charset = 0; - ctx->escape_offset = 0; - ctx->esc_values_i = 0; - ctx->saved_cursor_x = 0; - ctx->saved_cursor_y = 0; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - ctx->oob_output = FLANTERM_OOB_OUTPUT_ONLCR; -} - -static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c); - -void flanterm_write(struct flanterm_context *ctx, const char *buf, - size_t count) { - for (size_t i = 0; i < count; i++) { - flanterm_putchar(ctx, buf[i]); - } - - if (ctx->autoflush) { - ctx->double_buffer_flush(ctx); - } -} - -static void sgr(struct flanterm_context *ctx) { - size_t i = 0; - - if (!ctx->esc_values_i) - goto def; - - for (; i < ctx->esc_values_i; i++) { - size_t offset; - - if (ctx->esc_values[i] == 0) { - def: - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - ctx->bold = false; - ctx->bg_bold = false; - ctx->current_primary = (size_t)-1; - ctx->current_bg = (size_t)-1; - ctx->set_text_bg_default(ctx); - ctx->set_text_fg_default(ctx); - continue; - } - - else if (ctx->esc_values[i] == 1) { - ctx->bold = true; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg_bright(ctx, ctx->current_primary); - } else { - ctx->set_text_bg_bright(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default_bright(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 5) { - ctx->bg_bold = true; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg_bright(ctx, ctx->current_bg); - } else { - ctx->set_text_fg_bright(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default_bright(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 22) { - ctx->bold = false; - if (ctx->current_primary != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_fg(ctx, ctx->current_primary); - } else { - ctx->set_text_bg(ctx, ctx->current_primary); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_bg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] == 25) { - ctx->bg_bold = false; - if (ctx->current_bg != (size_t)-1) { - if (!ctx->reverse_video) { - ctx->set_text_bg(ctx, ctx->current_bg); - } else { - ctx->set_text_fg(ctx, ctx->current_bg); - } - } else { - if (!ctx->reverse_video) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_fg_default(ctx); - } - } - continue; - } - - else if (ctx->esc_values[i] >= 30 && ctx->esc_values[i] <= 37) { - offset = 30; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg; - } - - set_fg: - if ((ctx->bold && !ctx->reverse_video) || - (ctx->bg_bold && ctx->reverse_video)) { - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_fg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 40 && ctx->esc_values[i] <= 47) { - offset = 40; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg; - } - - set_bg: - if ((ctx->bold && ctx->reverse_video) || - (ctx->bg_bold && !ctx->reverse_video)) { - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - } else { - ctx->set_text_bg(ctx, ctx->esc_values[i] - offset); - } - continue; - } - - else if (ctx->esc_values[i] >= 90 && ctx->esc_values[i] <= 97) { - offset = 90; - ctx->current_primary = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_bg_bright; - } - - set_fg_bright: - ctx->set_text_fg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] >= 100 && ctx->esc_values[i] <= 107) { - offset = 100; - ctx->current_bg = ctx->esc_values[i] - offset; - - if (ctx->reverse_video) { - goto set_fg_bright; - } - - set_bg_bright: - ctx->set_text_bg_bright(ctx, ctx->esc_values[i] - offset); - continue; - } - - else if (ctx->esc_values[i] == 39) { - ctx->current_primary = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bold) { - ctx->set_text_fg_default(ctx); - } else { - ctx->set_text_fg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 49) { - ctx->current_bg = (size_t)-1; - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - if (!ctx->bg_bold) { - ctx->set_text_bg_default(ctx); - } else { - ctx->set_text_bg_default_bright(ctx); - } - - if (ctx->reverse_video) { - ctx->swap_palette(ctx); - } - - continue; - } - - else if (ctx->esc_values[i] == 7) { - if (!ctx->reverse_video) { - ctx->reverse_video = true; - ctx->swap_palette(ctx); - } - continue; - } - - else if (ctx->esc_values[i] == 27) { - if (ctx->reverse_video) { - ctx->reverse_video = false; - ctx->swap_palette(ctx); - } - continue; - } - - // 256/RGB - else if (ctx->esc_values[i] == 38 || ctx->esc_values[i] == 48) { - bool fg = ctx->esc_values[i] == 38; - - i++; - if (i >= ctx->esc_values_i) { - break; - } - - switch (ctx->esc_values[i]) { - case 2: { // RGB - if (i + 3 >= ctx->esc_values_i) { - goto out; - } - - uint32_t rgb_value = 0; - - rgb_value |= ctx->esc_values[i + 1] << 16; - rgb_value |= ctx->esc_values[i + 2] << 8; - rgb_value |= ctx->esc_values[i + 3]; - - i += 3; - - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - - break; - } - case 5: { // 256 colors - if (i + 1 >= ctx->esc_values_i) { - goto out; - } - - uint32_t col = ctx->esc_values[i + 1]; - - i++; - - if (col < 8) { - (fg ? ctx->set_text_fg : ctx->set_text_bg)(ctx, col); - } else if (col < 16) { - (fg ? ctx->set_text_fg_bright : ctx->set_text_bg_bright)(ctx, - col - 8); - } else if (col < 256) { - uint32_t rgb_value = col256[col - 16]; - (fg ? ctx->set_text_fg_rgb : ctx->set_text_bg_rgb)(ctx, rgb_value); - } - - break; - } - default: - continue; - } - } - } - -out:; -} - -static void dec_private_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->dec_private = false; - - if (ctx->esc_values_i == 0) { - return; - } - - bool set; - - switch (c) { - case 'h': - set = true; - break; - case 'l': - set = false; - break; - default: - return; - } - - switch (ctx->esc_values[0]) { - case 25: { - if (set) { - ctx->cursor_enabled = true; - } else { - ctx->cursor_enabled = false; - } - return; - } - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_DEC, ctx->esc_values_i, - (uintptr_t)ctx->esc_values, c); - } -} - -static void linux_private_parse(struct flanterm_context *ctx) { - if (ctx->esc_values_i == 0) { - return; - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_LINUX, ctx->esc_values_i, - (uintptr_t)ctx->esc_values, 0); - } -} - -static void mode_toggle(struct flanterm_context *ctx, uint8_t c) { - if (ctx->esc_values_i == 0) { - return; - } - - bool set; - - switch (c) { - case 'h': - set = true; - break; - case 'l': - set = false; - break; - default: - return; - } - - switch (ctx->esc_values[0]) { - case 4: - ctx->insert_mode = set; - return; - } - - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_MODE, ctx->esc_values_i, - (uintptr_t)ctx->esc_values, c); - } -} - -static void osc_parse(struct flanterm_context *ctx, uint8_t c) { - if (ctx->osc_escape && c == '\\') { - goto cleanup; - } - - ctx->osc_escape = false; - - switch (c) { - case 0x1b: - ctx->osc_escape = true; - return; - case '\a': - default: - break; - } - -cleanup: - ctx->osc_escape = false; - ctx->osc = false; - ctx->escape = false; -} - -static void control_sequence_parse(struct flanterm_context *ctx, uint8_t c) { - if (ctx->escape_offset == 2) { - switch (c) { - case '[': - ctx->discard_next = true; - goto cleanup; - case '?': - ctx->dec_private = true; - return; - } - } - - if (c >= '0' && c <= '9') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->rrr = true; - ctx->esc_values[ctx->esc_values_i] *= 10; - ctx->esc_values[ctx->esc_values_i] += c - '0'; - return; - } - - if (ctx->rrr == true) { - ctx->esc_values_i++; - ctx->rrr = false; - if (c == ';') - return; - } else if (c == ';') { - if (ctx->esc_values_i == FLANTERM_MAX_ESC_VALUES) { - return; - } - ctx->esc_values[ctx->esc_values_i] = 0; - ctx->esc_values_i++; - return; - } - - size_t esc_default; - switch (c) { - case 'J': - case 'K': - case 'q': - esc_default = 0; - break; - default: - esc_default = 1; - break; - } - - for (size_t i = ctx->esc_values_i; i < FLANTERM_MAX_ESC_VALUES; i++) { - ctx->esc_values[i] = esc_default; - } - - if (ctx->dec_private == true) { - dec_private_parse(ctx, c); - goto cleanup; - } - - bool r = ctx->scroll_enabled; - ctx->scroll_enabled = false; - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case 'F': - x = 0; - // FALLTHRU - case 'A': { - if (ctx->esc_values[0] > y) - ctx->esc_values[0] = y; - size_t orig_y = y; - size_t dest_y = y - ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= dest_y && - ctx->scroll_top_margin <= orig_y) || - (ctx->scroll_bottom_margin >= dest_y && - ctx->scroll_bottom_margin <= orig_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y < ctx->scroll_top_margin) { - dest_y = ctx->scroll_top_margin; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'E': - x = 0; - // FALLTHRU - case 'e': - case 'B': { - if (y + ctx->esc_values[0] > ctx->rows - 1) - ctx->esc_values[0] = (ctx->rows - 1) - y; - size_t orig_y = y; - size_t dest_y = y + ctx->esc_values[0]; - bool will_be_in_scroll_region = false; - if ((ctx->scroll_top_margin >= orig_y && - ctx->scroll_top_margin <= dest_y) || - (ctx->scroll_bottom_margin >= orig_y && - ctx->scroll_bottom_margin <= dest_y)) { - will_be_in_scroll_region = true; - } - if (will_be_in_scroll_region && dest_y >= ctx->scroll_bottom_margin) { - dest_y = ctx->scroll_bottom_margin - 1; - } - ctx->set_cursor_pos(ctx, x, dest_y); - break; - } - case 'a': - case 'C': - if (x + ctx->esc_values[0] > ctx->cols - 1) - ctx->esc_values[0] = (ctx->cols - 1) - x; - ctx->set_cursor_pos(ctx, x + ctx->esc_values[0], y); - break; - case 'D': - if (ctx->esc_values[0] > x) - ctx->esc_values[0] = x; - ctx->set_cursor_pos(ctx, x - ctx->esc_values[0], y); - break; - case 'c': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case 'd': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, x, ctx->esc_values[0]); - break; - case 'G': - case '`': - ctx->esc_values[0] -= 1; - if (ctx->esc_values[0] >= ctx->cols) - ctx->esc_values[0] = ctx->cols - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[0], y); - break; - case 'H': - case 'f': - if (ctx->esc_values[0] != 0) { - ctx->esc_values[0]--; - } - if (ctx->esc_values[1] != 0) { - ctx->esc_values[1]--; - } - if (ctx->esc_values[1] >= ctx->cols) - ctx->esc_values[1] = ctx->cols - 1; - if (ctx->esc_values[0] >= ctx->rows) - ctx->esc_values[0] = ctx->rows - 1; - ctx->set_cursor_pos(ctx, ctx->esc_values[1], ctx->esc_values[0]); - break; - case 'M': { - size_t count = - ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->scroll(ctx); - } - break; - } - case 'L': { - size_t old_scroll_top_margin = ctx->scroll_top_margin; - ctx->scroll_top_margin = y; - size_t count = - ctx->esc_values[0] > ctx->rows ? ctx->rows : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) { - ctx->revscroll(ctx); - } - ctx->scroll_top_margin = old_scroll_top_margin; - break; - } - case 'n': - switch (ctx->esc_values[0]) { - case 5: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_STATUS_REPORT, 0, 0, 0); - } - break; - case 6: - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_POS_REPORT, x + 1, y + 1, 0); - } - break; - } - break; - case 'q': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_KBD_LEDS, ctx->esc_values[0], 0, 0); - } - break; - case 'J': - switch (ctx->esc_values[0]) { - case 0: { - size_t rows_remaining = ctx->rows - (y + 1); - size_t cols_diff = ctx->cols - (x + 1); - size_t to_clear = rows_remaining * ctx->cols + cols_diff + 1; - for (size_t i = 0; i < to_clear; i++) { - ctx->raw_putchar(ctx, ' '); - } - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, 0); - bool b = false; - for (size_t yc = 0; yc < ctx->rows; yc++) { - for (size_t xc = 0; xc < ctx->cols; xc++) { - ctx->raw_putchar(ctx, ' '); - if (xc == x && yc == y) { - ctx->set_cursor_pos(ctx, x, y); - b = true; - break; - } - } - if (b == true) - break; - } - break; - } - case 2: - case 3: - ctx->clear(ctx, false); - break; - } - break; - case '@': - for (size_t i = ctx->cols - 1;; i--) { - ctx->move_character(ctx, i + ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, i, y); - ctx->raw_putchar(ctx, ' '); - if (i == x) { - break; - } - } - ctx->set_cursor_pos(ctx, x, y); - break; - case 'P': - for (size_t i = x + ctx->esc_values[0]; i < ctx->cols; i++) - ctx->move_character(ctx, i - ctx->esc_values[0], y, i, y); - ctx->set_cursor_pos(ctx, ctx->cols - ctx->esc_values[0], y); - // FALLTHRU - case 'X': { - size_t count = - ctx->esc_values[0] > ctx->cols ? ctx->cols : ctx->esc_values[0]; - for (size_t i = 0; i < count; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 'm': - sgr(ctx); - break; - case 's': - ctx->get_cursor_pos(ctx, &ctx->saved_cursor_x, &ctx->saved_cursor_y); - break; - case 'u': - ctx->set_cursor_pos(ctx, ctx->saved_cursor_x, ctx->saved_cursor_y); - break; - case 'K': - switch (ctx->esc_values[0]) { - case 0: { - for (size_t i = x; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - case 1: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < x; i++) - ctx->raw_putchar(ctx, ' '); - break; - } - case 2: { - ctx->set_cursor_pos(ctx, 0, y); - for (size_t i = 0; i < ctx->cols; i++) - ctx->raw_putchar(ctx, ' '); - ctx->set_cursor_pos(ctx, x, y); - break; - } - } - break; - case 'r': - if (ctx->esc_values[0] == 0) { - ctx->esc_values[0] = 1; - } - if (ctx->esc_values[1] == 0) { - ctx->esc_values[1] = 1; - } - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - if (ctx->esc_values_i > 0) { - ctx->scroll_top_margin = ctx->esc_values[0] - 1; - } - if (ctx->esc_values_i > 1) { - ctx->scroll_bottom_margin = ctx->esc_values[1]; - } - if (ctx->scroll_top_margin >= ctx->rows || - ctx->scroll_bottom_margin > ctx->rows || - ctx->scroll_top_margin >= (ctx->scroll_bottom_margin - 1)) { - ctx->scroll_top_margin = 0; - ctx->scroll_bottom_margin = ctx->rows; - } - ctx->set_cursor_pos(ctx, 0, 0); - break; - case 'l': - case 'h': - mode_toggle(ctx, c); - break; - case ']': - linux_private_parse(ctx); - break; - } - - ctx->scroll_enabled = r; - -cleanup: - ctx->control_sequence = false; - ctx->escape = false; -} - -static void restore_state(struct flanterm_context *ctx) { - ctx->bold = ctx->saved_state_bold; - ctx->bg_bold = ctx->saved_state_bg_bold; - ctx->reverse_video = ctx->saved_state_reverse_video; - ctx->current_charset = ctx->saved_state_current_charset; - ctx->current_primary = ctx->saved_state_current_primary; - ctx->current_bg = ctx->saved_state_current_bg; - - ctx->restore_state(ctx); -} - -static void save_state(struct flanterm_context *ctx) { - ctx->save_state(ctx); - - ctx->saved_state_bold = ctx->bold; - ctx->saved_state_bg_bold = ctx->bg_bold; - ctx->saved_state_reverse_video = ctx->reverse_video; - ctx->saved_state_current_charset = ctx->current_charset; - ctx->saved_state_current_primary = ctx->current_primary; - ctx->saved_state_current_bg = ctx->current_bg; -} - -static void escape_parse(struct flanterm_context *ctx, uint8_t c) { - ctx->escape_offset++; - - if (ctx->osc == true) { - osc_parse(ctx, c); - return; - } - - if (ctx->control_sequence == true) { - control_sequence_parse(ctx, c); - return; - } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case ']': - ctx->osc_escape = false; - ctx->osc = true; - return; - case '[': - for (size_t i = 0; i < FLANTERM_MAX_ESC_VALUES; i++) - ctx->esc_values[i] = 0; - ctx->esc_values_i = 0; - ctx->rrr = false; - ctx->control_sequence = true; - return; - case '7': - save_state(ctx); - break; - case '8': - restore_state(ctx); - break; - case 'c': - flanterm_context_reinit(ctx); - ctx->clear(ctx, true); - break; - case 'D': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, x, y); - } else { - ctx->set_cursor_pos(ctx, x, y + 1); - } - break; - case 'E': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y + 1); - } - break; - case 'M': - // "Reverse linefeed" - if (y == ctx->scroll_top_margin) { - ctx->revscroll(ctx); - ctx->set_cursor_pos(ctx, 0, y); - } else { - ctx->set_cursor_pos(ctx, 0, y - 1); - } - break; - case 'Z': - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_PRIVATE_ID, 0, 0, 0); - } - break; - case '(': - case ')': - ctx->g_select = c - '\''; - break; - } - - ctx->escape = false; -} - -static bool dec_special_print(struct flanterm_context *ctx, uint8_t c) { -#define FLANTERM_DEC_SPCL_PRN(C) \ - ctx->raw_putchar(ctx, (C)); \ - return true; - switch (c) { - case '`': - FLANTERM_DEC_SPCL_PRN(0x04) - case '0': - FLANTERM_DEC_SPCL_PRN(0xdb) - case '-': - FLANTERM_DEC_SPCL_PRN(0x18) - case ',': - FLANTERM_DEC_SPCL_PRN(0x1b) - case '.': - FLANTERM_DEC_SPCL_PRN(0x19) - case 'a': - FLANTERM_DEC_SPCL_PRN(0xb1) - case 'f': - FLANTERM_DEC_SPCL_PRN(0xf8) - case 'g': - FLANTERM_DEC_SPCL_PRN(0xf1) - case 'h': - FLANTERM_DEC_SPCL_PRN(0xb0) - case 'j': - FLANTERM_DEC_SPCL_PRN(0xd9) - case 'k': - FLANTERM_DEC_SPCL_PRN(0xbf) - case 'l': - FLANTERM_DEC_SPCL_PRN(0xda) - case 'm': - FLANTERM_DEC_SPCL_PRN(0xc0) - case 'n': - FLANTERM_DEC_SPCL_PRN(0xc5) - case 'q': - FLANTERM_DEC_SPCL_PRN(0xc4) - case 's': - FLANTERM_DEC_SPCL_PRN(0x5f) - case 't': - FLANTERM_DEC_SPCL_PRN(0xc3) - case 'u': - FLANTERM_DEC_SPCL_PRN(0xb4) - case 'v': - FLANTERM_DEC_SPCL_PRN(0xc1) - case 'w': - FLANTERM_DEC_SPCL_PRN(0xc2) - case 'x': - FLANTERM_DEC_SPCL_PRN(0xb3) - case 'y': - FLANTERM_DEC_SPCL_PRN(0xf3) - case 'z': - FLANTERM_DEC_SPCL_PRN(0xf2) - case '~': - FLANTERM_DEC_SPCL_PRN(0xfa) - case '_': - FLANTERM_DEC_SPCL_PRN(0xff) - case '+': - FLANTERM_DEC_SPCL_PRN(0x1a) - case '{': - FLANTERM_DEC_SPCL_PRN(0xe3) - case '}': - FLANTERM_DEC_SPCL_PRN(0x9c) - } -#undef FLANTERM_DEC_SPCL_PRN - - return false; -} - -// Following wcwidth related code inherited from: -// https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - -struct interval { - uint32_t first; - uint32_t last; -}; - -/* auxiliary function for binary search in interval table */ -static int bisearch(uint32_t ucs, const struct interval *table, int max) { - int min = 0; - int mid; - - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return 1; - } - - return 0; -} - -int mk_wcwidth(uint32_t ucs) { - /* sorted list of non-overlapping intervals of non-spacing characters */ - /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ - static const struct interval combining[] = { - {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, - {0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, - {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603}, - {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, - {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, - {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, - {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902}, - {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, - {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, - {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, - {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C}, - {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, - {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, - {0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, - {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C}, - {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, - {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, - {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, - {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC}, - {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, - {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, - {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, - {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, - {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, - {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, - {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, - {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, - {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, - {0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F}, - {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, - {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, - {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, - {0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, - {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, - {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, - {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, - {0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, - {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063}, - {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, - {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, - {0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, - {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, - {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, - {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, - {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, - {0xE0100, 0xE01EF}}; - - /* test for 8-bit control characters */ - if (ucs == 0) - return 0; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return 1; - - /* binary search in table of non-spacing characters */ - if (bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) - return 0; - - /* if we arrive here, ucs is not a combining or C0/C1 control character */ - - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && - ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); -} - -// End of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c inherited code - -static int unicode_to_cp437(uint64_t code_point) { - switch (code_point) { - case 0x263a: - return 1; - case 0x263b: - return 2; - case 0x2665: - return 3; - case 0x2666: - return 4; - case 0x2663: - return 5; - case 0x2660: - return 6; - case 0x2022: - return 7; - case 0x25d8: - return 8; - case 0x25cb: - return 9; - case 0x25d9: - return 10; - case 0x2642: - return 11; - case 0x2640: - return 12; - case 0x266a: - return 13; - case 0x266b: - return 14; - case 0x263c: - return 15; - case 0x25ba: - return 16; - case 0x25c4: - return 17; - case 0x2195: - return 18; - case 0x203c: - return 19; - case 0x00b6: - return 20; - case 0x00a7: - return 21; - case 0x25ac: - return 22; - case 0x21a8: - return 23; - case 0x2191: - return 24; - case 0x2193: - return 25; - case 0x2192: - return 26; - case 0x2190: - return 27; - case 0x221f: - return 28; - case 0x2194: - return 29; - case 0x25b2: - return 30; - case 0x25bc: - return 31; - - case 0x2302: - return 127; - case 0x00c7: - return 128; - case 0x00fc: - return 129; - case 0x00e9: - return 130; - case 0x00e2: - return 131; - case 0x00e4: - return 132; - case 0x00e0: - return 133; - case 0x00e5: - return 134; - case 0x00e7: - return 135; - case 0x00ea: - return 136; - case 0x00eb: - return 137; - case 0x00e8: - return 138; - case 0x00ef: - return 139; - case 0x00ee: - return 140; - case 0x00ec: - return 141; - case 0x00c4: - return 142; - case 0x00c5: - return 143; - case 0x00c9: - return 144; - case 0x00e6: - return 145; - case 0x00c6: - return 146; - case 0x00f4: - return 147; - case 0x00f6: - return 148; - case 0x00f2: - return 149; - case 0x00fb: - return 150; - case 0x00f9: - return 151; - case 0x00ff: - return 152; - case 0x00d6: - return 153; - case 0x00dc: - return 154; - case 0x00a2: - return 155; - case 0x00a3: - return 156; - case 0x00a5: - return 157; - case 0x20a7: - return 158; - case 0x0192: - return 159; - case 0x00e1: - return 160; - case 0x00ed: - return 161; - case 0x00f3: - return 162; - case 0x00fa: - return 163; - case 0x00f1: - return 164; - case 0x00d1: - return 165; - case 0x00aa: - return 166; - case 0x00ba: - return 167; - case 0x00bf: - return 168; - case 0x2310: - return 169; - case 0x00ac: - return 170; - case 0x00bd: - return 171; - case 0x00bc: - return 172; - case 0x00a1: - return 173; - case 0x00ab: - return 174; - case 0x00bb: - return 175; - case 0x2591: - return 176; - case 0x2592: - return 177; - case 0x2593: - return 178; - case 0x2502: - return 179; - case 0x2524: - return 180; - case 0x2561: - return 181; - case 0x2562: - return 182; - case 0x2556: - return 183; - case 0x2555: - return 184; - case 0x2563: - return 185; - case 0x2551: - return 186; - case 0x2557: - return 187; - case 0x255d: - return 188; - case 0x255c: - return 189; - case 0x255b: - return 190; - case 0x2510: - return 191; - case 0x2514: - return 192; - case 0x2534: - return 193; - case 0x252c: - return 194; - case 0x251c: - return 195; - case 0x2500: - return 196; - case 0x253c: - return 197; - case 0x255e: - return 198; - case 0x255f: - return 199; - case 0x255a: - return 200; - case 0x2554: - return 201; - case 0x2569: - return 202; - case 0x2566: - return 203; - case 0x2560: - return 204; - case 0x2550: - return 205; - case 0x256c: - return 206; - case 0x2567: - return 207; - case 0x2568: - return 208; - case 0x2564: - return 209; - case 0x2565: - return 210; - case 0x2559: - return 211; - case 0x2558: - return 212; - case 0x2552: - return 213; - case 0x2553: - return 214; - case 0x256b: - return 215; - case 0x256a: - return 216; - case 0x2518: - return 217; - case 0x250c: - return 218; - case 0x2588: - return 219; - case 0x2584: - return 220; - case 0x258c: - return 221; - case 0x2590: - return 222; - case 0x2580: - return 223; - case 0x03b1: - return 224; - case 0x00df: - return 225; - case 0x0393: - return 226; - case 0x03c0: - return 227; - case 0x03a3: - return 228; - case 0x03c3: - return 229; - case 0x00b5: - return 230; - case 0x03c4: - return 231; - case 0x03a6: - return 232; - case 0x0398: - return 233; - case 0x03a9: - return 234; - case 0x03b4: - return 235; - case 0x221e: - return 236; - case 0x03c6: - return 237; - case 0x03b5: - return 238; - case 0x2229: - return 239; - case 0x2261: - return 240; - case 0x00b1: - return 241; - case 0x2265: - return 242; - case 0x2264: - return 243; - case 0x2320: - return 244; - case 0x2321: - return 245; - case 0x00f7: - return 246; - case 0x2248: - return 247; - case 0x00b0: - return 248; - case 0x2219: - return 249; - case 0x00b7: - return 250; - case 0x221a: - return 251; - case 0x207f: - return 252; - case 0x00b2: - return 253; - case 0x25a0: - return 254; - } - - return -1; -} - -static void flanterm_putchar(struct flanterm_context *ctx, uint8_t c) { - if (ctx->discard_next || (c == 0x18 || c == 0x1a)) { - ctx->discard_next = false; - ctx->escape = false; - ctx->control_sequence = false; - ctx->unicode_remaining = 0; - ctx->osc = false; - ctx->osc_escape = false; - ctx->g_select = 0; - return; - } - - if (ctx->unicode_remaining != 0) { - if ((c & 0xc0) != 0x80) { - ctx->unicode_remaining = 0; - goto unicode_error; - } - - ctx->unicode_remaining--; - ctx->code_point |= (uint64_t)(c & 0x3f) << (6 * ctx->unicode_remaining); - if (ctx->unicode_remaining != 0) { - return; - } - - int cc = unicode_to_cp437(ctx->code_point); - - if (cc == -1) { - size_t replacement_width = (size_t)mk_wcwidth(ctx->code_point); - if (replacement_width > 0) { - ctx->raw_putchar(ctx, 0xfe); - } - for (size_t i = 1; i < replacement_width; i++) { - ctx->raw_putchar(ctx, ' '); - } - } else { - ctx->raw_putchar(ctx, cc); - } - return; - } - -unicode_error: - if (c >= 0xc0 && c <= 0xf7) { - if (c >= 0xc0 && c <= 0xdf) { - ctx->unicode_remaining = 1; - ctx->code_point = (uint64_t)(c & 0x1f) << 6; - } else if (c >= 0xe0 && c <= 0xef) { - ctx->unicode_remaining = 2; - ctx->code_point = (uint64_t)(c & 0x0f) << (6 * 2); - } else if (c >= 0xf0 && c <= 0xf7) { - ctx->unicode_remaining = 3; - ctx->code_point = (uint64_t)(c & 0x07) << (6 * 3); - } - return; - } - - if (ctx->escape == true) { - escape_parse(ctx, c); - return; - } - - if (ctx->g_select) { - ctx->g_select--; - switch (c) { - case 'B': - ctx->charsets[ctx->g_select] = CHARSET_DEFAULT; - break; - case '0': - ctx->charsets[ctx->g_select] = CHARSET_DEC_SPECIAL; - break; - } - ctx->g_select = 0; - return; - } - - size_t x, y; - ctx->get_cursor_pos(ctx, &x, &y); - - switch (c) { - case 0x00: - case 0x7f: - return; - case 0x1b: - ctx->escape_offset = 0; - ctx->escape = true; - return; - case '\t': - if ((x / ctx->tab_size + 1) >= ctx->cols) { - ctx->set_cursor_pos(ctx, ctx->cols - 1, y); - return; - } - ctx->set_cursor_pos(ctx, (x / ctx->tab_size + 1) * ctx->tab_size, y); - return; - case 0x0b: - case 0x0c: - case '\n': - if (y == ctx->scroll_bottom_margin - 1) { - ctx->scroll(ctx); - ctx->set_cursor_pos( - ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y); - } else { - ctx->set_cursor_pos( - ctx, (ctx->oob_output & FLANTERM_OOB_OUTPUT_ONLCR) ? 0 : x, y + 1); - } - return; - case '\b': - ctx->set_cursor_pos(ctx, x - 1, y); - return; - case '\r': - ctx->set_cursor_pos(ctx, 0, y); - return; - case '\a': - // The bell is handled by the kernel - if (ctx->callback != NULL) { - ctx->callback(ctx, FLANTERM_CB_BELL, 0, 0, 0); - } - return; - case 14: - // Move to G1 set - ctx->current_charset = 1; - return; - case 15: - // Move to G0 set - ctx->current_charset = 0; - return; - } - - if (ctx->insert_mode == true) { - for (size_t i = ctx->cols - 1;; i--) { - ctx->move_character(ctx, i + 1, y, i, y); - if (i == x) { - break; - } - } - } - - // Translate character set - switch (ctx->charsets[ctx->current_charset]) { - case CHARSET_DEFAULT: - break; - case CHARSET_DEC_SPECIAL: - if (dec_special_print(ctx, c)) { - return; - } - break; - } - - if (c >= 0x20 && c <= 0x7e) { - ctx->raw_putchar(ctx, c); - } else { - ctx->raw_putchar(ctx, 0xfe); - } -} - -void flanterm_flush(struct flanterm_context *ctx) { - ctx->double_buffer_flush(ctx); -} - -void flanterm_full_refresh(struct flanterm_context *ctx) { - ctx->full_refresh(ctx); -} - -void flanterm_deinit(struct flanterm_context *ctx, - void (*_free)(void *, size_t)) { - ctx->deinit(ctx, _free); -} - -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, - size_t *rows) { - *cols = ctx->cols; - *rows = ctx->rows; -} - -void flanterm_set_autoflush(struct flanterm_context *ctx, bool state) { - ctx->autoflush = state; -} - -void flanterm_set_callback(struct flanterm_context *ctx, - void (*callback)(struct flanterm_context *, uint64_t, - uint64_t, uint64_t, uint64_t)) { - ctx->callback = callback; -} - -uint64_t flanterm_get_oob_output(struct flanterm_context *ctx) { - return ctx->oob_output; -} - -void flanterm_set_oob_output(struct flanterm_context *ctx, - uint64_t oob_output) { - ctx->oob_output = oob_output; -} diff --git a/kernel/src/sys/gfx/flanterm/flanterm.h b/kernel/src/sys/gfx/flanterm/flanterm.h deleted file mode 100644 index a4d5b78..0000000 --- a/kernel/src/sys/gfx/flanterm/flanterm.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLANTERM_H -#define FLANTERM_H 1 - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_CB_DEC 10 -#define FLANTERM_CB_BELL 20 -#define FLANTERM_CB_PRIVATE_ID 30 -#define FLANTERM_CB_STATUS_REPORT 40 -#define FLANTERM_CB_POS_REPORT 50 -#define FLANTERM_CB_KBD_LEDS 60 -#define FLANTERM_CB_MODE 70 -#define FLANTERM_CB_LINUX 80 - -#define FLANTERM_OOB_OUTPUT_OCRNL (1 << 0) -#define FLANTERM_OOB_OUTPUT_OFDEL (1 << 1) -#define FLANTERM_OOB_OUTPUT_OFILL (1 << 2) -#define FLANTERM_OOB_OUTPUT_OLCUC (1 << 3) -#define FLANTERM_OOB_OUTPUT_ONLCR (1 << 4) -#define FLANTERM_OOB_OUTPUT_ONLRET (1 << 5) -#define FLANTERM_OOB_OUTPUT_ONOCR (1 << 6) -#define FLANTERM_OOB_OUTPUT_OPOST (1 << 7) - -#ifdef FLANTERM_IN_FLANTERM - -#include "flanterm_private.h" - -#else - -struct flanterm_context; - -#endif - -void flanterm_write(struct flanterm_context *ctx, const char *buf, - size_t count); -void flanterm_flush(struct flanterm_context *ctx); -void flanterm_full_refresh(struct flanterm_context *ctx); -void flanterm_deinit(struct flanterm_context *ctx, - void (*_free)(void *ptr, size_t size)); - -void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, - size_t *rows); -void flanterm_set_autoflush(struct flanterm_context *ctx, bool state); -void flanterm_set_callback(struct flanterm_context *ctx, - void (*callback)(struct flanterm_context *, uint64_t, - uint64_t, uint64_t, uint64_t)); -uint64_t flanterm_get_oob_output(struct flanterm_context *ctx); -void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/sys/gfx/flanterm/flanterm_private.h b/kernel/src/sys/gfx/flanterm/flanterm_private.h deleted file mode 100644 index 9b049af..0000000 --- a/kernel/src/sys/gfx/flanterm/flanterm_private.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (C) 2022-2025 mintsuki and contributors. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLANTERM_PRIVATE_H -#define FLANTERM_PRIVATE_H 1 - -#ifndef FLANTERM_IN_FLANTERM -#error \ - "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only." -#endif - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FLANTERM_MAX_ESC_VALUES 16 - -struct flanterm_context { - /* internal use */ - - size_t tab_size; - bool autoflush; - bool cursor_enabled; - bool scroll_enabled; - bool control_sequence; - bool escape; - bool osc; - bool osc_escape; - bool rrr; - bool discard_next; - bool bold; - bool bg_bold; - bool reverse_video; - bool dec_private; - bool insert_mode; - uint64_t code_point; - size_t unicode_remaining; - uint8_t g_select; - uint8_t charsets[2]; - size_t current_charset; - size_t escape_offset; - size_t esc_values_i; - size_t saved_cursor_x; - size_t saved_cursor_y; - size_t current_primary; - size_t current_bg; - size_t scroll_top_margin; - size_t scroll_bottom_margin; - uint32_t esc_values[FLANTERM_MAX_ESC_VALUES]; - uint64_t oob_output; - bool saved_state_bold; - bool saved_state_bg_bold; - bool saved_state_reverse_video; - size_t saved_state_current_charset; - size_t saved_state_current_primary; - size_t saved_state_current_bg; - - /* to be set by backend */ - - size_t rows, cols; - - void (*raw_putchar)(struct flanterm_context *, uint8_t c); - void (*clear)(struct flanterm_context *, bool move); - void (*set_cursor_pos)(struct flanterm_context *, size_t x, size_t y); - void (*get_cursor_pos)(struct flanterm_context *, size_t *x, size_t *y); - void (*set_text_fg)(struct flanterm_context *, size_t fg); - void (*set_text_bg)(struct flanterm_context *, size_t bg); - void (*set_text_fg_bright)(struct flanterm_context *, size_t fg); - void (*set_text_bg_bright)(struct flanterm_context *, size_t bg); - void (*set_text_fg_rgb)(struct flanterm_context *, uint32_t fg); - void (*set_text_bg_rgb)(struct flanterm_context *, uint32_t bg); - void (*set_text_fg_default)(struct flanterm_context *); - void (*set_text_bg_default)(struct flanterm_context *); - void (*set_text_fg_default_bright)(struct flanterm_context *); - void (*set_text_bg_default_bright)(struct flanterm_context *); - void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, - size_t old_x, size_t old_y); - void (*scroll)(struct flanterm_context *); - void (*revscroll)(struct flanterm_context *); - void (*swap_palette)(struct flanterm_context *); - void (*save_state)(struct flanterm_context *); - void (*restore_state)(struct flanterm_context *); - void (*double_buffer_flush)(struct flanterm_context *); - void (*full_refresh)(struct flanterm_context *); - void (*deinit)(struct flanterm_context *, void (*)(void *, size_t)); - - /* to be set by client */ - - void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, - uint64_t); -}; - -void flanterm_context_reinit(struct flanterm_context *ctx); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c deleted file mode 100644 index 4f3c313..0000000 --- a/kernel/src/sys/log.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "arch/x86_64/io.h" -#include "sys/gfx/flanterm/flanterm.h" -#include -#include -#include -#include - -extern struct flanterm_context *ft_ctx; - -static spinlock_t log_lock = {0}; - -void log(char *format, ...) { - // TODO: replace this call with a call to printf() when the RTC is - // implemented. - - // spinlock_acquire(&log_lock); - - char *date = "1970-01-01 00:00:00 | "; - if (ft_ctx) - flanterm_write(ft_ctx, date, strlen(date)); - - char buf[2048]; - va_list l; - va_start(l, format); - npf_vsnprintf(buf, 2048, format, l); - va_end(l); - - if (ft_ctx) - flanterm_write(ft_ctx, buf, strlen(buf)); - - for (int i = 0;; i++) { - if (date[i] == '\0') - break; - - outb(0xE9, date[i]); - } - - for (int i = 0;; i++) { - if (buf[i] == '\0') - break; - - outb(0xE9, buf[i]); - } - - // spinlock_release(&log_lock); -} \ No newline at end of file diff --git a/kernel/src/sys/log.h b/kernel/src/sys/log.h deleted file mode 100755 index 1d9545f..0000000 --- a/kernel/src/sys/log.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void log(char *format, ...); \ No newline at end of file diff --git a/kernel/src/sys/printf.c b/kernel/src/sys/printf.c deleted file mode 100644 index b453bcf..0000000 --- a/kernel/src/sys/printf.c +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2024 Sipaa Projects -// This code is part of the Soaplin kernel and is licensed under the terms of -// the MIT License. -#include "sys/gfx/flanterm/flanterm.h" -#include -#include - -#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 -#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 - -// Compile nanoprintf in this translation unit. -#define NANOPRINTF_IMPLEMENTATION -#include - -extern struct flanterm_context *ft_ctx; - -void printf(char *format, ...) { - char buf[2048]; - va_list lst; - va_start(lst, format); - npf_vsnprintf(buf, 2048, format, lst); - va_end(lst); - - // rt_print(buf); - if (ft_ctx) - flanterm_write(ft_ctx, buf, strlen(buf)); -} \ No newline at end of file diff --git a/kernel/src/sys/printf.h b/kernel/src/sys/printf.h deleted file mode 100755 index 759e840..0000000 --- a/kernel/src/sys/printf.h +++ /dev/null @@ -1,1320 +0,0 @@ -/* nanoprintf v0.5.3: a tiny embeddable printf replacement written in C. - https://github.com/charlesnicholson/nanoprintf - charles.nicholson+nanoprintf@gmail.com - dual-licensed under 0bsd and unlicense, take your pick. see eof for details. - */ - -#ifndef NANOPRINTF_H_INCLUDED -#define NANOPRINTF_H_INCLUDED - -#include -#include - -// Define this to fully sandbox nanoprintf inside of a translation unit. -#ifdef NANOPRINTF_VISIBILITY_STATIC -#define NPF_VISIBILITY static -#else -#define NPF_VISIBILITY extern -#endif - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) -#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) \ - __attribute__((format(printf, FORMAT_INDEX, VARGS_INDEX))) -#else -#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) -#endif - -// Public API - -#ifdef __cplusplus -extern "C" { -#endif - -// The npf_ functions all return the number of bytes required to express the -// fully-formatted string, not including the null terminator character. -// The npf_ functions do not return negative values, since the lack of 'l' -// length modifier support makes encoding errors impossible. - -NPF_VISIBILITY int npf_snprintf(char *buffer, size_t bufsz, const char *format, - ...) NPF_PRINTF_ATTR(3, 4); - -NPF_VISIBILITY int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, - va_list vlist) NPF_PRINTF_ATTR(3, 0); - -typedef void (*npf_putc)(int c, void *ctx); -NPF_VISIBILITY int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, - ...) NPF_PRINTF_ATTR(3, 4); - -NPF_VISIBILITY int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, - va_list vlist) NPF_PRINTF_ATTR(3, 0); - -#ifdef __cplusplus -} -#endif - -#endif // NANOPRINTF_H_INCLUDED - -/* The implementation of nanoprintf begins here, to be compiled only if - NANOPRINTF_IMPLEMENTATION is defined. In a multi-file library what follows - would be nanoprintf.c. */ - -#ifdef NANOPRINTF_IMPLEMENTATION - -#ifndef NANOPRINTF_IMPLEMENTATION_INCLUDED -#define NANOPRINTF_IMPLEMENTATION_INCLUDED - -#include -#include - -// The conversion buffer must fit at least UINT64_MAX in octal format with the -// leading '0'. -#ifndef NANOPRINTF_CONVERSION_BUFFER_SIZE -#define NANOPRINTF_CONVERSION_BUFFER_SIZE 23 -#endif -#if NANOPRINTF_CONVERSION_BUFFER_SIZE < 23 -#error The size of the conversion buffer must be at least 23 bytes. -#endif - -// Pick reasonable defaults if nothing's been configured. -#if !defined(NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS) -#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0 -#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0 -#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 -#endif - -// If anything's been configured, everything must be configured. -#ifndef NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif -#ifndef NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif - -// Ensure flags are compatible. -#if (NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1) && \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 0) -#error Precision format specifiers must be enabled if float support is enabled. -#endif - -// intmax_t / uintmax_t require stdint from c99 / c++11 -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 -#ifndef _MSC_VER -#ifdef __cplusplus -#if __cplusplus < 201103L -#error large format specifier support requires C++11 or later. -#endif -#else -#if __STDC_VERSION__ < 199409L -#error nanoprintf requires C99 or later. -#endif -#endif -#endif -#endif - -// Figure out if we can disable warnings with pragmas. -#ifdef __clang__ -#define NANOPRINTF_CLANG 1 -#define NANOPRINTF_GCC_PAST_4_6 0 -#else -#define NANOPRINTF_CLANG 0 -#if defined(__GNUC__) && \ - ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) -#define NANOPRINTF_GCC_PAST_4_6 1 -#else -#define NANOPRINTF_GCC_PAST_4_6 0 -#endif -#endif - -#if NANOPRINTF_CLANG || NANOPRINTF_GCC_PAST_4_6 -#define NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS 1 -#else -#define NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS 0 -#endif - -#if NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#ifdef __cplusplus -#pragma GCC diagnostic ignored "-Wold-style-cast" -#endif -#pragma GCC diagnostic ignored "-Wpadded" -#pragma GCC diagnostic ignored "-Wfloat-equal" -#if NANOPRINTF_CLANG -#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" -#pragma GCC diagnostic ignored "-Wcovered-switch-default" -#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#ifndef __APPLE__ -#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" -#endif -#elif NANOPRINTF_GCC_PAST_4_6 -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif -#endif - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4619) // there is no warning number 'number' -// C4619 has to be disabled first! -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4505) // unreferenced local function has been removed -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#pragma warning(disable : 4701) // potentially uninitialized local variable used -#pragma warning(disable : 4706) // assignment within conditional expression -#pragma warning(disable : 4710) // function not inlined -#pragma warning(disable : 4711) // function selected for inline expansion -#pragma warning(disable : 4820) // padding added after struct member -#pragma warning(disable : 5039) // potentially throwing function passed to - // extern C function -#pragma warning(disable : 5045) // compiler will insert Spectre mitigation for - // memory load -#pragma warning(disable : 5262) // implicit switch fall-through -#pragma warning(disable : 26812) // enum type is unscoped -#endif - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) -#define NPF_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) -#define NPF_NOINLINE __declspec(noinline) -#else -#define NPF_NOINLINE -#endif - -#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) || \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) -enum { - NPF_FMT_SPEC_OPT_NONE, - NPF_FMT_SPEC_OPT_LITERAL, - NPF_FMT_SPEC_OPT_STAR, -}; -#endif - -enum { - NPF_FMT_SPEC_LEN_MOD_NONE, - NPF_FMT_SPEC_LEN_MOD_SHORT, // 'h' - NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE, // 'L' - NPF_FMT_SPEC_LEN_MOD_CHAR, // 'hh' - NPF_FMT_SPEC_LEN_MOD_LONG, // 'l' -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG, // 'll' - NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX, // 'j' - NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET, // 'z' - NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT, // 't' -#endif -}; - -enum { - NPF_FMT_SPEC_CONV_NONE, - NPF_FMT_SPEC_CONV_PERCENT, // '%' - NPF_FMT_SPEC_CONV_CHAR, // 'c' - NPF_FMT_SPEC_CONV_STRING, // 's' - NPF_FMT_SPEC_CONV_SIGNED_INT, // 'i', 'd' -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_BINARY, // 'b' -#endif - NPF_FMT_SPEC_CONV_OCTAL, // 'o' - NPF_FMT_SPEC_CONV_HEX_INT, // 'x', 'X' - NPF_FMT_SPEC_CONV_UNSIGNED_INT, // 'u' - NPF_FMT_SPEC_CONV_POINTER, // 'p' -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_WRITEBACK, // 'n' -#endif -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - NPF_FMT_SPEC_CONV_FLOAT_DEC, // 'f', 'F' - NPF_FMT_SPEC_CONV_FLOAT_SCI, // 'e', 'E' - NPF_FMT_SPEC_CONV_FLOAT_SHORTEST, // 'g', 'G' - NPF_FMT_SPEC_CONV_FLOAT_HEX, // 'a', 'A' -#endif -}; - -typedef struct npf_format_spec { -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int field_width; - uint8_t field_width_opt; - char left_justified; // '-' - char leading_zero_pad; // '0' -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - int prec; - uint8_t prec_opt; -#endif - char prepend; // ' ' or '+' - char alt_form; // '#' - char case_adjust; // 'a' - 'A' - uint8_t length_modifier; - uint8_t conv_spec; -} npf_format_spec_t; - -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 -typedef long npf_int_t; -typedef unsigned long npf_uint_t; -#else -typedef intmax_t npf_int_t; -typedef uintmax_t npf_uint_t; -#endif - -typedef struct npf_bufputc_ctx { - char *dst; - size_t len; - size_t cur; -} npf_bufputc_ctx_t; - -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 -typedef char - npf_size_is_ptrdiff[(sizeof(size_t) == sizeof(ptrdiff_t)) ? 1 : -1]; -typedef ptrdiff_t npf_ssize_t; -#endif - -#ifdef _MSC_VER -#include -#endif - -static int npf_max(int x, int y) { return (x > y) ? x : y; } - -static int npf_parse_format_spec(char const *format, - npf_format_spec_t *out_spec) { - char const *cur = format; - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->left_justified = 0; - out_spec->leading_zero_pad = 0; -#endif - out_spec->case_adjust = 'a' - 'A'; // lowercase - out_spec->prepend = 0; - out_spec->alt_form = 0; - - while (*++cur) { // cur points at the leading '%' character - switch (*cur) { // Optional flags -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - case '-': - out_spec->left_justified = '-'; - out_spec->leading_zero_pad = 0; - continue; - case '0': - out_spec->leading_zero_pad = !out_spec->left_justified; - continue; -#endif - case '+': - out_spec->prepend = '+'; - continue; - case ' ': - if (out_spec->prepend == 0) { - out_spec->prepend = ' '; - } - continue; - case '#': - out_spec->alt_form = '#'; - continue; - default: - break; - } - break; - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE; - if (*cur == '*') { - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_STAR; - ++cur; - } else { - out_spec->field_width = 0; - while ((*cur >= '0') && (*cur <= '9')) { - out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL; - out_spec->field_width = (out_spec->field_width * 10) + (*cur++ - '0'); - } - } -#endif - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec = 0; - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; - if (*cur == '.') { - ++cur; - if (*cur == '*') { - out_spec->prec_opt = NPF_FMT_SPEC_OPT_STAR; - ++cur; - } else { - if (*cur == '-') { - ++cur; - } else { - out_spec->prec_opt = NPF_FMT_SPEC_OPT_LITERAL; - } - while ((*cur >= '0') && (*cur <= '9')) { - out_spec->prec = (out_spec->prec * 10) + (*cur++ - '0'); - } - } - } -#endif - - uint_fast8_t tmp_conv = NPF_FMT_SPEC_CONV_NONE; - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_NONE; - switch (*cur++) { // Length modifier - case 'h': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_SHORT; - if (*cur == 'h') { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_CHAR; - ++cur; - } - break; - case 'l': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG; -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - if (*cur == 'l') { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG; - ++cur; - } -#endif - break; -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'L': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE; - break; -#endif -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - case 'j': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX; - break; - case 'z': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET; - break; - case 't': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT; - break; -#endif - default: - --cur; - break; - } - - switch (*cur++) { // Conversion specifier - case '%': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; - - case 'c': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; - - case 's': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->leading_zero_pad = 0; -#endif - break; - - case 'i': - case 'd': - tmp_conv = NPF_FMT_SPEC_CONV_SIGNED_INT; - case 'o': - if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { - tmp_conv = NPF_FMT_SPEC_CONV_OCTAL; - } - case 'u': - if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { - tmp_conv = NPF_FMT_SPEC_CONV_UNSIGNED_INT; - } - case 'X': - if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { - out_spec->case_adjust = 0; - } - case 'x': - if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { - tmp_conv = NPF_FMT_SPEC_CONV_HEX_INT; - } - out_spec->conv_spec = (uint8_t)tmp_conv; -#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) && \ - (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) - if (out_spec->prec_opt != NPF_FMT_SPEC_OPT_NONE) { - out_spec->leading_zero_pad = 0; - } -#endif - break; - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'F': - out_spec->case_adjust = 0; - case 'f': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DEC; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { - out_spec->prec = 6; - } - break; - - case 'E': - out_spec->case_adjust = 0; - case 'e': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SCI; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { - out_spec->prec = 6; - } - break; - - case 'G': - out_spec->case_adjust = 0; - case 'g': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SHORTEST; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { - out_spec->prec = 6; - } - break; - - case 'A': - out_spec->case_adjust = 0; - case 'a': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_HEX; - if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { - out_spec->prec = 6; - } - break; -#endif - -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case 'n': - // todo: reject string if flags or width or precision exist - out_spec->conv_spec = NPF_FMT_SPEC_CONV_WRITEBACK; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; -#endif - - case 'p': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_POINTER; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; -#endif - break; - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - case 'B': - out_spec->case_adjust = 0; - case 'b': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_BINARY; - break; -#endif - - default: - return 0; - } - - return (int)(cur - format); -} - -static NPF_NOINLINE int npf_utoa_rev(npf_uint_t val, char *buf, - uint_fast8_t base, char case_adj) { - uint_fast8_t n = 0; - do { - int_fast8_t const d = (int_fast8_t)(val % base); - *buf++ = (char)(((d < 10) ? '0' : ('A' - 10 + case_adj)) + d); - ++n; - val /= base; - } while (val); - return (int)n; -} - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - -#include - -#if (DBL_MANT_DIG <= 11) && (DBL_MAX_EXP <= 16) -typedef uint_fast16_t npf_double_bin_t; -typedef int_fast8_t npf_ftoa_exp_t; -#elif (DBL_MANT_DIG <= 24) && (DBL_MAX_EXP <= 128) -typedef uint_fast32_t npf_double_bin_t; -typedef int_fast8_t npf_ftoa_exp_t; -#elif (DBL_MANT_DIG <= 53) && (DBL_MAX_EXP <= 1024) -typedef uint_fast64_t npf_double_bin_t; -typedef int_fast16_t npf_ftoa_exp_t; -#else -#error Unsupported width of the double type. -#endif - -// The floating point conversion code works with an unsigned integer type of any -// size. -#ifndef NANOPRINTF_CONVERSION_FLOAT_TYPE -#define NANOPRINTF_CONVERSION_FLOAT_TYPE unsigned int -#endif -typedef NANOPRINTF_CONVERSION_FLOAT_TYPE npf_ftoa_man_t; - -#if (NANOPRINTF_CONVERSION_BUFFER_SIZE <= UINT_FAST8_MAX) && \ - (UINT_FAST8_MAX <= INT_MAX) -typedef uint_fast8_t npf_ftoa_dec_t; -#else -typedef int npf_ftoa_dec_t; -#endif - -enum { - NPF_DOUBLE_EXP_MASK = DBL_MAX_EXP * 2 - 1, - NPF_DOUBLE_EXP_BIAS = DBL_MAX_EXP - 1, - NPF_DOUBLE_MAN_BITS = DBL_MANT_DIG - 1, - NPF_DOUBLE_BIN_BITS = sizeof(npf_double_bin_t) * CHAR_BIT, - NPF_FTOA_MAN_BITS = sizeof(npf_ftoa_man_t) * CHAR_BIT, - NPF_FTOA_SHIFT_BITS = - ((NPF_FTOA_MAN_BITS < DBL_MANT_DIG) ? NPF_FTOA_MAN_BITS : DBL_MANT_DIG) - - 1 -}; - -/* Generally, floating-point conversion implementations use - grisu2 (https://bit.ly/2JgMggX) and ryu (https://bit.ly/2RLXSg0) algorithms, - which are mathematically exact and fast, but require large lookup tables. - - This implementation was inspired by Wojciech MuÅ‚a's (zdjÄ™cia@garnek.pl) - algorithm (http://0x80.pl/notesen/2015-12-29-float-to-string.html) and - extended further by adding dynamic scaling and configurable integer width by - Oskars Rubenis (https://github.com/Okarss). */ - -static int npf_ftoa_rev(char *buf, npf_format_spec_t const *spec, double f) { - char const *ret = NULL; - npf_double_bin_t bin; - { // Union-cast is UB pre-C11, compiler optimizes byte-copy loop. - char const *src = (char const *)&f; - char *dst = (char *)&bin; - for (uint_fast8_t i = 0; i < sizeof(f); ++i) { - dst[i] = src[i]; - } - } - - // Unsigned -> signed int casting is IB and can raise a signal but generally - // doesn't. - npf_ftoa_exp_t exp = - (npf_ftoa_exp_t)((npf_ftoa_exp_t)(bin >> NPF_DOUBLE_MAN_BITS) & - NPF_DOUBLE_EXP_MASK); - - bin &= ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1; - if (exp == (npf_ftoa_exp_t)NPF_DOUBLE_EXP_MASK) { // special value - ret = (bin) ? "NAN" : "FNI"; - goto exit; - } - if (spec->prec > (NANOPRINTF_CONVERSION_BUFFER_SIZE - 2)) { - goto exit; - } - if (exp) { // normal number - bin |= (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS; - } else { // subnormal number - ++exp; - } - exp = (npf_ftoa_exp_t)(exp - NPF_DOUBLE_EXP_BIAS); - - uint_fast8_t carry; - carry = 0; - npf_ftoa_dec_t end, dec; - dec = (npf_ftoa_dec_t)spec->prec; - if (dec || spec->alt_form) { - buf[dec++] = '.'; - } - - { // Integer part - npf_ftoa_man_t man_i; - - if (exp >= 0) { - int_fast8_t shift_i = - (int_fast8_t)((exp > NPF_FTOA_SHIFT_BITS) ? (int)NPF_FTOA_SHIFT_BITS - : exp); - npf_ftoa_exp_t exp_i = (npf_ftoa_exp_t)(exp - shift_i); - shift_i = (int_fast8_t)(NPF_DOUBLE_MAN_BITS - shift_i); - man_i = (npf_ftoa_man_t)(bin >> shift_i); - - if (exp_i) { - if (shift_i) { - carry = (bin >> (shift_i - 1)) & 0x1; - } - exp = NPF_DOUBLE_MAN_BITS; // invalidate the fraction part - } - - // Scale the exponent from base-2 to base-10. - for (; exp_i; --exp_i) { - if (!(man_i & ((npf_ftoa_man_t)0x1 << (NPF_FTOA_MAN_BITS - 1)))) { - man_i = (npf_ftoa_man_t)(man_i << 1); - man_i = (npf_ftoa_man_t)(man_i | carry); - carry = 0; - } else { - if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { - goto exit; - } - buf[dec++] = '0'; - carry = (((uint_fast8_t)(man_i % 5) + carry) > 2); - man_i /= 5; - } - } - } else { - man_i = 0; - } - end = dec; - - do { // Print the integer - if (end >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { - goto exit; - } - buf[end++] = (char)('0' + (char)(man_i % 10)); - man_i /= 10; - } while (man_i); - } - - { // Fraction part - npf_ftoa_man_t man_f; - npf_ftoa_dec_t dec_f = (npf_ftoa_dec_t)spec->prec; - - if (exp < NPF_DOUBLE_MAN_BITS) { - int_fast8_t shift_f = (int_fast8_t)((exp < 0) ? -1 : exp); - npf_ftoa_exp_t exp_f = (npf_ftoa_exp_t)(exp - shift_f); - npf_double_bin_t bin_f = - bin << ((NPF_DOUBLE_BIN_BITS - NPF_DOUBLE_MAN_BITS) + shift_f); - - // This if-else statement can be completely optimized at compile time. - if (NPF_DOUBLE_BIN_BITS > NPF_FTOA_MAN_BITS) { - man_f = (npf_ftoa_man_t)(bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - - NPF_FTOA_MAN_BITS) % - NPF_DOUBLE_BIN_BITS)); - carry = (uint_fast8_t)((bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - - NPF_FTOA_MAN_BITS - 1) % - NPF_DOUBLE_BIN_BITS)) & - 0x1); - } else { - man_f = (npf_ftoa_man_t)((npf_ftoa_man_t)bin_f - << ((unsigned)(NPF_FTOA_MAN_BITS - - NPF_DOUBLE_BIN_BITS) % - NPF_FTOA_MAN_BITS)); - carry = 0; - } - - // Scale the exponent from base-2 to base-10 and prepare the first digit. - for (uint_fast8_t digit = 0; dec_f && (exp_f < 4); ++exp_f) { - if ((man_f > ((npf_ftoa_man_t)-4 / 5)) || digit) { - carry = (uint_fast8_t)(man_f & 0x1); - man_f = (npf_ftoa_man_t)(man_f >> 1); - } else { - man_f = (npf_ftoa_man_t)(man_f * 5); - if (carry) { - man_f = (npf_ftoa_man_t)(man_f + 3); - carry = 0; - } - if (exp_f < 0) { - buf[--dec_f] = '0'; - } else { - ++digit; - } - } - } - man_f = (npf_ftoa_man_t)(man_f + carry); - carry = (exp_f >= 0); - dec = 0; - } else { - man_f = 0; - } - - if (dec_f) { - // Print the fraction - for (;;) { - buf[--dec_f] = (char)('0' + (char)(man_f >> (NPF_FTOA_MAN_BITS - 4))); - man_f = (npf_ftoa_man_t)(man_f & ~((npf_ftoa_man_t)0xF - << (NPF_FTOA_MAN_BITS - 4))); - if (!dec_f) { - break; - } - man_f = (npf_ftoa_man_t)(man_f * 10); - } - man_f = (npf_ftoa_man_t)(man_f << 4); - } - if (exp < NPF_DOUBLE_MAN_BITS) { - carry &= (uint_fast8_t)(man_f >> (NPF_FTOA_MAN_BITS - 1)); - } - } - - // Round the number - for (; carry; ++dec) { - if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { - goto exit; - } - if (dec >= end) { - buf[end++] = '0'; - } - if (buf[dec] == '.') { - continue; - } - carry = (buf[dec] == '9'); - buf[dec] = (char)(carry ? '0' : (buf[dec] + 1)); - } - - return (int)end; -exit: - if (!ret) { - ret = "RRE"; - } - uint_fast8_t i; - for (i = 0; ret[i]; ++i) { - buf[i] = (char)(ret[i] + spec->case_adjust); - } - return (int)i; -} - -#endif // NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 -static int npf_bin_len(npf_uint_t u) { - // Return the length of the binary string format of 'u', preferring - // intrinsics. - if (!u) { - return 1; - } - -#ifdef _MSC_VER // Win64, use _BSR64 for everything. If x86, use _BSR when - // non-large. -#ifdef _M_X64 -#define NPF_HAVE_BUILTIN_CLZ -#define NPF_CLZ _BitScanReverse64 -#elif NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 -#define NPF_HAVE_BUILTIN_CLZ -#define NPF_CLZ _BitScanReverse -#endif -#ifdef NPF_HAVE_BUILTIN_CLZ - unsigned long idx; - NPF_CLZ(&idx, u); - return (int)(idx + 1); -#endif -#elif NANOPRINTF_CLANG || NANOPRINTF_GCC_PAST_4_6 -#define NPF_HAVE_BUILTIN_CLZ -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 -#define NPF_CLZ(X) ((sizeof(long long) * CHAR_BIT) - (size_t)__builtin_clzll(X)) -#else -#define NPF_CLZ(X) ((sizeof(long) * CHAR_BIT) - (size_t)__builtin_clzl(X)) -#endif - return (int)NPF_CLZ(u); -#endif - -#ifndef NPF_HAVE_BUILTIN_CLZ - int n; - for (n = 0; u; ++n, u >>= 1) - ; // slow but small software fallback - return n; -#else -#undef NPF_HAVE_BUILTIN_CLZ -#undef NPF_CLZ -#endif -} -#endif - -static void npf_bufputc(int c, void *ctx) { - npf_bufputc_ctx_t *bpc = (npf_bufputc_ctx_t *)ctx; - if (bpc->cur < bpc->len) { - bpc->dst[bpc->cur++] = (char)c; - } -} - -static void npf_bufputc_nop(int c, void *ctx) { - (void)c; - (void)ctx; -} - -typedef struct npf_cnt_putc_ctx { - npf_putc pc; - void *ctx; - int n; -} npf_cnt_putc_ctx_t; - -static void npf_putc_cnt(int c, void *ctx) { - npf_cnt_putc_ctx_t *pc_cnt = (npf_cnt_putc_ctx_t *)ctx; - ++pc_cnt->n; - pc_cnt->pc(c, pc_cnt->ctx); // sibling-call optimization -} - -#define NPF_PUTC(VAL) \ - do { \ - npf_putc_cnt((int)(VAL), &pc_cnt); \ - } while (0) - -#define NPF_EXTRACT(MOD, CAST_TO, EXTRACT_AS) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: \ - val = (CAST_TO)va_arg(args, EXTRACT_AS); \ - break - -#define NPF_WRITEBACK(MOD, TYPE) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: \ - *(va_arg(args, TYPE *)) = (TYPE)pc_cnt.n; \ - break - -int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list args) { - npf_format_spec_t fs; - char const *cur = format; - npf_cnt_putc_ctx_t pc_cnt; - pc_cnt.pc = pc; - pc_cnt.ctx = pc_ctx; - pc_cnt.n = 0; - - while (*cur) { - int const fs_len = (*cur != '%') ? 0 : npf_parse_format_spec(cur, &fs); - if (!fs_len) { - NPF_PUTC(*cur++); - continue; - } - cur += fs_len; - - // Extract star-args immediately -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - if (fs.field_width_opt == NPF_FMT_SPEC_OPT_STAR) { - fs.field_width = va_arg(args, int); - if (fs.field_width < 0) { - fs.field_width = -fs.field_width; - fs.left_justified = 1; - } - } -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.prec_opt == NPF_FMT_SPEC_OPT_STAR) { - fs.prec = va_arg(args, int); - if (fs.prec < 0) { - fs.prec_opt = NPF_FMT_SPEC_OPT_NONE; - } - } -#endif - - union { - char cbuf_mem[NANOPRINTF_CONVERSION_BUFFER_SIZE]; - npf_uint_t binval; - } u; - char *cbuf = u.cbuf_mem, sign_c = 0; - int cbuf_len = 0, need_0x = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int field_pad = 0; - char pad_c = 0; -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - int prec_pad = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int zero = 0; -#endif -#endif - - // Extract and convert the argument to string, point cbuf at the text. - switch (fs.conv_spec) { - case NPF_FMT_SPEC_CONV_PERCENT: - *cbuf = '%'; - cbuf_len = 1; - break; - - case NPF_FMT_SPEC_CONV_CHAR: - *cbuf = (char)va_arg(args, int); - cbuf_len = 1; - break; - - case NPF_FMT_SPEC_CONV_STRING: { - cbuf = va_arg(args, char *); -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - for (char const *s = cbuf; - ((fs.prec_opt == NPF_FMT_SPEC_OPT_NONE) || (cbuf_len < fs.prec)) && - *s; - ++s, ++cbuf_len) - ; -#else - for (char const *s = cbuf; *s; ++s, ++cbuf_len) - ; // strlen -#endif - } break; - - case NPF_FMT_SPEC_CONV_SIGNED_INT: { - npf_int_t val = 0; - switch (fs.length_modifier) { - NPF_EXTRACT(NONE, int, int); - NPF_EXTRACT(SHORT, short, int); - NPF_EXTRACT(LONG_DOUBLE, int, int); - NPF_EXTRACT(CHAR, char, int); - NPF_EXTRACT(LONG, long, long); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, long long, long long); - NPF_EXTRACT(LARGE_INTMAX, intmax_t, intmax_t); - NPF_EXTRACT(LARGE_SIZET, npf_ssize_t, npf_ssize_t); - NPF_EXTRACT(LARGE_PTRDIFFT, ptrdiff_t, ptrdiff_t); -#endif - default: - break; - } - - sign_c = (val < 0) ? '-' : fs.prepend; - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = !val; -#endif - // special case, if prec and value are 0, skip - if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { - cbuf_len = 0; - } else -#endif - { - npf_uint_t uval = (npf_uint_t)val; - if (val < 0) { - uval = 0 - uval; - } - cbuf_len = npf_utoa_rev(uval, cbuf, 10, fs.case_adjust); - } - } break; - -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_BINARY: -#endif - case NPF_FMT_SPEC_CONV_OCTAL: - case NPF_FMT_SPEC_CONV_HEX_INT: - case NPF_FMT_SPEC_CONV_UNSIGNED_INT: { - npf_uint_t val = 0; - - switch (fs.length_modifier) { - NPF_EXTRACT(NONE, unsigned, unsigned); - NPF_EXTRACT(SHORT, unsigned short, unsigned); - NPF_EXTRACT(LONG_DOUBLE, unsigned, unsigned); - NPF_EXTRACT(CHAR, unsigned char, unsigned); - NPF_EXTRACT(LONG, unsigned long, unsigned long); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, unsigned long long, unsigned long long); - NPF_EXTRACT(LARGE_INTMAX, uintmax_t, uintmax_t); - NPF_EXTRACT(LARGE_SIZET, size_t, size_t); - NPF_EXTRACT(LARGE_PTRDIFFT, size_t, size_t); -#endif - default: - break; - } - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = !val; -#endif - if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { - // Zero value and explicitly-requested zero precision means "print - // nothing". - if ((fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) && fs.alt_form) { - fs.prec = 1; // octal special case, print a single '0' - } - } else -#endif -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { - cbuf_len = npf_bin_len(val); - u.binval = val; - } else -#endif - { - uint_fast8_t const base = - (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) - ? 8u - : ((fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) ? 16u : 10u); - cbuf_len = npf_utoa_rev(val, cbuf, base, fs.case_adjust); - } - - if (val && fs.alt_form && (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL)) { - cbuf[cbuf_len++] = '0'; // OK to add leading octal '0' immediately. - } - - if (val && fs.alt_form) { // 0x or 0b but can't write it yet. - if (fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) { - need_0x = 'X'; - } -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - else if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { - need_0x = 'B'; - } -#endif - if (need_0x) { - need_0x += fs.case_adjust; - } - } - } break; - - case NPF_FMT_SPEC_CONV_POINTER: { - cbuf_len = npf_utoa_rev((npf_uint_t)(uintptr_t)va_arg(args, void *), cbuf, - 16, 'a' - 'A'); - need_0x = 'x'; - } break; - -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_WRITEBACK: - switch (fs.length_modifier) { - NPF_WRITEBACK(NONE, int); - NPF_WRITEBACK(SHORT, short); - NPF_WRITEBACK(LONG, long); - NPF_WRITEBACK(LONG_DOUBLE, double); - NPF_WRITEBACK(CHAR, signed char); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_WRITEBACK(LARGE_LONG_LONG, long long); - NPF_WRITEBACK(LARGE_INTMAX, intmax_t); - NPF_WRITEBACK(LARGE_SIZET, size_t); - NPF_WRITEBACK(LARGE_PTRDIFFT, ptrdiff_t); -#endif - default: - break; - } - break; -#endif - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_FLOAT_DEC: - case NPF_FMT_SPEC_CONV_FLOAT_SCI: - case NPF_FMT_SPEC_CONV_FLOAT_SHORTEST: - case NPF_FMT_SPEC_CONV_FLOAT_HEX: { - double val; - if (fs.length_modifier == NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE) { - val = (double)va_arg(args, long double); - } else { - val = va_arg(args, double); - } - - sign_c = (val < 0.) ? '-' : fs.prepend; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - zero = (val == 0.); -#endif - cbuf_len = npf_ftoa_rev(cbuf, &fs, val); - } break; -#endif - default: - break; - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - // Compute the field width pad character - if (fs.field_width_opt != NPF_FMT_SPEC_OPT_NONE) { - if (fs.leading_zero_pad) { // '0' flag is only legal with numeric types - if ((fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_CHAR) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_PERCENT)) { -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if ((fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec && zero) { - pad_c = ' '; - } else -#endif - { - pad_c = '0'; - } - } - } else { - pad_c = ' '; - } - } -#endif - - // Compute the number of bytes to truncate or '0'-pad. -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) { -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - // float precision is after the decimal point - if (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_DEC) -#endif - { - prec_pad = npf_max(0, fs.prec - cbuf_len); - } - } -#endif - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - // Given the full converted length, how many pad bytes? - field_pad = fs.field_width - cbuf_len - !!sign_c; - if (need_0x) { - field_pad -= 2; - } -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - field_pad -= prec_pad; -#endif - field_pad = npf_max(0, field_pad); - - // Apply right-justified field width if requested - if (!fs.left_justified && pad_c) { // If leading zeros pad, sign goes first. - if (pad_c == '0') { - if (sign_c) { - NPF_PUTC(sign_c); - sign_c = 0; - } - // Pad byte is '0', write '0x' before '0' pad chars. - if (need_0x) { - NPF_PUTC('0'); - NPF_PUTC(need_0x); - } - } - while (field_pad-- > 0) { - NPF_PUTC(pad_c); - } - // Pad byte is ' ', write '0x' after ' ' pad chars but before number. - if ((pad_c != '0') && need_0x) { - NPF_PUTC('0'); - NPF_PUTC(need_0x); - } - } else -#endif - { - if (need_0x) { - NPF_PUTC('0'); - NPF_PUTC(need_0x); - } - } // no pad, '0x' requested. - - // Write the converted payload - if (fs.conv_spec == NPF_FMT_SPEC_CONV_STRING) { - for (int i = 0; i < cbuf_len; ++i) { - NPF_PUTC(cbuf[i]); - } - } else { - if (sign_c) { - NPF_PUTC(sign_c); - } -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - while (prec_pad-- > 0) { - NPF_PUTC('0'); - } // int precision leads. -#endif -#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { - while (cbuf_len) { - NPF_PUTC('0' + ((u.binval >> --cbuf_len) & 1)); - } - } else -#endif - { - while (cbuf_len-- > 0) { - NPF_PUTC(cbuf[cbuf_len]); - } - } // payload is reversed - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - if (fs.left_justified && pad_c) { // Apply left-justified field width - while (field_pad-- > 0) { - NPF_PUTC(pad_c); - } - } -#endif - } - - return pc_cnt.n; -} - -#undef NPF_PUTC -#undef NPF_EXTRACT -#undef NPF_WRITEBACK - -int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, ...) { - va_list val; - va_start(val, format); - int const rv = npf_vpprintf(pc, pc_ctx, format, val); - va_end(val); - return rv; -} - -int npf_snprintf(char *buffer, size_t bufsz, const char *format, ...) { - va_list val; - va_start(val, format); - int const rv = npf_vsnprintf(buffer, bufsz, format, val); - va_end(val); - return rv; -} - -int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, - va_list vlist) { - npf_bufputc_ctx_t bufputc_ctx; - bufputc_ctx.dst = buffer; - bufputc_ctx.len = bufsz; - bufputc_ctx.cur = 0; - - npf_putc const pc = buffer ? npf_bufputc : npf_bufputc_nop; - int const n = npf_vpprintf(pc, &bufputc_ctx, format, vlist); - pc('\0', &bufputc_ctx); - - if (buffer && bufsz) { -#ifdef NANOPRINTF_SNPRINTF_SAFE_EMPTY_STRING_ON_OVERFLOW - if (n >= (int)bufsz) { - buffer[0] = '\0'; - } -#else - buffer[bufsz - 1] = '\0'; -#endif - } - - return n; -} - -#if NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS -#pragma GCC diagnostic pop -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif // NANOPRINTF_IMPLEMENTATION_INCLUDED -#endif // NANOPRINTF_IMPLEMENTATION - -/* - nanoprintf is dual-licensed under both the "Unlicense" and the - "Zero-Clause BSD" (0BSD) licenses. The intent of this dual-licensing - structure is to make nanoprintf as consumable as possible in as many - environments / countries / companies as possible without any - encumberances. - - The text of the two licenses follows below: - - ============================== UNLICENSE ============================== - - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to - - ================================ 0BSD ================================= - - Copyright (C) 2019- by Charles Nicholson - - - Permission to use, copy, modify, and/or distribute this software for - any purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -void printf(char *format, ...); \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c deleted file mode 100644 index 61febba..0000000 --- a/kernel/src/sys/syscall.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "sched/sched.h" -#include -#include -#include -#include - -static syscall syscall_table[1024]; - -static int syscall_initialized = 0; - -extern void __x86_64_syscall_init(); - -// Stub function for undefined syscalls. -static uint64_t __syscall_undefined() { return 0; } - -void syscall_handle(registers_t *regs) { - if (regs->rax >= 1024) { - log("syscall - syscall_handle was called with rax better than what Soaplin " - "supports (1024). did you forget to set rax?\n"); - return; - } - - if (curr_proc == NULL || curr_proc->regs.cs != 0x43) { - log("syscall - syscall_handle was called by the kernel. is this wanted?\n"); - return; - } - - if (syscall_table[regs->rax] == (syscall)__syscall_undefined) { - log("syscall - syscall_handle was called with an undefined system call. " - "(%d)\n", - regs->rax); - return; - } - - log("Hello!\n"); - - regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, - regs->rcx, regs->r8, regs->r9); - return; -} - -void syscall_register(int id, syscall handler) { - if (syscall_table[id] != (syscall)__syscall_undefined) { - log("syscall - warning: syscall_register has been called to try replacing " - "an existing syscall.\n"); - return; - } - - syscall_table[id] = handler; - log("syscall - System call %d has been set to %p\n", id, handler); -} - -extern void syscall_write(int fd, const char *buf, size_t count); -extern void syscall_exit(int exit_code); - -void syscall_init() { - for (int i = 0; i < 1024; i++) - syscall_table[i] = (syscall)__syscall_undefined; - - syscall_register(1, (syscall)syscall_write); - syscall_register(60, (syscall)syscall_exit); - - __x86_64_syscall_init(); -} \ No newline at end of file diff --git a/kernel/src/sys/syscall.h b/kernel/src/sys/syscall.h deleted file mode 100644 index d428af6..0000000 --- a/kernel/src/sys/syscall.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "arch/x86_64/idt.h" -#include - -/// A function that defines a system call. -/// NOTE: Arguments are defined as uint64_t, but you can simply put your own -/// type, and then cast your function to syscall. -typedef uint64_t (*syscall)(uint64_t rdi, uint64_t rsi, uint64_t rdx, - uint64_t rcx, uint64_t r8, uint64_t r9); - -/// Registers a system call. -/// NOTE: an existing system call cannot be replaced by another. -void syscall_register(int id, syscall handler); - -/// Called by the interupt handler, or the "syscall" instruction handler -void syscall_handle(registers_t *); - -/// Initialize the system calls. -void syscall_init(); \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_fs.c b/kernel/src/sys/syscalls/syscalls_fs.c deleted file mode 100644 index a89b106..0000000 --- a/kernel/src/sys/syscalls/syscalls_fs.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int syscall_write(int fd, const char *buf, size_t count) { - if (fd == 1) { - printf("%s", buf); // Prevent the buffer from being formatted. - return count; - } - - return 0; -} \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_proc.c b/kernel/src/sys/syscalls/syscalls_proc.c deleted file mode 100644 index 962d341..0000000 --- a/kernel/src/sys/syscalls/syscalls_proc.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int syscall_exit(int exit_code) { - sched_exit(exit_code); - return 0; -} \ No newline at end of file diff --git a/kernel/src/sys/uname.h b/kernel/src/sys/uname.h deleted file mode 100644 index 516d1f4..0000000 --- a/kernel/src/sys/uname.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -typedef struct __uname { - char sysname[128]; /* Operating system name */ - char nodename[128]; /* Name within communications network - to which the node is attached, if any */ - char release[128]; /* Operating system release */ - char version[128]; /* Operating system version */ - char machine[128]; /* Hardware type identifier */ -#ifdef _GNU_SOURCE - char domainname[]; /* NIS or YP domain name */ -#endif -} uname_t; \ No newline at end of file diff --git a/limine.conf b/limine.conf old mode 100755 new mode 100644 index df98d06..dc83e62 --- a/limine.conf +++ b/limine.conf @@ -1,9 +1,6 @@ -timeout: 3 -serial: yes -verbose: yes +timeout: 0 +quiet: yes -/SILD - Soaplin 1.0 +/Soaplin protocol: limine - - path: boot():/boot/soaplin - module_path: boot():/sk-hello.elf \ No newline at end of file + path: boot():/boot/kernel diff --git a/strings.txt b/strings.txt deleted file mode 100644 index 843bc51..0000000 --- a/strings.txt +++ /dev/null @@ -1,2709 +0,0 @@ -[A\] -AVAUATSH -E>E1 -[A\A]A^] -[A\A]] -AWAVAUATSH -\$ I -8f;X8 -_AXL9 -[A\A]A^A_] -@ff. -P#RH - AVAUATSH -T$ H -[A\A]A^A_] -D$(I -D$ I -\$HA -\$`A -d$8E -|$DL -D$(H -T$0I -D$ A - ff. -[A\] -H+= -AWAVAUATSH -tGE1 -[A\A]A^A_] -[A\A]A^A_] -[A\A]] -AWAVAUATSH -s6ff. -8[A\A]A^A_] -[A\A]A^] -AWAVI -[A\A]A^A_] -AVAUI -[A\A]A^] -[A\A]A^] -AXAYH -AUATI -s1H; -AUATSH -r%M9 -t&ff. -[A\A]] -AVAUATSH -[A\A]A^] -AVAUATSH -[A\A]A^] -AWAVAUATSH -tLff. -[A\A]A^A_] -[A\A]A^A_] -[A\] -AWAVAUATSH -P[A\A]A^A_] -AWAVAUATSL -[A\A]A^A_] -AWAVAUATSD -[A\A]A^A_] -[A\A]A^A_] -AWAVAUATSH - [A\A]A^A_] -AWAVAUA -ATSL -> tVI -[A\A]A^A_] -ATSH -UHE1 -UPE1 -[A\A]A^A_] -AWAVL -AUATI -E@<7 -([A\A]A^A_] -S@< -H9Ch -<5w2 -SxH9 -SxE1 -CpH9 -s H9 -KxE1 -KxI9 -kxI9 -sxH9 -KxH9 -KhH9 -spH9 -r H9 -SxH9 -8ff. -AWAVAUI -ATSH -x[A\A]A^A_] -<-t`H - ff. -tMHc -/v:H -ATSH -[A\] -[A\D -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j!PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j"PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j#PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j$PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j%PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j&PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j'PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j(PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j)PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j*PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j+PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j,PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j-PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j.PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j/PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j0PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j1PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j2PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j3PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j4PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j5PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j6PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j7PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j8PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j9PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j:PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j;PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j?PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j@PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jAPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jBPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jCPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jDPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jEPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jFPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jGPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jHPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jIPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jJPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jKPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jLPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jMPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jNPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jOPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jPPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jQPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jRPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jSPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jTPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jUPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jVPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jWPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jXPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jYPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jZPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j[PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j\PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j]PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j^PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j_PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j`PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jaPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jbPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jcPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jdPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jePQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jfPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jgPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jhPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jiPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jjPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jkPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jlPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jmPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jnPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -joPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jpPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jqPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jrPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jsPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jtPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -juPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jvPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jwPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jxPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jyPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -jzPQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j{PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j|PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j}PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -j~PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -PQRSUVWAPAQARASATAUAVAWH -A_A^A]A\A[AZAYAX_^][ZYXH -sj;r -\-+V -kSDI8{j -C{~9k{ -Exc' -bLv1 -gdt - initialized. -idt - initialized -A CPU exception occured. -smp - detected %d CPUs -smp - initialized -.strtab -kernel - loaded %d symbols -ioapic - initialized -lapic - initialized -elf - e_ident[EI_DATA]: %d -elf - e_ident[EI_CLASS]: %d -elf - e_ident[EI_OSABI]: %d -elf - e_machine: %d -elf - e_entry: %p -elf - e_type: %p -elf - e_phnum: %p -elf - ELF segment type: %d -elf - memset(%p, 0, 0x1000) -elf - memcpy(%p, %p, %d) -ksym: found %s at %p -ksym: not found -Test -pmm - out of memory. -vmm - initialized! -RSD PTR -acpi: Invalid RSDP signature! -APIC --- REGISTER DUMP -- -R13: %p, R14: %p, R15: %p -RSP: %p --- PAGE FAULT DETAILS -- -Error Code: %d -Flags: - - Page Not Present - - Protection Violation - - Write Access - - Read Access - - User-Mode Access - - Kernel-Mode Access - - Reserved Bits Set - - Instruction Fetch --- BACKTRACE -- -* %p (current) -* %p -1970-01-01 00:00:00 | -Hello! -smp - CPU %d started (LAPIC ID: %d) -smp - CPU %d is the bootstrap processor (LAPIC ID: %d) -kernel - how did i even boot? *starts galaxy brain meme* -elf - loading failed: magic is incorrect -elf - loading failed: is the file built for amd64? -elf - loading failed: ELF type isn't ET_EXEC -elf - loaded ELF program in memory. -elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset 0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx -elf - pmm page alloc failed. out of memory? -elf - vmm_map_user(%p, %p, %p, %d) -elf - vmm_map(%p, %p, %p, %d) - Soaplin 0.7-sild is booting up your computer... -kernel - vma ctx creation failed. halting -kernel - Soaplin initialized sucessfully. -pmm - %dmb is available to us. -pmm - could not free the page: stack overflow. -vma - creating VMA context with pagemap: 0x%.16llx -vma - failed to allocate VMA context -vma - allocated VMA context at 0x%.16llx -vma - zeroed out VMA context at 0x%.16llx -vma - failed to allocate root region -vma - allocated root region at 0x%.16llx -vma - VMA context created at 0x%.16llx with root region at 0x%.16llx -vma - invalid context or root passed to vma_alloc -vma - failed to allocate new VMA region -vma - failed to allocate physical memory for VMA region -vmm - Soaplin only supports 4-level paging! -vmm - mapping .requests section... -vmm - mapping .text section... -vmm - mapping .rodata section... -vmm - mapping .data section... -vmm - mapping address from 0x0 to 0x100000000... -sched - As there's nothing to schedule, the scheduler entered standbymode. -sched - Standby mode has beendisabled. -sched - created process '%s' (pid: %d, rip: %p) -sched - Process %d exited with code %d! -madt: Failed to find MADT table! -RDI: %p, RSI: %p, RDX: %p, RCX: %p, R8: %p, R9: %p -RAX: %p, RBP: %p, RBX: %p, R10: %p, R11: %p, R12: %p -RIP: %p, CS: %x, SS: %x, RFLAGS: %d, INTERRUPT: %d, ERROR CODE: %d -This appears to be a page fault. -Faulting Address (CR2): 0x%lx - _ __ _ ___ _ -| |/ /___ _ _ _ _ ___| | | _ \__ _ _ _ (_)__ -| ' -8ll8 -6666666 -66666666 -66666666 -66666 -666666666666666666666666 -6666666666666 -6666666 -66666667666666666666670? -?076666666666666 -666666666666670766666666 -66666 -66666666 -6666666 -666666666666666? -?666666666666666 -66666666 -lllllll -fffff|`` -ffff< -0``|```0 -8ll8 -lllll -||||||| - rsp -$ ist -#log -&isr -(isr - low - low -%log -%log -+log -2msr -3low -!log -(cr2 -/bpp -/map -8$3% -U)bg -U)fg -U)bg -U)fg - ctx - ctx - ctx - ctx - ctx - ctx -Fret -$osc -$rrr -!ctx -!ctx -!ctx - ctx - ucs - ucs - max - ctx - ctx - ctx - ctx - ctx - ctx - ctx - ctx - ctx -6sgr -'ctx -8def -9out -)ctx -)buf -'ctx - 'buf -o'lst - #val - #val -!cur -src/arch/x86_64/idt.asm -/home/raphm/Projets/sild/soaplin/kernel/src/arch/x86_64/ -NASM 2.16.03 -src/arch/x86_64/syscall.asm -/home/raphm/Projets/sild/soaplin/kernel/src/arch/x86_64/ -NASM 2.16.03 -src/premain.asm -/home/raphm/Projets/sild/soaplin/kernel/src/ -NASM 2.16.03 -:! ; -!(:! -9!1I -Y!*W! - &3$ - &4$ - &4$ - &4$ - &4$ -U#P<% - $0."@ -U#P<% - $0." -*P s -Tk s -*k s -*k s - O s -Sl s - l s - l s -;t s -Yt s -;t s -Yt s -.. X -.] X - * x -.i=I -& -flanterm.h -src/sys/printf.c -src/sys/syscall.c -src/sys/syscalls/syscalls_proc.c -src/sys/syscalls -GCC: (GNU) 15.1.1 20250425 -gdt.c -idt.c -vectors -idtr -io.c -pit.c -smp.c -smp_request -syscall.c -sym.c -exec_file_rq -__ksym_symtab -__ksym_symcount -__ksym_strtab -ioapic.c -lapic.c -elf.c -string.c -main.c -framebuffer_request -module_request -limine_requests_end_marker -limine_requests_start_marker -limine_base_revision -liballoc.c -allocate_new_page -l_allocated -l_warningCount -l_memRoot -l_bestBet -l_inuse -liballoc_soaplin.c -liballoc_lock_var -memop.c -pmm.c -vma.c -vmm.c -__vmm_get_next_lvl -pmrq -sched.c -schedule.part.0 -acpi.c -__acpi_rsdt_ptr -__acpi_uses_xsdt -rsdp_req -madt.c -panic.c -__panic_display_regs -__panic_regdump -fb.c -bump_alloc -base_offset_added.0 -bump_alloc_ptr -bump_alloc_pool -flanterm_fb_save_state -flanterm_fb_restore_state -flanterm_fb_swap_palette -push_to_queue -flanterm_fb_revscroll -flanterm_fb_scroll -flanterm_fb_set_cursor_pos -flanterm_fb_get_cursor_pos -flanterm_fb_move_character -flanterm_fb_set_text_fg -flanterm_fb_set_text_bg -flanterm_fb_set_text_fg_bright -flanterm_fb_set_text_bg_bright -flanterm_fb_set_text_fg_rgb -flanterm_fb_set_text_bg_rgb -flanterm_fb_set_text_fg_default -flanterm_fb_set_text_bg_default -flanterm_fb_set_text_fg_default_bright -flanterm_fb_set_text_bg_default_bright -draw_cursor -flanterm_fb_double_buffer_flush -flanterm_fb_full_refresh -flanterm_fb_deinit -bump_allocated_instance -plot_char_scaled_canvas -plot_char_unscaled_canvas -plot_char_unscaled_uncanvas -plot_char_scaled_uncanvas -flanterm_fb_clear -flanterm_fb_raw_putchar -builtin_font -flanterm.c -combining.0 -col256 -log.c -printf.c -npf_utoa_rev -npf_bufputc -npf_bufputc_nop -__syscall_undefined -syscall_table -syscalls_proc.c -src/arch/x86_64/idt.asm -isr_stub_0 -isr_stub_1 -isr_stub_2 -isr_stub_3 -isr_stub_4 -isr_stub_5 -isr_stub_6 -isr_stub_7 -isr_stub_8 -isr_stub_9 -isr_stub_10 -isr_stub_11 -isr_stub_12 -isr_stub_13 -isr_stub_14 -isr_stub_15 -isr_stub_16 -isr_stub_17 -isr_stub_18 -isr_stub_19 -isr_stub_20 -isr_stub_21 -isr_stub_22 -isr_stub_23 -isr_stub_24 -isr_stub_25 -isr_stub_26 -isr_stub_27 -isr_stub_28 -isr_stub_29 -isr_stub_30 -isr_stub_31 -isr_stub_32 -isr_stub_33 -isr_stub_34 -isr_stub_35 -isr_stub_36 -isr_stub_37 -isr_stub_38 -isr_stub_39 -isr_stub_40 -isr_stub_41 -isr_stub_42 -isr_stub_43 -isr_stub_44 -isr_stub_45 -isr_stub_46 -isr_stub_47 -isr_stub_48 -isr_stub_49 -isr_stub_50 -isr_stub_51 -isr_stub_52 -isr_stub_53 -isr_stub_54 -isr_stub_55 -isr_stub_56 -isr_stub_57 -isr_stub_58 -isr_stub_59 -isr_stub_60 -isr_stub_61 -isr_stub_62 -isr_stub_63 -isr_stub_64 -isr_stub_65 -isr_stub_66 -isr_stub_67 -isr_stub_68 -isr_stub_69 -isr_stub_70 -isr_stub_71 -isr_stub_72 -isr_stub_73 -isr_stub_74 -isr_stub_75 -isr_stub_76 -isr_stub_77 -isr_stub_78 -isr_stub_79 -isr_stub_80 -isr_stub_81 -isr_stub_82 -isr_stub_83 -isr_stub_84 -isr_stub_85 -isr_stub_86 -isr_stub_87 -isr_stub_88 -isr_stub_89 -isr_stub_90 -isr_stub_91 -isr_stub_92 -isr_stub_93 -isr_stub_94 -isr_stub_95 -isr_stub_96 -isr_stub_97 -isr_stub_98 -isr_stub_99 -isr_stub_100 -isr_stub_101 -isr_stub_102 -isr_stub_103 -isr_stub_104 -isr_stub_105 -isr_stub_106 -isr_stub_107 -isr_stub_108 -isr_stub_109 -isr_stub_110 -isr_stub_111 -isr_stub_112 -isr_stub_113 -isr_stub_114 -isr_stub_115 -isr_stub_116 -isr_stub_117 -isr_stub_118 -isr_stub_119 -isr_stub_120 -isr_stub_121 -isr_stub_122 -isr_stub_123 -isr_stub_124 -isr_stub_125 -isr_stub_126 -isr_stub_127 -isr_stub_128 -isr_stub_129 -isr_stub_130 -isr_stub_131 -isr_stub_132 -isr_stub_133 -isr_stub_134 -isr_stub_135 -isr_stub_136 -isr_stub_137 -isr_stub_138 -isr_stub_139 -isr_stub_140 -isr_stub_141 -isr_stub_142 -isr_stub_143 -isr_stub_144 -isr_stub_145 -isr_stub_146 -isr_stub_147 -isr_stub_148 -isr_stub_149 -isr_stub_150 -isr_stub_151 -isr_stub_152 -isr_stub_153 -isr_stub_154 -isr_stub_155 -isr_stub_156 -isr_stub_157 -isr_stub_158 -isr_stub_159 -isr_stub_160 -isr_stub_161 -isr_stub_162 -isr_stub_163 -isr_stub_164 -isr_stub_165 -isr_stub_166 -isr_stub_167 -isr_stub_168 -isr_stub_169 -isr_stub_170 -isr_stub_171 -isr_stub_172 -isr_stub_173 -isr_stub_174 -isr_stub_175 -isr_stub_176 -isr_stub_177 -isr_stub_178 -isr_stub_179 -isr_stub_180 -isr_stub_181 -isr_stub_182 -isr_stub_183 -isr_stub_184 -isr_stub_185 -isr_stub_186 -isr_stub_187 -isr_stub_188 -isr_stub_189 -isr_stub_190 -isr_stub_191 -isr_stub_192 -isr_stub_193 -isr_stub_194 -isr_stub_195 -isr_stub_196 -isr_stub_197 -isr_stub_198 -isr_stub_199 -isr_stub_200 -isr_stub_201 -isr_stub_202 -isr_stub_203 -isr_stub_204 -isr_stub_205 -isr_stub_206 -isr_stub_207 -isr_stub_208 -isr_stub_209 -isr_stub_210 -isr_stub_211 -isr_stub_212 -isr_stub_213 -isr_stub_214 -isr_stub_215 -isr_stub_216 -isr_stub_217 -isr_stub_218 -isr_stub_219 -isr_stub_220 -isr_stub_221 -isr_stub_222 -isr_stub_223 -isr_stub_224 -isr_stub_225 -isr_stub_226 -isr_stub_227 -isr_stub_228 -isr_stub_229 -isr_stub_230 -isr_stub_231 -isr_stub_232 -isr_stub_233 -isr_stub_234 -isr_stub_235 -isr_stub_236 -isr_stub_237 -isr_stub_238 -isr_stub_239 -isr_stub_240 -isr_stub_241 -isr_stub_242 -isr_stub_243 -isr_stub_244 -isr_stub_245 -isr_stub_246 -isr_stub_247 -isr_stub_248 -isr_stub_249 -isr_stub_250 -isr_stub_251 -isr_stub_252 -isr_stub_253 -isr_stub_254 -isr_stub_255 -src/arch/x86_64/syscall.asm -src/premain.asm -font.c -smp_init -acpi_madt_iso_length -flanterm_fb_init -rodata_end_ld -syscall_handle -sched_exit -kernel_vma_context -liballoc_unlock -lapic_eoi -proc_list -hhdm_offset -acpi_madt_ioapic_list -vmm_init -memcpy -acpi_init -ioapic_get_gsi -malloc -lapic_init -vma_create_context -standby -karq -reqs_end_ld -vmm_alloc_pm -gdt_init -rodata_start_ld -ioapic_init -__kmain -curr_proc -ksym_init -ioapic_redirect_irq -schedule -bootstrap_lapic_id -pit_enable -virt_to_phys -liballoc_lock -pit_init -npf_vsnprintf -vma_alloc -idt_init -smp_entry -pmm_request_page -vmm_map -acpi_madt_ioapic_length -hhdm_req -acpi_madt_iso_list -panic_ctx -current_pid -flanterm_write -vmm_release_pm -irq_handler_table -liballoc_alloc -__x86_64_syscall_init -__panic_display_ascii_art -syscall_exit -npf_vpprintf -panic -vmm_kernel_pm_exists -memcmp -sched_create -tick -vmm_kernel_pm -ksym_fromip -outb -def_table -ft_ctx -memset -pmm_free_page -idt_int_handler -acpi_lapic_addr -flanterm_context_reinit -strcmp -vmm_map_user -acpi_find_table -idt_register_irq -VGA8 -text_end_ld -pmm_init -ioapic_redirect_gsi -reqs_start_ld -pit_handler -smp_cpu_count -vmm_current_pm -tss_list -isr_stub_table -vmm_load_pagemap -mk_wcwidth -sched_init -strlen -madt_init -text_start_ld -mm_req -syscall_entry -elf_load -kstack -_memmap -.symtab -.strtab -.shstrtab -.text -.limine_requests -.rodata -.data -.bss -.debug_info -.debug_abbrev -.debug_loclists -.debug_aranges -.debug_rnglists -.debug_line -.debug_str -.debug_line_str -.comment diff --git a/testing/build.sh b/testing/build.sh deleted file mode 100755 index ff9f5f5..0000000 --- a/testing/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -nasm -f elf64 test.asm -o test.o -ld -T link.ld -nostdlib --no-dynamic-linker --strip-all test.o -o sk-hello.elf -echo "Test executable has been built successfully." \ No newline at end of file diff --git a/testing/link.ld b/testing/link.ld deleted file mode 100644 index d234f6a..0000000 --- a/testing/link.ld +++ /dev/null @@ -1,23 +0,0 @@ -OUTPUT_FORMAT("elf64-x86-64") -ENTRY(_start) - -SECTIONS { - . = 0x100000; - - .text : { - *(.text) - } - - .rodata : { - *(.rodata) - } - - .data : { - *(.data) - } - - .bss : { - *(COMMON) - *(.bss) - } -} \ No newline at end of file diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf deleted file mode 100755 index cff52868face31f7facb3cb71fb5d455a1ac0fff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4480 zcmeI0ziz@X5XQ}a2?prIhHhd)o|zB}6$4uyj2Eh~xfL76 ztvp%A6Jf=_{9DiM;!oeMcEk4v45LaflkhqboO$@Y9oU^!JFqLGV_E7bGeA&xxMi&8}NV=`ZCok{`%6U4*l)Bi_S!0(USeaQ2LTR0{*xbP!s30lJZ(;)dRlSoR;lD|M diff --git a/txt.txt b/txt.txt deleted file mode 100644 index 3e59680..0000000 --- a/txt.txt +++ /dev/null @@ -1,559 +0,0 @@ -En-tête ELF: - Magique: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 - Classe: ELF64 - Données: complément à 2, système à octets de poids faible d'abord (little endian) - Version: 1 (actuelle) - OS/ABI: UNIX - System V - Version ABI: 0 - Type: EXEC (fichier exécutable) - Machine: Advanced Micro Devices X86-64 - Version: 0x1 - Adresse du point d'entrée: 0xffffffff8000d040 - Début des en-têtes de programme : 64 (octets dans le fichier) - Début des en-têtes de section : 308160 (octets dans le fichier) - Fanions: 0x0 - Taille de cet en-tête: 64 (octets) - Taille de l'en-tête du programme: 56 (octets) - Nombre d'en-tête du programme: 4 - Taille des en-têtes de section: 64 (octets) - Nombre d'en-têtes de section: 18 - Table d'index des chaînes d'en-tête de section: 17 - -En-têtes de section : - [Nr] Nom Type Adresse Décalage - Taille TaillEntrée Fanion Lien Info Alignement - [ 0] NULL 0000000000000000 00000000 - 0000000000000000 0000000000000000 0 0 0 - [ 1] .text PROGBITS ffffffff80000000 00001000 - 000000000000d052 0000000000000000 AX 0 0 64 - [ 2] .limine_requests PROGBITS ffffffff8000e000 0000f000 - 00000000000002a0 0000000000000000 WA 0 0 32 - [ 3] .rodata PROGBITS ffffffff8000f000 00010000 - 0000000000004de0 0000000000000000 A 0 0 32 - [ 4] .data PROGBITS ffffffff80014000 00015000 - 0000000000001060 0000000000000000 WA 0 0 32 - [ 5] .bss NOBITS ffffffff80015060 00016060 - 00000000000e2f00 0000000000000000 WA 0 0 32 - [ 6] .debug_info PROGBITS 0000000000000000 00016060 - 0000000000010054 0000000000000000 0 0 1 - [ 7] .debug_abbrev PROGBITS 0000000000000000 000260b4 - 0000000000003d55 0000000000000000 0 0 1 - [ 8] .debug_loclists PROGBITS 0000000000000000 00029e09 - 000000000000b554 0000000000000000 0 0 1 - [ 9] .debug_aranges PROGBITS 0000000000000000 0003535d - 0000000000000d70 0000000000000000 0 0 1 - [10] .debug_rnglists PROGBITS 0000000000000000 000360cd - 00000000000017ea 0000000000000000 0 0 1 - [11] .debug_line PROGBITS 0000000000000000 000378b7 - 000000000000ce27 0000000000000000 0 0 1 - [12] .debug_str PROGBITS 0000000000000000 000446de - 0000000000002468 0000000000000001 MS 0 0 1 - [13] .debug_line_str PROGBITS 0000000000000000 00046b46 - 0000000000000474 0000000000000001 MS 0 0 1 - [14] .comment PROGBITS 0000000000000000 00046fba - 000000000000001b 0000000000000001 MS 0 0 1 - [15] .symtab SYMTAB 0000000000000000 00046fd8 - 0000000000002b68 0000000000000018 16 359 8 - [16] .strtab STRTAB 0000000000000000 00049b40 - 00000000000017bc 0000000000000000 0 0 1 - [17] .shstrtab STRTAB 0000000000000000 0004b2fc - 00000000000000be 0000000000000000 0 0 1 -Clé des fanions : - W (écriture), A (allocation), X (exécution), M (fusion), S (chaînes), I (info), - L (ordre des liens), O (traitement supplémentaire par l'OS requis), G (groupe), - T (TLS), C (compressé), x (inconnu), o (spécifique à l'OS), E (exclu), - D (mbind), l (grand), p (processor specific) - -Il n'y a pas de groupe de section dans ce fichier. - -En-têtes de programme : - Type Décalage Adr.virt Adr.phys. - Taille fichier Taille mémoire Fanion Alignement - LOAD 0x000000000000f000 0xffffffff8000e000 0xffffffff8000e000 - 0x00000000000002a0 0x00000000000002a0 RW 0x1000 - LOAD 0x0000000000001000 0xffffffff80000000 0xffffffff80000000 - 0x000000000000d052 0x000000000000d052 R E 0x1000 - LOAD 0x0000000000010000 0xffffffff8000f000 0xffffffff8000f000 - 0x0000000000004de0 0x0000000000004de0 R 0x1000 - LOAD 0x0000000000015000 0xffffffff80014000 0xffffffff80014000 - 0x0000000000001060 0x00000000000e3f60 RW 0x1000 - - Correspondance section/segment : - Sections de segment... - 00 .limine_requests - 01 .text - 02 .rodata - 03 .data .bss - -Il n'y a pas de section dynamique dans ce fichier. - -Il n'y a pas de réadressages dans ce fichier. -Pas d'information de déroulement spécifique au processeur à décoder - -La table de symboles « .symtab » contient 463 entrées : - Num: Valeur Tail Type Lien Vis Ndx Nom - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND - 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS gdt.c - 2: 0000000000000000 0 FILE LOCAL DEFAULT ABS idt.c - 3: ffffffff8001cb70 4096 OBJECT LOCAL DEFAULT 5 idt - 4: ffffffff8001c760 1024 OBJECT LOCAL DEFAULT 5 vectors - 5: ffffffff8001cb60 10 OBJECT LOCAL DEFAULT 5 idtr - 6: 0000000000000000 0 FILE LOCAL DEFAULT ABS io.c - 7: 0000000000000000 0 FILE LOCAL DEFAULT ABS pit.c - 8: 0000000000000000 0 FILE LOCAL DEFAULT ABS smp.c - 9: ffffffff8000e020 56 OBJECT LOCAL DEFAULT 2 smp_request - 10: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscall.c - 11: 0000000000000000 0 FILE LOCAL DEFAULT ABS sym.c - 12: ffffffff8000e060 48 OBJECT LOCAL DEFAULT 2 exec_file_rq - 13: ffffffff8001db90 8 OBJECT LOCAL DEFAULT 5 __ksym_symtab - 14: ffffffff8001db80 4 OBJECT LOCAL DEFAULT 5 __ksym_symcount - 15: ffffffff8001db88 8 OBJECT LOCAL DEFAULT 5 __ksym_strtab - 16: 0000000000000000 0 FILE LOCAL DEFAULT ABS ioapic.c - 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS lapic.c - 18: 0000000000000000 0 FILE LOCAL DEFAULT ABS elf.c - 19: 0000000000000000 0 FILE LOCAL DEFAULT ABS string.c - 20: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c - 21: ffffffff8000e0e0 48 OBJECT LOCAL DEFAULT 2 framebuffer_request - 22: ffffffff8000e0a0 64 OBJECT LOCAL DEFAULT 2 module_request - 23: ffffffff8000e290 16 OBJECT LOCAL DEFAULT 2 limine_requests_[...] - 24: ffffffff8000e000 32 OBJECT LOCAL DEFAULT 2 limine_requests_[...] - 25: ffffffff8000e110 24 OBJECT LOCAL DEFAULT 2 limine_base_revision - 26: 0000000000000000 0 FILE LOCAL DEFAULT ABS liballoc.c - 27: ffffffff80000fb0 129 FUNC LOCAL DEFAULT 1 allocate_new_page - 28: ffffffff8001fbc0 8 OBJECT LOCAL DEFAULT 5 l_allocated - 29: ffffffff8001fbb0 8 OBJECT LOCAL DEFAULT 5 l_warningCount - 30: ffffffff8001fbd0 8 OBJECT LOCAL DEFAULT 5 l_memRoot - 31: ffffffff8001fbc8 8 OBJECT LOCAL DEFAULT 5 l_bestBet - 32: ffffffff8001fbb8 8 OBJECT LOCAL DEFAULT 5 l_inuse - 33: 0000000000000000 0 FILE LOCAL DEFAULT ABS liballoc_soaplin.c - 34: ffffffff8001fbd8 4 OBJECT LOCAL DEFAULT 5 liballoc_lock_var - 35: 0000000000000000 0 FILE LOCAL DEFAULT ABS memop.c - 36: 0000000000000000 0 FILE LOCAL DEFAULT ABS pmm.c - 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS vma.c - 38: 0000000000000000 0 FILE LOCAL DEFAULT ABS vmm.c - 39: ffffffff80001a20 144 FUNC LOCAL DEFAULT 1 __vmm_get_next_lvl - 40: ffffffff8000e200 72 OBJECT LOCAL DEFAULT 2 pmrq - 41: 0000000000000000 0 FILE LOCAL DEFAULT ABS sched.c - 42: ffffffff80002050 254 FUNC LOCAL DEFAULT 1 schedule.part.0 - 43: 0000000000000000 0 FILE LOCAL DEFAULT ABS acpi.c - 44: ffffffff8001fc40 8 OBJECT LOCAL DEFAULT 5 __acpi_rsdt_ptr - 45: ffffffff8001fc48 4 OBJECT LOCAL DEFAULT 5 __acpi_uses_xsdt - 46: ffffffff8000e260 48 OBJECT LOCAL DEFAULT 2 rsdp_req - 47: 0000000000000000 0 FILE LOCAL DEFAULT ABS madt.c - 48: 0000000000000000 0 FILE LOCAL DEFAULT ABS panic.c - 49: ffffffff80002790 527 FUNC LOCAL DEFAULT 1 __panic_display_regs - 50: ffffffff80020c60 176 OBJECT LOCAL DEFAULT 5 __panic_regdump - 51: 0000000000000000 0 FILE LOCAL DEFAULT ABS fb.c - 52: ffffffff80002cd0 75 FUNC LOCAL DEFAULT 1 bump_alloc - 53: ffffffff80020d10 1 OBJECT LOCAL DEFAULT 5 base_offset_added.0 - 54: ffffffff80020d18 8 OBJECT LOCAL DEFAULT 5 bump_alloc_ptr - 55: ffffffff80020d20 0xd5228 OBJECT LOCAL DEFAULT 5 bump_alloc_pool - 56: ffffffff80002d20 43 FUNC LOCAL DEFAULT 1 flanterm_fb_save[...] - 57: ffffffff80002d50 43 FUNC LOCAL DEFAULT 1 flanterm_fb_rest[...] - 58: ffffffff80002d80 27 FUNC LOCAL DEFAULT 1 flanterm_fb_swap[...] - 59: ffffffff80002da0 163 FUNC LOCAL DEFAULT 1 push_to_queue - 60: ffffffff80002e50 211 FUNC LOCAL DEFAULT 1 flanterm_fb_revscroll - 61: ffffffff80002f30 213 FUNC LOCAL DEFAULT 1 flanterm_fb_scroll - 62: ffffffff80003010 69 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 63: ffffffff80003060 60 FUNC LOCAL DEFAULT 1 flanterm_fb_get_[...] - 64: ffffffff800030a0 113 FUNC LOCAL DEFAULT 1 flanterm_fb_move[...] - 65: ffffffff80003120 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 66: ffffffff80003130 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 67: ffffffff80003140 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 68: ffffffff80003150 14 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 69: ffffffff80003160 55 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 70: ffffffff800031a0 55 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 71: ffffffff800031e0 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 72: ffffffff800031f0 11 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 73: ffffffff80003200 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 74: ffffffff80003210 13 FUNC LOCAL DEFAULT 1 flanterm_fb_set_[...] - 75: ffffffff80003220 238 FUNC LOCAL DEFAULT 1 draw_cursor - 76: ffffffff80003310 346 FUNC LOCAL DEFAULT 1 flanterm_fb_doub[...] - 77: ffffffff80003480 368 FUNC LOCAL DEFAULT 1 flanterm_fb_full[...] - 78: ffffffff800035f0 185 FUNC LOCAL DEFAULT 1 flanterm_fb_deinit - 79: ffffffff80020d11 1 OBJECT LOCAL DEFAULT 5 bump_allocated_i[...] - 80: ffffffff800036b0 469 FUNC LOCAL DEFAULT 1 plot_char_scaled[...] - 81: ffffffff80003890 289 FUNC LOCAL DEFAULT 1 plot_char_unscal[...] - 82: ffffffff800039c0 311 FUNC LOCAL DEFAULT 1 plot_char_unscal[...] - 83: ffffffff80003b00 416 FUNC LOCAL DEFAULT 1 plot_char_scaled[...] - 84: ffffffff80003ca0 256 FUNC LOCAL DEFAULT 1 flanterm_fb_clear - 85: ffffffff80003da0 395 FUNC LOCAL DEFAULT 1 flanterm_fb_raw_[...] - 86: ffffffff8000ffa0 4096 OBJECT LOCAL DEFAULT 3 builtin_font - 87: 0000000000000000 0 FILE LOCAL DEFAULT ABS flanterm.c - 88: ffffffff80013100 1136 OBJECT LOCAL DEFAULT 3 combining.0 - 89: ffffffff80013580 960 OBJECT LOCAL DEFAULT 3 col256 - 90: 0000000000000000 0 FILE LOCAL DEFAULT ABS log.c - 91: 0000000000000000 0 FILE LOCAL DEFAULT ABS printf.c - 92: ffffffff80006c40 113 FUNC LOCAL DEFAULT 1 npf_utoa_rev - 93: ffffffff80006cc0 26 FUNC LOCAL DEFAULT 1 npf_bufputc - 94: ffffffff80006ce0 1 FUNC LOCAL DEFAULT 1 npf_bufputc_nop - 95: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscall.c - 96: ffffffff800084e0 3 FUNC LOCAL DEFAULT 1 __syscall_undefined - 97: ffffffff800f5f60 8192 OBJECT LOCAL DEFAULT 5 syscall_table - 98: 0000000000000000 0 FILE LOCAL DEFAULT ABS syscalls_proc.c - 99: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/arch/x86_64/[...] - 100: ffffffff80008660 0 NOTYPE LOCAL DEFAULT 1 isr_stub_0 - 101: ffffffff800086a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_1 - 102: ffffffff800086e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_2 - 103: ffffffff80008720 0 NOTYPE LOCAL DEFAULT 1 isr_stub_3 - 104: ffffffff80008760 0 NOTYPE LOCAL DEFAULT 1 isr_stub_4 - 105: ffffffff800087a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_5 - 106: ffffffff800087e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_6 - 107: ffffffff80008820 0 NOTYPE LOCAL DEFAULT 1 isr_stub_7 - 108: ffffffff80008860 0 NOTYPE LOCAL DEFAULT 1 isr_stub_8 - 109: ffffffff8000889e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_9 - 110: ffffffff800088de 0 NOTYPE LOCAL DEFAULT 1 isr_stub_10 - 111: ffffffff8000891c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_11 - 112: ffffffff8000895a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_12 - 113: ffffffff80008998 0 NOTYPE LOCAL DEFAULT 1 isr_stub_13 - 114: ffffffff800089d6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_14 - 115: ffffffff80008a14 0 NOTYPE LOCAL DEFAULT 1 isr_stub_15 - 116: ffffffff80008a54 0 NOTYPE LOCAL DEFAULT 1 isr_stub_16 - 117: ffffffff80008a94 0 NOTYPE LOCAL DEFAULT 1 isr_stub_17 - 118: ffffffff80008ad2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_18 - 119: ffffffff80008b12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_19 - 120: ffffffff80008b52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_20 - 121: ffffffff80008b92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_21 - 122: ffffffff80008bd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_22 - 123: ffffffff80008c12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_23 - 124: ffffffff80008c52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_24 - 125: ffffffff80008c92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_25 - 126: ffffffff80008cd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_26 - 127: ffffffff80008d12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_27 - 128: ffffffff80008d52 0 NOTYPE LOCAL DEFAULT 1 isr_stub_28 - 129: ffffffff80008d92 0 NOTYPE LOCAL DEFAULT 1 isr_stub_29 - 130: ffffffff80008dd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_30 - 131: ffffffff80008e10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_31 - 132: ffffffff80008e50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_32 - 133: ffffffff80008e90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_33 - 134: ffffffff80008ed0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_34 - 135: ffffffff80008f10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_35 - 136: ffffffff80008f50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_36 - 137: ffffffff80008f90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_37 - 138: ffffffff80008fd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_38 - 139: ffffffff80009010 0 NOTYPE LOCAL DEFAULT 1 isr_stub_39 - 140: ffffffff80009050 0 NOTYPE LOCAL DEFAULT 1 isr_stub_40 - 141: ffffffff80009090 0 NOTYPE LOCAL DEFAULT 1 isr_stub_41 - 142: ffffffff800090d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_42 - 143: ffffffff80009110 0 NOTYPE LOCAL DEFAULT 1 isr_stub_43 - 144: ffffffff80009150 0 NOTYPE LOCAL DEFAULT 1 isr_stub_44 - 145: ffffffff80009190 0 NOTYPE LOCAL DEFAULT 1 isr_stub_45 - 146: ffffffff800091d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_46 - 147: ffffffff80009210 0 NOTYPE LOCAL DEFAULT 1 isr_stub_47 - 148: ffffffff80009250 0 NOTYPE LOCAL DEFAULT 1 isr_stub_48 - 149: ffffffff80009290 0 NOTYPE LOCAL DEFAULT 1 isr_stub_49 - 150: ffffffff800092d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_50 - 151: ffffffff80009310 0 NOTYPE LOCAL DEFAULT 1 isr_stub_51 - 152: ffffffff80009350 0 NOTYPE LOCAL DEFAULT 1 isr_stub_52 - 153: ffffffff80009390 0 NOTYPE LOCAL DEFAULT 1 isr_stub_53 - 154: ffffffff800093d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_54 - 155: ffffffff80009410 0 NOTYPE LOCAL DEFAULT 1 isr_stub_55 - 156: ffffffff80009450 0 NOTYPE LOCAL DEFAULT 1 isr_stub_56 - 157: ffffffff80009490 0 NOTYPE LOCAL DEFAULT 1 isr_stub_57 - 158: ffffffff800094d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_58 - 159: ffffffff80009510 0 NOTYPE LOCAL DEFAULT 1 isr_stub_59 - 160: ffffffff80009550 0 NOTYPE LOCAL DEFAULT 1 isr_stub_60 - 161: ffffffff80009590 0 NOTYPE LOCAL DEFAULT 1 isr_stub_61 - 162: ffffffff800095d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_62 - 163: ffffffff80009610 0 NOTYPE LOCAL DEFAULT 1 isr_stub_63 - 164: ffffffff80009650 0 NOTYPE LOCAL DEFAULT 1 isr_stub_64 - 165: ffffffff80009690 0 NOTYPE LOCAL DEFAULT 1 isr_stub_65 - 166: ffffffff800096d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_66 - 167: ffffffff80009710 0 NOTYPE LOCAL DEFAULT 1 isr_stub_67 - 168: ffffffff80009750 0 NOTYPE LOCAL DEFAULT 1 isr_stub_68 - 169: ffffffff80009790 0 NOTYPE LOCAL DEFAULT 1 isr_stub_69 - 170: ffffffff800097d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_70 - 171: ffffffff80009810 0 NOTYPE LOCAL DEFAULT 1 isr_stub_71 - 172: ffffffff80009850 0 NOTYPE LOCAL DEFAULT 1 isr_stub_72 - 173: ffffffff80009890 0 NOTYPE LOCAL DEFAULT 1 isr_stub_73 - 174: ffffffff800098d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_74 - 175: ffffffff80009910 0 NOTYPE LOCAL DEFAULT 1 isr_stub_75 - 176: ffffffff80009950 0 NOTYPE LOCAL DEFAULT 1 isr_stub_76 - 177: ffffffff80009990 0 NOTYPE LOCAL DEFAULT 1 isr_stub_77 - 178: ffffffff800099d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_78 - 179: ffffffff80009a10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_79 - 180: ffffffff80009a50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_80 - 181: ffffffff80009a90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_81 - 182: ffffffff80009ad0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_82 - 183: ffffffff80009b10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_83 - 184: ffffffff80009b50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_84 - 185: ffffffff80009b90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_85 - 186: ffffffff80009bd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_86 - 187: ffffffff80009c10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_87 - 188: ffffffff80009c50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_88 - 189: ffffffff80009c90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_89 - 190: ffffffff80009cd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_90 - 191: ffffffff80009d10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_91 - 192: ffffffff80009d50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_92 - 193: ffffffff80009d90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_93 - 194: ffffffff80009dd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_94 - 195: ffffffff80009e10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_95 - 196: ffffffff80009e50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_96 - 197: ffffffff80009e90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_97 - 198: ffffffff80009ed0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_98 - 199: ffffffff80009f10 0 NOTYPE LOCAL DEFAULT 1 isr_stub_99 - 200: ffffffff80009f50 0 NOTYPE LOCAL DEFAULT 1 isr_stub_100 - 201: ffffffff80009f90 0 NOTYPE LOCAL DEFAULT 1 isr_stub_101 - 202: ffffffff80009fd0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_102 - 203: ffffffff8000a010 0 NOTYPE LOCAL DEFAULT 1 isr_stub_103 - 204: ffffffff8000a050 0 NOTYPE LOCAL DEFAULT 1 isr_stub_104 - 205: ffffffff8000a090 0 NOTYPE LOCAL DEFAULT 1 isr_stub_105 - 206: ffffffff8000a0d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_106 - 207: ffffffff8000a110 0 NOTYPE LOCAL DEFAULT 1 isr_stub_107 - 208: ffffffff8000a150 0 NOTYPE LOCAL DEFAULT 1 isr_stub_108 - 209: ffffffff8000a190 0 NOTYPE LOCAL DEFAULT 1 isr_stub_109 - 210: ffffffff8000a1d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_110 - 211: ffffffff8000a210 0 NOTYPE LOCAL DEFAULT 1 isr_stub_111 - 212: ffffffff8000a250 0 NOTYPE LOCAL DEFAULT 1 isr_stub_112 - 213: ffffffff8000a290 0 NOTYPE LOCAL DEFAULT 1 isr_stub_113 - 214: ffffffff8000a2d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_114 - 215: ffffffff8000a310 0 NOTYPE LOCAL DEFAULT 1 isr_stub_115 - 216: ffffffff8000a350 0 NOTYPE LOCAL DEFAULT 1 isr_stub_116 - 217: ffffffff8000a390 0 NOTYPE LOCAL DEFAULT 1 isr_stub_117 - 218: ffffffff8000a3d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_118 - 219: ffffffff8000a410 0 NOTYPE LOCAL DEFAULT 1 isr_stub_119 - 220: ffffffff8000a450 0 NOTYPE LOCAL DEFAULT 1 isr_stub_120 - 221: ffffffff8000a490 0 NOTYPE LOCAL DEFAULT 1 isr_stub_121 - 222: ffffffff8000a4d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_122 - 223: ffffffff8000a510 0 NOTYPE LOCAL DEFAULT 1 isr_stub_123 - 224: ffffffff8000a550 0 NOTYPE LOCAL DEFAULT 1 isr_stub_124 - 225: ffffffff8000a590 0 NOTYPE LOCAL DEFAULT 1 isr_stub_125 - 226: ffffffff8000a5d0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_126 - 227: ffffffff8000a610 0 NOTYPE LOCAL DEFAULT 1 isr_stub_127 - 228: ffffffff8000a650 0 NOTYPE LOCAL DEFAULT 1 isr_stub_128 - 229: ffffffff8000a693 0 NOTYPE LOCAL DEFAULT 1 isr_stub_129 - 230: ffffffff8000a6d6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_130 - 231: ffffffff8000a719 0 NOTYPE LOCAL DEFAULT 1 isr_stub_131 - 232: ffffffff8000a75c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_132 - 233: ffffffff8000a79f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_133 - 234: ffffffff8000a7e2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_134 - 235: ffffffff8000a825 0 NOTYPE LOCAL DEFAULT 1 isr_stub_135 - 236: ffffffff8000a868 0 NOTYPE LOCAL DEFAULT 1 isr_stub_136 - 237: ffffffff8000a8ab 0 NOTYPE LOCAL DEFAULT 1 isr_stub_137 - 238: ffffffff8000a8ee 0 NOTYPE LOCAL DEFAULT 1 isr_stub_138 - 239: ffffffff8000a931 0 NOTYPE LOCAL DEFAULT 1 isr_stub_139 - 240: ffffffff8000a974 0 NOTYPE LOCAL DEFAULT 1 isr_stub_140 - 241: ffffffff8000a9b7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_141 - 242: ffffffff8000a9fa 0 NOTYPE LOCAL DEFAULT 1 isr_stub_142 - 243: ffffffff8000aa3d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_143 - 244: ffffffff8000aa80 0 NOTYPE LOCAL DEFAULT 1 isr_stub_144 - 245: ffffffff8000aac3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_145 - 246: ffffffff8000ab06 0 NOTYPE LOCAL DEFAULT 1 isr_stub_146 - 247: ffffffff8000ab49 0 NOTYPE LOCAL DEFAULT 1 isr_stub_147 - 248: ffffffff8000ab8c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_148 - 249: ffffffff8000abcf 0 NOTYPE LOCAL DEFAULT 1 isr_stub_149 - 250: ffffffff8000ac12 0 NOTYPE LOCAL DEFAULT 1 isr_stub_150 - 251: ffffffff8000ac55 0 NOTYPE LOCAL DEFAULT 1 isr_stub_151 - 252: ffffffff8000ac98 0 NOTYPE LOCAL DEFAULT 1 isr_stub_152 - 253: ffffffff8000acdb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_153 - 254: ffffffff8000ad1e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_154 - 255: ffffffff8000ad61 0 NOTYPE LOCAL DEFAULT 1 isr_stub_155 - 256: ffffffff8000ada4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_156 - 257: ffffffff8000ade7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_157 - 258: ffffffff8000ae2a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_158 - 259: ffffffff8000ae6d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_159 - 260: ffffffff8000aeb0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_160 - 261: ffffffff8000aef3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_161 - 262: ffffffff8000af36 0 NOTYPE LOCAL DEFAULT 1 isr_stub_162 - 263: ffffffff8000af79 0 NOTYPE LOCAL DEFAULT 1 isr_stub_163 - 264: ffffffff8000afbc 0 NOTYPE LOCAL DEFAULT 1 isr_stub_164 - 265: ffffffff8000afff 0 NOTYPE LOCAL DEFAULT 1 isr_stub_165 - 266: ffffffff8000b042 0 NOTYPE LOCAL DEFAULT 1 isr_stub_166 - 267: ffffffff8000b085 0 NOTYPE LOCAL DEFAULT 1 isr_stub_167 - 268: ffffffff8000b0c8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_168 - 269: ffffffff8000b10b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_169 - 270: ffffffff8000b14e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_170 - 271: ffffffff8000b191 0 NOTYPE LOCAL DEFAULT 1 isr_stub_171 - 272: ffffffff8000b1d4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_172 - 273: ffffffff8000b217 0 NOTYPE LOCAL DEFAULT 1 isr_stub_173 - 274: ffffffff8000b25a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_174 - 275: ffffffff8000b29d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_175 - 276: ffffffff8000b2e0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_176 - 277: ffffffff8000b323 0 NOTYPE LOCAL DEFAULT 1 isr_stub_177 - 278: ffffffff8000b366 0 NOTYPE LOCAL DEFAULT 1 isr_stub_178 - 279: ffffffff8000b3a9 0 NOTYPE LOCAL DEFAULT 1 isr_stub_179 - 280: ffffffff8000b3ec 0 NOTYPE LOCAL DEFAULT 1 isr_stub_180 - 281: ffffffff8000b42f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_181 - 282: ffffffff8000b472 0 NOTYPE LOCAL DEFAULT 1 isr_stub_182 - 283: ffffffff8000b4b5 0 NOTYPE LOCAL DEFAULT 1 isr_stub_183 - 284: ffffffff8000b4f8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_184 - 285: ffffffff8000b53b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_185 - 286: ffffffff8000b57e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_186 - 287: ffffffff8000b5c1 0 NOTYPE LOCAL DEFAULT 1 isr_stub_187 - 288: ffffffff8000b604 0 NOTYPE LOCAL DEFAULT 1 isr_stub_188 - 289: ffffffff8000b647 0 NOTYPE LOCAL DEFAULT 1 isr_stub_189 - 290: ffffffff8000b68a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_190 - 291: ffffffff8000b6cd 0 NOTYPE LOCAL DEFAULT 1 isr_stub_191 - 292: ffffffff8000b710 0 NOTYPE LOCAL DEFAULT 1 isr_stub_192 - 293: ffffffff8000b753 0 NOTYPE LOCAL DEFAULT 1 isr_stub_193 - 294: ffffffff8000b796 0 NOTYPE LOCAL DEFAULT 1 isr_stub_194 - 295: ffffffff8000b7d9 0 NOTYPE LOCAL DEFAULT 1 isr_stub_195 - 296: ffffffff8000b81c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_196 - 297: ffffffff8000b85f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_197 - 298: ffffffff8000b8a2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_198 - 299: ffffffff8000b8e5 0 NOTYPE LOCAL DEFAULT 1 isr_stub_199 - 300: ffffffff8000b928 0 NOTYPE LOCAL DEFAULT 1 isr_stub_200 - 301: ffffffff8000b96b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_201 - 302: ffffffff8000b9ae 0 NOTYPE LOCAL DEFAULT 1 isr_stub_202 - 303: ffffffff8000b9f1 0 NOTYPE LOCAL DEFAULT 1 isr_stub_203 - 304: ffffffff8000ba34 0 NOTYPE LOCAL DEFAULT 1 isr_stub_204 - 305: ffffffff8000ba77 0 NOTYPE LOCAL DEFAULT 1 isr_stub_205 - 306: ffffffff8000baba 0 NOTYPE LOCAL DEFAULT 1 isr_stub_206 - 307: ffffffff8000bafd 0 NOTYPE LOCAL DEFAULT 1 isr_stub_207 - 308: ffffffff8000bb40 0 NOTYPE LOCAL DEFAULT 1 isr_stub_208 - 309: ffffffff8000bb83 0 NOTYPE LOCAL DEFAULT 1 isr_stub_209 - 310: ffffffff8000bbc6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_210 - 311: ffffffff8000bc09 0 NOTYPE LOCAL DEFAULT 1 isr_stub_211 - 312: ffffffff8000bc4c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_212 - 313: ffffffff8000bc8f 0 NOTYPE LOCAL DEFAULT 1 isr_stub_213 - 314: ffffffff8000bcd2 0 NOTYPE LOCAL DEFAULT 1 isr_stub_214 - 315: ffffffff8000bd15 0 NOTYPE LOCAL DEFAULT 1 isr_stub_215 - 316: ffffffff8000bd58 0 NOTYPE LOCAL DEFAULT 1 isr_stub_216 - 317: ffffffff8000bd9b 0 NOTYPE LOCAL DEFAULT 1 isr_stub_217 - 318: ffffffff8000bdde 0 NOTYPE LOCAL DEFAULT 1 isr_stub_218 - 319: ffffffff8000be21 0 NOTYPE LOCAL DEFAULT 1 isr_stub_219 - 320: ffffffff8000be64 0 NOTYPE LOCAL DEFAULT 1 isr_stub_220 - 321: ffffffff8000bea7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_221 - 322: ffffffff8000beea 0 NOTYPE LOCAL DEFAULT 1 isr_stub_222 - 323: ffffffff8000bf2d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_223 - 324: ffffffff8000bf70 0 NOTYPE LOCAL DEFAULT 1 isr_stub_224 - 325: ffffffff8000bfb3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_225 - 326: ffffffff8000bff6 0 NOTYPE LOCAL DEFAULT 1 isr_stub_226 - 327: ffffffff8000c039 0 NOTYPE LOCAL DEFAULT 1 isr_stub_227 - 328: ffffffff8000c07c 0 NOTYPE LOCAL DEFAULT 1 isr_stub_228 - 329: ffffffff8000c0bf 0 NOTYPE LOCAL DEFAULT 1 isr_stub_229 - 330: ffffffff8000c102 0 NOTYPE LOCAL DEFAULT 1 isr_stub_230 - 331: ffffffff8000c145 0 NOTYPE LOCAL DEFAULT 1 isr_stub_231 - 332: ffffffff8000c188 0 NOTYPE LOCAL DEFAULT 1 isr_stub_232 - 333: ffffffff8000c1cb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_233 - 334: ffffffff8000c20e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_234 - 335: ffffffff8000c251 0 NOTYPE LOCAL DEFAULT 1 isr_stub_235 - 336: ffffffff8000c294 0 NOTYPE LOCAL DEFAULT 1 isr_stub_236 - 337: ffffffff8000c2d7 0 NOTYPE LOCAL DEFAULT 1 isr_stub_237 - 338: ffffffff8000c31a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_238 - 339: ffffffff8000c35d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_239 - 340: ffffffff8000c3a0 0 NOTYPE LOCAL DEFAULT 1 isr_stub_240 - 341: ffffffff8000c3e3 0 NOTYPE LOCAL DEFAULT 1 isr_stub_241 - 342: ffffffff8000c426 0 NOTYPE LOCAL DEFAULT 1 isr_stub_242 - 343: ffffffff8000c469 0 NOTYPE LOCAL DEFAULT 1 isr_stub_243 - 344: ffffffff8000c4ac 0 NOTYPE LOCAL DEFAULT 1 isr_stub_244 - 345: ffffffff8000c4ef 0 NOTYPE LOCAL DEFAULT 1 isr_stub_245 - 346: ffffffff8000c532 0 NOTYPE LOCAL DEFAULT 1 isr_stub_246 - 347: ffffffff8000c575 0 NOTYPE LOCAL DEFAULT 1 isr_stub_247 - 348: ffffffff8000c5b8 0 NOTYPE LOCAL DEFAULT 1 isr_stub_248 - 349: ffffffff8000c5fb 0 NOTYPE LOCAL DEFAULT 1 isr_stub_249 - 350: ffffffff8000c63e 0 NOTYPE LOCAL DEFAULT 1 isr_stub_250 - 351: ffffffff8000c681 0 NOTYPE LOCAL DEFAULT 1 isr_stub_251 - 352: ffffffff8000c6c4 0 NOTYPE LOCAL DEFAULT 1 isr_stub_252 - 353: ffffffff8000c707 0 NOTYPE LOCAL DEFAULT 1 isr_stub_253 - 354: ffffffff8000c74a 0 NOTYPE LOCAL DEFAULT 1 isr_stub_254 - 355: ffffffff8000c78d 0 NOTYPE LOCAL DEFAULT 1 isr_stub_255 - 356: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/arch/x86_64/[...] - 357: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/premain.asm - 358: 0000000000000000 0 FILE LOCAL DEFAULT ABS font.c - 359: ffffffff80000350 236 FUNC GLOBAL DEFAULT 1 smp_init - 360: ffffffff80006af0 285 FUNC GLOBAL DEFAULT 1 log - 361: ffffffff80008420 189 FUNC GLOBAL DEFAULT 1 printf - 362: ffffffff8001fc58 4 OBJECT GLOBAL DEFAULT 5 acpi_madt_iso_length - 363: ffffffff80003f40 3011 FUNC GLOBAL DEFAULT 1 flanterm_fb_init - 364: ffffffff80013de0 0 NOTYPE GLOBAL DEFAULT 3 rodata_end_ld - 365: ffffffff800084f0 184 FUNC GLOBAL DEFAULT 1 syscall_handle - 366: ffffffff800024c0 78 FUNC GLOBAL DEFAULT 1 sched_exit - 367: ffffffff8001fc08 8 OBJECT GLOBAL DEFAULT 5 kernel_vma_context - 368: ffffffff80001400 13 FUNC GLOBAL DEFAULT 1 liballoc_unlock - 369: ffffffff80000920 19 FUNC GLOBAL DEFAULT 1 lapic_eoi - 370: ffffffff8001fc38 8 OBJECT GLOBAL DEFAULT 5 proc_list - 371: ffffffff8001fbe0 8 OBJECT GLOBAL DEFAULT 5 hhdm_offset - 372: ffffffff80020460 2048 OBJECT GLOBAL DEFAULT 5 acpi_madt_ioapic_list - 373: ffffffff80001ce0 721 FUNC GLOBAL DEFAULT 1 vmm_init - 374: ffffffff80001430 36 FUNC GLOBAL DEFAULT 1 memcpy - 375: ffffffff8001db74 4 OBJECT GLOBAL DEFAULT 5 ctr - 376: ffffffff80002600 134 FUNC GLOBAL DEFAULT 1 acpi_init - 377: ffffffff80000760 102 FUNC GLOBAL DEFAULT 1 ioapic_get_gsi - 378: ffffffff80001040 904 FUNC GLOBAL DEFAULT 1 malloc - 379: ffffffff800008f0 38 FUNC GLOBAL DEFAULT 1 lapic_init - 380: ffffffff800017d0 249 FUNC GLOBAL DEFAULT 1 vma_create_context - 381: ffffffff8001fc28 4 OBJECT GLOBAL DEFAULT 5 standby - 382: ffffffff8000e1c0 48 OBJECT GLOBAL DEFAULT 2 karq - 383: ffffffff8000e2a0 0 NOTYPE GLOBAL DEFAULT 2 reqs_end_ld - 384: ffffffff80001ac0 157 FUNC GLOBAL DEFAULT 1 vmm_alloc_pm - 385: ffffffff80000000 183 FUNC GLOBAL DEFAULT 1 gdt_init - 386: ffffffff8000f000 0 NOTYPE GLOBAL DEFAULT 3 rodata_start_ld - 387: ffffffff80000650 257 FUNC GLOBAL DEFAULT 1 ioapic_init - 388: ffffffff80000df0 435 FUNC GLOBAL DEFAULT 1 __kmain - 389: ffffffff8001fc30 8 OBJECT GLOBAL DEFAULT 5 curr_proc - 390: ffffffff800004a0 283 FUNC GLOBAL DEFAULT 1 ksym_init - 391: ffffffff80000880 111 FUNC GLOBAL DEFAULT 1 ioapic_redirect_irq - 392: ffffffff8001fbf0 24 OBJECT GLOBAL DEFAULT 5 stack - 393: ffffffff80002510 27 FUNC GLOBAL DEFAULT 1 schedule - 394: ffffffff8001db7c 4 OBJECT GLOBAL DEFAULT 5 bootstrap_lapic_id - 395: ffffffff8001fba8 8 OBJECT GLOBAL DEFAULT 5 fb - 396: ffffffff80000300 20 FUNC GLOBAL DEFAULT 1 pit_enable - 397: ffffffff80001bc0 144 FUNC GLOBAL DEFAULT 1 virt_to_phys - 398: ffffffff800013d0 35 FUNC GLOBAL DEFAULT 1 liballoc_lock - 399: ffffffff800002c0 51 FUNC GLOBAL DEFAULT 1 pit_init - 400: ffffffff800083a0 127 FUNC GLOBAL DEFAULT 1 npf_vsnprintf - 401: ffffffff800018e0 316 FUNC GLOBAL DEFAULT 1 vma_alloc - 402: ffffffff80000120 246 FUNC GLOBAL DEFAULT 1 idt_init - 403: ffffffff80000320 33 FUNC GLOBAL DEFAULT 1 smp_entry - 404: ffffffff80001710 104 FUNC GLOBAL DEFAULT 1 pmm_request_page - 405: ffffffff80001c50 140 FUNC GLOBAL DEFAULT 1 vmm_map - 406: ffffffff8001fc5c 4 OBJECT GLOBAL DEFAULT 5 acpi_madt_ioapic[...] - 407: ffffffff8000e140 48 OBJECT GLOBAL DEFAULT 2 hhdm_req - 408: ffffffff8001fc60 2048 OBJECT GLOBAL DEFAULT 5 acpi_madt_iso_list - 409: ffffffff80002b40 393 FUNC GLOBAL DEFAULT 1 panic_ctx - 410: ffffffff8001fc2c 4 OBJECT GLOBAL DEFAULT 5 current_pid - 411: ffffffff80004d00 7649 FUNC GLOBAL DEFAULT 1 flanterm_write - 412: ffffffff80001b60 64 FUNC GLOBAL DEFAULT 1 vmm_release_pm - 413: ffffffff8001c060 1792 OBJECT GLOBAL DEFAULT 5 irq_handler_table - 414: ffffffff80001410 26 FUNC GLOBAL DEFAULT 1 liballoc_alloc - 415: ffffffff80000440 84 FUNC GLOBAL DEFAULT 1 __x86_64_syscall_init - 416: ffffffff800029a0 90 FUNC GLOBAL DEFAULT 1 __panic_display_[...] - 417: ffffffff80008650 13 FUNC GLOBAL DEFAULT 1 syscall_exit - 418: ffffffff80006d00 5792 FUNC GLOBAL DEFAULT 1 npf_vpprintf - 419: ffffffff80002a00 307 FUNC GLOBAL DEFAULT 1 panic - 420: ffffffff8001fc10 4 OBJECT GLOBAL DEFAULT 5 vmm_kernel_pm_exists - 421: ffffffff800014c0 67 FUNC GLOBAL DEFAULT 1 memcmp - 422: ffffffff800021d0 752 FUNC GLOBAL DEFAULT 1 sched_create - 423: ffffffff8001db70 4 OBJECT GLOBAL DEFAULT 5 tick - 424: ffffffff8001fc20 8 OBJECT GLOBAL DEFAULT 5 vmm_kernel_pm - 425: ffffffff800005c0 144 FUNC GLOBAL DEFAULT 1 ksym_fromip - 426: ffffffff800085c0 138 FUNC GLOBAL DEFAULT 1 syscall_init - 427: ffffffff80000290 6 FUNC GLOBAL DEFAULT 1 outb - 428: ffffffff80014000 88 OBJECT GLOBAL DEFAULT 4 def_table - 429: ffffffff8001fba0 8 OBJECT GLOBAL DEFAULT 5 ft_ctx - 430: ffffffff80001460 68 FUNC GLOBAL DEFAULT 1 memset - 431: ffffffff80001780 76 FUNC GLOBAL DEFAULT 1 pmm_free_page - 432: ffffffff80000220 101 FUNC GLOBAL DEFAULT 1 idt_int_handler - 433: ffffffff8001fc50 8 OBJECT GLOBAL DEFAULT 5 acpi_lapic_addr - 434: ffffffff80004b10 136 FUNC GLOBAL DEFAULT 1 flanterm_context[...] - 435: ffffffff80000da0 80 FUNC GLOBAL DEFAULT 1 strcmp - 436: ffffffff80001fc0 137 FUNC GLOBAL DEFAULT 1 vmm_map_user - 437: ffffffff80002530 206 FUNC GLOBAL DEFAULT 1 acpi_find_table - 438: ffffffff800000c0 88 FUNC GLOBAL DEFAULT 1 idt_register_irq - 439: ffffffff80014060 4096 OBJECT GLOBAL DEFAULT 4 VGA8 - 440: ffffffff8000d052 0 NOTYPE GLOBAL DEFAULT 1 text_end_ld - 441: ffffffff80001540 451 FUNC GLOBAL DEFAULT 1 pmm_init - 442: ffffffff800007d0 156 FUNC GLOBAL DEFAULT 1 ioapic_redirect_gsi - 443: ffffffff8000e000 0 NOTYPE GLOBAL DEFAULT 2 reqs_start_ld - 444: ffffffff800002a0 18 FUNC GLOBAL DEFAULT 1 pit_handler - 445: ffffffff8001db78 4 OBJECT GLOBAL DEFAULT 5 smp_cpu_count - 446: ffffffff8001fc18 8 OBJECT GLOBAL DEFAULT 5 vmm_current_pm - 447: ffffffff80015060 28672 OBJECT GLOBAL DEFAULT 5 tss_list - 448: ffffffff8000c7d0 0 NOTYPE GLOBAL DEFAULT 1 isr_stub_table - 449: ffffffff80014000 0 NOTYPE GLOBAL DEFAULT 4 data_start_ld - 450: ffffffff80001ba0 31 FUNC GLOBAL DEFAULT 1 vmm_load_pagemap - 451: ffffffff80004ba0 331 FUNC GLOBAL DEFAULT 1 mk_wcwidth - 452: ffffffff800f7f60 0 NOTYPE GLOBAL DEFAULT 5 data_end_ld - 453: ffffffff8000d040 0 NOTYPE GLOBAL DEFAULT 1 kmain - 454: ffffffff80002150 123 FUNC GLOBAL DEFAULT 1 sched_init - 455: ffffffff80000d60 35 FUNC GLOBAL DEFAULT 1 strlen - 456: ffffffff800026a0 233 FUNC GLOBAL DEFAULT 1 madt_init - 457: ffffffff80000000 0 NOTYPE GLOBAL DEFAULT 1 text_start_ld - 458: ffffffff8000e180 48 OBJECT GLOBAL DEFAULT 2 mm_req - 459: ffffffff8000cfd0 0 NOTYPE GLOBAL DEFAULT 1 syscall_entry - 460: ffffffff80000940 1050 FUNC GLOBAL DEFAULT 1 elf_load - 461: ffffffff8001dba0 8192 OBJECT GLOBAL DEFAULT 5 kstack - 462: ffffffff8001fbe8 8 OBJECT GLOBAL DEFAULT 5 _memmap - -Aucune information de version repérée dans ce fichier. diff --git a/util/get_vaddr_info.py b/util/get_vaddr_info.py deleted file mode 100755 index 6020da7..0000000 --- a/util/get_vaddr_info.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 - -import sys - -if len(sys.argv) != 2: - print(f"Usage: {sys.argv[0]} ") - sys.exit(1) - -va = int(sys.argv[1], 16) - -def extract_index(name, shift): - return (va >> shift) & 0x1FF - -print(f"Virtual address : 0x{va:016x}") -print(f"PML4 index : {extract_index('PML4', 39)}") -print(f"PDPT index : {extract_index('PDPT', 30)}") -print(f" PD index : {extract_index('PD', 21)}") -print(f" PT index : {extract_index('PT', 12)}") -print(f" Offset : {va & 0xFFF}") From 89bb8c8a4b7efdd600239b4806d4181302a68fc8 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 15:54:12 +0200 Subject: [PATCH 20/30] kernel: add some basic features + feat list: + * gdt/idt + * brokie pmm --- kernel/GNUmakefile | 13 ++-- kernel/src/arch/aarch64/cpu.c | 10 +++ kernel/src/arch/cpu.h | 10 +++ kernel/src/arch/la64/cpu.c | 10 +++ kernel/src/arch/riscv/cpu.c | 10 +++ kernel/src/arch/x86_64/cpu.c | 14 +++++ kernel/src/arch/x86_64/gdt.asm | 20 ++++++ kernel/src/arch/x86_64/gdt.c | 60 ++++++++++++++++++ kernel/src/arch/x86_64/gdt.h | 43 +++++++++++++ kernel/src/arch/x86_64/idt.asm | 111 +++++++++++++++++++++++++++++++++ kernel/src/arch/x86_64/idt.c | 60 ++++++++++++++++++ kernel/src/arch/x86_64/idt.h | 51 +++++++++++++++ kernel/src/boot/limine.c | 52 +++++++++++++++ kernel/src/boot/limine.h | 22 ++++++- kernel/src/config.h | 11 ++++ kernel/src/dev/tty.c | 26 +++++++- kernel/src/dev/tty.h | 11 +++- kernel/src/lib/ansi.c | 29 +++++++++ kernel/src/lib/ansi.h | 15 +++++ kernel/src/lib/log.c | 53 ++++++++++++++++ kernel/src/lib/log.h | 35 +++++++++++ kernel/src/lib/logoutputs_sk.c | 26 ++++++++ kernel/src/lib/logoutputs_sk.h | 16 +++++ kernel/src/lib/npf.c | 18 ++++++ kernel/src/lib/string.c | 7 +++ kernel/src/lib/string.h | 7 +++ kernel/src/main.c | 23 ++++++- kernel/src/mm/memop.c | 19 +++--- kernel/src/mm/memop.h | 7 +++ kernel/src/mm/pmm.c | 65 +++++++++++++++++++ kernel/src/mm/pmm.h | 23 +++++++ 31 files changed, 854 insertions(+), 23 deletions(-) create mode 100644 kernel/src/arch/x86_64/gdt.asm create mode 100644 kernel/src/arch/x86_64/gdt.c create mode 100644 kernel/src/arch/x86_64/gdt.h create mode 100644 kernel/src/arch/x86_64/idt.asm create mode 100644 kernel/src/arch/x86_64/idt.c create mode 100644 kernel/src/arch/x86_64/idt.h create mode 100644 kernel/src/config.h create mode 100644 kernel/src/lib/ansi.c create mode 100644 kernel/src/lib/ansi.h create mode 100644 kernel/src/lib/log.c create mode 100644 kernel/src/lib/log.h create mode 100644 kernel/src/lib/logoutputs_sk.c create mode 100644 kernel/src/lib/logoutputs_sk.h create mode 100644 kernel/src/lib/npf.c create mode 100644 kernel/src/mm/pmm.c create mode 100644 kernel/src/mm/pmm.h diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index 0d7f9ff..a859d42 100644 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -57,6 +57,13 @@ override CFLAGS += \ -ffunction-sections \ -fdata-sections +ifeq ($(CC_IS_CLANG), 1) + # Force Clang to use it's own linker instead of the host's one, since it + # might be used for cross-compilation. + override LDFLAGS += \ + -fuse-ld=lld +endif + # Internal C preprocessor flags that should not be changed by the user. override CPPFLAGS := \ -I src \ @@ -66,12 +73,6 @@ override CPPFLAGS := \ -MMD \ -MP -ifeq ($(ARCH),x86_64) - # Internal nasm flags that should not be changed by the user. - override NASMFLAGS += \ - -Wall -endif - # Architecture specific internal flags. ifeq ($(ARCH),x86_64) ifeq ($(CC_IS_CLANG),1) diff --git a/kernel/src/arch/aarch64/cpu.c b/kernel/src/arch/aarch64/cpu.c index d7f43b1..48fee8b 100644 --- a/kernel/src/arch/aarch64/cpu.c +++ b/kernel/src/arch/aarch64/cpu.c @@ -1,7 +1,17 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * cpu.c - AArch64 CPU control implementation. + */ + #if defined (__aarch64__) #include +void arch_init_stage1() { +} + void hcf() { for (;;) { asm ("wfi"); diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index 5d30628..11a28af 100644 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -1,4 +1,14 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * cpu.h - CPU control and management functions. + */ + #pragma once +// Stage 1 initialization: Core components (such as the GDT & IDT on x86_64...) +void arch_init_stage1(); + // Disable interrupts and halt the system. void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/la64/cpu.c b/kernel/src/arch/la64/cpu.c index cf58c4d..6abe756 100644 --- a/kernel/src/arch/la64/cpu.c +++ b/kernel/src/arch/la64/cpu.c @@ -1,7 +1,17 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * cpu.c - LoongArch64 CPU control implementation. + */ + #if defined (__loongarch64) #include +void arch_init_stage1() { +} + void hcf() { for (;;) { asm ("idle 0"); diff --git a/kernel/src/arch/riscv/cpu.c b/kernel/src/arch/riscv/cpu.c index 4717e48..658b2a4 100644 --- a/kernel/src/arch/riscv/cpu.c +++ b/kernel/src/arch/riscv/cpu.c @@ -1,7 +1,17 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * cpu.c - RISC-V CPU control implementation. + */ + #if defined (__riscv) #include +void arch_init_stage1() { +} + void hcf() { for (;;) { asm ("wfi"); diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c index 688812b..99c591a 100644 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -1,7 +1,21 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * cpu.c - x86_64 CPU control implementation. + */ + #if defined (__x86_64__) +#include +#include #include +void arch_init_stage1() { + gdt_init(); + idt_init(); +} + void hcf() { asm ("cli"); for (;;) { diff --git a/kernel/src/arch/x86_64/gdt.asm b/kernel/src/arch/x86_64/gdt.asm new file mode 100644 index 0000000..224581b --- /dev/null +++ b/kernel/src/arch/x86_64/gdt.asm @@ -0,0 +1,20 @@ +bits 64 + +section .text + global gdt_reload_segments + +gdt_reload_segments: + ; Reload CS register: + PUSH 0x08 ; Push code segment to stack, 0x08 is a stand-in for your code segment + LEA RAX, [rel .reload_CS] ; Load address of .reload_CS into RAX + PUSH RAX ; Push this value to the stack + RETFQ ; Perform a far return, RETFQ or LRETQ depending on syntax +.reload_CS: + ; Reload data segment registers + MOV AX, 0x10 ; 0x10 is a stand-in for your data segment + MOV DS, AX + MOV ES, AX + MOV FS, AX + MOV GS, AX + MOV SS, AX + RET \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c new file mode 100644 index 0000000..f916dfe --- /dev/null +++ b/kernel/src/arch/x86_64/gdt.c @@ -0,0 +1,60 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * gdt.c - x86_64 Global Descriptor Table implementation. + */ + +#include "lib/log.h" +#if defined(__x86_64__) + +#include +#include +#include + +gdt_table gdt = {{ + 0x0000000000000000, // 0x0, null + + 0x00af9b000000ffff, // 0x8, 64-bit code + 0x00af93000000ffff, // 0x10, 64-bit data + + 0x00affb000000ffff, // 0x18, usermode 64-bit code + 0x00aff3000000ffff // 0x20, usermode 64-bit data +}, {}}; + +tssr tss_list[255]; +static uint64_t __gdt_kstack[4096]; + +extern void gdt_reload_segments(); + +void gdt_init() { + memset(&tss_list[0], 0, sizeof(tssr)); + tss_list[0].rsp[0] = (uint64_t)__gdt_kstack; + tss_list[0].iopb = sizeof(tssr); + uintptr_t tss = (uintptr_t)&tss_list[0]; + + gdt.tss_entry = (tss_entry){ + .length = sizeof(tss_entry), + .base = (uint16_t)(tss & 0xFFFF), + .base1 = (uint8_t)((tss >> 16) & 0xFF), + .flags = 0x89, + .flags1 = 0, + .base2 = (uint8_t)((tss >> 24) & 0xFF), + .base3 = (uint32_t)(tss >> 32), + .resv = 0, + }; + + gdtr gdtr = { + .size = (sizeof(gdt_table)) - 1, + .address = (uint64_t)&gdt + }; + + __asm__ volatile("lgdt %0\n\t" : : "m"(gdtr) : "memory"); + __asm__ volatile("ltr %0\n\t" : : "r"((uint16_t)0x28)); // 0x20 (last GDT entry) + 0x8 (size of a GDT entry) + + gdt_reload_segments(); + + debug("arch: GDT & TSS initialized.\n"); +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.h b/kernel/src/arch/x86_64/gdt.h new file mode 100644 index 0000000..d7a3e61 --- /dev/null +++ b/kernel/src/arch/x86_64/gdt.h @@ -0,0 +1,43 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * gdt.h - x86_64 Global Descriptor Table definitions. + */ + +#pragma once + +#include + +typedef struct tss_entry { + uint16_t length; + uint16_t base; + uint8_t base1; + uint8_t flags; + uint8_t flags1; + uint8_t base2; + uint32_t base3; + uint32_t resv; +} __attribute__((packed)) tss_entry; + +typedef struct { + uint64_t entries[5]; + struct tss_entry tss_entry; +} __attribute__((packed)) gdt_table; + +typedef struct { + uint16_t size; + uint64_t address; +} __attribute__((packed)) gdtr; + +typedef struct { + uint32_t resv; + uint64_t rsp[4]; + uint64_t resv1; + uint64_t ist[7]; + uint64_t resv2; + uint16_t resv3; + uint16_t iopb; +} __attribute__((packed)) tssr; // 1 TSSR per CPU. + +void gdt_init(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.asm b/kernel/src/arch/x86_64/idt.asm new file mode 100644 index 0000000..fec724d --- /dev/null +++ b/kernel/src/arch/x86_64/idt.asm @@ -0,0 +1,111 @@ + +%macro pushall 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 +%endmacro + +%macro popall 0 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +%macro isr_err_stub 1 +isr_stub_%+%1: + push %1 ; push intno into the stack + + pushall + + mov rdi, rsp ; put the stack as the first arg. + + call idt_interrupt_handler + + popall + + add rsp, 16 + iretq +%endmacro + +%macro isr_no_err_stub 1 +isr_stub_%+%1: + push 0 ; push the error code (0) into the stack + push %1 ; push intno into the stack + + pushall + + mov rdi, rsp ; put the stack as the first arg. + + call idt_interrupt_handler + + popall + + add rsp, 16 + iretq +%endmacro + +extern idt_interrupt_handler +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dq isr_stub_%+i +%assign i i+1 +%endrep \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c new file mode 100644 index 0000000..34e8589 --- /dev/null +++ b/kernel/src/arch/x86_64/idt.c @@ -0,0 +1,60 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * idt.c - x86_64 Interrupt Descriptor Table implementation. + */ +#if defined(__x86_64__) + +#include "arch/cpu.h" +#include "lib/log.h" +#include + +__attribute__((aligned(0x10))) +static idt_entry_t idt[256]; +static idtr_t idtr; + +void idt_interrupt_handler(registers_t *regs) { + fatal("Kernel panic: CPU exception %d\n", regs->int_no); + fatal("rax: %p, rbx: %p, rbp: %p, rdx\n", regs->rax, regs->rbx, regs->rbp, regs->rdx); + fatal("rdi: %p, rsi: %p, rcx: %p\n", regs->rdi, regs->rsi, regs->rcx); + fatal("r8: %p, r9: %p, r10: %p\n", regs->r8, regs->r8, regs->r10); + fatal("r11: %p, r12: %p, r13: %p\n", regs->r11, regs->r12, regs->r13); + fatal("r14: %p, r15: %p\n", regs->r14, regs->r15); + fatal("rip: %p, cs: %p, ss: %p\n", regs->rip, regs->cs, regs->ss); + fatal("rflags: %p, err: %p, rsp: %p\n", regs->rflags, regs->err_code, regs->rsp); + hcf(); +} + +void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { + idt_entry_t* descriptor = &idt[vector]; + + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x08; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; +} + +static bool vectors[32]; + +extern void* isr_stub_table[]; + +void idt_init() { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 32 - 1; + + for (uint8_t vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = true; + } + + __asm__ volatile ("lidt %0" : : "m"(idtr)); + __asm__ volatile ("sti"); + + debug("arch: IDT loaded successfully\n"); +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h new file mode 100644 index 0000000..e66648e --- /dev/null +++ b/kernel/src/arch/x86_64/idt.h @@ -0,0 +1,51 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * idt.h - x86_64 Interrupt Descriptor Table declarations. + */ +#pragma once + +#include + +typedef struct { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rbx; + uint64_t rdx; + uint64_t rcx; + uint64_t rax; + uint64_t int_no; + uint64_t err_code; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} __attribute__((packed)) registers_t; + +typedef struct { + uint16_t isr_low; + uint16_t kernel_cs; + uint8_t ist; + uint8_t attributes; + uint16_t isr_mid; + uint32_t isr_high; + uint32_t reserved; +} __attribute__((packed)) idt_entry_t; + +typedef struct { + uint16_t limit; + uint64_t base; +} __attribute__((packed)) idtr_t; + +void idt_init(void); \ No newline at end of file diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index 67178c1..f913498 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -1,4 +1,12 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * limine.c - Limine bootloader interface implementation. + */ + #include "deps/limine.h" +#include "limine.h" #include #include #include @@ -12,12 +20,34 @@ static volatile struct limine_framebuffer_request framebuffer_request = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_bootloader_info_request bl_info_request = { + .id = LIMINE_BOOTLOADER_INFO_REQUEST, + .revision = 0 +}; + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_firmware_type_request firmware_type_req = { + .id = LIMINE_FIRMWARE_TYPE_REQUEST, + .revision = 0 +}; + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_memmap_request memmap_req = { + .id = LIMINE_MEMMAP_REQUEST, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; __attribute__((used, section(".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; + +static limine_bootinfo_t __limine_bootinfo; + + bool limine_ensure_baserev() { return LIMINE_BASE_REVISION_SUPPORTED; } limine_fb_t *limine_get_fb(int id) { @@ -27,4 +57,26 @@ limine_fb_t *limine_get_fb(int id) { if (id >= (int32_t)framebuffer_request.response->framebuffer_count) // Limine, WHY putting the FB count as a 64-bit integer??? I never seen someone with 0xFFFFFFFFFFFFFFFF screens return NULL; return framebuffer_request.response->framebuffers[id]; +} + +struct limine_memmap_response *limine_get_memmap() { + return memmap_req.response; +} + +limine_bootinfo_t *limine_get_bootinfo() { + __limine_bootinfo.bl_name = bl_info_request.response->name; + __limine_bootinfo.bl_ver = bl_info_request.response->version; + __limine_bootinfo.fw_type = firmware_type_req.response->firmware_type; + +#if defined(__x86_64__) + __limine_bootinfo.arch = "x86_64"; +#elif defined(__aarch64__) + __limine_bootinfo.arch = "aarch64"; +#elif defined(__riscv) + __limine_bootinfo.arch = "riscv"; +#elif defined(__loongarch64) + __limine_bootinfo.arch = "loongarch64"; +#endif + + return &__limine_bootinfo; } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index 9173039..443cd44 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -1,3 +1,10 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * limine.h - Limine bootloader interface declarations. + */ + #pragma once #include @@ -5,8 +12,21 @@ typedef struct limine_framebuffer limine_fb_t; +typedef struct { + char *bl_name; + char *bl_ver; + char *arch; + int fw_type; +} limine_bootinfo_t; + // Ensure that the used boot loader supports the kernel's LBP revision bool limine_ensure_baserev(); // Get a framebuffer -limine_fb_t *limine_get_fb(int id); \ No newline at end of file +limine_fb_t *limine_get_fb(int id); + +// Get some informations about how the kernel was booted +limine_bootinfo_t *limine_get_bootinfo(); + +// Get the memory map. +struct limine_memmap_response *limine_get_memmap(); \ No newline at end of file diff --git a/kernel/src/config.h b/kernel/src/config.h new file mode 100644 index 0000000..38af8b2 --- /dev/null +++ b/kernel/src/config.h @@ -0,0 +1,11 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * config.h - Kernel configuration definitions. + */ + +#pragma once + +#define KERNEL_NAME "Soaplin" +#define KERNEL_VER "0.0.1" \ No newline at end of file diff --git a/kernel/src/dev/tty.c b/kernel/src/dev/tty.c index 3ddccfb..9d64dd3 100644 --- a/kernel/src/dev/tty.c +++ b/kernel/src/dev/tty.c @@ -1,7 +1,15 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * tty.c - Terminal interface implementation. + */ -#include +#include #include #include +#include +#include #include struct flanterm_context *tty0_ctx; @@ -26,6 +34,20 @@ void tty_init() { ); } -void tty_write_raw(char *str) { +void tty_putc(char c) { + flanterm_write(tty0_ctx, &c, 1); +} + +void tty_puts(char *str) { flanterm_write(tty0_ctx, str, strlen(str)); +} + +void tty_printf(char *fmt, ...) { + char buf[2048]; + va_list l; + va_start(l, fmt); + npf_vsnprintf(buf, 2048, fmt, l); + va_end(l); + + tty_puts(buf); } \ No newline at end of file diff --git a/kernel/src/dev/tty.h b/kernel/src/dev/tty.h index 14fc734..03b838c 100644 --- a/kernel/src/dev/tty.h +++ b/kernel/src/dev/tty.h @@ -1,4 +1,13 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * tty.h - Terminal interface declarations. + */ + #pragma once void tty_init(); -void tty_write_raw(char *str); \ No newline at end of file +void tty_putc(char c); +void tty_puts(char *str); +void tty_printf(char *fmt, ...); \ No newline at end of file diff --git a/kernel/src/lib/ansi.c b/kernel/src/lib/ansi.c new file mode 100644 index 0000000..0eb8c87 --- /dev/null +++ b/kernel/src/lib/ansi.c @@ -0,0 +1,29 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * ansi.c - ANSI escape sequence generation functions implementation. + */ + +#include +#include +#include + +static char __ansi_bg_buf[32]; +static char __ansi_fg_buf[32]; + +char *ansi_gen_bg(uint8_t r, uint8_t g, uint8_t b) { + int len = npf_snprintf(__ansi_bg_buf, sizeof(__ansi_bg_buf), "\033[48;2;%d;%d;%d;m", r, g, b); + if (len < 0 || len >= (int)sizeof(__ansi_bg_buf)) { + return "\033[0m"; + } + return __ansi_bg_buf; +} + +char *ansi_gen_fg(uint8_t r, uint8_t g, uint8_t b) { + int len = npf_snprintf(__ansi_fg_buf, sizeof(__ansi_fg_buf), "\033[38;2;%d;%d;%d;m", r, g, b); + if (len < 0 || len >= (int)sizeof(__ansi_fg_buf)) { + return "\033[0m"; + } + return __ansi_fg_buf; +} \ No newline at end of file diff --git a/kernel/src/lib/ansi.h b/kernel/src/lib/ansi.h new file mode 100644 index 0000000..2036e2e --- /dev/null +++ b/kernel/src/lib/ansi.h @@ -0,0 +1,15 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * ansi.h - ANSI escape sequence generation functions. + */ + +#pragma once +#include + +#define ANSI_CLEAR_SCREEN "\033[H\033[2J" +#define ANSI_RESET_COLOR "\033[39m\\033[49m" + +char *ansi_gen_bg(uint8_t r, uint8_t g, uint8_t b); +char *ansi_gen_fg(uint8_t r, uint8_t g, uint8_t b); \ No newline at end of file diff --git a/kernel/src/lib/log.c b/kernel/src/lib/log.c new file mode 100644 index 0000000..e21cf80 --- /dev/null +++ b/kernel/src/lib/log.c @@ -0,0 +1,53 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * log.c - Kernel logging interface. + */ +#include +#include + +static int __logger_max_loglevel = 0; +static log_output_func __logger_outputs[16]; +static int __logger_output_count = 0; + +static char* prelog[7] = { + "\033[38;2;169;68;66;mFAULT | \033[39m", + "\033[38;2;217;83;79;mERROR | \033[39m", + "\033[38;2;240;173;78;mWARN | \033[39m", + "\033[38;2;240;240;240;mNOTICE | \033[39m", + "\033[38;2;92;184;92;mINFO | \033[39m", + "\033[38;2;87;201;193;mDEBUG | \033[39m", + "\033[38;2;150;150;150;mTRACE | \033[39m", +}; + +void log_init(int max_loglevel) { + __logger_max_loglevel = max_loglevel; +} + +bool log_register_output(log_output_func fn) { + if (fn && __logger_output_count <= 16) { + __logger_output_count ++; + __logger_outputs[__logger_output_count - 1] = fn; + return true; + } + return false; +} + +void log(int loglevel, char *str, ...) { + if (__logger_max_loglevel == 0 || __logger_output_count == 0) + return; // The user forgot to initialize the logger. + + if (loglevel > __logger_max_loglevel) + return; // The user does not want this type of log to show up. + + va_list vl; + va_start(vl, str); + + for (int i = 0; i < __logger_output_count; i++) { + __logger_outputs[i](prelog[loglevel - 1], (void*)0); + __logger_outputs[i](str, &vl); + } + + va_end(vl); +} \ No newline at end of file diff --git a/kernel/src/lib/log.h b/kernel/src/lib/log.h new file mode 100644 index 0000000..6c47f8e --- /dev/null +++ b/kernel/src/lib/log.h @@ -0,0 +1,35 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * log.h - Kernel logging interface. + */ + +#pragma once + +// Log levels in order of increasing severity +#include +#include + +#define LOGLEVEL_TRACE 7 +#define LOGLEVEL_DEBUG 6 +#define LOGLEVEL_INFO 5 +#define LOGLEVEL_NOTICE 4 +#define LOGLEVEL_WARNING 3 +#define LOGLEVEL_ERROR 2 +#define LOGLEVEL_FATAL 1 + +typedef void(*log_output_func)(char *str, va_list *vl); + +void log_init(int max_loglevel); +bool log_register_output(log_output_func fn); +void log(int loglevel, char *str, ...); + +// Shortcuts to log +#define trace(str, ...) log(LOGLEVEL_TRACE, str, ##__VA_ARGS__) +#define debug(str, ...) log(LOGLEVEL_DEBUG, str, ##__VA_ARGS__) +#define info(str, ...) log(LOGLEVEL_INFO, str, ##__VA_ARGS__) +#define notice(str, ...) log(LOGLEVEL_NOTICE, str, ##__VA_ARGS__) +#define warn(str, ...) log(LOGLEVEL_WARNING, str, ##__VA_ARGS__) +#define error(str, ...) log(LOGLEVEL_ERROR, str, ##__VA_ARGS__) +#define fatal(str, ...) log(LOGLEVEL_FATAL, str, ##__VA_ARGS__) \ No newline at end of file diff --git a/kernel/src/lib/logoutputs_sk.c b/kernel/src/lib/logoutputs_sk.c new file mode 100644 index 0000000..4276d48 --- /dev/null +++ b/kernel/src/lib/logoutputs_sk.c @@ -0,0 +1,26 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * logoutputs_sk.c - Output functions for the logger + */ +#include "deps/npf.h" +#include +#include + +void sklogoutput_tty(char *str, va_list *vl) { + if (!vl) { + tty_puts(str); + return; + } + + char buf[2048]; + npf_vsnprintf(buf, 2048, str, *vl); + tty_puts(buf); +} + +void sklogoutput_e9(char *str, va_list *vl) { + // TODO: implement this + (void)str; + (void)vl; +} \ No newline at end of file diff --git a/kernel/src/lib/logoutputs_sk.h b/kernel/src/lib/logoutputs_sk.h new file mode 100644 index 0000000..bb51ff0 --- /dev/null +++ b/kernel/src/lib/logoutputs_sk.h @@ -0,0 +1,16 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * logoutputs_sk.h - Output functions for the logger + */ + +#pragma once + +// Output to the terminal. +#include + +void sklogoutput_tty(char *str, va_list *vl); + +// Output to QEMU & Bochs's E9 port. +void sklogoutput_e9(char *str, va_list *vl); \ No newline at end of file diff --git a/kernel/src/lib/npf.c b/kernel/src/lib/npf.c new file mode 100644 index 0000000..59df675 --- /dev/null +++ b/kernel/src/lib/npf.c @@ -0,0 +1,18 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * npf.c - nanoprintf configuration and implementation. + */ + +#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 1 + +// Compile nanoprintf in this translation unit. +#define NANOPRINTF_IMPLEMENTATION +#include \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c index a345e2d..98652b5 100644 --- a/kernel/src/lib/string.c +++ b/kernel/src/lib/string.c @@ -1,3 +1,10 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * string.c - String manipulation functions implementation. + */ + #include size_t strlen(char *str) { diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h index 4e6e619..b0d1424 100644 --- a/kernel/src/lib/string.h +++ b/kernel/src/lib/string.h @@ -1,3 +1,10 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * string.h - String manipulation functions. + */ + #pragma once #include diff --git a/kernel/src/main.c b/kernel/src/main.c index b4c2057..14c33ba 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,15 +1,36 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * main.c - Kernel entry point and initialization. + */ + #include #include #include + #include #include +#include #include +#include +#include +#include +#include void kmain(void) { tty_init(); + log_init(LOGLEVEL_TRACE); + log_register_output(sklogoutput_tty); - tty_write_raw("Hello, World!\n"); + limine_bootinfo_t *bi = limine_get_bootinfo(); + trace("%s %s-%s (booted using %s %s, with firmware type %d)\n", KERNEL_NAME, KERNEL_VER, + bi->arch, bi->bl_name, bi->bl_ver, bi->fw_type); + arch_init_stage1(); + + pmm_init(); + // We're done, just hang... hcf(); } diff --git a/kernel/src/mm/memop.c b/kernel/src/mm/memop.c index 8910891..1bd42be 100644 --- a/kernel/src/mm/memop.c +++ b/kernel/src/mm/memop.c @@ -1,18 +1,14 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * memop.c - Memory operations implementation. + */ + #include #include void *memcpy(void *restrict dest, const void *restrict src, size_t n) { -#if defined(__x86_64__) - long d0, d1, d2; - asm volatile( - "rep ; movsq\n\t movq %4,%%rcx\n\t""rep ; movsb\n\t": "=&c" (d0), - "=&D" (d1), - "=&S" (d2): "0" (n >> 3), - "g" (n & 7), - "1" (dest), - "2" (src): "memory" - ); -#else uint8_t *restrict pdest = (uint8_t *restrict)dest; const uint8_t *restrict psrc = (const uint8_t *restrict)src; @@ -21,7 +17,6 @@ void *memcpy(void *restrict dest, const void *restrict src, size_t n) { } return dest; -#endif } void *memset(void *s, int c, size_t n) { diff --git a/kernel/src/mm/memop.h b/kernel/src/mm/memop.h index 1d75ae1..d556d74 100644 --- a/kernel/src/mm/memop.h +++ b/kernel/src/mm/memop.h @@ -1,3 +1,10 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * memop.h - Memory operations declarations. + */ + #pragma once #include diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c new file mode 100644 index 0000000..da05a58 --- /dev/null +++ b/kernel/src/mm/pmm.c @@ -0,0 +1,65 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * pmm.c - Physical memory allocator + */ + +#include "arch/cpu.h" +#include +#include + +#include +#include +#include +#include + +uint64_t pmm_available_pages = 0; +uint64_t pmm_total_pages = 0; + +static pmm_page_t* pmm_free_list_head = NULL; + +void pmm_free_page(void *mem) { + pmm_page_t *page = (pmm_page_t*)mem; + page->next = pmm_free_list_head; + pmm_free_list_head = page; + + pmm_available_pages++; +} + +void *pmm_alloc_page() { + if (!pmm_free_list_head) + { + fatal("pmm: out of memory!\n"); + hcf(); + } + + pmm_available_pages--; + + pmm_page_t *page = pmm_free_list_head; + pmm_free_list_head = page->next; + + memset(page, 0, PMM_PAGE_SIZE); + return page; +} + +void pmm_init() { + struct limine_memmap_response *mmap = limine_get_memmap(); + + for (uint64_t i = 0; i < mmap->entry_count; i++) { + struct limine_memmap_entry *entry = mmap->entries[i]; + + if (entry->type == LIMINE_MEMMAP_USABLE) + { + trace("pmm: found a usable memory block: %p-%p\n", entry->base, entry->base + entry->length); + + uint64_t newlen = ALIGN_UP(entry->length, PMM_PAGE_SIZE); + for (uint64_t j = 0; j < newlen; j += PMM_PAGE_SIZE) { + pmm_free_page((void*)(entry->base + j)); + pmm_total_pages++; + } + } + } + + trace("pmm: %d pages available\n", pmm_available_pages); +} \ No newline at end of file diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h new file mode 100644 index 0000000..db52cc5 --- /dev/null +++ b/kernel/src/mm/pmm.h @@ -0,0 +1,23 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * pmm.c - Physical memory allocator + */ + +#pragma once + +#include + +#define DIV_ROUND_UP(x, y) \ + (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) +#define ALIGN_UP(x, y) (DIV_ROUND_UP(x, y) * (uint64_t)(y)) +#define ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y)) + +#define PMM_PAGE_SIZE 0x1000 // We are using 4kb pages. + +typedef struct __pmm_page { + struct __pmm_page *next; +} pmm_page_t; + +void pmm_init(); \ No newline at end of file From 9c21f343bab84ba31daf3a66e3c55da746386a01 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 17:24:30 +0200 Subject: [PATCH 21/30] pmm: implement a new form of allocator --- kernel/src/boot/limine.c | 11 ++++++ kernel/src/boot/limine.h | 4 ++- kernel/src/main.c | 8 ++++- kernel/src/mm/pmm.c | 57 ++++++++++++++++++++++------- kernel/src/mm/pmm.h | 25 +++++++++++++ kernel/src/mm/pmm.md | 78 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 kernel/src/mm/pmm.md diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index f913498..abcdf0c 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -38,6 +38,12 @@ static volatile struct limine_memmap_request memmap_req = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_hhdm_request hhdm_req = { + .id = LIMINE_HHDM_REQUEST, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -79,4 +85,9 @@ limine_bootinfo_t *limine_get_bootinfo() { #endif return &__limine_bootinfo; +} + +uint64_t limine_get_hhdm_offset() +{ + return hhdm_req.response->offset; } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index 443cd44..3142f9d 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -29,4 +29,6 @@ limine_fb_t *limine_get_fb(int id); limine_bootinfo_t *limine_get_bootinfo(); // Get the memory map. -struct limine_memmap_response *limine_get_memmap(); \ No newline at end of file +struct limine_memmap_response *limine_get_memmap(); + +uint64_t limine_get_hhdm_offset(); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 14c33ba..05437c7 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include void kmain(void) { @@ -30,7 +31,12 @@ void kmain(void) { arch_init_stage1(); pmm_init(); - + uint8_t* mem = pmm_alloc_page() + 0xFFFF800000000000; + memcpy(mem, "HelloWorld\0", 11); + trace("pmm: Read from allocated memory: %s\n", mem); + pmm_free_page(mem); + trace("pmm: Freed memory.\n"); + // We're done, just hang... hcf(); } diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c index da05a58..ae39604 100644 --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -17,29 +17,54 @@ uint64_t pmm_available_pages = 0; uint64_t pmm_total_pages = 0; -static pmm_page_t* pmm_free_list_head = NULL; +static pmm_region_t *pmm_region_list_head = NULL; +static pmm_page_t *pmm_free_list_head = NULL; void pmm_free_page(void *mem) { pmm_page_t *page = (pmm_page_t*)mem; - page->next = pmm_free_list_head; + pmm_page_t *page_hhalf = (pmm_page_t*)higher_half((uint64_t)page); + page_hhalf->next = pmm_free_list_head; pmm_free_list_head = page; pmm_available_pages++; } +static void __pmm_steal_pages_from_region_head(int pages) { + pmm_region_list_head->length -= PMM_PAGE_SIZE; + void *page = (void*)pmm_region_list_head->base + + pmm_region_list_head->length; + pmm_free_page(page); + + if (pmm_region_list_head->length == 0) + { + // If a region is totally consumed, + // we can turn it into a free page :) + // So our 4kb aren't really lost + void *mem = (void*)pmm_region_list_head; + pmm_region_list_head = pmm_region_list_head->next; + + pmm_free_page(mem); + } +} + void *pmm_alloc_page() { if (!pmm_free_list_head) { - fatal("pmm: out of memory!\n"); - hcf(); + if (!pmm_region_list_head) { + fatal("pmm: out of memory!\n"); + hcf(); + } + __pmm_steal_pages_from_region_head(4); + // et voila, we now have 4 free pages to allocate } pmm_available_pages--; pmm_page_t *page = pmm_free_list_head; - pmm_free_list_head = page->next; + pmm_page_t *page_hhalf = (pmm_page_t*)higher_half((uint64_t)page); + pmm_free_list_head = page_hhalf->next; - memset(page, 0, PMM_PAGE_SIZE); + //memset(page_hhalf, 0, PMM_PAGE_SIZE); return page; } @@ -49,15 +74,23 @@ void pmm_init() { for (uint64_t i = 0; i < mmap->entry_count; i++) { struct limine_memmap_entry *entry = mmap->entries[i]; - if (entry->type == LIMINE_MEMMAP_USABLE) + if (entry->type == LIMINE_MEMMAP_USABLE || + entry->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE) { trace("pmm: found a usable memory block: %p-%p\n", entry->base, entry->base + entry->length); - uint64_t newlen = ALIGN_UP(entry->length, PMM_PAGE_SIZE); - for (uint64_t j = 0; j < newlen; j += PMM_PAGE_SIZE) { - pmm_free_page((void*)(entry->base + j)); - pmm_total_pages++; - } + uint64_t newlen = ALIGN_DOWN(entry->length, PMM_PAGE_SIZE); + + // Give a page to store the PMM region. + // When the region is fully consumed, the + // page is freed so that it can be used (i love recycling) + pmm_region_t *reg = (pmm_region_t*)higher_half(entry->base); + reg->base = entry->base + PMM_PAGE_SIZE; + reg->length = newlen - PMM_PAGE_SIZE; + reg->next = pmm_region_list_head; + pmm_region_list_head = reg; + + pmm_available_pages += reg->length / PMM_PAGE_SIZE; } } diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h index db52cc5..70d5fc7 100644 --- a/kernel/src/mm/pmm.h +++ b/kernel/src/mm/pmm.h @@ -8,6 +8,7 @@ #pragma once #include +#include #define DIV_ROUND_UP(x, y) \ (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) @@ -20,4 +21,28 @@ typedef struct __pmm_page { struct __pmm_page *next; } pmm_page_t; +typedef struct __pmm_region { + uint64_t base; + uint64_t length; + struct __pmm_region *next; +} pmm_region_t; + +inline uint64_t higher_half(uint64_t addr) { + uint64_t hhdm_off = limine_get_hhdm_offset(); + if (addr > hhdm_off) + return addr; + + return addr + hhdm_off; +} + +inline uint64_t physical(uint64_t addr) { + uint64_t hhdm_off = limine_get_hhdm_offset(); + if (addr < hhdm_off) + return addr; + + return addr - hhdm_off; +} + +void pmm_free_page(void *mem); +void *pmm_alloc_page(); void pmm_init(); \ No newline at end of file diff --git a/kernel/src/mm/pmm.md b/kernel/src/mm/pmm.md new file mode 100644 index 0000000..a5bad46 --- /dev/null +++ b/kernel/src/mm/pmm.md @@ -0,0 +1,78 @@ +# Soaplin's Physical Memory Manager + +The Physical Memory Manager (PMM) in Soaplin uses a lazy-loading design that efficiently manages physical memory pages while minimizing boot time overhead. + +## Design Overview + +The PMM uses a two-level allocation strategy: +1. Region List - tracks large blocks of available physical memory +2. Free Page List - manages individual pages ready for immediate allocation + +### Memory Regions + +Each memory region is tracked by a `pmm_region_t` structure that contains: +- Base address of the available memory +- Length of remaining memory +- Pointer to next region + +The region structure is cleverly stored in the first page of the region itself, making the overhead minimal (just one 4KB page per region). +When the region has been totally consumed, it's metadata page is turned +into a free page that can be allocated. + +### Free Page List + +The free page list is a singly-linked list of individual pages that are ready for immediate allocation. It gets refilled from regions only when needed. + +## Lazy Loading + +Instead of initializing all free pages at boot time, the PMM: +1. Only initializes region structures during boot +2. Adds pages to the free list on-demand +3. Consumes memory regions gradually as needed + +This approach provides several benefits: +- Very fast boot times regardless of RAM size +- Memory overhead proportional to number of regions, not total RAM +- No performance penalty during normal operation + +## Memory Organization + +Physical memory is organized as follows: +- Each region's first page contains the region metadata +- Remaining pages in each region are available for allocation +- Pages are standard 4KB size +- Free pages are linked together in the free list + +## Usage + +The PMM provides three main functions: +- `pmm_init()` - Initializes the PMM from the bootloader's memory map +- `pmm_alloc_page()` - Allocates a single 4KB page +- `pmm_free_page()` - Returns a page to the free list + +## Implementation Details + +### Region Initialization +During boot, the PMM: +1. Receives memory map from Limine +2. Identifies usable memory regions +3. Sets up region tracking structures +4. Calculates total available pages + +### Page Allocation +When allocating pages: +1. First tries the free list +2. If free list is empty: + - Takes 4 pages from current region + - Adds it to free list + - Updates region metadata + - If the region has been consumed + - Let the next region take the head + - Free the region's metadata page. +3. Returns the page to the caller + +### Memory Tracking +The PMM maintains counters for: +- Total available pages +- Currently free pages +This allows for memory usage monitoring and OOM detection. From 33f88512d45e030d0ca70e00d968e1cb28a48954 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 18:58:22 +0200 Subject: [PATCH 22/30] vmm: brokie paging :) --- kernel/linker-x86_64.ld | 8 ++ kernel/src/arch/aarch64/cpu.c | 8 ++ kernel/src/arch/cpu.h | 8 ++ kernel/src/arch/la64/cpu.c | 8 ++ kernel/src/arch/riscv/cpu.c | 8 ++ kernel/src/arch/x86_64/cpu.c | 29 ++++++ kernel/src/boot/limine.c | 13 ++- kernel/src/boot/limine.h | 4 +- kernel/src/main.c | 6 +- kernel/src/mm/pmm.c | 32 +++--- kernel/src/mm/pmm.md | 78 --------------- kernel/src/mm/vmm.c | 177 ++++++++++++++++++++++++++++++++++ kernel/src/mm/vmm.h | 45 +++++++++ 13 files changed, 324 insertions(+), 100 deletions(-) delete mode 100644 kernel/src/mm/pmm.md create mode 100644 kernel/src/mm/vmm.c create mode 100644 kernel/src/mm/vmm.h diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld index b8e1485..7dbf287 100644 --- a/kernel/linker-x86_64.ld +++ b/kernel/linker-x86_64.ld @@ -25,29 +25,36 @@ SECTIONS /* Define a section to contain the Limine requests and assign it to its own PHDR */ .limine_requests : { + reqs_start_ld = .; KEEP(*(.limine_requests_start)) KEEP(*(.limine_requests)) KEEP(*(.limine_requests_end)) + reqs_end_ld = .; } :limine_requests /* Move to the next memory page for .text */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .text : { + text_start_ld = .; *(.text .text.*) + text_end_ld = .; } :text /* Move to the next memory page for .rodata */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { + rodata_start_ld = .; *(.rodata .rodata.*) + rodata_end_ld = .; } :rodata /* Move to the next memory page for .data */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .data : { + data_start_ld = .; *(.data .data.*) } :data @@ -58,6 +65,7 @@ SECTIONS .bss : { *(.bss .bss.*) *(COMMON) + data_end_ld = .; } :data /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ diff --git a/kernel/src/arch/aarch64/cpu.c b/kernel/src/arch/aarch64/cpu.c index 48fee8b..f2d3feb 100644 --- a/kernel/src/arch/aarch64/cpu.c +++ b/kernel/src/arch/aarch64/cpu.c @@ -12,6 +12,14 @@ void arch_init_stage1() { } +void cpu_load_pm(pagemap_t pm) { + +} + +void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { + +} + void hcf() { for (;;) { asm ("wfi"); diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index 11a28af..8c56fa6 100644 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -7,8 +7,16 @@ #pragma once +#include "mm/vmm.h" + // Stage 1 initialization: Core components (such as the GDT & IDT on x86_64...) void arch_init_stage1(); +// Load a pagemap +void cpu_load_pm(pagemap_t pm); + +// Invalidate a page table entry +void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr); + // Disable interrupts and halt the system. void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/la64/cpu.c b/kernel/src/arch/la64/cpu.c index 6abe756..5c41bca 100644 --- a/kernel/src/arch/la64/cpu.c +++ b/kernel/src/arch/la64/cpu.c @@ -12,6 +12,14 @@ void arch_init_stage1() { } +void cpu_load_pm(pagemap_t pm) { + +} + +void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { + +} + void hcf() { for (;;) { asm ("idle 0"); diff --git a/kernel/src/arch/riscv/cpu.c b/kernel/src/arch/riscv/cpu.c index 658b2a4..3dcdf96 100644 --- a/kernel/src/arch/riscv/cpu.c +++ b/kernel/src/arch/riscv/cpu.c @@ -12,6 +12,14 @@ void arch_init_stage1() { } +void cpu_load_pm(pagemap_t pm) { + +} + +void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { + +} + void hcf() { for (;;) { asm ("wfi"); diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c index 99c591a..b54c8e1 100644 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -5,17 +5,46 @@ * cpu.c - x86_64 CPU control implementation. */ +#include "mm/vmm.h" #if defined (__x86_64__) #include #include #include +#include void arch_init_stage1() { gdt_init(); idt_init(); } +void cpu_load_pm(pagemap_t pm) { + if (!pm) + return; + + __asm__ volatile("mov %0, %%cr3" : : "r"(physical((uint64_t)pm)) : "memory"); +} + +static uint64_t read_cr3(void) +{ + unsigned long val; + asm volatile ( "mov %%cr3, %0" : "=r"(val) ); + return val; +} + +void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { + uint64_t cr3 = read_cr3(); + if (physical((uint64_t)pm) != cr3) + { + // load the provided PM in cr3, invalidate the page and return into the previous cr3. + cpu_load_pm(pm); + asm volatile ( "invlpg (%0)" : : "b"(vaddr) : "memory" ); + cpu_load_pm((pagemap_t)cr3); + return; + } + asm volatile ( "invlpg (%0)" : : "b"(vaddr) : "memory" ); +} + void hcf() { asm ("cli"); for (;;) { diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index abcdf0c..2294d64 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -44,6 +44,12 @@ static volatile struct limine_hhdm_request hhdm_req = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_executable_address_request kaddr_req = { + .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -87,7 +93,6 @@ limine_bootinfo_t *limine_get_bootinfo() { return &__limine_bootinfo; } -uint64_t limine_get_hhdm_offset() -{ - return hhdm_req.response->offset; -} \ No newline at end of file +uint64_t limine_get_hhdm_offset() { return hhdm_req.response->offset; } +uint64_t limine_get_kernel_vaddr() { return kaddr_req.response->virtual_base; } +uint64_t limine_get_kernel_paddr() { return kaddr_req.response->physical_base; } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index 3142f9d..96a1a91 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -31,4 +31,6 @@ limine_bootinfo_t *limine_get_bootinfo(); // Get the memory map. struct limine_memmap_response *limine_get_memmap(); -uint64_t limine_get_hhdm_offset(); \ No newline at end of file +uint64_t limine_get_hhdm_offset(); +uint64_t limine_get_kernel_vaddr(); +uint64_t limine_get_kernel_paddr(); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 05437c7..e6593da 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -5,6 +5,7 @@ * main.c - Kernel entry point and initialization. */ +#include "mm/vmm.h" #include #include #include @@ -31,11 +32,12 @@ void kmain(void) { arch_init_stage1(); pmm_init(); - uint8_t* mem = pmm_alloc_page() + 0xFFFF800000000000; + vmm_init(); + /*uint8_t* mem = pmm_alloc_page() + 0xFFFF800000000000; memcpy(mem, "HelloWorld\0", 11); trace("pmm: Read from allocated memory: %s\n", mem); pmm_free_page(mem); - trace("pmm: Freed memory.\n"); + trace("pmm: Freed memory.\n");*/ // We're done, just hang... hcf(); diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c index ae39604..e3d9be9 100644 --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -23,27 +23,29 @@ static pmm_page_t *pmm_free_list_head = NULL; void pmm_free_page(void *mem) { pmm_page_t *page = (pmm_page_t*)mem; pmm_page_t *page_hhalf = (pmm_page_t*)higher_half((uint64_t)page); - page_hhalf->next = pmm_free_list_head; - pmm_free_list_head = page; + page_hhalf->next = (pmm_page_t*)higher_half((uint64_t)pmm_free_list_head); + pmm_free_list_head = page_hhalf; pmm_available_pages++; } static void __pmm_steal_pages_from_region_head(int pages) { - pmm_region_list_head->length -= PMM_PAGE_SIZE; - void *page = (void*)pmm_region_list_head->base + - pmm_region_list_head->length; - pmm_free_page(page); + for (int i = 0; i < pages; i++) { + pmm_region_list_head->length -= PMM_PAGE_SIZE; + void *page = (void*)pmm_region_list_head->base + + pmm_region_list_head->length; + pmm_free_page(page); - if (pmm_region_list_head->length == 0) - { - // If a region is totally consumed, - // we can turn it into a free page :) - // So our 4kb aren't really lost - void *mem = (void*)pmm_region_list_head; - pmm_region_list_head = pmm_region_list_head->next; - - pmm_free_page(mem); + if (pmm_region_list_head->length == 0) + { + // If a region is totally consumed, + // we can turn it into a free page :) + // So our 4kb aren't really lost + void *mem = (void*)pmm_region_list_head; + pmm_region_list_head = pmm_region_list_head->next; + + pmm_free_page(mem); + } } } diff --git a/kernel/src/mm/pmm.md b/kernel/src/mm/pmm.md deleted file mode 100644 index a5bad46..0000000 --- a/kernel/src/mm/pmm.md +++ /dev/null @@ -1,78 +0,0 @@ -# Soaplin's Physical Memory Manager - -The Physical Memory Manager (PMM) in Soaplin uses a lazy-loading design that efficiently manages physical memory pages while minimizing boot time overhead. - -## Design Overview - -The PMM uses a two-level allocation strategy: -1. Region List - tracks large blocks of available physical memory -2. Free Page List - manages individual pages ready for immediate allocation - -### Memory Regions - -Each memory region is tracked by a `pmm_region_t` structure that contains: -- Base address of the available memory -- Length of remaining memory -- Pointer to next region - -The region structure is cleverly stored in the first page of the region itself, making the overhead minimal (just one 4KB page per region). -When the region has been totally consumed, it's metadata page is turned -into a free page that can be allocated. - -### Free Page List - -The free page list is a singly-linked list of individual pages that are ready for immediate allocation. It gets refilled from regions only when needed. - -## Lazy Loading - -Instead of initializing all free pages at boot time, the PMM: -1. Only initializes region structures during boot -2. Adds pages to the free list on-demand -3. Consumes memory regions gradually as needed - -This approach provides several benefits: -- Very fast boot times regardless of RAM size -- Memory overhead proportional to number of regions, not total RAM -- No performance penalty during normal operation - -## Memory Organization - -Physical memory is organized as follows: -- Each region's first page contains the region metadata -- Remaining pages in each region are available for allocation -- Pages are standard 4KB size -- Free pages are linked together in the free list - -## Usage - -The PMM provides three main functions: -- `pmm_init()` - Initializes the PMM from the bootloader's memory map -- `pmm_alloc_page()` - Allocates a single 4KB page -- `pmm_free_page()` - Returns a page to the free list - -## Implementation Details - -### Region Initialization -During boot, the PMM: -1. Receives memory map from Limine -2. Identifies usable memory regions -3. Sets up region tracking structures -4. Calculates total available pages - -### Page Allocation -When allocating pages: -1. First tries the free list -2. If free list is empty: - - Takes 4 pages from current region - - Adds it to free list - - Updates region metadata - - If the region has been consumed - - Let the next region take the head - - Free the region's metadata page. -3. Returns the page to the caller - -### Memory Tracking -The PMM maintains counters for: -- Total available pages -- Currently free pages -This allows for memory usage monitoring and OOM detection. diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c new file mode 100644 index 0000000..f4ce7d3 --- /dev/null +++ b/kernel/src/mm/vmm.c @@ -0,0 +1,177 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * vmm.c - Virtual memory manager + */ + +#include "boot/limine.h" +#include "lib/log.h" +#include +#include + +#include +#include +#include +#include +#include + +pagemap_t vmm_kernel_pm = NULL; +pagemap_t vmm_current_pm = NULL; + +void vmm_init() { +#if !defined(__x86_64__) + fatal("vmm: not implemented\n"); + hcf(); +#endif + // Our objective here is to recreate the + // kernel page map that Limine provide us + + vmm_kernel_pm = vmm_alloc_pm(); + + uint64_t kvaddr = limine_get_kernel_vaddr(); + uint64_t kpaddr = limine_get_kernel_paddr(); + uint64_t reqs_start = ALIGN_DOWN((uint64_t)reqs_start_ld, PMM_PAGE_SIZE); + uint64_t reqs_end = ALIGN_UP((uint64_t)reqs_end_ld, PMM_PAGE_SIZE); + uint64_t text_start = ALIGN_DOWN((uint64_t)text_start_ld, PMM_PAGE_SIZE); + uint64_t text_end = ALIGN_UP((uint64_t)text_end_ld, PMM_PAGE_SIZE); + uint64_t rodata_start = ALIGN_DOWN((uint64_t)rodata_start_ld, PMM_PAGE_SIZE); + uint64_t rodata_end = ALIGN_UP((uint64_t)rodata_end_ld, PMM_PAGE_SIZE); + uint64_t data_start = ALIGN_DOWN((uint64_t)data_start_ld, PMM_PAGE_SIZE); + uint64_t data_end = ALIGN_UP((uint64_t)data_end_ld, PMM_PAGE_SIZE); + + // Now, map the kernel's sections + for (uint64_t i = reqs_start; i < reqs_end; i += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_WRITE); // why would i write into Limine requests? + trace("vmm: Mapped limine rqs: PW\n"); + for (uint64_t i = text_start; i < text_end; i += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT); + trace("vmm: Mapped text: P\n"); + for (uint64_t i = rodata_start; i < rodata_end; i += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_NX); + trace("vmm: Mapped rodata: P NX\n"); + for (uint64_t i = data_start; i < data_end; i += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_WRITE | PTE_NX); + trace("vmm: Mapped data: PW NX\n"); + + // Map the lower 4 GiB into the higher-half + for (uint64_t i = 0; i < 0x100000000; i += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); + trace("vmm: Mapped lower 4gib to higher half with flags: PW\n"); + + cpu_load_pm(vmm_kernel_pm); + + trace("vmm: Initialized.\n"); +} + +void vmm_load_pm(pagemap_t pm) { + if (!pm) + return; + + vmm_current_pm = pm; + cpu_load_pm((pagemap_t)physical((uint64_t)pm)); +} + +pagemap_t vmm_alloc_pm() { + pagemap_t pm = (pagemap_t)higher_half((uint64_t)pmm_alloc_page()); + memset((void*)pm, 0, PMM_PAGE_SIZE); + + if (vmm_kernel_pm) + { + for (int i = 256; i < 512; i++) + pm[i] = vmm_kernel_pm[i]; + } + + return pm; +} + +void vmm_free_pm(pagemap_t pm) { + if (pm == vmm_kernel_pm) + { + warn("vmm: Who tried to free the kernel's pagemap?!\n"); + return; + } + pmm_free_page((void*)pm); +} + +static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, + uint64_t flags, bool alloc) { + if (level[entry] & PTE_PRESENT) + return (uint64_t *)higher_half(PTE_GET_ADDR(level[entry])); + if (alloc) { + uint64_t *pml = (uint64_t *)higher_half((uint64_t)pmm_alloc_page()); + memset(pml, 0, PMM_PAGE_SIZE); + level[entry] = (uint64_t)physical((uint64_t)pml) | flags; + return pml; + } + return NULL; +} + +void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { + if (!pm) return; + + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, PTE_PRESENT | PTE_WRITE, true); + + pml1[pml1_entry] = paddr | flags; +} + +void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, + uint64_t flags) { + if (!pm) return; + + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, flags, true); + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags, true); + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags, true); + + pml1[pml1_entry] = paddr | flags; +} + +void vmm_unmap(pagemap_t pm, uint64_t vaddr) { + if (!pm) return; + + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, 0, false); + if (!pml3) return; + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); + if (!pml2) return; + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); + if (!pml1) return; + + pml1[pml1_entry] = 0; + cpu_invalidate_page(pm, vaddr); +} + +void vmm_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { + if (!pm) return; + + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, 0, false); + if (!pml3) return; + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); + if (!pml2) return; + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); + if (!pml1) return; + + uint64_t paddr = pml1[pml1_entry] & PTE_ADDR_MASK; + pml1[pml1_entry] = paddr | flags; +} \ No newline at end of file diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h new file mode 100644 index 0000000..7b769c6 --- /dev/null +++ b/kernel/src/mm/vmm.h @@ -0,0 +1,45 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * vmm.c - Virtual memory manager + */ + +#pragma once + +// Page flags +#include + +#define PTE_ADDR_MASK 0x000ffffffffff000 +#define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) +#define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) + +#define PTE_PRESENT (1 << 0) +#define PTE_WRITE (1 << 1) +#define PTE_USER (1 << 2) +#define PTE_NX (1ULL << 63) // NX = No eXecute. + +typedef uint64_t *pagemap_t; + +// These are defined in the linker file. +extern char reqs_start_ld; +extern char reqs_end_ld; + +extern char text_start_ld; +extern char text_end_ld; + +extern char rodata_start_ld; +extern char rodata_end_ld; + +extern char data_start_ld; +extern char data_end_ld; + +void vmm_init(); +pagemap_t vmm_alloc_pm(); +void vmm_free_pm(pagemap_t pm); + +void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); +void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, + uint64_t flags); +void vmm_unmap(pagemap_t pm, uint64_t vaddr); +void vmm_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags); \ No newline at end of file From 875dc2685bdedc3c6ad71c9d0837b0643ca26c09 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 19:36:49 +0200 Subject: [PATCH 23/30] vmm: broken vmm --- kernel/src/mm/pmm.c | 21 +++++++++++++-------- kernel/src/mm/vmm.c | 2 ++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c index e3d9be9..1d75182 100644 --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -21,10 +21,13 @@ static pmm_region_t *pmm_region_list_head = NULL; static pmm_page_t *pmm_free_list_head = NULL; void pmm_free_page(void *mem) { - pmm_page_t *page = (pmm_page_t*)mem; - pmm_page_t *page_hhalf = (pmm_page_t*)higher_half((uint64_t)page); - page_hhalf->next = (pmm_page_t*)higher_half((uint64_t)pmm_free_list_head); - pmm_free_list_head = page_hhalf; + if (!mem) + return; + + pmm_page_t *page = (pmm_page_t*)higher_half((uint64_t)mem); + page->next = pmm_free_list_head ? (pmm_page_t*)higher_half((uint64_t)pmm_free_list_head) : 0x0; + pmm_free_list_head = page; + //trace("pmm: free: page free list head is now %p\n", page); pmm_available_pages++; } @@ -35,6 +38,7 @@ static void __pmm_steal_pages_from_region_head(int pages) { void *page = (void*)pmm_region_list_head->base + pmm_region_list_head->length; pmm_free_page(page); + //trace("pmm: stealer: page is %p\n", page); if (pmm_region_list_head->length == 0) { @@ -63,11 +67,12 @@ void *pmm_alloc_page() { pmm_available_pages--; pmm_page_t *page = pmm_free_list_head; - pmm_page_t *page_hhalf = (pmm_page_t*)higher_half((uint64_t)page); - pmm_free_list_head = page_hhalf->next; + trace("pmm: alloc: page is %p\n", page); + pmm_free_list_head = page->next; + //trace("pmm: alloc: free page list head is now %p\n", page); - //memset(page_hhalf, 0, PMM_PAGE_SIZE); - return page; + memset(page, 0, PMM_PAGE_SIZE); + return (void*)physical((uint64_t)page); } void pmm_init() { diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index f4ce7d3..112ef16 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -96,6 +96,7 @@ void vmm_free_pm(pagemap_t pm) { static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags, bool alloc) { + //trace("level: %p, level[entry]: %p\n", level, level + entry); if (level[entry] & PTE_PRESENT) return (uint64_t *)higher_half(PTE_GET_ADDR(level[entry])); if (alloc) { @@ -110,6 +111,7 @@ static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { if (!pm) return; + //trace("pm: %p, vaddr: %p, paddr: %p\n", pm, vaddr, paddr); uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; From c658f738e49d2cc162e27c26015e680a38e82220 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Sun, 18 May 2025 21:45:14 +0200 Subject: [PATCH 24/30] vmm: Use the kernel's ELF file to map the sections (and now works!) --- kernel/linker-x86_64.ld | 8 -- kernel/src/arch/x86_64/idt.c | 49 ++++++++++++ kernel/src/boot/limine.c | 20 ++++- kernel/src/boot/limine.h | 3 +- kernel/src/exec/elf.h | 150 +++++++++++++++++++++++++++++++++++ kernel/src/lib/npf.c | 4 +- kernel/src/mm/pmm.c | 3 - kernel/src/mm/vmm.c | 58 +++++++------- kernel/src/mm/vmm.h | 14 +--- 9 files changed, 250 insertions(+), 59 deletions(-) create mode 100644 kernel/src/exec/elf.h diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld index 7dbf287..b8e1485 100644 --- a/kernel/linker-x86_64.ld +++ b/kernel/linker-x86_64.ld @@ -25,36 +25,29 @@ SECTIONS /* Define a section to contain the Limine requests and assign it to its own PHDR */ .limine_requests : { - reqs_start_ld = .; KEEP(*(.limine_requests_start)) KEEP(*(.limine_requests)) KEEP(*(.limine_requests_end)) - reqs_end_ld = .; } :limine_requests /* Move to the next memory page for .text */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .text : { - text_start_ld = .; *(.text .text.*) - text_end_ld = .; } :text /* Move to the next memory page for .rodata */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .rodata : { - rodata_start_ld = .; *(.rodata .rodata.*) - rodata_end_ld = .; } :rodata /* Move to the next memory page for .data */ . = ALIGN(CONSTANT(MAXPAGESIZE)); .data : { - data_start_ld = .; *(.data .data.*) } :data @@ -65,7 +58,6 @@ SECTIONS .bss : { *(.bss .bss.*) *(COMMON) - data_end_ld = .; } :data /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index 34e8589..664b958 100644 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -14,6 +14,54 @@ __attribute__((aligned(0x10))) static idt_entry_t idt[256]; static idtr_t idtr; +static void __panic_display_bt(registers_t *regs) { + if (regs->cs == 0x43 || regs->cs == 0x3B) { + fatal("The backtrace can't be dumped from a userspace process.\n"); + return; // Don't try to backtrace userspace + } + + fatal("-- BACKTRACE --\n"); + + // First print the current instruction pointer from the interrupt frame + if (regs->rip) { + fatal("* %p (current)\n", regs->rip); + } + + uint64_t *frame = (uint64_t*)regs->rbp; + if (!frame || (uint64_t)frame < 0xffffffff80000000) { + fatal("No further stack frames available\n"); + return; + } + + // Frame format in x86_64: + // [rbp] -> previous rbp + // [rbp+8] -> return address + int depth = 0; + while (frame && depth < 16) { // Limit depth to avoid infinite loops + // Validate both frame and return address pointers + uint64_t *ret_addr_ptr = frame + 1; + if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) { + break; + } + + uint64_t ret_addr = *ret_addr_ptr; + if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) { + break; + } + + fatal("* %p\n", ret_addr); + + uint64_t next_rbp = *frame; + if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) { + break; + } + + frame = (uint64_t*)next_rbp; + depth++; + } + fatal("\n"); +} + void idt_interrupt_handler(registers_t *regs) { fatal("Kernel panic: CPU exception %d\n", regs->int_no); fatal("rax: %p, rbx: %p, rbp: %p, rdx\n", regs->rax, regs->rbx, regs->rbp, regs->rdx); @@ -23,6 +71,7 @@ void idt_interrupt_handler(registers_t *regs) { fatal("r14: %p, r15: %p\n", regs->r14, regs->r15); fatal("rip: %p, cs: %p, ss: %p\n", regs->rip, regs->cs, regs->ss); fatal("rflags: %p, err: %p, rsp: %p\n", regs->rflags, regs->err_code, regs->rsp); + __panic_display_bt(regs); hcf(); } diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index 2294d64..a41457b 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -5,11 +5,11 @@ * limine.c - Limine bootloader interface implementation. */ -#include "deps/limine.h" -#include "limine.h" #include #include #include +#include +#include __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); @@ -50,6 +50,19 @@ static volatile struct limine_executable_address_request kaddr_req = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_executable_file_request execfile_req = { + .id = LIMINE_EXECUTABLE_FILE_REQUEST, + .revision = 0 +}; + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_paging_mode_request pgmode_req = { + .id = LIMINE_PAGING_MODE_REQUEST, + .mode = LIMINE_PAGING_MODE_X86_64_4LVL, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -95,4 +108,5 @@ limine_bootinfo_t *limine_get_bootinfo() { uint64_t limine_get_hhdm_offset() { return hhdm_req.response->offset; } uint64_t limine_get_kernel_vaddr() { return kaddr_req.response->virtual_base; } -uint64_t limine_get_kernel_paddr() { return kaddr_req.response->physical_base; } \ No newline at end of file +uint64_t limine_get_kernel_paddr() { return kaddr_req.response->physical_base; } +uint64_t limine_get_kernel_ehdr_addr() { return (uint64_t)execfile_req.response->executable_file->address; } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index 96a1a91..d65ed79 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -33,4 +33,5 @@ struct limine_memmap_response *limine_get_memmap(); uint64_t limine_get_hhdm_offset(); uint64_t limine_get_kernel_vaddr(); -uint64_t limine_get_kernel_paddr(); \ No newline at end of file +uint64_t limine_get_kernel_paddr(); +uint64_t limine_get_kernel_ehdr_addr(); \ No newline at end of file diff --git a/kernel/src/exec/elf.h b/kernel/src/exec/elf.h new file mode 100644 index 0000000..8870c54 --- /dev/null +++ b/kernel/src/exec/elf.h @@ -0,0 +1,150 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * elf.h - ELF definitions + */ + +#pragma once + +#include + +// ELF magic. +#define EI_MAG0 0 +#define ELFMAG0 0x7f + +#define EI_MAG1 1 +#define ELFMAG1 'E' + +#define EI_MAG2 2 +#define ELFMAG2 'L' + +#define EI_MAG3 3 +#define ELFMAG3 'F' + +// ELF class +#define EI_CLASS 4 +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +// Is processor-specific data little-endian or big-endian? +#define EI_DATA 5 +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +// ELF version +#define EI_VERSION 6 +#define EV_NONE 0 +#define EV_CURRENT 1 + +// ELF ABI +#define EI_OSABI 7 +#define ELFOSABI_NONE 0 +#define ELFOSABI_SYSV 0 +#define ELFOSABI_HPUX 1 +#define ELFOSABI_NETBSD 2 +#define ELFOSABI_LINUX 3 +#define ELFOSABI_SOLARIS 6 +#define ELFOSABI_IRIX 8 +#define ELFOSABI_FREEBSD 9 +#define ELFOSABI_TRU64 10 +#define ELFOSABI_ARM 97 +#define ELFOSABI_STANDALONE 255 + +// ABI version +#define EI_ABIVERSION 8 + +// Unused bytes. +#define EI_PAD 9 + +// Magic size. +#define EI_NIDENT 16 + +// e_type +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 + +// e_machine (we only included machines supported by Soaplin.) +#define EM_X86_64 62 + +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; +typedef uint16_t Elf64_Section; +typedef uint16_t Elf64_Versym; +typedef uint8_t Elf_Byte; +typedef uint16_t Elf64_Half; +typedef int32_t Elf64_Sword; +typedef uint32_t Elf64_Word; +typedef int64_t Elf64_Sxword; +typedef uint64_t Elf64_Xword; + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; +} Elf64_Ehdr; + +#define SHN_UNDEF 0 + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 + +#define PF_X (1 << 0) +#define PF_W (1 << 1) +#define PF_R (1 << 2) + +typedef struct { + uint32_t p_type; + uint32_t p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + uint64_t p_filesz; + uint64_t p_memsz; + uint64_t p_align; +} Elf64_Phdr; + +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 + +typedef struct { + uint32_t st_name; + unsigned char st_info; + unsigned char st_other; + uint16_t st_shndx; + Elf64_Addr st_value; + uint64_t st_size; +} Elf64_Sym; + +typedef struct { + uint32_t sh_name; + uint32_t sh_type; + uint64_t sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + uint64_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint64_t sh_addralign; + uint64_t sh_entsize; +} Elf64_Shdr; diff --git a/kernel/src/lib/npf.c b/kernel/src/lib/npf.c index 59df675..6669543 100644 --- a/kernel/src/lib/npf.c +++ b/kernel/src/lib/npf.c @@ -6,12 +6,12 @@ */ #define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_SMALL_FORMAT_SPECIFIERS 1 #define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 #define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 // Compile nanoprintf in this translation unit. #define NANOPRINTF_IMPLEMENTATION diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c index 1d75182..1959403 100644 --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -27,7 +27,6 @@ void pmm_free_page(void *mem) { pmm_page_t *page = (pmm_page_t*)higher_half((uint64_t)mem); page->next = pmm_free_list_head ? (pmm_page_t*)higher_half((uint64_t)pmm_free_list_head) : 0x0; pmm_free_list_head = page; - //trace("pmm: free: page free list head is now %p\n", page); pmm_available_pages++; } @@ -67,9 +66,7 @@ void *pmm_alloc_page() { pmm_available_pages--; pmm_page_t *page = pmm_free_list_head; - trace("pmm: alloc: page is %p\n", page); pmm_free_list_head = page->next; - //trace("pmm: alloc: free page list head is now %p\n", page); memset(page, 0, PMM_PAGE_SIZE); return (void*)physical((uint64_t)page); diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index 112ef16..9233b09 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -5,12 +5,13 @@ * vmm.c - Virtual memory manager */ -#include "boot/limine.h" -#include "lib/log.h" #include #include #include +#include +#include +#include #include #include #include @@ -31,36 +32,37 @@ void vmm_init() { uint64_t kvaddr = limine_get_kernel_vaddr(); uint64_t kpaddr = limine_get_kernel_paddr(); - uint64_t reqs_start = ALIGN_DOWN((uint64_t)reqs_start_ld, PMM_PAGE_SIZE); - uint64_t reqs_end = ALIGN_UP((uint64_t)reqs_end_ld, PMM_PAGE_SIZE); - uint64_t text_start = ALIGN_DOWN((uint64_t)text_start_ld, PMM_PAGE_SIZE); - uint64_t text_end = ALIGN_UP((uint64_t)text_end_ld, PMM_PAGE_SIZE); - uint64_t rodata_start = ALIGN_DOWN((uint64_t)rodata_start_ld, PMM_PAGE_SIZE); - uint64_t rodata_end = ALIGN_UP((uint64_t)rodata_end_ld, PMM_PAGE_SIZE); - uint64_t data_start = ALIGN_DOWN((uint64_t)data_start_ld, PMM_PAGE_SIZE); - uint64_t data_end = ALIGN_UP((uint64_t)data_end_ld, PMM_PAGE_SIZE); + + char *elf_addr = (char *)limine_get_kernel_ehdr_addr(); + Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elf_addr; - // Now, map the kernel's sections - for (uint64_t i = reqs_start; i < reqs_end; i += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_WRITE); // why would i write into Limine requests? - trace("vmm: Mapped limine rqs: PW\n"); - for (uint64_t i = text_start; i < text_end; i += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT); - trace("vmm: Mapped text: P\n"); - for (uint64_t i = rodata_start; i < rodata_end; i += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_NX); - trace("vmm: Mapped rodata: P NX\n"); - for (uint64_t i = data_start; i < data_end; i += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, i, i - kvaddr + kpaddr, PTE_PRESENT | PTE_WRITE | PTE_NX); - trace("vmm: Mapped data: PW NX\n"); + for (uint16_t i = 0; i < ehdr->e_phnum; i++) { + Elf64_Phdr *cur_phdr = (Elf64_Phdr*)(elf_addr + ehdr->e_phoff + (i * ehdr->e_phentsize)); + if (cur_phdr->p_type != PT_LOAD) + continue; + + uintptr_t phys = (cur_phdr->p_vaddr - kvaddr) + kpaddr; + uint64_t flags = PTE_PRESENT; + if ((cur_phdr->p_flags & PF_X) == 0) { + flags |= PTE_NX; + } + if (cur_phdr->p_flags & PF_W) { + flags |= PTE_WRITE; + } + + size_t length = ALIGN_UP(cur_phdr->p_memsz, PMM_PAGE_SIZE); + + for (uint64_t i = 0; i < length; i += PMM_PAGE_SIZE) { + vmm_map(vmm_kernel_pm, cur_phdr->p_vaddr + i, phys + i, flags); + } + trace("vmm: Mapped range: %p -> %p (length: %x)\n", phys, cur_phdr->p_vaddr, length); + } - // Map the lower 4 GiB into the higher-half for (uint64_t i = 0; i < 0x100000000; i += PMM_PAGE_SIZE) vmm_map(vmm_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); - trace("vmm: Mapped lower 4gib to higher half with flags: PW\n"); - - cpu_load_pm(vmm_kernel_pm); + trace("vmm: Mapped range: %p -> %p (length: %x)\n", 0x0, 0xFFFF800000000000, 0x100000000); + vmm_load_pm(vmm_kernel_pm); trace("vmm: Initialized.\n"); } @@ -96,7 +98,6 @@ void vmm_free_pm(pagemap_t pm) { static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags, bool alloc) { - //trace("level: %p, level[entry]: %p\n", level, level + entry); if (level[entry] & PTE_PRESENT) return (uint64_t *)higher_half(PTE_GET_ADDR(level[entry])); if (alloc) { @@ -111,7 +112,6 @@ static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { if (!pm) return; - //trace("pm: %p, vaddr: %p, paddr: %p\n", pm, vaddr, paddr); uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h index 7b769c6..6414cf4 100644 --- a/kernel/src/mm/vmm.h +++ b/kernel/src/mm/vmm.h @@ -21,23 +21,11 @@ typedef uint64_t *pagemap_t; -// These are defined in the linker file. -extern char reqs_start_ld; -extern char reqs_end_ld; - -extern char text_start_ld; -extern char text_end_ld; - -extern char rodata_start_ld; -extern char rodata_end_ld; - -extern char data_start_ld; -extern char data_end_ld; - void vmm_init(); pagemap_t vmm_alloc_pm(); void vmm_free_pm(pagemap_t pm); +void vmm_load_pm(pagemap_t pm); void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); From 16246cc1671d10cfafe6e92a013dee761aa140fb Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 19 May 2025 07:25:31 +0200 Subject: [PATCH 25/30] mm: Changes + vmm: Rename to "paging" + vma: Start implementation --- README.md | 7 +++- kernel/src/arch/cpu.h | 2 +- kernel/src/arch/x86_64/cpu.c | 2 +- kernel/src/main.c | 10 ++--- kernel/src/mm/{vmm.c => paging.c} | 64 +++++++++++++++---------------- kernel/src/mm/{vmm.h => paging.h} | 18 ++++----- kernel/src/mm/vma.c | 45 ++++++++++++++++++++++ kernel/src/mm/vma.h | 28 ++++++++++++++ 8 files changed, 125 insertions(+), 51 deletions(-) rename kernel/src/mm/{vmm.c => paging.c} (67%) rename kernel/src/mm/{vmm.h => paging.h} (55%) create mode 100644 kernel/src/mm/vma.c create mode 100644 kernel/src/mm/vma.h diff --git a/README.md b/README.md index 80a7dd1..a21ce3d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ # Soaplin (rewrite) This is a carefully rewritten version of Soaplin, that should be held with super glue instead of -0.99$ duct tape bought on TEMU. \ No newline at end of file +0.99$ duct tape bought on TEMU. + +## Features +* Support for compiling the kernel on armv8, RISC-V, and LoongArch64 (even though the kernel doesn't do anything on these architectures) +* Free list PMM with lazy loading +* x86_64 paging \ No newline at end of file diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index 8c56fa6..87d4114 100644 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -7,7 +7,7 @@ #pragma once -#include "mm/vmm.h" +#include "mm/paging.h" // Stage 1 initialization: Core components (such as the GDT & IDT on x86_64...) void arch_init_stage1(); diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c index b54c8e1..1b4378a 100644 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -5,13 +5,13 @@ * cpu.c - x86_64 CPU control implementation. */ -#include "mm/vmm.h" #if defined (__x86_64__) #include #include #include #include +#include "mm/paging.h" void arch_init_stage1() { gdt_init(); diff --git a/kernel/src/main.c b/kernel/src/main.c index e6593da..6dfce8c 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -5,7 +5,6 @@ * main.c - Kernel entry point and initialization. */ -#include "mm/vmm.h" #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include "mm/paging.h" void kmain(void) { tty_init(); @@ -32,12 +32,8 @@ void kmain(void) { arch_init_stage1(); pmm_init(); - vmm_init(); - /*uint8_t* mem = pmm_alloc_page() + 0xFFFF800000000000; - memcpy(mem, "HelloWorld\0", 11); - trace("pmm: Read from allocated memory: %s\n", mem); - pmm_free_page(mem); - trace("pmm: Freed memory.\n");*/ + pg_init(); + // We're done, just hang... hcf(); diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/paging.c similarity index 67% rename from kernel/src/mm/vmm.c rename to kernel/src/mm/paging.c index 9233b09..8c7f181 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/paging.c @@ -14,13 +14,13 @@ #include #include #include -#include +#include #include -pagemap_t vmm_kernel_pm = NULL; -pagemap_t vmm_current_pm = NULL; +pagemap_t pg_kernel_pm = NULL; +pagemap_t pg_current_pm = NULL; -void vmm_init() { +void pg_init() { #if !defined(__x86_64__) fatal("vmm: not implemented\n"); hcf(); @@ -28,7 +28,7 @@ void vmm_init() { // Our objective here is to recreate the // kernel page map that Limine provide us - vmm_kernel_pm = vmm_alloc_pm(); + pg_kernel_pm = pg_alloc_pm(); uint64_t kvaddr = limine_get_kernel_vaddr(); uint64_t kpaddr = limine_get_kernel_paddr(); @@ -53,42 +53,42 @@ void vmm_init() { size_t length = ALIGN_UP(cur_phdr->p_memsz, PMM_PAGE_SIZE); for (uint64_t i = 0; i < length; i += PMM_PAGE_SIZE) { - vmm_map(vmm_kernel_pm, cur_phdr->p_vaddr + i, phys + i, flags); + pg_map(pg_kernel_pm, cur_phdr->p_vaddr + i, phys + i, flags); } trace("vmm: Mapped range: %p -> %p (length: %x)\n", phys, cur_phdr->p_vaddr, length); } for (uint64_t i = 0; i < 0x100000000; i += PMM_PAGE_SIZE) - vmm_map(vmm_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); + pg_map(pg_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); trace("vmm: Mapped range: %p -> %p (length: %x)\n", 0x0, 0xFFFF800000000000, 0x100000000); - vmm_load_pm(vmm_kernel_pm); + pg_load_pm(pg_kernel_pm); trace("vmm: Initialized.\n"); } -void vmm_load_pm(pagemap_t pm) { +void pg_load_pm(pagemap_t pm) { if (!pm) return; - vmm_current_pm = pm; + pg_current_pm = pm; cpu_load_pm((pagemap_t)physical((uint64_t)pm)); } -pagemap_t vmm_alloc_pm() { +pagemap_t pg_alloc_pm() { pagemap_t pm = (pagemap_t)higher_half((uint64_t)pmm_alloc_page()); memset((void*)pm, 0, PMM_PAGE_SIZE); - if (vmm_kernel_pm) + if (pg_kernel_pm) { for (int i = 256; i < 512; i++) - pm[i] = vmm_kernel_pm[i]; + pm[i] = pg_kernel_pm[i]; } return pm; } -void vmm_free_pm(pagemap_t pm) { - if (pm == vmm_kernel_pm) +void pg_free_pm(pagemap_t pm) { + if (pm == pg_kernel_pm) { warn("vmm: Who tried to free the kernel's pagemap?!\n"); return; @@ -96,7 +96,7 @@ void vmm_free_pm(pagemap_t pm) { pmm_free_page((void*)pm); } -static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, +static uint64_t *__pg_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags, bool alloc) { if (level[entry] & PTE_PRESENT) return (uint64_t *)higher_half(PTE_GET_ADDR(level[entry])); @@ -109,7 +109,7 @@ static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, return NULL; } -void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { +void pg_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { if (!pm) return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; @@ -117,14 +117,14 @@ void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, PTE_PRESENT | PTE_WRITE, true); - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, PTE_PRESENT | PTE_WRITE, true); - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, PTE_PRESENT | PTE_WRITE, true); pml1[pml1_entry] = paddr | flags; } -void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, +void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { if (!pm) return; @@ -133,14 +133,14 @@ void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, flags, true); - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags, true); - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags, true); + uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, flags, true); + uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, flags, true); + uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, flags, true); pml1[pml1_entry] = paddr | flags; } -void vmm_unmap(pagemap_t pm, uint64_t vaddr) { +void pg_unmap(pagemap_t pm, uint64_t vaddr) { if (!pm) return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; @@ -148,18 +148,18 @@ void vmm_unmap(pagemap_t pm, uint64_t vaddr) { uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, 0, false); + uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); if (!pml3) return; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); + uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); if (!pml2) return; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); + uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); if (!pml1) return; pml1[pml1_entry] = 0; cpu_invalidate_page(pm, vaddr); } -void vmm_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { +void pg_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { if (!pm) return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; @@ -167,11 +167,11 @@ void vmm_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __vmm_get_next_lvl(pm , pml4_entry, 0, false); + uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); if (!pml3) return; - uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false); + uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); if (!pml2) return; - uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false); + uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); if (!pml1) return; uint64_t paddr = pml1[pml1_entry] & PTE_ADDR_MASK; diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/paging.h similarity index 55% rename from kernel/src/mm/vmm.h rename to kernel/src/mm/paging.h index 6414cf4..2426208 100644 --- a/kernel/src/mm/vmm.h +++ b/kernel/src/mm/paging.h @@ -2,7 +2,7 @@ * The Soaplin Kernel * Copyright (C) 2025 The SILD Project * - * vmm.c - Virtual memory manager + * pg.c - Virtual memory manager */ #pragma once @@ -21,13 +21,13 @@ typedef uint64_t *pagemap_t; -void vmm_init(); -pagemap_t vmm_alloc_pm(); -void vmm_free_pm(pagemap_t pm); +void pg_init(); +pagemap_t pg_alloc_pm(); +void pg_free_pm(pagemap_t pm); -void vmm_load_pm(pagemap_t pm); -void vmm_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); -void vmm_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, +void pg_load_pm(pagemap_t pm); +void pg_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); +void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); -void vmm_unmap(pagemap_t pm, uint64_t vaddr); -void vmm_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags); \ No newline at end of file +void pg_unmap(pagemap_t pm, uint64_t vaddr); +void pg_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags); \ No newline at end of file diff --git a/kernel/src/mm/vma.c b/kernel/src/mm/vma.c new file mode 100644 index 0000000..af7638b --- /dev/null +++ b/kernel/src/mm/vma.c @@ -0,0 +1,45 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * vma.c - Virtual memory allocator + */ + +#include +#include + +#include +#include "mm/vma.h" +#include "mm/pmm.h" + +vma_ctx_t *vma_alloc_ctx(pagemap_t pm, uint64_t start) { + if (pm == NULL) + return NULL; + + vma_ctx_t *ctx = (vma_ctx_t *)higher_half((uint64_t)pmm_alloc_page()); + ctx->pm = pm; + + vma_region_t *root_reg = (vma_region_t *)higher_half((uint64_t)pmm_alloc_page()); + root_reg->start = start; + root_reg->length = 0; + root_reg->next = NULL; + + ctx->root = root_reg; + return ctx; +} + +void vma_free_ctx(vma_ctx_t *ctx) { + if (!ctx || + !ctx->pm || + !ctx->root) + return; + + vma_region_t *reg = ctx->root; + while (reg) { + vma_region_t *next = reg->next; + pmm_free_page((void*)physical((uint64_t)reg)); + reg = next; + } + + pmm_free_page((void*)physical((uint64_t)ctx)); +} \ No newline at end of file diff --git a/kernel/src/mm/vma.h b/kernel/src/mm/vma.h new file mode 100644 index 0000000..f3174f9 --- /dev/null +++ b/kernel/src/mm/vma.h @@ -0,0 +1,28 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * vma.h - Virtual memory allocator + */ + +#pragma once + +#include "mm/paging.h" + +typedef struct __vma_region { + uint64_t start; + uint64_t pflags; + + // Length is in pages, not in bytes. + uint64_t length; + + struct __vma_region *next; +} vma_region_t; + +typedef struct { + pagemap_t pm; + vma_region_t *root; +} vma_ctx_t; + +vma_ctx_t *vma_alloc_ctx(pagemap_t pm, uint64_t start); +void vma_free_ctx (vma_ctx_t *ctx); \ No newline at end of file From dcea7360d2be2f926db937297e379b12726c8468 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Mon, 19 May 2025 17:56:29 +0200 Subject: [PATCH 26/30] vma: Implement VMA. + acpi: Start implementation of table lookup + cpu: Remove useless argument to "cpu_invalidate_page" + cpu (x86_64): Removed "read_cr3" + arch/x86_64: Replace debug with trace for GDT & IDT initialization. --- README.md | 10 ++++- kernel/src/acpi/acpi.c | 43 +++++++++++++++++++++ kernel/src/acpi/acpi.h | 28 ++++++++++++++ kernel/src/arch/aarch64/cpu.c | 2 +- kernel/src/arch/cpu.h | 2 +- kernel/src/arch/la64/cpu.c | 2 +- kernel/src/arch/riscv/cpu.c | 2 +- kernel/src/arch/x86_64/cpu.c | 18 +-------- kernel/src/arch/x86_64/gdt.c | 2 +- kernel/src/arch/x86_64/idt.c | 4 +- kernel/src/boot/limine.c | 9 ++++- kernel/src/boot/limine.h | 3 +- kernel/src/main.c | 7 +++- kernel/src/mm/paging.c | 20 +++++++++- kernel/src/mm/paging.h | 10 ++++- kernel/src/mm/pmm.c | 2 +- kernel/src/mm/vma.c | 72 ++++++++++++++++++++++++++++++++++- kernel/src/mm/vma.h | 3 ++ 18 files changed, 205 insertions(+), 34 deletions(-) create mode 100644 kernel/src/acpi/acpi.c create mode 100644 kernel/src/acpi/acpi.h diff --git a/README.md b/README.md index a21ce3d..24de99e 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,12 @@ This is a carefully rewritten version of Soaplin, that should be held with super ## Features * Support for compiling the kernel on armv8, RISC-V, and LoongArch64 (even though the kernel doesn't do anything on these architectures) * Free list PMM with lazy loading -* x86_64 paging \ No newline at end of file +* x86_64 paging + +## To do +* ACPI & MADT +* IOAPIC / LAPIC +* SMP +* Multithreaded scheduler +* VFS +* Tar file system \ No newline at end of file diff --git a/kernel/src/acpi/acpi.c b/kernel/src/acpi/acpi.c new file mode 100644 index 0000000..81e1efb --- /dev/null +++ b/kernel/src/acpi/acpi.c @@ -0,0 +1,43 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * acpi.c - ACPI table lookup + */ + +#include + +#include +#include +#include +#include +#include + +static bool __acpi_use_xsdt; +static uint64_t __acpi_rsdt_addr; + +void acpi_init() { + acpi_rsdp_t *rsdp = (acpi_rsdp_t*)limine_get_rsdp(); + if (memcmp(rsdp->sign, "RSD PTR ", 8)) + { + fatal("acpi: ACPI RSDP is corrupt\n"); + hcf(); + } + + if (rsdp->rev >= 2) + { + trace("acpi: ACPI v2.0 or later detected: Using XSDT.\n"); + + acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; + __acpi_use_xsdt = 1; + __acpi_rsdt_addr = xsdp->xsdt_addr; + + goto initialized; + } + + __acpi_use_xsdt = 0; + __acpi_rsdt_addr = rsdp->rsdt_addr; // Do not use a pointer, to shut up the compiler. + +initialized: + trace("acpi: Initialized!\n"); +} \ No newline at end of file diff --git a/kernel/src/acpi/acpi.h b/kernel/src/acpi/acpi.h new file mode 100644 index 0000000..5a929da --- /dev/null +++ b/kernel/src/acpi/acpi.h @@ -0,0 +1,28 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * acpi.h - ACPI definitions + */ + +#pragma once + +#include + +typedef struct { + char sign[8]; + char chksum; + char oemid[6]; + char rev; + uint32_t rsdt_addr; +} acpi_rsdp_t; + +typedef struct { + acpi_rsdp_t base; + uint32_t len; + uint64_t xsdt_addr; + char chksumex; +} acpi_xsdp_t; + +void acpi_init(); +void acpi_init(); \ No newline at end of file diff --git a/kernel/src/arch/aarch64/cpu.c b/kernel/src/arch/aarch64/cpu.c index f2d3feb..0e0f378 100644 --- a/kernel/src/arch/aarch64/cpu.c +++ b/kernel/src/arch/aarch64/cpu.c @@ -16,7 +16,7 @@ void cpu_load_pm(pagemap_t pm) { } -void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { +void cpu_invalidate_page(uint64_t vaddr) { } diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index 87d4114..97b5307 100644 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -16,7 +16,7 @@ void arch_init_stage1(); void cpu_load_pm(pagemap_t pm); // Invalidate a page table entry -void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr); +void cpu_invalidate_page(uint64_t vaddr); // Disable interrupts and halt the system. void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/la64/cpu.c b/kernel/src/arch/la64/cpu.c index 5c41bca..8b2fd40 100644 --- a/kernel/src/arch/la64/cpu.c +++ b/kernel/src/arch/la64/cpu.c @@ -16,7 +16,7 @@ void cpu_load_pm(pagemap_t pm) { } -void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { +void cpu_invalidate_page(uint64_t vaddr) { } diff --git a/kernel/src/arch/riscv/cpu.c b/kernel/src/arch/riscv/cpu.c index 3dcdf96..e671ac9 100644 --- a/kernel/src/arch/riscv/cpu.c +++ b/kernel/src/arch/riscv/cpu.c @@ -16,7 +16,7 @@ void cpu_load_pm(pagemap_t pm) { } -void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { +void cpu_invalidate_page(uint64_t vaddr) { } diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c index 1b4378a..858beca 100644 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -25,23 +25,7 @@ void cpu_load_pm(pagemap_t pm) { __asm__ volatile("mov %0, %%cr3" : : "r"(physical((uint64_t)pm)) : "memory"); } -static uint64_t read_cr3(void) -{ - unsigned long val; - asm volatile ( "mov %%cr3, %0" : "=r"(val) ); - return val; -} - -void cpu_invalidate_page(pagemap_t pm, uint64_t vaddr) { - uint64_t cr3 = read_cr3(); - if (physical((uint64_t)pm) != cr3) - { - // load the provided PM in cr3, invalidate the page and return into the previous cr3. - cpu_load_pm(pm); - asm volatile ( "invlpg (%0)" : : "b"(vaddr) : "memory" ); - cpu_load_pm((pagemap_t)cr3); - return; - } +void cpu_invalidate_page(uint64_t vaddr) { asm volatile ( "invlpg (%0)" : : "b"(vaddr) : "memory" ); } diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c index f916dfe..97b04a4 100644 --- a/kernel/src/arch/x86_64/gdt.c +++ b/kernel/src/arch/x86_64/gdt.c @@ -54,7 +54,7 @@ void gdt_init() { gdt_reload_segments(); - debug("arch: GDT & TSS initialized.\n"); + trace("arch: GDT & TSS initialized.\n"); } #endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index 664b958..520c0b3 100644 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -70,7 +70,7 @@ void idt_interrupt_handler(registers_t *regs) { fatal("r11: %p, r12: %p, r13: %p\n", regs->r11, regs->r12, regs->r13); fatal("r14: %p, r15: %p\n", regs->r14, regs->r15); fatal("rip: %p, cs: %p, ss: %p\n", regs->rip, regs->cs, regs->ss); - fatal("rflags: %p, err: %p, rsp: %p\n", regs->rflags, regs->err_code, regs->rsp); + fatal("rflags: %p, err: %d, rsp: %p\n", regs->rflags, regs->err_code, regs->rsp); __panic_display_bt(regs); hcf(); } @@ -103,7 +103,7 @@ void idt_init() { __asm__ volatile ("lidt %0" : : "m"(idtr)); __asm__ volatile ("sti"); - debug("arch: IDT loaded successfully\n"); + trace("arch: IDT loaded successfully\n"); } #endif \ No newline at end of file diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index a41457b..d936ffd 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -63,6 +63,12 @@ static volatile struct limine_paging_mode_request pgmode_req = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_rsdp_request rsdp_req = { + .id = LIMINE_RSDP_REQUEST, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -109,4 +115,5 @@ limine_bootinfo_t *limine_get_bootinfo() { uint64_t limine_get_hhdm_offset() { return hhdm_req.response->offset; } uint64_t limine_get_kernel_vaddr() { return kaddr_req.response->virtual_base; } uint64_t limine_get_kernel_paddr() { return kaddr_req.response->physical_base; } -uint64_t limine_get_kernel_ehdr_addr() { return (uint64_t)execfile_req.response->executable_file->address; } \ No newline at end of file +uint64_t limine_get_kernel_ehdr_addr() { return (uint64_t)execfile_req.response->executable_file->address; } +uint64_t limine_get_rsdp() { return rsdp_req.response->address + limine_get_hhdm_offset(); } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index d65ed79..f264a30 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -34,4 +34,5 @@ struct limine_memmap_response *limine_get_memmap(); uint64_t limine_get_hhdm_offset(); uint64_t limine_get_kernel_vaddr(); uint64_t limine_get_kernel_paddr(); -uint64_t limine_get_kernel_ehdr_addr(); \ No newline at end of file +uint64_t limine_get_kernel_ehdr_addr(); +uint64_t limine_get_rsdp(); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index 6dfce8c..daa02d2 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include "mm/paging.h" +#include "mm/vma.h" void kmain(void) { tty_init(); @@ -26,7 +28,7 @@ void kmain(void) { log_register_output(sklogoutput_tty); limine_bootinfo_t *bi = limine_get_bootinfo(); - trace("%s %s-%s (booted using %s %s, with firmware type %d)\n", KERNEL_NAME, KERNEL_VER, + info("%s %s-%s (booted using %s %s, with firmware type %d)\n", KERNEL_NAME, KERNEL_VER, bi->arch, bi->bl_name, bi->bl_ver, bi->fw_type); arch_init_stage1(); @@ -34,7 +36,8 @@ void kmain(void) { pmm_init(); pg_init(); + acpi_init(); - // We're done, just hang... + // We're done, just hang... for now. hcf(); } diff --git a/kernel/src/mm/paging.c b/kernel/src/mm/paging.c index 8c7f181..6ef555d 100644 --- a/kernel/src/mm/paging.c +++ b/kernel/src/mm/paging.c @@ -109,6 +109,24 @@ static uint64_t *__pg_get_next_lvl(uint64_t *level, uint64_t entry, return NULL; } +uint64_t pg_physical(pagemap_t pm, uint64_t vaddr) { + if (!pm) return 0; + + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); + if (!pml3) return 0; + uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); + if (!pml2) return 0; + uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); + if (!pml1) return 0; + + return pml1[pml1_entry] & PTE_ADDR_MASK; +} + void pg_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { if (!pm) return; @@ -156,7 +174,7 @@ void pg_unmap(pagemap_t pm, uint64_t vaddr) { if (!pml1) return; pml1[pml1_entry] = 0; - cpu_invalidate_page(pm, vaddr); + cpu_invalidate_page(vaddr); } void pg_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { diff --git a/kernel/src/mm/paging.h b/kernel/src/mm/paging.h index 2426208..c41eec2 100644 --- a/kernel/src/mm/paging.h +++ b/kernel/src/mm/paging.h @@ -10,7 +10,7 @@ // Page flags #include -#define PTE_ADDR_MASK 0x000ffffffffff000 +#define PTE_ADDR_MASK 0x000ffffffffff000ull #define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) #define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) @@ -21,11 +21,17 @@ typedef uint64_t *pagemap_t; +extern pagemap_t pg_kernel_pm; +extern pagemap_t pg_current_pm; + + void pg_init(); + pagemap_t pg_alloc_pm(); void pg_free_pm(pagemap_t pm); - void pg_load_pm(pagemap_t pm); + +uint64_t pg_physical(pagemap_t pm, uint64_t vaddr); void pg_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c index 1959403..7cac5c4 100644 --- a/kernel/src/mm/pmm.c +++ b/kernel/src/mm/pmm.c @@ -81,7 +81,7 @@ void pmm_init() { if (entry->type == LIMINE_MEMMAP_USABLE || entry->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE) { - trace("pmm: found a usable memory block: %p-%p\n", entry->base, entry->base + entry->length); + trace("pmm: Found an usable memory block: %p-%p\n", entry->base, entry->base + entry->length); uint64_t newlen = ALIGN_DOWN(entry->length, PMM_PAGE_SIZE); diff --git a/kernel/src/mm/vma.c b/kernel/src/mm/vma.c index af7638b..d22caf3 100644 --- a/kernel/src/mm/vma.c +++ b/kernel/src/mm/vma.c @@ -8,6 +8,8 @@ #include #include +#include "lib/log.h" +#include "mm/memop.h" #include #include "mm/vma.h" #include "mm/pmm.h" @@ -28,6 +30,74 @@ vma_ctx_t *vma_alloc_ctx(pagemap_t pm, uint64_t start) { return ctx; } +void *vma_alloc(vma_ctx_t *ctx, size_t length, uint64_t flags) { + if (!ctx || !ctx->pm || !ctx->root) + return NULL; + + vma_region_t *current = ctx->root; + while (current) { + if (current->next == NULL || current->start + (current->length * PMM_PAGE_SIZE) < current->next->start) + { + vma_region_t *reg = (vma_region_t*)higher_half((uint64_t)pmm_alloc_page()); + memset((void*)reg, 0, sizeof(vma_region_t)); + reg->start = current->start + (current->length * PMM_PAGE_SIZE); + reg->length = length; + reg->pflags = flags; + reg->next = current->next; + current->next = reg; + + // Now, allocate the memory + for (uint64_t i = 0; i < length; i++) { + uint64_t physical = (uint64_t)pmm_alloc_page(); + pg_map(ctx->pm, reg->start + (i * PMM_PAGE_SIZE), physical, flags); + } + + return (void*)reg->start; + } + + current = current->next; + } + return NULL; +} + +static void __vma_free_region(vma_ctx_t *ctx, vma_region_t *target) { + for (uint64_t i = 0; i < target->length; i++) { + uint64_t vaddr = target->start + (i * PMM_PAGE_SIZE); + uint64_t paddr = pg_physical(ctx->pm, vaddr); + pg_unmap(ctx->pm, vaddr); + pmm_free_page((void*)paddr); + } + + pmm_free_page((void*)physical((uint64_t)target)); +} + +void vma_free(vma_ctx_t *ctx, void *addr) { + if (!ctx || !ctx->pm || !ctx->root || !addr) + return; + + vma_region_t *last = NULL; + vma_region_t *target = ctx->root; + + while (target) { + if (target->start == (uint64_t)addr) + break; + + last = target; + target = target->next; + } + + if (!target) + return; + + if (last) + last->next = target->next; + else + ctx->root = target->next; + + // Unallocate the memory + __vma_free_region(ctx, target); +} + void vma_free_ctx(vma_ctx_t *ctx) { if (!ctx || !ctx->pm || @@ -37,7 +107,7 @@ void vma_free_ctx(vma_ctx_t *ctx) { vma_region_t *reg = ctx->root; while (reg) { vma_region_t *next = reg->next; - pmm_free_page((void*)physical((uint64_t)reg)); + __vma_free_region(ctx, reg); reg = next; } diff --git a/kernel/src/mm/vma.h b/kernel/src/mm/vma.h index f3174f9..3b6e123 100644 --- a/kernel/src/mm/vma.h +++ b/kernel/src/mm/vma.h @@ -8,6 +8,7 @@ #pragma once #include "mm/paging.h" +#include typedef struct __vma_region { uint64_t start; @@ -25,4 +26,6 @@ typedef struct { } vma_ctx_t; vma_ctx_t *vma_alloc_ctx(pagemap_t pm, uint64_t start); +void *vma_alloc(vma_ctx_t *ctx, size_t length, uint64_t flags); +void vma_free(vma_ctx_t *ctx, void *addr); void vma_free_ctx (vma_ctx_t *ctx); \ No newline at end of file From b2cf9b471067ad2d6e93b47c50634851a5e718b8 Mon Sep 17 00:00:00 2001 From: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Tue, 20 May 2025 08:29:23 +0200 Subject: [PATCH 27/30] kernel: Implemented various features + lapic: Start implementation + ioapic: Start implementation + apic: Now properly working + madt: Start implementation + pit: Start implementation + smp: Start implementation (only grabs the bootstrap processor's LAPIC ID) --- kernel/src/acpi/acpi.c | 35 ++++++++- kernel/src/acpi/acpi.h | 30 +++++++- kernel/src/acpi/madt.c | 42 +++++++++++ kernel/src/acpi/madt.h | 61 ++++++++++++++++ kernel/src/arch/cpu.h | 7 ++ kernel/src/arch/x86_64/cpu.h | 0 kernel/src/arch/x86_64/idt.asm | 15 ++-- kernel/src/arch/x86_64/idt.c | 129 ++++++++++++++++----------------- kernel/src/arch/x86_64/idt.h | 11 +++ kernel/src/arch/x86_64/io.h | 23 ++++++ kernel/src/arch/x86_64/pit.c | 30 ++++++++ kernel/src/arch/x86_64/smp.c | 17 +++++ kernel/src/arch/x86_64/smp.h | 12 +++ kernel/src/boot/limine.c | 9 ++- kernel/src/boot/limine.h | 3 +- kernel/src/dev/ioapic.c | 87 ++++++++++++++++++++++ kernel/src/dev/ioapic.h | 17 +++++ kernel/src/dev/lapic.c | 33 +++++++++ kernel/src/dev/lapic.h | 26 +++++++ kernel/src/main.c | 12 ++- kernel/src/mm/pmm.md | 0 kernel/src/mm/vmm.c | 0 22 files changed, 520 insertions(+), 79 deletions(-) create mode 100644 kernel/src/acpi/madt.c create mode 100644 kernel/src/acpi/madt.h create mode 100644 kernel/src/arch/x86_64/cpu.h create mode 100644 kernel/src/arch/x86_64/io.h create mode 100644 kernel/src/arch/x86_64/pit.c create mode 100644 kernel/src/arch/x86_64/smp.c create mode 100644 kernel/src/arch/x86_64/smp.h create mode 100644 kernel/src/dev/ioapic.c create mode 100644 kernel/src/dev/ioapic.h create mode 100644 kernel/src/dev/lapic.c create mode 100644 kernel/src/dev/lapic.h create mode 100644 kernel/src/mm/pmm.md create mode 100644 kernel/src/mm/vmm.c diff --git a/kernel/src/acpi/acpi.c b/kernel/src/acpi/acpi.c index 81e1efb..e063caa 100644 --- a/kernel/src/acpi/acpi.c +++ b/kernel/src/acpi/acpi.c @@ -12,10 +12,41 @@ #include #include #include +#include +#include static bool __acpi_use_xsdt; static uint64_t __acpi_rsdt_addr; +void *acpi_find_table(char *sign) { + if (__acpi_use_xsdt) { + acpi_xsdt_t *xsdt = (acpi_xsdt_t*)__acpi_rsdt_addr; + uint32_t entries = (xsdt->hdr.len - sizeof(xsdt->hdr)) / 8; + + for (uint32_t i = 0; i < entries; i++) + { + acpi_sdt_hdr_t *h = (acpi_sdt_hdr_t *)higher_half(*((uint64_t*)xsdt->entries + i)); + if (!memcmp(h->sign, sign, 4)) + return (void *) h; + } + + return NULL; + } + + acpi_rsdt_t *rsdt = (acpi_rsdt_t*)__acpi_rsdt_addr; + int entries = (rsdt->hdr.len - sizeof(rsdt->hdr)) / 4; + uint32_t *entries_hhalf = (uint32_t *)higher_half((uint64_t)rsdt->entries); + + for (int i = 0; i < entries; i++) + { + acpi_sdt_hdr_t *h = (acpi_sdt_hdr_t *)(entries_hhalf[i] + (i * sizeof(uint32_t))); + if (!memcmp(h->sign, sign, 4)) + return (void *) h; + } + + return NULL; +} + void acpi_init() { acpi_rsdp_t *rsdp = (acpi_rsdp_t*)limine_get_rsdp(); if (memcmp(rsdp->sign, "RSD PTR ", 8)) @@ -30,13 +61,13 @@ void acpi_init() { acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; __acpi_use_xsdt = 1; - __acpi_rsdt_addr = xsdp->xsdt_addr; + __acpi_rsdt_addr = higher_half(xsdp->xsdt_addr); goto initialized; } __acpi_use_xsdt = 0; - __acpi_rsdt_addr = rsdp->rsdt_addr; // Do not use a pointer, to shut up the compiler. + __acpi_rsdt_addr = higher_half(rsdp->rsdt_addr); // Do not use a pointer, to shut up the compiler. initialized: trace("acpi: Initialized!\n"); diff --git a/kernel/src/acpi/acpi.h b/kernel/src/acpi/acpi.h index 5a929da..75ee2c2 100644 --- a/kernel/src/acpi/acpi.h +++ b/kernel/src/acpi/acpi.h @@ -15,14 +15,36 @@ typedef struct { char oemid[6]; char rev; uint32_t rsdt_addr; -} acpi_rsdp_t; +} __attribute__((packed)) acpi_rsdp_t; typedef struct { acpi_rsdp_t base; uint32_t len; uint64_t xsdt_addr; char chksumex; -} acpi_xsdp_t; +} __attribute__((packed)) acpi_xsdp_t; -void acpi_init(); -void acpi_init(); \ No newline at end of file +typedef struct { + char sign[4]; + uint32_t len; + uint8_t rev; + uint8_t chksum; + char oemid[6]; + char oemtabid[8]; + uint32_t oemrev; + uint32_t creaid; + uint32_t crearev; +} __attribute__((packed)) acpi_sdt_hdr_t; + +typedef struct { + acpi_sdt_hdr_t hdr; + char entries[]; +} acpi_rsdt_t; + +typedef struct { + acpi_sdt_hdr_t hdr; + char entries[]; +} acpi_xsdt_t; + +void *acpi_find_table(char *sign); +void acpi_init(); \ No newline at end of file diff --git a/kernel/src/acpi/madt.c b/kernel/src/acpi/madt.c new file mode 100644 index 0000000..eb03144 --- /dev/null +++ b/kernel/src/acpi/madt.c @@ -0,0 +1,42 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * madt.c - MADT lookup + */ + +#include "acpi/acpi.h" +#include "lib/log.h" +#include + +acpi_madt_ioapic_t* madt_ioapic_list[128]; +acpi_madt_iso_t* madt_iso_list[128]; + +uint32_t madt_ioapic_len = 0; +uint32_t madt_iso_len = 0; + +uint64_t *madt_lapic_addr = (uint64_t *)0; + +void madt_init() { + void *addr = acpi_find_table("APIC"); + acpi_madt_t *madt = (acpi_madt_t *)addr; + uint64_t offset = 0; + + while (1) { + if (offset > madt->hdr.len - sizeof(acpi_madt_t)) + break; + + madt_entry *entry = (madt_entry *)(madt->table + offset); + + if (entry->type == 1) + madt_ioapic_list[madt_ioapic_len++] = (acpi_madt_ioapic_t *)entry; + else if (entry->type == 2) + madt_iso_list[madt_iso_len++] = (acpi_madt_iso_t *)entry; + else if (entry->type == 5) + madt_lapic_addr = (uint64_t *)((acpi_madt_lapic_addr_override_t *)entry)->plapic; + + offset += entry->len; + } + + trace("madt: Initialized\n"); +} diff --git a/kernel/src/acpi/madt.h b/kernel/src/acpi/madt.h new file mode 100644 index 0000000..78bf28b --- /dev/null +++ b/kernel/src/acpi/madt.h @@ -0,0 +1,61 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * madt.h - MADT lookup + */ +#pragma once + +#include +#include + +typedef struct { + acpi_sdt_hdr_t hdr; + uint32_t lapic_addr; + uint32_t flags; + char table[]; +} acpi_madt_t; + +typedef struct { + uint8_t type; + uint8_t len; +} madt_entry; + +typedef struct { + madt_entry entry; + uint8_t cpu_id; + uint8_t lapic_id; + uint32_t flags; +} acpi_madt_lapic_t; + +typedef struct { + madt_entry entry; + uint8_t ioapic_id; + uint8_t reserved; + uint32_t ioapic_addr; + uint32_t gsi_base; +} acpi_madt_ioapic_t; + +typedef struct { + madt_entry entry; + uint8_t bus; + uint8_t source; + uint32_t gsi; + uint16_t flags; +} acpi_madt_iso_t; // iso = interrupt source override + +typedef struct { + madt_entry entry; + uint16_t reserved; + uint64_t plapic; +} acpi_madt_lapic_addr_override_t; + +extern acpi_madt_ioapic_t* madt_ioapic_list[128]; +extern acpi_madt_iso_t* madt_iso_list[128]; + +extern uint32_t madt_ioapic_len; +extern uint32_t madt_iso_len; + +extern uint64_t *lapic_addr; + +void madt_init(); \ No newline at end of file diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index 97b5307..76861ff 100644 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -18,5 +18,12 @@ void cpu_load_pm(pagemap_t pm); // Invalidate a page table entry void cpu_invalidate_page(uint64_t vaddr); +// Initialize SMP. The implementations are in arch since the Limine +// structure changes depending on the architecture. +void cpu_init_smp(); + +// Initialize the CPU's timer +void cpu_init_timer(); + // Disable interrupts and halt the system. void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu.h b/kernel/src/arch/x86_64/cpu.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/arch/x86_64/idt.asm b/kernel/src/arch/x86_64/idt.asm index fec724d..48b69b9 100644 --- a/kernel/src/arch/x86_64/idt.asm +++ b/kernel/src/arch/x86_64/idt.asm @@ -37,11 +37,9 @@ %macro isr_err_stub 1 isr_stub_%+%1: - push %1 ; push intno into the stack - + push %1 pushall - - mov rdi, rsp ; put the stack as the first arg. + mov rdi, rsp call idt_interrupt_handler @@ -102,10 +100,17 @@ isr_no_err_stub 29 isr_err_stub 30 isr_no_err_stub 31 +%assign i 32 +%rep 224 + isr_no_err_stub i +%assign i i+1 +%endrep + + global isr_stub_table isr_stub_table: %assign i 0 -%rep 32 +%rep 256 dq isr_stub_%+i %assign i i+1 %endrep \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index 520c0b3..33985c6 100644 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -4,65 +4,38 @@ * * idt.c - x86_64 Interrupt Descriptor Table implementation. */ + +#include "dev/lapic.h" #if defined(__x86_64__) -#include "arch/cpu.h" -#include "lib/log.h" +#include + +#include #include +#include +#include +#include __attribute__((aligned(0x10))) static idt_entry_t idt[256]; static idtr_t idtr; -static void __panic_display_bt(registers_t *regs) { - if (regs->cs == 0x43 || regs->cs == 0x3B) { - fatal("The backtrace can't be dumped from a userspace process.\n"); - return; // Don't try to backtrace userspace - } +static uint8_t __idt_vectors[256]; +static interrupt_handler __idt_external_handlers[256]; - fatal("-- BACKTRACE --\n"); +void idt_register_handler(uint8_t vector, void *isr) { + if (vector <= 16) + ioapic_redir_irq(bootstrap_lapic_id, vector + 32, vector, false); - // First print the current instruction pointer from the interrupt frame - if (regs->rip) { - fatal("* %p (current)\n", regs->rip); - } - - uint64_t *frame = (uint64_t*)regs->rbp; - if (!frame || (uint64_t)frame < 0xffffffff80000000) { - fatal("No further stack frames available\n"); - return; - } - - // Frame format in x86_64: - // [rbp] -> previous rbp - // [rbp+8] -> return address - int depth = 0; - while (frame && depth < 16) { // Limit depth to avoid infinite loops - // Validate both frame and return address pointers - uint64_t *ret_addr_ptr = frame + 1; - if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) { - break; - } - - uint64_t ret_addr = *ret_addr_ptr; - if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) { - break; - } - - fatal("* %p\n", ret_addr); - - uint64_t next_rbp = *frame; - if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) { - break; - } - - frame = (uint64_t*)next_rbp; - depth++; - } - fatal("\n"); + __idt_external_handlers[vector] = isr; + __idt_vectors[vector <= 16 ? vector + 32 : vector] = vector <= 16 ? VT_HWI : VT_SWI; } void idt_interrupt_handler(registers_t *regs) { + if (__idt_vectors[regs->int_no] == VT_SPURIOUS || __idt_vectors[regs->int_no] == VT_NONE) + return; + + if (regs->int_no < 32) { fatal("Kernel panic: CPU exception %d\n", regs->int_no); fatal("rax: %p, rbx: %p, rbp: %p, rdx\n", regs->rax, regs->rbx, regs->rbp, regs->rdx); fatal("rdi: %p, rsi: %p, rcx: %p\n", regs->rdi, regs->rsi, regs->rcx); @@ -71,39 +44,65 @@ void idt_interrupt_handler(registers_t *regs) { fatal("r14: %p, r15: %p\n", regs->r14, regs->r15); fatal("rip: %p, cs: %p, ss: %p\n", regs->rip, regs->cs, regs->ss); fatal("rflags: %p, err: %d, rsp: %p\n", regs->rflags, regs->err_code, regs->rsp); - __panic_display_bt(regs); hcf(); + } + + int vec = regs->int_no; + if (vec >= 32 && vec < 48) + vec -= 32; + + if (__idt_vectors[regs->int_no] == VT_HWI) { + interrupt_handler i = __idt_external_handlers[vec]; + i(regs); + } else if (__idt_vectors[regs->int_no] == VT_SWI) { + interrupt_handler i = __idt_external_handlers[regs->int_no]; + i(regs); + } + + lapic_eoi(); } void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { - idt_entry_t* descriptor = &idt[vector]; + idt_entry_t* descriptor = &idt[vector]; - descriptor->isr_low = (uint64_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x08; - descriptor->ist = 0; - descriptor->attributes = flags; - descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; - descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; - descriptor->reserved = 0; + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x08; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; } -static bool vectors[32]; extern void* isr_stub_table[]; void idt_init() { - idtr.base = (uintptr_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 32 - 1; + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - for (uint8_t vector = 0; vector < 32; vector++) { - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - vectors[vector] = true; - } + for (uint8_t vector = 0; vector < 32; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + __idt_vectors[vector] = VT_EXCEPTION; + } + trace("idt: Exception vectors has been set!\n"); - __asm__ volatile ("lidt %0" : : "m"(idtr)); - __asm__ volatile ("sti"); + for (uint8_t vector = 32; vector < 48; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + __idt_vectors[vector] = VT_HWI; + } + trace("idt: Hardware interrupt vectors has been set!\n"); + for (uint16_t vector = 48; vector < 256; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + __idt_vectors[vector] = VT_NONE; + } + __idt_vectors[IDT_SPURIOUS_INT] = VT_SPURIOUS; + trace("idt: Spurious interrupt vector has been set!\n"); - trace("arch: IDT loaded successfully\n"); + __asm__ volatile ("lidt %0" : : "m"(idtr)); + __asm__ volatile ("sti"); + + trace("arch: IDT loaded successfully\n"); } #endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h index e66648e..7c8707c 100644 --- a/kernel/src/arch/x86_64/idt.h +++ b/kernel/src/arch/x86_64/idt.h @@ -8,6 +8,14 @@ #include +#define VT_NONE 0 +#define VT_EXCEPTION 1 +#define VT_HWI 2 +#define VT_SWI 3 +#define VT_SPURIOUS 4 + +#define IDT_SPURIOUS_INT 0xFF + typedef struct { uint64_t r15; uint64_t r14; @@ -33,6 +41,8 @@ typedef struct { uint64_t ss; } __attribute__((packed)) registers_t; +typedef void(*interrupt_handler)(registers_t*); + typedef struct { uint16_t isr_low; uint16_t kernel_cs; @@ -48,4 +58,5 @@ typedef struct { uint64_t base; } __attribute__((packed)) idtr_t; +void idt_register_handler(uint8_t vector, void *isr); void idt_init(void); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/io.h b/kernel/src/arch/x86_64/io.h new file mode 100644 index 0000000..4892c8e --- /dev/null +++ b/kernel/src/arch/x86_64/io.h @@ -0,0 +1,23 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * io.h - x86_64 I/O functions + */ + +#pragma once + +#include + +inline void outb(uint16_t port, uint8_t val) { + __asm__ volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory"); +} + +inline uint8_t inb(uint16_t port) { + uint8_t ret; + __asm__ volatile ( "inb %w1, %b0" + : "=a"(ret) + : "Nd"(port) + : "memory"); + return ret; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c new file mode 100644 index 0000000..d61cd7b --- /dev/null +++ b/kernel/src/arch/x86_64/pit.c @@ -0,0 +1,30 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * pit.c - x86_64 Programmable Interval Timer implementation. + */ +#if defined(__x86_64__) + +#include +#include +#include + +void pit_handler(registers_t *reg) { + trace("pit: Interrupt!\n"); +} + +void cpu_init_timer() { + outb(0x43, 0x36); + + uint16_t div = (uint16_t)(1193180 / 1000); + + // Since the PIT uses 8-bit IO operations, + // we need to split div in 2. + outb(0x40, (uint8_t)div); + outb(0x40, (uint8_t)(div >> 8)); + + idt_register_handler(0, pit_handler); +} + +#endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c new file mode 100644 index 0000000..3253f7f --- /dev/null +++ b/kernel/src/arch/x86_64/smp.c @@ -0,0 +1,17 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * smp.c - x86_64 Symetric Multiprocessing implementation + */ + +#include +#include +#include + +uint32_t bootstrap_lapic_id; + +void cpu_init_smp() { + struct limine_mp_response *smp = limine_get_smp(); + bootstrap_lapic_id = smp->bsp_lapic_id; +} diff --git a/kernel/src/arch/x86_64/smp.h b/kernel/src/arch/x86_64/smp.h new file mode 100644 index 0000000..06c3422 --- /dev/null +++ b/kernel/src/arch/x86_64/smp.h @@ -0,0 +1,12 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * smp.c - x86_64 Symetric Multiprocessing definitions + */ + + #pragma once + +#include + +extern uint32_t bootstrap_lapic_id; \ No newline at end of file diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c index d936ffd..151c9d8 100644 --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -69,6 +69,12 @@ static volatile struct limine_rsdp_request rsdp_req = { .revision = 0 }; +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_mp_request smp_req = { + .id = LIMINE_MP_REQUEST, + .revision = 0 +}; + __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; @@ -116,4 +122,5 @@ uint64_t limine_get_hhdm_offset() { return hhdm_req.response->offset; } uint64_t limine_get_kernel_vaddr() { return kaddr_req.response->virtual_base; } uint64_t limine_get_kernel_paddr() { return kaddr_req.response->physical_base; } uint64_t limine_get_kernel_ehdr_addr() { return (uint64_t)execfile_req.response->executable_file->address; } -uint64_t limine_get_rsdp() { return rsdp_req.response->address + limine_get_hhdm_offset(); } \ No newline at end of file +uint64_t limine_get_rsdp() { return rsdp_req.response->address + limine_get_hhdm_offset(); } +struct limine_mp_response *limine_get_smp() { return smp_req.response; } \ No newline at end of file diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h index f264a30..4c5522d 100644 --- a/kernel/src/boot/limine.h +++ b/kernel/src/boot/limine.h @@ -35,4 +35,5 @@ uint64_t limine_get_hhdm_offset(); uint64_t limine_get_kernel_vaddr(); uint64_t limine_get_kernel_paddr(); uint64_t limine_get_kernel_ehdr_addr(); -uint64_t limine_get_rsdp(); \ No newline at end of file +uint64_t limine_get_rsdp(); +struct limine_mp_response *limine_get_smp(); \ No newline at end of file diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c new file mode 100644 index 0000000..831c455 --- /dev/null +++ b/kernel/src/dev/ioapic.c @@ -0,0 +1,87 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * ioapic.c - I/O APIC implementation. + */ + +#include +#include + +#include +#include +#include +#include + +static void __ioapic_write(acpi_madt_ioapic_t *ioapic, uint32_t reg, uint32_t val) { + *(volatile uint32_t *)(higher_half(ioapic->ioapic_addr)) = reg; + *(volatile uint32_t *)(higher_half(ioapic->ioapic_addr+0x10)) = val; +} +static uint32_t __ioapic_read(acpi_madt_ioapic_t *ioapic, uint32_t reg) { + *(volatile uint32_t *)(higher_half(ioapic->ioapic_addr)) = reg; + return *(volatile uint32_t *)(higher_half(ioapic->ioapic_addr+0x10)); +} + +void ioapic_init() { + acpi_madt_ioapic_t *ioapic = madt_ioapic_list[0]; + + uint32_t value = __ioapic_read(ioapic, IOAPIC_VERSION); + uint32_t count = (value >> 16) & 0xFF; + + for (uint8_t i = 0; i <= count; ++i) { + __ioapic_write(ioapic, + IOAPIC_REDTBL+2 * i, + 0x00010000 | (32 + i)); + __ioapic_write(ioapic, + IOAPIC_REDTBL + 2 * i + 1, 0); + } + + trace("ioapic: Initialized\n"); +} + +uint32_t ioapic_gsi_count(acpi_madt_ioapic_t* ioapic) { + return (__ioapic_read(ioapic, 1) & 0xff0000) >> 16; +} + +acpi_madt_ioapic_t *ioapic_get_gsi(uint32_t gsi) { + for (uint32_t i = 0; i < madt_ioapic_len; i++) { + acpi_madt_ioapic_t* ioapic = madt_ioapic_list[i]; + if (ioapic->gsi_base <= gsi && ioapic->gsi_base + ioapic_gsi_count(ioapic) > gsi) + return ioapic; + } + return NULL; +} + +void ioapic_redirect_gsi(uint32_t lapic_id, uint8_t vec, uint32_t gsi, uint16_t flags, bool mask) { + acpi_madt_ioapic_t* ioapic = ioapic_get_gsi(gsi); + + uint64_t redirect = vec; + + if ((flags & (1 << 1)) != 0) { + redirect |= (1 << 13); + } + + if ((flags & (1 << 3)) != 0) { + redirect |= (1 << 15); + } + + if (mask) redirect |= (1 << 16); + else redirect &= ~(1 << 16); + + redirect |= (uint64_t)lapic_id << 56; + + uint32_t redtbl = (gsi - ioapic->gsi_base) * 2 + 16; + __ioapic_write(ioapic, redtbl, (uint32_t)redirect); + __ioapic_write(ioapic, redtbl + 1, (uint32_t)(redirect >> 32)); +} + +void ioapic_redir_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask) { + uint8_t idx = 0; + acpi_madt_iso_t* iso = NULL; + + for (idx = 0; idx < madt_iso_len; ++idx) { + iso = madt_iso_list[idx]; + if (iso->source == irq) { ioapic_redirect_gsi(lapic_id, vec, iso->gsi, iso->flags, mask); return; } + } + ioapic_redirect_gsi(lapic_id, vec, irq, 0, mask); +} \ No newline at end of file diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h new file mode 100644 index 0000000..df39a1f --- /dev/null +++ b/kernel/src/dev/ioapic.h @@ -0,0 +1,17 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * ioapic.c - I/O APIC definitions. + */ + +#pragma once + +#include +#include + +#define IOAPIC_VERSION 0x1 +#define IOAPIC_REDTBL 0x10 + +void ioapic_init(); +void ioapic_redir_irq(uint32_t lapic_id, uint8_t vec, uint8_t irq, bool mask); \ No newline at end of file diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c new file mode 100644 index 0000000..50bf04e --- /dev/null +++ b/kernel/src/dev/lapic.c @@ -0,0 +1,33 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * lapic.c - Local APIC implementation. + */ + +#include "dev/lapic.h" +#include "arch/x86_64/idt.h" +#include "lib/log.h" +#include "mm/pmm.h" +#include + +static uint64_t __lapic_pbase = 0xfee00000; +static uint64_t __lapic_vbase; + +static void __lapic_write(uint32_t reg, uint32_t val) { *(volatile uint32_t *)(__lapic_vbase + reg) = val; } +static uint32_t __lapic_read(uint32_t reg) { return *(volatile uint32_t *)(__lapic_vbase + reg); } +static void __lapic_write_svr(uint32_t reg, lapic_svr_entry e) { *(volatile uint32_t *)(__lapic_vbase + reg) = *(uint32_t*)&e; } + +void lapic_init() { + __lapic_vbase = higher_half(__lapic_pbase); + __lapic_write_svr(LAPIC_SVR, (lapic_svr_entry){ .swenabled = true, .vec = IDT_SPURIOUS_INT }); + trace("lapic: Initialized\n"); +} + +void lapic_eoi() { + __lapic_write(LAPIC_EOI, 0x0); +} + +uint32_t lapic_get_id() { + return __lapic_read(LAPIC_ID) >> LAPIC_ICDESTSHIFT; +} \ No newline at end of file diff --git a/kernel/src/dev/lapic.h b/kernel/src/dev/lapic.h new file mode 100644 index 0000000..5697054 --- /dev/null +++ b/kernel/src/dev/lapic.h @@ -0,0 +1,26 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * lapic.h - Local APIC definitions. + */ + +#pragma once + +#include +#include + +#define LAPIC_ID 0x20 +#define LAPIC_SVR 0xF0 +#define LAPIC_EOI 0xB0 + +#define LAPIC_ICDESTSHIFT 24 + +typedef struct { + uint8_t vec; + bool swenabled; +} lapic_svr_entry; + +void lapic_init(); +void lapic_eoi(); +uint32_t lapic_get_id(); \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c index daa02d2..d34e903 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,8 @@ #include #include #include +#include "dev/ioapic.h" +#include "dev/lapic.h" #include "mm/paging.h" #include "mm/vma.h" @@ -37,7 +40,14 @@ void kmain(void) { pg_init(); acpi_init(); + madt_init(); + lapic_init(); + ioapic_init(); + cpu_init_smp(); + cpu_init_timer(); + while (1) + ;; // We're done, just hang... for now. - hcf(); + //hcf(); } diff --git a/kernel/src/mm/pmm.md b/kernel/src/mm/pmm.md new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c new file mode 100644 index 0000000..e69de29 From edbb5d106df45b7b949abe5b6848076c5a35c8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M?= Date: Sun, 1 Jun 2025 22:45:43 +0200 Subject: [PATCH 28/30] kernel: whatever changes i didn't keep track of lol --- .gitignore | 0 GNUmakefile | 0 LICENSE | 0 README.md | 4 +- kernel/.gitignore | 0 kernel/GNUmakefile | 0 kernel/linker-aarch64.ld | 0 kernel/linker-loongarch64.ld | 0 kernel/linker-riscv64.ld | 0 kernel/linker-x86_64.ld | 0 kernel/src/acpi/acpi.c | 0 kernel/src/acpi/acpi.h | 0 kernel/src/acpi/madt.c | 0 kernel/src/acpi/madt.h | 0 kernel/src/arch/aarch64/cpu.c | 0 kernel/src/arch/cpu.h | 3 + kernel/src/arch/la64/cpu.c | 0 kernel/src/arch/riscv/cpu.c | 0 kernel/src/arch/x86_64/cpu.c | 4 + kernel/src/arch/x86_64/cpu.h | 0 kernel/src/arch/x86_64/gdt.asm | 6 ++ kernel/src/arch/x86_64/gdt.c | 2 - kernel/src/arch/x86_64/gdt.h | 0 kernel/src/arch/x86_64/idt.asm | 6 ++ kernel/src/arch/x86_64/idt.c | 9 +- kernel/src/arch/x86_64/idt.h | 3 +- kernel/src/arch/x86_64/io.h | 0 kernel/src/arch/x86_64/pit.c | 3 +- kernel/src/arch/x86_64/smp.c | 12 +++ kernel/src/arch/x86_64/smp.h | 0 kernel/src/boot/limine.c | 2 +- kernel/src/boot/limine.h | 0 kernel/src/config.h | 0 kernel/src/dev/ioapic.c | 0 kernel/src/dev/ioapic.h | 0 kernel/src/dev/lapic.c | 6 ++ kernel/src/dev/lapic.h | 1 + kernel/src/dev/tty.c | 0 kernel/src/dev/tty.h | 0 kernel/src/fs/vfs.h | 45 ++++++++ kernel/src/lib/ansi.c | 0 kernel/src/lib/ansi.h | 0 kernel/src/lib/log.c | 4 + kernel/src/lib/log.h | 0 kernel/src/lib/logoutputs_sk.c | 0 kernel/src/lib/logoutputs_sk.h | 0 kernel/src/lib/npf.c | 0 kernel/src/lib/spinlock.c | 25 +++++ kernel/src/lib/spinlock.h | 13 +++ kernel/src/lib/string.c | 0 kernel/src/lib/string.h | 0 kernel/src/main.c | 5 + kernel/src/mm/memop.c | 0 kernel/src/mm/memop.h | 0 kernel/src/mm/paging.c | 173 +++++++++++++++++-------------- kernel/src/mm/paging.h | 0 kernel/src/mm/pmm.c | 0 kernel/src/mm/pmm.h | 0 kernel/src/mm/pmm.md | 0 kernel/src/mm/vma.c | 0 kernel/src/mm/vma.h | 0 kernel/src/mm/vmm.c | 0 kernel/src/{ => proc}/exec/elf.h | 0 kernel/src/proc/exec/exec.h | 30 ++++++ kernel/src/proc/sched.c | 3 + kernel/src/proc/sched.h | 69 ++++++++++++ limine.conf | 0 67 files changed, 340 insertions(+), 88 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 GNUmakefile mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 kernel/.gitignore mode change 100644 => 100755 kernel/GNUmakefile mode change 100644 => 100755 kernel/linker-aarch64.ld mode change 100644 => 100755 kernel/linker-loongarch64.ld mode change 100644 => 100755 kernel/linker-riscv64.ld mode change 100644 => 100755 kernel/linker-x86_64.ld mode change 100644 => 100755 kernel/src/acpi/acpi.c mode change 100644 => 100755 kernel/src/acpi/acpi.h mode change 100644 => 100755 kernel/src/acpi/madt.c mode change 100644 => 100755 kernel/src/acpi/madt.h mode change 100644 => 100755 kernel/src/arch/aarch64/cpu.c mode change 100644 => 100755 kernel/src/arch/cpu.h mode change 100644 => 100755 kernel/src/arch/la64/cpu.c mode change 100644 => 100755 kernel/src/arch/riscv/cpu.c mode change 100644 => 100755 kernel/src/arch/x86_64/cpu.c mode change 100644 => 100755 kernel/src/arch/x86_64/cpu.h mode change 100644 => 100755 kernel/src/arch/x86_64/gdt.asm mode change 100644 => 100755 kernel/src/arch/x86_64/gdt.c mode change 100644 => 100755 kernel/src/arch/x86_64/gdt.h mode change 100644 => 100755 kernel/src/arch/x86_64/idt.asm mode change 100644 => 100755 kernel/src/arch/x86_64/idt.c mode change 100644 => 100755 kernel/src/arch/x86_64/idt.h mode change 100644 => 100755 kernel/src/arch/x86_64/io.h mode change 100644 => 100755 kernel/src/arch/x86_64/pit.c mode change 100644 => 100755 kernel/src/arch/x86_64/smp.c mode change 100644 => 100755 kernel/src/arch/x86_64/smp.h mode change 100644 => 100755 kernel/src/boot/limine.c mode change 100644 => 100755 kernel/src/boot/limine.h mode change 100644 => 100755 kernel/src/config.h mode change 100644 => 100755 kernel/src/dev/ioapic.c mode change 100644 => 100755 kernel/src/dev/ioapic.h mode change 100644 => 100755 kernel/src/dev/lapic.c mode change 100644 => 100755 kernel/src/dev/lapic.h mode change 100644 => 100755 kernel/src/dev/tty.c mode change 100644 => 100755 kernel/src/dev/tty.h create mode 100755 kernel/src/fs/vfs.h mode change 100644 => 100755 kernel/src/lib/ansi.c mode change 100644 => 100755 kernel/src/lib/ansi.h mode change 100644 => 100755 kernel/src/lib/log.c mode change 100644 => 100755 kernel/src/lib/log.h mode change 100644 => 100755 kernel/src/lib/logoutputs_sk.c mode change 100644 => 100755 kernel/src/lib/logoutputs_sk.h mode change 100644 => 100755 kernel/src/lib/npf.c create mode 100755 kernel/src/lib/spinlock.c create mode 100755 kernel/src/lib/spinlock.h mode change 100644 => 100755 kernel/src/lib/string.c mode change 100644 => 100755 kernel/src/lib/string.h mode change 100644 => 100755 kernel/src/main.c mode change 100644 => 100755 kernel/src/mm/memop.c mode change 100644 => 100755 kernel/src/mm/memop.h mode change 100644 => 100755 kernel/src/mm/paging.c mode change 100644 => 100755 kernel/src/mm/paging.h mode change 100644 => 100755 kernel/src/mm/pmm.c mode change 100644 => 100755 kernel/src/mm/pmm.h mode change 100644 => 100755 kernel/src/mm/pmm.md mode change 100644 => 100755 kernel/src/mm/vma.c mode change 100644 => 100755 kernel/src/mm/vma.h delete mode 100644 kernel/src/mm/vmm.c rename kernel/src/{ => proc}/exec/elf.h (100%) mode change 100644 => 100755 create mode 100644 kernel/src/proc/exec/exec.h create mode 100644 kernel/src/proc/sched.c create mode 100644 kernel/src/proc/sched.h mode change 100644 => 100755 limine.conf diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/GNUmakefile b/GNUmakefile old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 24de99e..91d8cd6 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ This is a carefully rewritten version of Soaplin, that should be held with super * Support for compiling the kernel on armv8, RISC-V, and LoongArch64 (even though the kernel doesn't do anything on these architectures) * Free list PMM with lazy loading * x86_64 paging - -## To do * ACPI & MADT * IOAPIC / LAPIC + +## To do * SMP * Multithreaded scheduler * VFS diff --git a/kernel/.gitignore b/kernel/.gitignore old mode 100644 new mode 100755 diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile old mode 100644 new mode 100755 diff --git a/kernel/linker-aarch64.ld b/kernel/linker-aarch64.ld old mode 100644 new mode 100755 diff --git a/kernel/linker-loongarch64.ld b/kernel/linker-loongarch64.ld old mode 100644 new mode 100755 diff --git a/kernel/linker-riscv64.ld b/kernel/linker-riscv64.ld old mode 100644 new mode 100755 diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld old mode 100644 new mode 100755 diff --git a/kernel/src/acpi/acpi.c b/kernel/src/acpi/acpi.c old mode 100644 new mode 100755 diff --git a/kernel/src/acpi/acpi.h b/kernel/src/acpi/acpi.h old mode 100644 new mode 100755 diff --git a/kernel/src/acpi/madt.c b/kernel/src/acpi/madt.c old mode 100644 new mode 100755 diff --git a/kernel/src/acpi/madt.h b/kernel/src/acpi/madt.h old mode 100644 new mode 100755 diff --git a/kernel/src/arch/aarch64/cpu.c b/kernel/src/arch/aarch64/cpu.c old mode 100644 new mode 100755 diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h old mode 100644 new mode 100755 index 76861ff..df89abf --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -25,5 +25,8 @@ void cpu_init_smp(); // Initialize the CPU's timer void cpu_init_timer(); +// Enable/disable interrupts. +void cpu_enable_ints(int enabled); + // Disable interrupts and halt the system. void hcf(); \ No newline at end of file diff --git a/kernel/src/arch/la64/cpu.c b/kernel/src/arch/la64/cpu.c old mode 100644 new mode 100755 diff --git a/kernel/src/arch/riscv/cpu.c b/kernel/src/arch/riscv/cpu.c old mode 100644 new mode 100755 diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c old mode 100644 new mode 100755 index 858beca..d1707c6 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -29,6 +29,10 @@ void cpu_invalidate_page(uint64_t vaddr) { asm volatile ( "invlpg (%0)" : : "b"(vaddr) : "memory" ); } +void cpu_enable_ints(int enabled) { + if (enabled) asm("sti"); else asm("cli"); +} + void hcf() { asm ("cli"); for (;;) { diff --git a/kernel/src/arch/x86_64/cpu.h b/kernel/src/arch/x86_64/cpu.h old mode 100644 new mode 100755 diff --git a/kernel/src/arch/x86_64/gdt.asm b/kernel/src/arch/x86_64/gdt.asm old mode 100644 new mode 100755 index 224581b..4bdcbb4 --- a/kernel/src/arch/x86_64/gdt.asm +++ b/kernel/src/arch/x86_64/gdt.asm @@ -1,3 +1,9 @@ +; +; The Soaplin Kernel +; Copyright (C) 2025 The SILD Project +; +; gdt.asm - Utility for reloading the segments. + bits 64 section .text diff --git a/kernel/src/arch/x86_64/gdt.c b/kernel/src/arch/x86_64/gdt.c old mode 100644 new mode 100755 index 97b04a4..ac9f4df --- a/kernel/src/arch/x86_64/gdt.c +++ b/kernel/src/arch/x86_64/gdt.c @@ -53,8 +53,6 @@ void gdt_init() { __asm__ volatile("ltr %0\n\t" : : "r"((uint16_t)0x28)); // 0x20 (last GDT entry) + 0x8 (size of a GDT entry) gdt_reload_segments(); - - trace("arch: GDT & TSS initialized.\n"); } #endif \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.h b/kernel/src/arch/x86_64/gdt.h old mode 100644 new mode 100755 diff --git a/kernel/src/arch/x86_64/idt.asm b/kernel/src/arch/x86_64/idt.asm old mode 100644 new mode 100755 index 48b69b9..24f9435 --- a/kernel/src/arch/x86_64/idt.asm +++ b/kernel/src/arch/x86_64/idt.asm @@ -1,3 +1,9 @@ +; +; The Soaplin Kernel +; Copyright (C) 2025 The SILD Project +; +; idt.asm - Defines the handler for IDT entries. +; %macro pushall 0 push rax diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c old mode 100644 new mode 100755 index 33985c6..a3c918c --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -77,6 +77,10 @@ void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { extern void* isr_stub_table[]; +void idt_load() { + __asm__ volatile ("lidt %0" : : "m"(idtr)); +} + void idt_init() { idtr.base = (uintptr_t)&idt[0]; idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; @@ -99,9 +103,8 @@ void idt_init() { __idt_vectors[IDT_SPURIOUS_INT] = VT_SPURIOUS; trace("idt: Spurious interrupt vector has been set!\n"); - __asm__ volatile ("lidt %0" : : "m"(idtr)); - __asm__ volatile ("sti"); - + //__asm__ volatile ("sti"); + idt_load(); trace("arch: IDT loaded successfully\n"); } diff --git a/kernel/src/arch/x86_64/idt.h b/kernel/src/arch/x86_64/idt.h old mode 100644 new mode 100755 index 7c8707c..5afa21a --- a/kernel/src/arch/x86_64/idt.h +++ b/kernel/src/arch/x86_64/idt.h @@ -59,4 +59,5 @@ typedef struct { } __attribute__((packed)) idtr_t; void idt_register_handler(uint8_t vector, void *isr); -void idt_init(void); \ No newline at end of file +void idt_init(void); +void idt_load(); \ No newline at end of file diff --git a/kernel/src/arch/x86_64/io.h b/kernel/src/arch/x86_64/io.h old mode 100644 new mode 100755 diff --git a/kernel/src/arch/x86_64/pit.c b/kernel/src/arch/x86_64/pit.c old mode 100644 new mode 100755 index d61cd7b..c1a804b --- a/kernel/src/arch/x86_64/pit.c +++ b/kernel/src/arch/x86_64/pit.c @@ -8,10 +8,11 @@ #include #include +#include #include void pit_handler(registers_t *reg) { - trace("pit: Interrupt!\n"); + //trace("pit: Interrupt from %d!\n", lapic_get_id()); } void cpu_init_timer() { diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c old mode 100644 new mode 100755 index 3253f7f..50cea7f --- a/kernel/src/arch/x86_64/smp.c +++ b/kernel/src/arch/x86_64/smp.c @@ -5,13 +5,25 @@ * smp.c - x86_64 Symetric Multiprocessing implementation */ +#include "arch/cpu.h" +#include "arch/x86_64/gdt.h" +#include "arch/x86_64/idt.h" +#include "dev/lapic.h" +#include "mm/paging.h" #include #include +#include #include uint32_t bootstrap_lapic_id; +// TODO: initialize the CPUs + void cpu_init_smp() { struct limine_mp_response *smp = limine_get_smp(); bootstrap_lapic_id = smp->bsp_lapic_id; + + /*for (uint64_t i = 0; i < smp->cpu_count; i++) { + trace("smp: Starting CPU %d\n", i); + }*/ } diff --git a/kernel/src/arch/x86_64/smp.h b/kernel/src/arch/x86_64/smp.h old mode 100644 new mode 100755 diff --git a/kernel/src/boot/limine.c b/kernel/src/boot/limine.c old mode 100644 new mode 100755 index 151c9d8..df2c24a --- a/kernel/src/boot/limine.c +++ b/kernel/src/boot/limine.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); diff --git a/kernel/src/boot/limine.h b/kernel/src/boot/limine.h old mode 100644 new mode 100755 diff --git a/kernel/src/config.h b/kernel/src/config.h old mode 100644 new mode 100755 diff --git a/kernel/src/dev/ioapic.c b/kernel/src/dev/ioapic.c old mode 100644 new mode 100755 diff --git a/kernel/src/dev/ioapic.h b/kernel/src/dev/ioapic.h old mode 100644 new mode 100755 diff --git a/kernel/src/dev/lapic.c b/kernel/src/dev/lapic.c old mode 100644 new mode 100755 index 50bf04e..7e00f78 --- a/kernel/src/dev/lapic.c +++ b/kernel/src/dev/lapic.c @@ -28,6 +28,12 @@ void lapic_eoi() { __lapic_write(LAPIC_EOI, 0x0); } +void lapic_ipi(uint32_t id, uint8_t dat) { + __lapic_write(0x310, id << LAPIC_ICDESTSHIFT); + __lapic_write(0x300, dat); +} + + uint32_t lapic_get_id() { return __lapic_read(LAPIC_ID) >> LAPIC_ICDESTSHIFT; } \ No newline at end of file diff --git a/kernel/src/dev/lapic.h b/kernel/src/dev/lapic.h old mode 100644 new mode 100755 index 5697054..e473a76 --- a/kernel/src/dev/lapic.h +++ b/kernel/src/dev/lapic.h @@ -23,4 +23,5 @@ typedef struct { void lapic_init(); void lapic_eoi(); +void lapic_ipi(uint32_t id, uint8_t dat); uint32_t lapic_get_id(); \ No newline at end of file diff --git a/kernel/src/dev/tty.c b/kernel/src/dev/tty.c old mode 100644 new mode 100755 diff --git a/kernel/src/dev/tty.h b/kernel/src/dev/tty.h old mode 100644 new mode 100755 diff --git a/kernel/src/fs/vfs.h b/kernel/src/fs/vfs.h new file mode 100755 index 0000000..6beb202 --- /dev/null +++ b/kernel/src/fs/vfs.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +struct vnode; + +#define VN_FILE 1 +#define VN_DIR 2 + +typedef uint32_t vnode_type_t; + +typedef struct vnode_ops { + int (*read)(struct vnode *vn, void *buf, size_t off, size_t size); + int (*lookup)(struct vnode *vn, const char *name, struct vnode **out); +} vnode_ops_t; + +typedef struct vnode { + char name[256]; + vnode_type_t type; + uint32_t refcount; + struct vnode* parent; // If this vnode exists, then it's parent too. + + struct vnode_ops *ops; + void *internal; +} vnode_t; + +typedef struct mountpoint { + char name[32]; + struct fs *fs; + vnode_t *mountpoint; +} mountpoint_t; + +typedef struct fs { + char name[32]; + struct vnode *root; + int (*mount)(struct fs *fs, struct vnode *mountpoint); +} fs_t; + +void vfs_init(void); +int vfs_mount(char *path, fs_t *fs); +int vfs_unmount(char *path); +int vfs_open(vnode_t *curdir, const char *path, vnode_t **out); +int vfs_read(vnode_t *vn, void *buf, size_t off, size_t size); +vnode_t *vfs_create_node(char *name, vnode_type_t type); \ No newline at end of file diff --git a/kernel/src/lib/ansi.c b/kernel/src/lib/ansi.c old mode 100644 new mode 100755 diff --git a/kernel/src/lib/ansi.h b/kernel/src/lib/ansi.h old mode 100644 new mode 100755 diff --git a/kernel/src/lib/log.c b/kernel/src/lib/log.c old mode 100644 new mode 100755 index e21cf80..7baa324 --- a/kernel/src/lib/log.c +++ b/kernel/src/lib/log.c @@ -6,10 +6,12 @@ */ #include #include +#include static int __logger_max_loglevel = 0; static log_output_func __logger_outputs[16]; static int __logger_output_count = 0; +static spinlock_t __logger_lock; static char* prelog[7] = { "\033[38;2;169;68;66;mFAULT | \033[39m", @@ -41,6 +43,7 @@ void log(int loglevel, char *str, ...) { if (loglevel > __logger_max_loglevel) return; // The user does not want this type of log to show up. + sl_acquire(&__logger_lock); va_list vl; va_start(vl, str); @@ -50,4 +53,5 @@ void log(int loglevel, char *str, ...) { } va_end(vl); + sl_release(&__logger_lock); } \ No newline at end of file diff --git a/kernel/src/lib/log.h b/kernel/src/lib/log.h old mode 100644 new mode 100755 diff --git a/kernel/src/lib/logoutputs_sk.c b/kernel/src/lib/logoutputs_sk.c old mode 100644 new mode 100755 diff --git a/kernel/src/lib/logoutputs_sk.h b/kernel/src/lib/logoutputs_sk.h old mode 100644 new mode 100755 diff --git a/kernel/src/lib/npf.c b/kernel/src/lib/npf.c old mode 100644 new mode 100755 diff --git a/kernel/src/lib/spinlock.c b/kernel/src/lib/spinlock.c new file mode 100755 index 0000000..88bc6c1 --- /dev/null +++ b/kernel/src/lib/spinlock.c @@ -0,0 +1,25 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * spinlock.c - Spinlock implementation. + */ + +#include + +void sl_acquire(spinlock_t volatile *plock) +{ + while (!__sync_bool_compare_and_swap(plock, 0, 1)) + { + while (*plock) + { + asm("pause"); + } + } +} + +void sl_release(spinlock_t volatile *plock) +{ + __sync_lock_release(plock); +} + diff --git a/kernel/src/lib/spinlock.h b/kernel/src/lib/spinlock.h new file mode 100755 index 0000000..07c18cd --- /dev/null +++ b/kernel/src/lib/spinlock.h @@ -0,0 +1,13 @@ +/* + * The Soaplin Kernel + * Copyright (C) 2025 The SILD Project + * + * spinlock.h - Spinlock definitions. + */ + +#pragma once + +typedef unsigned int spinlock_t; + +void sl_acquire(spinlock_t volatile *plock); +void sl_release(spinlock_t volatile *plock); \ No newline at end of file diff --git a/kernel/src/lib/string.c b/kernel/src/lib/string.c old mode 100644 new mode 100755 diff --git a/kernel/src/lib/string.h b/kernel/src/lib/string.h old mode 100644 new mode 100755 diff --git a/kernel/src/main.c b/kernel/src/main.c old mode 100644 new mode 100755 index d34e903..a8345ec --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -20,6 +20,7 @@ #include #include #include +#include "arch/x86_64/smp.h" #include "dev/ioapic.h" #include "dev/lapic.h" #include "mm/paging.h" @@ -46,6 +47,10 @@ void kmain(void) { cpu_init_smp(); cpu_init_timer(); + + cpu_enable_ints(1); + //lapic_ipi(bootstrap_lapic_id, 32); + while (1) ;; // We're done, just hang... for now. diff --git a/kernel/src/mm/memop.c b/kernel/src/mm/memop.c old mode 100644 new mode 100755 diff --git a/kernel/src/mm/memop.h b/kernel/src/mm/memop.h old mode 100644 new mode 100755 diff --git a/kernel/src/mm/paging.c b/kernel/src/mm/paging.c old mode 100644 new mode 100755 index 6ef555d..dd2953a --- a/kernel/src/mm/paging.c +++ b/kernel/src/mm/paging.c @@ -10,11 +10,11 @@ #include #include -#include #include #include -#include #include +#include +#include #include pagemap_t pg_kernel_pm = NULL; @@ -22,82 +22,83 @@ pagemap_t pg_current_pm = NULL; void pg_init() { #if !defined(__x86_64__) - fatal("vmm: not implemented\n"); - hcf(); + fatal("vmm: not implemented\n"); + hcf(); #endif - // Our objective here is to recreate the - // kernel page map that Limine provide us + // Our objective here is to recreate the + // kernel page map that Limine provide us - pg_kernel_pm = pg_alloc_pm(); + pg_kernel_pm = pg_alloc_pm(); - uint64_t kvaddr = limine_get_kernel_vaddr(); - uint64_t kpaddr = limine_get_kernel_paddr(); - - char *elf_addr = (char *)limine_get_kernel_ehdr_addr(); - Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elf_addr; + uint64_t kvaddr = limine_get_kernel_vaddr(); + uint64_t kpaddr = limine_get_kernel_paddr(); - for (uint16_t i = 0; i < ehdr->e_phnum; i++) { - Elf64_Phdr *cur_phdr = (Elf64_Phdr*)(elf_addr + ehdr->e_phoff + (i * ehdr->e_phentsize)); - if (cur_phdr->p_type != PT_LOAD) - continue; + char *elf_addr = (char *)limine_get_kernel_ehdr_addr(); + Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elf_addr; - uintptr_t phys = (cur_phdr->p_vaddr - kvaddr) + kpaddr; - uint64_t flags = PTE_PRESENT; - if ((cur_phdr->p_flags & PF_X) == 0) { - flags |= PTE_NX; - } - if (cur_phdr->p_flags & PF_W) { - flags |= PTE_WRITE; - } + for (uint16_t i = 0; i < ehdr->e_phnum; i++) { + Elf64_Phdr *cur_phdr = + (Elf64_Phdr *)(elf_addr + ehdr->e_phoff + (i * ehdr->e_phentsize)); + if (cur_phdr->p_type != PT_LOAD) + continue; - size_t length = ALIGN_UP(cur_phdr->p_memsz, PMM_PAGE_SIZE); - - for (uint64_t i = 0; i < length; i += PMM_PAGE_SIZE) { - pg_map(pg_kernel_pm, cur_phdr->p_vaddr + i, phys + i, flags); - } - trace("vmm: Mapped range: %p -> %p (length: %x)\n", phys, cur_phdr->p_vaddr, length); + uintptr_t phys = (cur_phdr->p_vaddr - kvaddr) + kpaddr; + uint64_t flags = PTE_PRESENT; + if ((cur_phdr->p_flags & PF_X) == 0) { + flags |= PTE_NX; + } + if (cur_phdr->p_flags & PF_W) { + flags |= PTE_WRITE; } - for (uint64_t i = 0; i < 0x100000000; i += PMM_PAGE_SIZE) - pg_map(pg_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); - trace("vmm: Mapped range: %p -> %p (length: %x)\n", 0x0, 0xFFFF800000000000, 0x100000000); + size_t length = ALIGN_UP(cur_phdr->p_memsz, PMM_PAGE_SIZE); - pg_load_pm(pg_kernel_pm); - trace("vmm: Initialized.\n"); + for (uint64_t i = 0; i < length; i += PMM_PAGE_SIZE) { + pg_map(pg_kernel_pm, cur_phdr->p_vaddr + i, phys + i, flags); + } + trace("vmm: Mapped range: %p -> %p (length: %x)\n", phys, cur_phdr->p_vaddr, + length); + } + + for (uint64_t i = 0; i < 0x100000000; i += PMM_PAGE_SIZE) + pg_map(pg_kernel_pm, higher_half(i), i, PTE_PRESENT | PTE_WRITE); + trace("vmm: Mapped range: %p -> %p (length: %x)\n", 0x0, 0xFFFF800000000000, + 0x100000000); + + pg_load_pm(pg_kernel_pm); + trace("vmm: Initialized.\n"); } void pg_load_pm(pagemap_t pm) { - if (!pm) - return; + if (!pm) + return; - pg_current_pm = pm; - cpu_load_pm((pagemap_t)physical((uint64_t)pm)); + pg_current_pm = pm; + cpu_load_pm((pagemap_t)physical((uint64_t)pm)); } pagemap_t pg_alloc_pm() { - pagemap_t pm = (pagemap_t)higher_half((uint64_t)pmm_alloc_page()); - memset((void*)pm, 0, PMM_PAGE_SIZE); + pagemap_t pm = (pagemap_t)higher_half((uint64_t)pmm_alloc_page()); + memset((void *)pm, 0, PMM_PAGE_SIZE); - if (pg_kernel_pm) - { - for (int i = 256; i < 512; i++) - pm[i] = pg_kernel_pm[i]; - } + if (pg_kernel_pm) { + for (int i = 256; i < 512; i++) + pm[i] = pg_kernel_pm[i]; + } - return pm; + return pm; } void pg_free_pm(pagemap_t pm) { - if (pm == pg_kernel_pm) - { - warn("vmm: Who tried to free the kernel's pagemap?!\n"); - return; - } - pmm_free_page((void*)pm); + if (pm == pg_kernel_pm) { + warn("vmm: Who tried to free the kernel's pagemap?!\n"); + return; + } + pmm_free_page((void *)pm); } static uint64_t *__pg_get_next_lvl(uint64_t *level, uint64_t entry, - uint64_t flags, bool alloc) { + uint64_t flags, bool alloc) { if (level[entry] & PTE_PRESENT) return (uint64_t *)higher_half(PTE_GET_ADDR(level[entry])); if (alloc) { @@ -110,48 +111,56 @@ static uint64_t *__pg_get_next_lvl(uint64_t *level, uint64_t entry, } uint64_t pg_physical(pagemap_t pm, uint64_t vaddr) { - if (!pm) return 0; + if (!pm) + return 0; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); - if (!pml3) return 0; + uint64_t *pml3 = __pg_get_next_lvl(pm, pml4_entry, 0, false); + if (!pml3) + return 0; uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); - if (!pml2) return 0; + if (!pml2) + return 0; uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); - if (!pml1) return 0; + if (!pml1) + return 0; return pml1[pml1_entry] & PTE_ADDR_MASK; } void pg_map(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { - if (!pm) return; + if (!pm) + return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, PTE_PRESENT | PTE_WRITE, true); - uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, PTE_PRESENT | PTE_WRITE, true); - uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml3 = + __pg_get_next_lvl(pm, pml4_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml2 = + __pg_get_next_lvl(pml3, pml3_entry, PTE_PRESENT | PTE_WRITE, true); + uint64_t *pml1 = + __pg_get_next_lvl(pml2, pml2_entry, PTE_PRESENT | PTE_WRITE, true); pml1[pml1_entry] = paddr | flags; } -void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, - uint64_t flags) { - if (!pm) return; +void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { + if (!pm) + return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, flags, true); + uint64_t *pml3 = __pg_get_next_lvl(pm, pml4_entry, flags, true); uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, flags, true); uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, flags, true); @@ -159,38 +168,46 @@ void pg_map_user(pagemap_t pm, uint64_t vaddr, uint64_t paddr, } void pg_unmap(pagemap_t pm, uint64_t vaddr) { - if (!pm) return; + if (!pm) + return; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); - if (!pml3) return; + uint64_t *pml3 = __pg_get_next_lvl(pm, pml4_entry, 0, false); + if (!pml3) + return; uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); - if (!pml2) return; + if (!pml2) + return; uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); - if (!pml1) return; + if (!pml1) + return; pml1[pml1_entry] = 0; cpu_invalidate_page(vaddr); } void pg_protect(pagemap_t pm, uint64_t vaddr, uint64_t flags) { - if (!pm) return; - + if (!pm) + return; + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; - uint64_t *pml3 = __pg_get_next_lvl(pm , pml4_entry, 0, false); - if (!pml3) return; + uint64_t *pml3 = __pg_get_next_lvl(pm, pml4_entry, 0, false); + if (!pml3) + return; uint64_t *pml2 = __pg_get_next_lvl(pml3, pml3_entry, 0, false); - if (!pml2) return; + if (!pml2) + return; uint64_t *pml1 = __pg_get_next_lvl(pml2, pml2_entry, 0, false); - if (!pml1) return; + if (!pml1) + return; uint64_t paddr = pml1[pml1_entry] & PTE_ADDR_MASK; pml1[pml1_entry] = paddr | flags; diff --git a/kernel/src/mm/paging.h b/kernel/src/mm/paging.h old mode 100644 new mode 100755 diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c old mode 100644 new mode 100755 diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h old mode 100644 new mode 100755 diff --git a/kernel/src/mm/pmm.md b/kernel/src/mm/pmm.md old mode 100644 new mode 100755 diff --git a/kernel/src/mm/vma.c b/kernel/src/mm/vma.c old mode 100644 new mode 100755 diff --git a/kernel/src/mm/vma.h b/kernel/src/mm/vma.h old mode 100644 new mode 100755 diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c deleted file mode 100644 index e69de29..0000000 diff --git a/kernel/src/exec/elf.h b/kernel/src/proc/exec/elf.h old mode 100644 new mode 100755 similarity index 100% rename from kernel/src/exec/elf.h rename to kernel/src/proc/exec/elf.h diff --git a/kernel/src/proc/exec/exec.h b/kernel/src/proc/exec/exec.h new file mode 100644 index 0000000..2901de9 --- /dev/null +++ b/kernel/src/proc/exec/exec.h @@ -0,0 +1,30 @@ + +// Structure for an executable program loaded into memory. + +#include "mm/paging.h" +#include + +typedef enum { + EXEC_FMT_ELF, + EXEC_FMT_PE, + EXEC_FMT_MACHO, + EXEC_FMT_SCRIPT +} exec_format_t; + +typedef struct exec { + pagemap_t pm; + + void *rwdata_start; + size_t rwdata_len; + + uint64_t entry; + + int argc; // 0 for useds + char **argv; // NULL when the executable is a used + + char *path; + exec_format_t format; + + size_t usecount; // -1 for users, else, the number of processes sharing the executable's read only sections + struct exec *used; // The reference executable. +} exec_t; \ No newline at end of file diff --git a/kernel/src/proc/sched.c b/kernel/src/proc/sched.c new file mode 100644 index 0000000..680fa12 --- /dev/null +++ b/kernel/src/proc/sched.c @@ -0,0 +1,3 @@ +void sched_init() { + +} \ No newline at end of file diff --git a/kernel/src/proc/sched.h b/kernel/src/proc/sched.h new file mode 100644 index 0000000..e30a605 --- /dev/null +++ b/kernel/src/proc/sched.h @@ -0,0 +1,69 @@ +#pragma once + +#include "arch/x86_64/idt.h" +#include "mm/paging.h" +#include +#include + +struct process; + +typedef enum thread_state { + THREAD_READY, + THREAD_RUNNING, + THREAD_BLOCKED, + THREAD_TERMINATED +} thread_state_t; + +typedef enum process_type { + PT_USER, + PT_KERNEL +} process_type_t; + +typedef enum process_state { + PS_ZOMBIE, + PS_ACTIVE, + PS_TERMINATED +} process_state_t; + +typedef struct thread { + size_t tid; + registers_t regs; + uint64_t stack_base; + uint64_t stack_end; + thread_state_t state; + + struct process *parent; + + // Local only: Only lists the process' threads + struct thread *next; + struct thread *prev; +} thread_t; + +// Global thread list +typedef struct thread_list { + struct thread *next; + struct thread *prev; +} thread_list_t; + +typedef struct process { + char *name; + size_t pid; + pagemap_t pm; + thread_t *threads; + exec_t *exec_clone; + process_type_t type; + process_state_t state; + + struct process *next_sibling; + struct process *prev_sibling; + + struct process *children; + struct process *parent; +} process_t; + +extern thread_t *current_thread; +extern process_t *current_process; +extern thread_list_t *thread_list_head; + +void sched_init(); +void schedule(); \ No newline at end of file diff --git a/limine.conf b/limine.conf old mode 100644 new mode 100755 From 033d85bd2f50390c425567f0bb907ccd1fe63805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M?= Date: Mon, 2 Jun 2025 21:05:51 +0200 Subject: [PATCH 29/30] cpu: move apic to x86_64 --- kernel/src/arch/cpu.h | 3 +++ kernel/src/arch/x86_64/cpu.c | 7 +++++++ kernel/src/arch/x86_64/idt.c | 4 ++-- kernel/src/{dev => arch/x86_64}/ioapic.c | 0 kernel/src/{dev => arch/x86_64}/ioapic.h | 0 kernel/src/{dev => arch/x86_64}/lapic.c | 2 +- kernel/src/{dev => arch/x86_64}/lapic.h | 0 kernel/src/arch/x86_64/smp.c | 4 ---- kernel/src/main.c | 4 ++-- 9 files changed, 15 insertions(+), 9 deletions(-) rename kernel/src/{dev => arch/x86_64}/ioapic.c (100%) rename kernel/src/{dev => arch/x86_64}/ioapic.h (100%) rename kernel/src/{dev => arch/x86_64}/lapic.c (97%) rename kernel/src/{dev => arch/x86_64}/lapic.h (100%) diff --git a/kernel/src/arch/cpu.h b/kernel/src/arch/cpu.h index df89abf..bb197f9 100755 --- a/kernel/src/arch/cpu.h +++ b/kernel/src/arch/cpu.h @@ -25,6 +25,9 @@ void cpu_init_smp(); // Initialize the CPU's timer void cpu_init_timer(); +// Initialize the APIC. +void cpu_init_apic(); + // Enable/disable interrupts. void cpu_enable_ints(int enabled); diff --git a/kernel/src/arch/x86_64/cpu.c b/kernel/src/arch/x86_64/cpu.c index d1707c6..7a48f09 100755 --- a/kernel/src/arch/x86_64/cpu.c +++ b/kernel/src/arch/x86_64/cpu.c @@ -7,6 +7,8 @@ #if defined (__x86_64__) +#include "arch/x86_64/lapic.h" +#include "arch/x86_64/ioapic.h" #include #include #include @@ -33,6 +35,11 @@ void cpu_enable_ints(int enabled) { if (enabled) asm("sti"); else asm("cli"); } +void cpu_init_apic() { + lapic_init(); + ioapic_init(); +} + void hcf() { asm ("cli"); for (;;) { diff --git a/kernel/src/arch/x86_64/idt.c b/kernel/src/arch/x86_64/idt.c index a3c918c..e14ffd4 100755 --- a/kernel/src/arch/x86_64/idt.c +++ b/kernel/src/arch/x86_64/idt.c @@ -5,7 +5,6 @@ * idt.c - x86_64 Interrupt Descriptor Table implementation. */ -#include "dev/lapic.h" #if defined(__x86_64__) #include @@ -13,7 +12,8 @@ #include #include #include -#include +#include +#include "arch/x86_64/lapic.h" #include __attribute__((aligned(0x10))) diff --git a/kernel/src/dev/ioapic.c b/kernel/src/arch/x86_64/ioapic.c similarity index 100% rename from kernel/src/dev/ioapic.c rename to kernel/src/arch/x86_64/ioapic.c diff --git a/kernel/src/dev/ioapic.h b/kernel/src/arch/x86_64/ioapic.h similarity index 100% rename from kernel/src/dev/ioapic.h rename to kernel/src/arch/x86_64/ioapic.h diff --git a/kernel/src/dev/lapic.c b/kernel/src/arch/x86_64/lapic.c similarity index 97% rename from kernel/src/dev/lapic.c rename to kernel/src/arch/x86_64/lapic.c index 7e00f78..f1d2bc2 100755 --- a/kernel/src/dev/lapic.c +++ b/kernel/src/arch/x86_64/lapic.c @@ -5,7 +5,7 @@ * lapic.c - Local APIC implementation. */ -#include "dev/lapic.h" +#include "arch/x86_64/lapic.h" #include "arch/x86_64/idt.h" #include "lib/log.h" #include "mm/pmm.h" diff --git a/kernel/src/dev/lapic.h b/kernel/src/arch/x86_64/lapic.h similarity index 100% rename from kernel/src/dev/lapic.h rename to kernel/src/arch/x86_64/lapic.h diff --git a/kernel/src/arch/x86_64/smp.c b/kernel/src/arch/x86_64/smp.c index 50cea7f..7e92c8a 100755 --- a/kernel/src/arch/x86_64/smp.c +++ b/kernel/src/arch/x86_64/smp.c @@ -6,10 +6,6 @@ */ #include "arch/cpu.h" -#include "arch/x86_64/gdt.h" -#include "arch/x86_64/idt.h" -#include "dev/lapic.h" -#include "mm/paging.h" #include #include #include diff --git a/kernel/src/main.c b/kernel/src/main.c index a8345ec..00af298 100755 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -42,8 +42,8 @@ void kmain(void) { acpi_init(); madt_init(); - lapic_init(); - ioapic_init(); + + cpu_init_apic(); cpu_init_smp(); cpu_init_timer(); From 3c09d65774024ee53f1640771ac8b186c4a9d1e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20M?= Date: Mon, 2 Jun 2025 21:06:37 +0200 Subject: [PATCH 30/30] main: remove references to APIC --- kernel/src/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/src/main.c b/kernel/src/main.c index 00af298..9d7b627 100755 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -21,8 +21,6 @@ #include #include #include "arch/x86_64/smp.h" -#include "dev/ioapic.h" -#include "dev/lapic.h" #include "mm/paging.h" #include "mm/vma.h"