From 49ce1a2d4579e698b5f850381c440980ac19979b Mon Sep 17 00:00:00 2001 From: Andreew Gregory Date: Mon, 6 Apr 2026 05:20:00 +0300 Subject: [PATCH] I think I fixed a bunch of stuff --- Makefile | 1 + bootmain.c | 2 +- console.c | 2 +- cpu/idt.c | 18 ++++++++++++------ cpu/memlayout.h | 3 ++- drivers/pit.c | 4 ++-- kernel.c | 10 +++------- kernel/kstart.S | 4 ++-- kernel/vm.c | 41 ++++++++++++++++++++++++++--------------- proc.c | 24 ++++++++++++++---------- proc.h | 12 ++++++++++++ syscall.h | 4 +++- user/crt.c | 4 ++-- user/shout.c | 8 ++++++-- 14 files changed, 87 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 18f22ab..e09fd6a 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ CFLAGS = -fno-pic -ffreestanding -static -fno-builtin -fno-strict-aliasing \ -I. \ -Wall -Wno-unused-result -Wno-unused-variable -Wno-unused-but-set-variable -ggdb -m32 -Werror -fno-omit-frame-pointer -Os CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) +CFLAGS += -Wno-unused-variable -Wno-unused-function ASMFLAGS = -m32 -ffreestanding -c -g -I. ifeq ($(LLVM),on) diff --git a/bootmain.c b/bootmain.c index 516b61b..9e936b0 100644 --- a/bootmain.c +++ b/bootmain.c @@ -27,7 +27,7 @@ bootmain(void) void (*entry)(void); uchar* pa; - elf = (Elf32_Ehdr*)0x20000; // scratch space + elf = (Elf32_Ehdr*)0x30000; // scratch space // Read 1st page off disk readseg((uchar*)elf, 4096, 0); diff --git a/console.c b/console.c index 1064b89..e4b53d4 100644 --- a/console.c +++ b/console.c @@ -14,6 +14,6 @@ void panic(const char* msg) { printk(msg); asm("cli"); while (1) { - asm("hlt"); + asm volatile("hlt"); } } diff --git a/cpu/idt.c b/cpu/idt.c index 06669df..e742efd 100644 --- a/cpu/idt.c +++ b/cpu/idt.c @@ -117,11 +117,17 @@ void trap(registers_t *r) { } } -static void* get_userspace_ptr(uint32_t ptr) { - if (ptr > KERNBASE) { - return 0; - } - // FIXME: check if ptr is mapped and a valid 0-terminated string +/* takes a ptr that is supposed to be from userspace. If it is not, we + * return 0, if it is a valid userspace pointer, we return the usable + * kernelspace pointer + */ +uint32_t is_userspace_ptr_mapped(uint32_t ptr) { + // todo: implement + return ptr; +} + +static void* get_userspace_cstr(uint32_t ptr) { + // todo: implement return (void*)(ptr); } @@ -151,7 +157,7 @@ static void handle_syscall(registers_t* r) { r->eax = 0; break; case SYS_puts: - r->eax = handle_puts(get_userspace_ptr(r->ebx)); + r->eax = handle_puts(get_userspace_cstr(r->ebx)); break; default: printk("Unknown syscall\n"); diff --git a/cpu/memlayout.h b/cpu/memlayout.h index 62dfd22..b0cc49a 100644 --- a/cpu/memlayout.h +++ b/cpu/memlayout.h @@ -38,4 +38,5 @@ #define PTE_PCD 0x010 // Cache-Disable #define PTE_A 0x020 // Accessed #define PTE_D 0x040 // Dirty -#define PTE_PS 0x080 // Page Size +// entries of page tables don't have PS +#define PDE_PS 0x080 // Page Size diff --git a/drivers/pit.c b/drivers/pit.c index 7b8edc1..21d44d6 100644 --- a/drivers/pit.c +++ b/drivers/pit.c @@ -62,7 +62,7 @@ void init_pit() { add_timer_callback(dec_sleep_counter); } -static int sleep_counter = 0; +static volatile int sleep_counter = 0; static void dec_sleep_counter(void) { sleep_counter--; @@ -71,6 +71,6 @@ static void dec_sleep_counter(void) { void msleep(int ms) { sleep_counter = ms / 10; while (sleep_counter > 0) { - asm("hlt"); + asm volatile("hlt"); } } diff --git a/kernel.c b/kernel.c index 0a8bbcb..24d3a1f 100644 --- a/kernel.c +++ b/kernel.c @@ -45,10 +45,6 @@ void read_line_input(char* buf, size_t* ret_len, size_t cap) { } else if (keycode == KEYCODE_BACKSPACE) { unsigned scr_offset = vga_get_cursor(); if (len > 0 && scr_offset > 0) { - // if (scr_offset % VGA_COLS) { - // vga_set - // } - // vga_set_char() vga_set_char(scr_offset - 1, ' '); vga_set_cursor(scr_offset - 1); len--; @@ -68,7 +64,7 @@ void read_line_input(char* buf, size_t* ret_len, size_t cap) { } } - asm("hlt"); + asm volatile("hlt"); size_t count = kbd_state_shrd.len; if (count > 0) { cli(); @@ -87,9 +83,9 @@ void read_line_input(char* buf, size_t* ret_len, size_t cap) { void kmain() { - freerange(P2V(2u<<20), P2V(3u<<20)); + freerange(P2V(3u<<20), P2V(4u<<20)); kvmalloc(); // map all of physical memory at KERNBASE - freerange(P2V(3u<<20), P2V(PHYSTOP)); + freerange(P2V(4u<<20), P2V(PHYSTOP)); load_gdt(); init_keyboard(); diff --git a/kernel/kstart.S b/kernel/kstart.S index e1e87b8..609ca8b 100644 --- a/kernel/kstart.S +++ b/kernel/kstart.S @@ -23,11 +23,11 @@ _start: mov cr4, eax // Identity map low 4 MiB - mov dword ptr [0x1000], 0 | PTE_P | PTE_W | PTE_PS + mov dword ptr [0x1000], 0 | PTE_P | PTE_W | PDE_PS // KERNBASE = 0x8000_0000 // Same mapping for the first 4 MiB after KERNBASE - mov dword ptr [0x1000 + ((KERNBASE >> 22) * 4)], 0 | PTE_P | PTE_W | PTE_PS + mov dword ptr [0x1000 + ((KERNBASE >> 22) * 4)], 0 | PTE_P | PTE_W | PDE_PS // Load physical address of PD into CR3 mov edi, 0x1000 diff --git a/kernel/vm.c b/kernel/vm.c index 7ece1ec..77fa8dc 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -12,7 +12,7 @@ pde_t *setupkvm(void) { // Map physical memory to KERNBASE..KERNBASE+PHYSTOP for (uintptr_t pa = 0; pa < PHYSTOP; pa += 4 << 20) { uintptr_t va = KERNBASE + pa; - kvm[PDX(va)] = pa | PTE_P | PTE_W | PTE_PS; + kvm[PDX(va)] = pa | PTE_P | PTE_W | PDE_PS; } return kvm; } @@ -27,6 +27,9 @@ void switchkvm(void) lcr3(V2P(kvm)); // switch to the kernel page table } +/* Before that point we worked with 4Mb kernel space huge pages + * But now we work with 4Kb userspace normal pages */ + // Return the address of the PTE in page table pgdir // that corresponds to virtual address va. If alloc!=0, // create any required page table pages. @@ -38,9 +41,16 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc) pde = &pgdir[PDX(va)]; if (*pde & PTE_P) { + // we get an address from that entry of PgDir + // (that should point to physical memory of a page table), + // then we add KERNBASE, getting a pointer to table + // (which means the first table entry) in kernel virtual memory pgtab = (pte_t *)P2V(PTE_ADDR(*pde)); } else { - if (!alloc || (pgtab = (pte_t *)kalloc()) == 0) + if (!alloc) + return 0; + pgtab = (pte_t *)kalloc(); + if (pgtab == 0) return 0; // Make sure all those PTE_P bits are zero. memset(pgtab, 0, PGSIZE); @@ -53,19 +63,17 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc) } // Create PTEs for virtual addresses starting at va that refer to -// physical addresses starting at pa. va and size might not -// be page-aligned. +// physical addresses starting at pa. +// size might not be page-aligned. static int -mappages(pde_t *pgdir, void *va, uintptr_t size, uintptr_t pa, int perm) -{ - char *a, *last; - pte_t *pte; - - a = (char *)PGROUNDDOWN((uintptr_t)va); - last = (char *)PGROUNDDOWN(((uintptr_t)va) + size - 1); - for (;;) - { - if ((pte = walkpgdir(pgdir, a, 1)) == 0) +mappages(pde_t *pgdir, void *va, uintptr_t size, uintptr_t pa, int perm){ + if ((uintptr_t)va % PGSIZE != 0) + panic("Why??"); + char* a = va; + char* last = (char *)PGROUNDDOWN(((uintptr_t)va) + size - 1); + for (;;){ + pte_t *pte = walkpgdir(pgdir, a, 1); + if (pte == 0) return -1; if (*pte & PTE_P) panic("remap"); @@ -78,8 +86,11 @@ mappages(pde_t *pgdir, void *va, uintptr_t size, uintptr_t pa, int perm) return 0; } +// top may be not page-aligned int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top) { - for (uintptr_t a = PGROUNDUP(base); a < top; a += PGSIZE) { + if (base % PGSIZE != 0) + panic("You should at least consider killing yourself"); + for (uintptr_t a = base; a < top; a += PGSIZE) { char *pa = kalloc(); if (pa == 0) { return -1; diff --git a/proc.c b/proc.c index ecfd065..a8730b8 100644 --- a/proc.c +++ b/proc.c @@ -1,12 +1,4 @@ -#include "elf.h" #include "proc.h" -#include "fs/fs.h" -#include "cpu/gdt.h" -#include "cpu/isr.h" -#include "cpu/memlayout.h" -#include "kernel/mem.h" -#include "lib/string.h" -#include "console.h" struct context { // matches the behavior of swtch() @@ -35,6 +27,10 @@ struct vm { void trapret(); void swtch(void** oldstack, void* newstack); +pde_t *get_user_proc_page_directory() { + return vm.user_task->pgdir; +} + void run_elf(const char* name) { struct stat statbuf; if (stat(name, &statbuf) != 0) { @@ -45,9 +41,17 @@ void run_elf(const char* name) { if (!vm.user_task) { vm.user_task = kalloc(); } + // todo: this code contains 9999 memory leaks but I don't care + // todo: yabloko is fucking shit made my monkeys, I want to forget this fucking nightmare vm.user_task->pgdir = setupkvm(); - allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size); - allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE, USER_STACK_BASE); + if (allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size)) { + printk("Fail: out of memory\n"); + return; + } + if (allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE, USER_STACK_BASE)) { + printk("Fail: out of memory\n"); + return; + } switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom, vm.user_task->pgdir); if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) { diff --git a/proc.h b/proc.h index 54ede88..f4acc84 100644 --- a/proc.h +++ b/proc.h @@ -1,4 +1,16 @@ #pragma once +#include "elf.h" +#include "fs/fs.h" +#include "cpu/gdt.h" +#include "cpu/isr.h" +#include "cpu/memlayout.h" +#include "kernel/mem.h" +#include "lib/string.h" +#include "console.h" + + +pde_t* get_user_proc_page_directory(); + void run_elf(const char* name); _Noreturn void killproc(); diff --git a/syscall.h b/syscall.h index 7973ecb..368bb69 100644 --- a/syscall.h +++ b/syscall.h @@ -1,5 +1,7 @@ #pragma once +#include + enum { T_SYSCALL = 0x84, SYS_exit = 0, @@ -8,4 +10,4 @@ enum { SYS_puts = 3, }; -int syscall(int call, int arg); +int syscall(int call, uintptr_t arg); diff --git a/user/crt.c b/user/crt.c index 5032810..2da5a33 100644 --- a/user/crt.c +++ b/user/crt.c @@ -2,8 +2,8 @@ int main(); -int syscall(int call, int arg) { - asm("int $0x84": "+a"(call) : "b"(arg)); +int syscall(int call, uintptr_t arg) { + asm volatile("int $0x84": "+a"(call) : "b"(arg)); return call; } diff --git a/user/shout.c b/user/shout.c index 4f77e42..c9a90f4 100644 --- a/user/shout.c +++ b/user/shout.c @@ -10,7 +10,11 @@ void userspace_puts(const char* s) { int main() { const char* spell = "cra cra trif traf not sgnieflet\n"; - userspace_puts(spell); - syscall(SYS_puts, (uint32_t)spell); + const char* spell2 = "Pam pam pam pam parapapapapam\n"; + const char* spell3 = "Zhopu podotri\n"; + // userspace_puts(spell); + syscall(SYS_puts, (uintptr_t)spell); + syscall(SYS_puts, (uint32_t)spell2); + syscall(SYS_puts, (uint32_t)spell3); return 0; }