diff --git a/README.md b/README.md index 78f8577..f21eb20 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ gdb kernel.elf ## Documentation -Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](DEVELOPERS.md). They are full of useful resources around Blank OS. You'll learn how to use the system and how to contribute to it. +Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](docs/USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](docs/DEVELOPERS.md). They are full of useful resources around Blank OS. You'll learn how to use the system and how to contribute to it. ### Resources diff --git a/DEVELOPERS.md b/docs/DEVELOPERS.md similarity index 100% rename from DEVELOPERS.md rename to docs/DEVELOPERS.md diff --git a/USERS.md b/docs/USERS.md similarity index 100% rename from USERS.md rename to docs/USERS.md diff --git a/link.ld b/link.ld index bc9c8dd..1b9cf99 100644 --- a/link.ld +++ b/link.ld @@ -27,4 +27,6 @@ SECTIONS { *(COMMON) *(.bss) } + + end = .; _end = .; __end = .; } diff --git a/src/kernel/kheap.c b/src/kernel/kheap.c new file mode 100644 index 0000000..439a081 --- /dev/null +++ b/src/kernel/kheap.c @@ -0,0 +1,42 @@ +#include "kheap.h" + +#include "../libc/stdint.h" + +extern uint32_t end; +uint32_t placement_address = (uint32_t)&end; + +uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys) +{ + if (align == 1 && (placement_address & 0x00000FFF)) + { + placement_address &= 0xFFFFF000; + placement_address += 0x1000; + } + if (phys) + { + *phys = placement_address; + } + uint32_t tmp = placement_address; + placement_address += sz; + return tmp; +} + +uint32_t kmalloc_a(uint32_t sz) +{ + return kmalloc_int(sz, 1, 0); +} + +uint32_t kmalloc_p(uint32_t sz, uint32_t *phys) +{ + return kmalloc_int(sz, 0, phys); +} + +uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys) +{ + return kmalloc_int(sz, 1, phys); +} + +uint32_t kmalloc(uint32_t sz) +{ + return kmalloc_int(sz, 0, 0); +} diff --git a/src/kernel/kheap.h b/src/kernel/kheap.h new file mode 100644 index 0000000..7e16d91 --- /dev/null +++ b/src/kernel/kheap.h @@ -0,0 +1,11 @@ +#ifndef KHEAP_H +#define KHEAP_H + +#include "../libc/stdint.h" + +uint32_t kmalloc_a(uint32_t sz); +uint32_t kmalloc_p(uint32_t sz, uint32_t *phys); +uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys); +uint32_t kmalloc(uint32_t sz); + +#endif diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index fdbdc33..38807de 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -3,7 +3,7 @@ #include "gdt.h" #include "idt.h" #include "system.h" -//#include +#include "paging.h" char* ascii_title = "\n" @@ -36,6 +36,12 @@ void kmain(unsigned int multiboot_info_address) colorputs(ascii_title, 10); colorputs(" by @xamidev - star the repo for a cookie!\n\n", 14); + init_paging(); + printf("Hello, paging world!\n"); + + uint32_t *ptr = (uint32_t*)0xA0000000; + uint32_t do_page_fault = *ptr; + timer_install(); serial_printf(2, "%d\tinitialized timer handler", global_ticks); keyboard_install(); diff --git a/src/kernel/paging.c b/src/kernel/paging.c new file mode 100644 index 0000000..c49efa4 --- /dev/null +++ b/src/kernel/paging.c @@ -0,0 +1,150 @@ +#include "../libc/stdint.h" +#include "paging.h" +#include "../libc/stdio.h" +#include "system.h" +#include "kheap.h" + + +uint32_t *frames; +uint32_t nframes; + +extern uint32_t placement_address; + +#define INDEX_FROM_BIT(a) (a/(8*4)) +#define OFFSET_FROM_BIT(a) (a%(8*4)) + +static void set_frame(uint32_t frame_addr) +{ + uint32_t frame = frame_addr/0x1000; + uint32_t idx = INDEX_FROM_BIT(frame); + uint32_t off = OFFSET_FROM_BIT(frame); + frames[idx] |= (0x1 << off); +} + +static void clear_frame(uint32_t frame_addr) +{ + uint32_t frame = frame_addr/0x1000; + uint32_t idx = INDEX_FROM_BIT(frame); + uint32_t off = OFFSET_FROM_BIT(frame); + frames[idx] &= ~(0x1 << off); +} + +/* +static uint32_t test_frame(uint32_t frame_addr) +{ + uint32_t frame = frame_addr/0x1000; + uint32_t idx = INDEX_FROM_BIT(frame); + uint32_t off = OFFSET_FROM_BIT(frame); + return (frames[idx] & (0x1 << off)); +} +*/ + +static uint32_t first_frame() +{ + uint32_t i, j; + for (i=0; iframe != 0) + { + return; + } else { + uint32_t idx = first_frame(); + if (idx == (uint32_t)-1) + { + panic(); + } + set_frame(idx*0x1000); + page->present = 1; + page->rw = (is_writeable)?1:0; + page->user = (is_kernel)?0:1; + page->frame = idx; + } +} + +void free_frame(page_t *page) +{ + uint32_t frame; + if (!(frame=page->frame)) + { + return; + } else { + clear_frame(frame); + page->frame = 0x0; + } +} + +void init_paging() +{ + uint32_t mem_end_page = 0x10000000; + nframes = mem_end_page / 0x1000; + frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes)); + memset(frames, 0, INDEX_FROM_BIT(nframes)); + + page_directory_t* kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t)); + memset(kernel_directory, 0, sizeof(page_directory_t)); + //page_directory_t* current_directory = kernel_directory; + + unsigned int i = 0; + while (i < placement_address) + { + alloc_frame(get_page(i, 1, kernel_directory), 0, 0); + i += 0x1000; + } + + irq_install_handler(14, page_fault); + + switch_page_directory(kernel_directory); +} + +void switch_page_directory(page_directory_t *dir) +{ + //page_directory_t* current_directory = dir; + asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical)); + uint32_t cr0; + asm volatile("mov %%cr0, %0": "=r"(cr0)); + cr0 |= 0x80000000; + asm volatile("mov %0, %%cr0":: "r"(cr0)); +} + +page_t *get_page(uint32_t address, int make, page_directory_t *dir) +{ + address /= 0x1000; + uint32_t table_idx = address / 1024; + if (dir->tables[table_idx]) + { + return &dir->tables[table_idx]->pages[address%1024]; + } else if (make) + { + uint32_t tmp; + dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), &tmp); + memset(dir->tables[table_idx], 0, 0x1000); + dir->tablesPhysical[table_idx] = tmp | 0x7; + return &dir->tables[table_idx]->pages[address%1024]; + } else { + return 0; + } + return 0; +} + +void page_fault() +{ + puts("Page fault"); + panic(); +} diff --git a/src/kernel/paging.h b/src/kernel/paging.h new file mode 100644 index 0000000..ee485ad --- /dev/null +++ b/src/kernel/paging.h @@ -0,0 +1,34 @@ +#ifndef PAGING_H +#define PAGING_H + +#include "system.h" +#include "../libc/stdint.h" +typedef struct +{ + uint32_t present : 1; + uint32_t rw : 1; + uint32_t user : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t unused : 7; + uint32_t frame : 20; +} page_t; + +typedef struct +{ + page_t pages[1024]; +} page_table_t; + +typedef struct +{ + page_table_t *tables[1024]; + uint32_t tablesPhysical[1024]; + uint32_t physicalAsddr; +} page_directory_t; + +void init_paging(); +void switch_page_directory(page_directory_t *new); +page_t *get_page(uint32_t address, int make, page_directory_t *dir); +void page_fault(); + +#endif diff --git a/src/kernel/system.c b/src/kernel/system.c index 9ac43db..78f050e 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -1,4 +1,5 @@ #include "system.h" +#include "../libc/stdint.h" void *memset(void *dest, char val, size_t count) { @@ -6,3 +7,8 @@ void *memset(void *dest, char val, size_t count) for(; count != 0; count--) *temp++ = val; return dest; } + +void panic() +{ + for (;;); +} diff --git a/src/kernel/system.h b/src/kernel/system.h index a2884c3..86749e6 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -1,6 +1,8 @@ #ifndef SYSTEM_H #define SYSTEM_H +#include "../libc/stdint.h" + typedef int size_t; void *memset(void *dest, char val, size_t count); @@ -13,6 +15,7 @@ struct regs unsigned int eip, cs, eflags, useresp, ss; }; +void panic(); void isr_install(); void irq_install(); void irq_install_handler(int irq, void (*handler)(struct regs *r));