I think I fixed a bunch of stuff
This commit is contained in:
parent
2503938fc4
commit
49ce1a2d45
1
Makefile
1
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)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -14,6 +14,6 @@ void panic(const char* msg) {
|
||||
printk(msg);
|
||||
asm("cli");
|
||||
while (1) {
|
||||
asm("hlt");
|
||||
asm volatile("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
16
cpu/idt.c
16
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;
|
||||
/* 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;
|
||||
}
|
||||
// FIXME: check if ptr is mapped and a valid 0-terminated string
|
||||
|
||||
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");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
10
kernel.c
10
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();
|
||||
|
||||
@ -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
|
||||
|
||||
41
kernel/vm.c
41
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;
|
||||
|
||||
24
proc.c
24
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) {
|
||||
|
||||
12
proc.h
12
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();
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user