diff --git a/.env b/.env index 972c2e5..c3ca14b 100644 --- a/.env +++ b/.env @@ -5,7 +5,7 @@ LD = $(ARCH)-$(FORMAT)-ld AS = nasm AR = ar -CFLAGS = -ffreestanding -m32 -O2 -Wall -Wextra -pedantic # -DKERNEL_LOG -LDFLAGS = -nostdlib +CFLAGS = -ffreestanding -m32 -O2 -Wall -Wextra -pedantic +LDFLAGS = -nostdlib -export-dynamic QEMU = qemu-system-i386 diff --git a/kernel/arch/i686/linker.ld b/kernel/arch/i686/linker.ld index ae48afb..abf70cc 100644 --- a/kernel/arch/i686/linker.ld +++ b/kernel/arch/i686/linker.ld @@ -7,9 +7,9 @@ SECTIONS { kernel_start = .; .bootstrap : { - *(.bootstrap.data) - *(.bootstrap.stack) *(.bootstrap.text) + *(.bootstrap.data) + *(.bootstrap.bss) } . += 0xC0000000; @@ -30,7 +30,6 @@ SECTIONS { { *(COMMON) *(.bss) - *(.stack) } kernel_end = .; diff --git a/kernel/include/sys.h b/kernel/include/arch.h similarity index 93% rename from kernel/include/sys.h rename to kernel/include/arch.h index 003f85c..eb233f0 100644 --- a/kernel/include/sys.h +++ b/kernel/include/arch.h @@ -1,5 +1,7 @@ #pragma once +#include + extern void arch_init(void *boot_info); extern void arch_update(void); extern void arch_halt(void); diff --git a/kernel/include/arch/i686/acpi.h b/kernel/include/arch/i686/acpi.h index bb35010..47bcc88 100644 --- a/kernel/include/arch/i686/acpi.h +++ b/kernel/include/arch/i686/acpi.h @@ -102,5 +102,5 @@ struct FixedACPIDescriptionTable { struct GenericAddressStructure x_gpe1_block; }; -void acpi_init(void *rsdp); -void acpi_poweroff(void); +extern void acpi_init(void); +extern void acpi_poweroff(void); diff --git a/kernel/include/arch/i686/mboot.h b/kernel/include/arch/i686/mboot.h index 394071f..2ebc983 100644 --- a/kernel/include/arch/i686/mboot.h +++ b/kernel/include/arch/i686/mboot.h @@ -12,7 +12,7 @@ struct BootTag { uint32_t type; uint32_t size; union { - char cmdline[CMDLINE_MAX]; + char cmdline[CMDLINE_MAX + 1]; struct MemoryMap *memory_map; struct RootSystemDescriptionPointer *rsdp; } data; @@ -26,9 +26,9 @@ struct BootInfo { enum BootTagID { ID_CMDLINE = 0, - iD_MEMORYMAP = 6, + ID_MEMORYMAP = 6, ID_RSDP = 14 }; -void load_boot_info(void* boot_info); -bool get_boot_tag(enum BootTagID id, struct BootTag **tag); +extern void load_boot_info(void* boot_info); +extern bool get_boot_tag(enum BootTagID id, struct BootTag **tag); diff --git a/kernel/include/arch/i686/paging.h b/kernel/include/arch/i686/paging.h new file mode 100644 index 0000000..3c0c335 --- /dev/null +++ b/kernel/include/arch/i686/paging.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +struct page_directory_t { // 32 bits + unsigned int present : 1; + unsigned int rw_flag : 1; + unsigned int access_lvl : 1; //0 is for only ring0. 1 is for anybody. + unsigned int write_through : 1; + unsigned int cache_off : 1; + unsigned int accessed : 1; + unsigned int zero : 1; + unsigned int page_size : 1; + unsigned int unused : 4; + unsigned int tbl_addr : 20; +}; + +struct page_table_t { // 32 bits + unsigned int present : 1; + unsigned int rw_flag : 1; + unsigned int access_lvl : 1; //0 is for only ring0. 1 is for anybody. + unsigned int write_through : 1; + unsigned int cache_off : 1; + unsigned int accessed : 1; + unsigned int dirty : 1; + unsigned int zero : 1; + unsigned int global : 1; + unsigned int reserved : 3; + unsigned int phys_addr : 20; +}; + +extern void ident_map_addr(void *addr, size_t len); +extern void ident_unmap_addr(void *addr, size_t len); diff --git a/kernel/include/drivers/vga.h b/kernel/include/drivers/vga.h index 68e8690..6b3b796 100644 --- a/kernel/include/drivers/vga.h +++ b/kernel/include/drivers/vga.h @@ -27,6 +27,7 @@ enum vga_color { void vgatext_write_char(char c, enum vga_color color, uint8_t x, uint8_t y); void vgatext_write_data(uint16_t data, uint16_t index); void vgatext_write_buf(const uint16_t *buffer); + void vgatext_cur_mov(uint8_t x, uint8_t y); void vgatext_cur_resize(uint8_t start, uint8_t end); void vgatext_cur_visible(bool visible); diff --git a/kernel/include/memory.h b/kernel/include/memory.h index 07a55c0..db8b761 100644 --- a/kernel/include/memory.h +++ b/kernel/include/memory.h @@ -1,6 +1,13 @@ #pragma once +#include + extern int memory_lock(void); extern int memory_unlock(void); extern void *memory_alloc_page(int); extern int memory_free_page(void* ,int); + +extern void *malloc(size_t size); +extern void free(void *ptr); +extern void *calloc(size_t nobj, size_t size); +extern void *realloc(void *p, size_t size); diff --git a/kernel/include/time.h b/kernel/include/time.h index 2e86a69..7cf0aa0 100644 --- a/kernel/include/time.h +++ b/kernel/include/time.h @@ -36,6 +36,11 @@ extern struct Time get_utctime(void); */ extern struct Time get_localtime(void); +/** + * Return the time on the system clock + */ +extern size_t get_systemtime(void); + /** * Converts the time into a string format * @param time the current time diff --git a/kernel/src/arch/i686/acpi.c b/kernel/src/arch/i686/acpi.c index 7807558..17155ce 100644 --- a/kernel/src/arch/i686/acpi.c +++ b/kernel/src/arch/i686/acpi.c @@ -1,3 +1,5 @@ +#include "arch/i686/mboot.h" +#include "arch/i686/paging.h" #include #include #include @@ -73,20 +75,25 @@ static void read_s5_addr(void) { } } -void acpi_init(void *ptr) { - - struct RootSystemDescriptionPointer *rsdp = ptr; +void acpi_init(void) { + struct BootTag *tag; + if (!get_boot_tag(ID_RSDP, &tag)) { + panic("Could not find RSDP"); + } + struct RootSystemDescriptionPointer *rsdp = tag->data.rsdp; if (!checksum((uint8_t*) rsdp, sizeof(struct RootSystemDescriptionPointer))) { panic("RSDP checksum failed to validate"); } - uintptr_t rsdt_ptr = rsdp->rsdt_address; rsdt = (void *) rsdt_ptr; + ident_map_addr(rsdt, 1000); if (!checksum((uint8_t*) &rsdt->header, rsdt->header.length)) { panic("RSDT checksum failed to validate"); } - + return; + fadt = find_fadt(); + if (fadt == NULL) { panic("Could not find FADT"); } @@ -98,6 +105,7 @@ void acpi_init(void *ptr) { read_s5_addr(); outb(fadt->smi_command_port,fadt->acpi_enable); + panic("C"); } void acpi_poweroff(void) { diff --git a/kernel/src/arch/i686/sys.c b/kernel/src/arch/i686/arch.c similarity index 88% rename from kernel/src/arch/i686/sys.c rename to kernel/src/arch/i686/arch.c index 209fea4..5cabdf8 100644 --- a/kernel/src/arch/i686/sys.c +++ b/kernel/src/arch/i686/arch.c @@ -1,4 +1,5 @@ -#include +#include "print.h" +#include #include #include #include @@ -14,9 +15,7 @@ void arch_init(void *boot_info) { pic_remap(); load_boot_info(boot_info); - - /* havent refactored to work with paging yet */ - // acpi_init(); + acpi_init(); // memory_init(); ps2ctrl_init(); diff --git a/kernel/src/arch/i686/drivers/rtc.c b/kernel/src/arch/i686/drivers/rtc.c index ba69d15..5f21f0a 100644 --- a/kernel/src/arch/i686/drivers/rtc.c +++ b/kernel/src/arch/i686/drivers/rtc.c @@ -1,6 +1,6 @@ #include "time.h" #include -#include +#include #include #include @@ -55,10 +55,9 @@ static void update_localtime(void) { localtime = time; // if tz is UTC, we dont need to do anythin - if (last_timezone == UTC) { - cur_localtime = localtime; - return; - } + if (last_timezone == UTC) return; + + localtime.hour += last_timezone; // check if day rolled over change = localtime.hour < 0 ? -1 : localtime.hour >= 24 ? 1 : 0; @@ -109,8 +108,6 @@ year: localtime.year -= 1900; - cur_localtime = localtime; - } void rtc_update(void) { @@ -137,6 +134,7 @@ void rtc_update(void) { update_localtime(); cur_time = time; + cur_localtime = localtime; } struct Time rtc_utctime(void) { @@ -147,6 +145,7 @@ struct Time rtc_localtime(enum Timezone tz) { if (tz != last_timezone) { last_timezone = tz; update_localtime(); + cur_localtime = localtime; } return cur_localtime; } diff --git a/kernel/src/arch/i686/drivers/vga.c b/kernel/src/arch/i686/drivers/vga.c index a41ce54..dcf6ceb 100644 --- a/kernel/src/arch/i686/drivers/vga.c +++ b/kernel/src/arch/i686/drivers/vga.c @@ -21,7 +21,7 @@ void vgatext_write_buf(const uint16_t *src) { } void vgatext_cur_mov(uint8_t x, uint8_t y) { -; const uint16_t pos = y * VGA_TEXT_W + x; + const uint16_t pos = y * VGA_TEXT_W + x; outb(0x3D4, 0x0F); outb(0x3D5, (uint8_t) (pos & 0xFF)); diff --git a/kernel/src/arch/i686/idt.c b/kernel/src/arch/i686/idt.c index 04fd5f8..3ec32b0 100644 --- a/kernel/src/arch/i686/idt.c +++ b/kernel/src/arch/i686/idt.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -10,8 +10,7 @@ #include #include #include - -#include "tty/term.h" +#include struct IdtEntry { uint16_t isr_low; @@ -41,31 +40,18 @@ enum IDTFlags { IDT_FLAG_PRESENT = 0x80, }; -#define WIDTH 30 -static char buf[WIDTH]; -static int timer = -1; +static size_t timer = 0; void idt_pic_eoi(uint8_t exception) { pic_eoi(exception - PIC_REMAP_OFFSET); } void idt_pic_timer(void) { - timer += 1; - if (timer % 20 != 0) return; +} - uint32_t state = term_save(); - - term_setfg(VGA_LIGHT_GREEN); - term_setpos(TERM_W - WIDTH - 1, 0); - for (size_t i = 0; i < WIDTH; i++) putchar(' '); - term_setpos(TERM_W - WIDTH - 1, 0); - - struct Time t = get_localtime(); - timetostr(&t, "%a %b %d %Y %H:%M:%S", buf, WIDTH); - printk("%s", buf); - - term_load(state); +size_t get_systemtime(void) { + return timer; } void idt_pic_keyboard(void) { diff --git a/kernel/src/arch/i686/mboot.c b/kernel/src/arch/i686/mboot.c index 108812f..9cb8c16 100644 --- a/kernel/src/arch/i686/mboot.c +++ b/kernel/src/arch/i686/mboot.c @@ -1,3 +1,4 @@ +#include "print.h" #include #include #include @@ -11,12 +12,13 @@ static void read_cmdline(struct BootTag *tag, char *data, uint8_t len) { panic("multiboot2 cmd line to long\nmax is %d but was provided %d\n", CMDLINE_MAX, len); memcpy(tag->data.cmdline, data, len); + tag->data.cmdline[len] = '\0'; info.tags[ID_CMDLINE] = *tag; } static void read_memorymap(struct BootTag *tag, uint32_t *data) { tag->data.memory_map = (struct MemoryMap *) data; - info.tags[iD_MEMORYMAP] = *tag; + info.tags[ID_MEMORYMAP] = *tag; } static void read_rsdp(struct BootTag *tag, char *data) { @@ -36,7 +38,7 @@ static uint32_t *read_tag(uint32_t *data) { case ID_CMDLINE: read_cmdline(&tag, (char *)(data + 2), data_len); break; - case iD_MEMORYMAP: + case ID_MEMORYMAP: read_memorymap(&tag, data + 2); break; case ID_RSDP: diff --git a/kernel/src/arch/i686/memory.c b/kernel/src/arch/i686/memory.c index 29f1f56..ec4c43c 100644 --- a/kernel/src/arch/i686/memory.c +++ b/kernel/src/arch/i686/memory.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -126,7 +126,7 @@ void memory_init(void) { kernel_end_addr = (uintptr_t) &kernel_end; struct BootTag *tag; - if (!get_boot_tag(iD_MEMORYMAP, &tag)) { + if (!get_boot_tag(ID_MEMORYMAP, &tag)) { panic("No multiboot memory map found"); } diff --git a/kernel/src/arch/i686/paging.asm b/kernel/src/arch/i686/paging.asm index f74cc55..0e0a87f 100644 --- a/kernel/src/arch/i686/paging.asm +++ b/kernel/src/arch/i686/paging.asm @@ -1,17 +1,20 @@ global page_directory +global page_tables global paging_init global paging_finish global KERNEL_MAPPING -KERNEL_MAPPING equ 0xC0000000 -VGABUF equ 0x000B8000 +KERNEL_MAPPING equ 0xC0000000 +VGABUF equ 0x000B8000 + +%define mapped(addr) addr - KERNEL_MAPPING section .bss align 4096 page_directory: -resb 4096 -page_table1: -resb 4096 +resb 1024 * 4 +page_tables: +resb 1024 * 1024 * 4 section .bootstrap.text align 8 @@ -20,14 +23,14 @@ paging_init: extern kernel_end paging_load: - mov edi, page_table1 - KERNEL_MAPPING + mov edi, mapped(page_tables) mov esi, 0 mov ecx, 1023 paging_cmp: cmp esi, kernel_start jl paging_add - cmp esi, kernel_end - KERNEL_MAPPING + cmp esi, mapped(kernel_end) jge paging_map mov edx, esi @@ -40,13 +43,27 @@ paging_add: loop paging_cmp paging_map: - mov dword [page_table1 - KERNEL_MAPPING + 1023 * 4], VGABUF | 0x003 - mov dword [page_directory - KERNEL_MAPPING + 0], page_table1 - KERNEL_MAPPING + 0x003 - mov dword [page_directory - KERNEL_MAPPING + 768 * 4], page_table1 - KERNEL_MAPPING + 0x003 - mov ecx, page_directory - KERNEL_MAPPING + lea eax, mapped(page_directory) + push eax + extern setup_pgdir + call mapped(setup_pgdir) + add esp, 0x04 + + ; map VGA buffer + mov dword [mapped(page_tables) + 1023 * 4], VGABUF + 0x003 + + ; map 8MB for the kernel + mov dword [mapped(page_directory) + 0 * 4], mapped(page_tables) + 0x003 + mov dword [mapped(page_directory) + 1 * 4], mapped(page_tables) + 0x400000000 + 0x003 + mov dword [mapped(page_directory) + 768 * 4], mapped(page_tables) + 0x003 + mov dword [mapped(page_directory) + 769 * 4], mapped(page_tables) + 0x400000000 + 0x003 + + ; tell the MMU where the page dir is + mov ecx, mapped(page_directory) mov cr3, ecx + ; finally init paging mov ecx, cr0 or ecx, 0x80010000 mov cr0, ecx @@ -56,7 +73,9 @@ paging_map: section .text align 8 paging_finish: - mov dword [page_directory], 0 + ; remove the 8MB ident mapping + mov dword [page_directory + 0 * 4], 0 + mov dword [page_directory + 1 * 4], 0 mov ecx, cr3 mov cr3, ecx ret diff --git a/kernel/src/arch/i686/paging.c b/kernel/src/arch/i686/paging.c new file mode 100644 index 0000000..b0fd4ca --- /dev/null +++ b/kernel/src/arch/i686/paging.c @@ -0,0 +1,71 @@ +#include "panic.h" +#include "arch.h" +#include +#include +#include +#include +#include + +extern struct page_directory_t page_directory[1024]; +extern struct page_table_t page_tables[1024][1024]; +// static uintptr_t KERNEL_MAPPING = 0xC0000000; + +void setup_pgdir(struct page_directory_t pgdir[1024]) { + for(int i = 0; i < 1024; i++) { + pgdir[i].present = 0; + pgdir[i].rw_flag = 1; + pgdir[i].access_lvl = 0; + } +} + +void paging_ident(struct page_table_t tbl[1024]) { + size_t size = 1024; + for(size_t i = 0; i < size; i++) { + tbl[i].rw_flag = 1; + tbl[i].access_lvl = 0; + tbl[i].phys_addr = i; + tbl[i].present = 1; + } +} + +void map_page(struct page_table_t tbl[1024], void *addr) { + uintptr_t ptr = (uintptr_t) addr; + ptr &= 0xfffff000; + ptr >>= 16; + for(size_t i = 0; i < 4096; i++) { + tbl[i].rw_flag = 1; + tbl[i].access_lvl = 0; + tbl[i].phys_addr = ptr / 4096 + i; + tbl[i].present = 1; + } +} + +void unmap_page(struct page_table_t tbl[1024]) { + for(size_t i = 0; i < 4096; i++) { + tbl[i].rw_flag = 1; + tbl[i].access_lvl = 0; + tbl[i].phys_addr = 0; + tbl[i].present = 0; + } +} + +void ident_map_addr(void *addr, size_t len) { + uintptr_t ptr = (uintptr_t) addr; + int i = ptr / 0x400000; + // int c = len / 0x1000 + (len % 0x1000 ? 1 : 0); + // for (; c > 0; c--, i++) { + // paging_ident(page_tables[i]); + // } + paging_ident(page_tables[i]); +} + +void ident_unmap_addr(void *addr, size_t len) { + uintptr_t ptr = (uintptr_t) addr; + int i = ptr / 0x1000; + int c = len / 0x1000 + (len % 0x1000 ? 1 : 0); + for (; c > 0; c--, i++) { + page_tables[i / 1024][i % 1024].present = 0; + page_tables[i / 1024][i % 1024].rw_flag = 1; + page_tables[i / 1024][i % 1024].access_lvl = 0; + } +} diff --git a/kernel/src/arch/i686/pic.c b/kernel/src/arch/i686/pic.c index f5d0f94..223586c 100644 --- a/kernel/src/arch/i686/pic.c +++ b/kernel/src/arch/i686/pic.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/kernel/src/arch/i686/start.asm b/kernel/src/arch/i686/start.asm index 2151b51..98b59be 100644 --- a/kernel/src/arch/i686/start.asm +++ b/kernel/src/arch/i686/start.asm @@ -1,7 +1,6 @@ global start bits 32 - ; create the multiboot header section .bootstrap.data align 8 @@ -17,7 +16,7 @@ mb_end: ; create the stack for bootstrapping -section .bootstrap.stack +section .bootstrap.bss align 16 bootstrap_stack_start: resb 1024 ; 1 KiB @@ -25,7 +24,7 @@ bootstrap_stack_end: ; create the stack for the kernel -section .stack +section .bss align 16 stack_start: resb 16384 ; 16 KiB @@ -46,6 +45,7 @@ start: jmp near load_kernel + ; initalize kernel after it has been loaded in higher half section .text align 8 @@ -53,7 +53,7 @@ load_kernel: ; init stack mov esp, stack_end mov ebp, stack_end - + ; load global descripter table extern load_gdt call load_gdt @@ -64,14 +64,12 @@ load_kernel: ; initalize the FPU finit - - ; push multiboot header - extern KERNEL_MAPPING - add ebx, KERNEL_MAPPING - push ebx ; start kernel sti + extern KERNEL_MAPPING + add ebx, KERNEL_MAPPING + push ebx call kernel_main extern kernel_main diff --git a/kernel/src/main.c b/kernel/src/main.c index 33e4cea..674d2c1 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -3,12 +3,15 @@ #include #include #include -#include +#include +#include #include #include #include #include +#define WIDTH 30 +static char buf[WIDTH]; static double x = 0, y = 0; void kernel_main(void *boot_info) { @@ -23,7 +26,6 @@ void kernel_main(void *boot_info) { while(1) { arch_wait_int(); - arch_update(); struct Keycode code = ps2kb_get(); if(code.key != KEY_NONE) { @@ -52,6 +54,20 @@ void kernel_main(void *boot_info) { printk(" x%d y%d\n", (int)x, (int)y); } + uint32_t state = term_save(); + + term_setfg(VGA_LIGHT_GREEN); + term_setpos(TERM_W - WIDTH - 1, 0); + for (size_t i = 0; i < WIDTH; i++) putchar(' '); + term_setpos(TERM_W - WIDTH - 1, 0); + + struct Time t = get_localtime(); + timetostr(&t, "%a %b %d %Y %H:%M:%S", buf, WIDTH); + printk("%s", buf); + + term_load(state); + + arch_update(); term_flush(); } } diff --git a/kernel/src/memory.c b/kernel/src/memory.c index e8d864b..57fdd68 100644 --- a/kernel/src/memory.c +++ b/kernel/src/memory.c @@ -26,7 +26,7 @@ struct boundary_tag { #define MODE MODE_BEST -struct boundary_tag* l_freePages[MAXEXP]; +struct boundary_tag *l_freePages[MAXEXP]; int l_completePages[MAXEXP]; static int l_initialized = 0; @@ -79,7 +79,7 @@ static inline void remove_tag(struct boundary_tag *tag) { tag->index = -1; } -static inline struct boundary_tag* melt_left(struct boundary_tag *tag) { +static inline struct boundary_tag *melt_left(struct boundary_tag *tag) { struct boundary_tag *left = tag->split_left; left->real_size += tag->real_size; @@ -91,7 +91,7 @@ static inline struct boundary_tag* melt_left(struct boundary_tag *tag) { } -static inline struct boundary_tag* absorb_right(struct boundary_tag *tag) { +static inline struct boundary_tag *absorb_right(struct boundary_tag *tag) { struct boundary_tag *right = tag->split_right; remove_tag(right); @@ -105,7 +105,7 @@ static inline struct boundary_tag* absorb_right(struct boundary_tag *tag) { return tag; } -static inline struct boundary_tag* split_tag(struct boundary_tag* tag) { +static inline struct boundary_tag *split_tag(struct boundary_tag *tag) { unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size; struct boundary_tag *new_tag = @@ -130,7 +130,7 @@ static inline struct boundary_tag* split_tag(struct boundary_tag* tag) { return new_tag; } -static struct boundary_tag* allocate_new_tag(unsigned int size) { +static struct boundary_tag *allocate_new_tag(unsigned int size) { unsigned int pages; unsigned int usage; struct boundary_tag *tag; @@ -268,7 +268,7 @@ void free(void *ptr) { memory_unlock(); } -void* calloc(size_t nobj, size_t size) { +void *calloc(size_t nobj, size_t size) { int real_size; void *p; @@ -281,7 +281,7 @@ void* calloc(size_t nobj, size_t size) { return p; } -void* realloc(void *p, size_t size) { +void *realloc(void *p, size_t size) { void *ptr; struct boundary_tag *tag; size_t real_size; diff --git a/kernel/src/panic.c b/kernel/src/panic.c index 96ad3b9..9aa1b73 100644 --- a/kernel/src/panic.c +++ b/kernel/src/panic.c @@ -1,10 +1,15 @@ -#include +#include #include #include #include #include #include +struct stackframe { + struct stackframe* ebp; + uint32_t eip; +}; + __attribute__((noreturn)) void _panic_impl(char* msg, int line, char* file, ...) { arch_disable_int(); diff --git a/kernel/src/term.c b/kernel/src/term.c index 4b42a6a..9f4dc8f 100644 --- a/kernel/src/term.c +++ b/kernel/src/term.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include "drivers/vga.h"