Sun, 31 Dec 2017 14:05:33 +0100
14 files changed,
162 insertions(+),
32 deletions(-)
M
kernel/os_interrupts.c
→
kernel/os_interrupts.c
@@ -1,5 +1,5 @@
#include "os_interrupts.h" -#include "os_text.h" +#include "driv_text.h" #define HARDWARE_INTERRUPT (0b10001110) #define SYSCALL_INTERRUPT (0b11101110)
M
kernel/os_keyboard.c
→
kernel/driv_keyboard.c
@@ -1,6 +1,6 @@
-#include "os_keyboard.h" +#include "driv_keyboard.h" #include "os_interrupts.h" -#include "os_pic.h" +#include "driv_pic.h" #include "assembly.h"
M
kernel/os_main.c
→
kernel/os_main.c
@@ -1,6 +1,7 @@
-#include "os_text.h" +#include "driv_text.h" #include "os_interrupts.h" -#include "os_pic.h" +#include "driv_pic.h" +#include "os_scheduler.h" int os_init(void) { pic_init();@@ -14,6 +15,8 @@ int os_main(void) {
const char* string[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; text_write("Hallo! :)"); + + sched_exec(); return 0; }
M
kernel/os_paging.c
→
kernel/os_paging.c
@@ -1,8 +1,9 @@
#include "os_paging.h" #include "linker.h" #include "os_page_allocator.h" +#include "os_string.h" -//#define MAKE_PAGE_ENTRY(addr, flags) (uint32_t)(((uint32_t)(addr) & 0xFFFFF000) | (flags)) +#define MAKE_PAGE_ENTRY(addr, flags) (uint32_t)(((uint32_t)(addr) & 0xFFFFF000) | (flags)) #define PAGE_DIRECTORY (PAGE_DIR_ENTRY[PAGE_ENTRY_COUNT]) #define PAGE_TABLE (PAGE_TABLE_ENTRY[PAGE_ENTRY_COUNT])@@ -10,35 +11,96 @@
#define PAGE_DIR_INDEX(addr) (((uint32_t)(addr) >> 22) % PAGE_ENTRY_COUNT) #define PAGE_TABLE_INDEX(addr) (((uint32_t)(addr) >> 12) % PAGE_ENTRY_COUNT) -#define PAGE_TABLE_MAPPED_ADDR(index) ((PAGE_TABLE_ENTRY*)(PAGE_SIZE * PAGE_ENTRY_COUNT * (PAGE_ENTRY_COUNT - 1) + PAGE_SIZE * index)) -#define PAGE_DIR_MAPPED_ADDR ((PAGE_DIR_ENTRY*)(PAGE_TABLE_MAPPED_ADDR(PAGE_ENTRY_COUNT - 1))) +#define PAGE_MAPPED_ADDR(dir_index, table_index) (void*)((dir_index * PAGE_ENTRY_COUNT + table_index) * PAGE_SIZE) -/* -int map_page_to(void* page_addr, uint32_t dir_index, uint32_t table_index) { - PAGE_DIR_ENTRY* page_dir = PAGE_DIR_MAPPED_ADDR; +#define PAGE_TABLE_MAPPED_ADDR(index) \ + ((PAGE_TABLE_ENTRY*)(PAGE_MAPPED_ADDR((PAGE_ENTRY_COUNT - 1), index))) +#define PAGE_DIR_MAPPED_ADDR \ + ((PAGE_DIR_ENTRY*)(PAGE_TABLE_MAPPED_ADDR(PAGE_ENTRY_COUNT - 1))) - if (!(page_dir[dir_index].present)) { - #warning implement this - // acquire new page table +#define PAGE_TABLE_ALT_MAPPED_ADDR(index) \ + ((PAGE_TABLE_ENTRY*)(PAGE_MAPPED_ADDR((PAGE_ENTRY_COUNT - 2), index))) +#define PAGE_DIR_ALT_MAPPED_ADDR \ + ((PAGE_DIR_ENTRY*)(PAGE_TABLE_ALT_MAPPED_ADDR(PAGE_ENTRY_COUNT - 1))) + +#define PAGE_TABLE_FLAGS 0b000000000011 + +/*! +* WARNING: This method assumes the target page directory has already been mounted +* to the second to last page directory entry +*/ +inline int is_addr_available(uint32_t dir_index, uint32_t table_index) { + PAGE_DIR_ENTRY* page_dir = PAGE_DIR_ALT_MAPPED_ADDR; + PAGE_TABLE_ENTRY* page_table = PAGE_TABLE_ALT_MAPPED_ADDR(table_index); + + if(!(page_dir[dir_index].fields.present)) { + return 1; + } else if (!(page_table[table_index].fields.present)) { + return 1; + } else { + return 0; } +} - PAGE_TABLE_ENTRY* page_table = PAGE_TABLE_MAPPED_ADDR(dir_index); +/*! +* WARNING: This method assumes the target page directory has already been mounted +* to the second to last page directory entry +*/ +int map_page_to(PHYS_ADDR page_addr, uint32_t dir_index, uint32_t table_index, uint32_t flags) { + PAGE_DIR_ENTRY* page_dir = PAGE_DIR_ALT_MAPPED_ADDR; + PAGE_TABLE_ENTRY* page_table = PAGE_TABLE_ALT_MAPPED_ADDR(dir_index); + + int tmp = 0; - if (!(page_table[table_index].present)) { - #warning implement this + if (!(page_dir[dir_index].fields.present)) { + // acquire new page table + void *new_page_table = get_free_page(); + page_dir[dir_index].entry = MAKE_PAGE_ENTRY(new_page_table, PAGE_TABLE_FLAGS); + } + + if (!(page_table[table_index].fields.present)) { // map page + page_table[table_index].entry = MAKE_PAGE_ENTRY(page_addr, flags); + return 1; } else { // didn't works - return -1; + return 0; } } -void* map_first_free(void* page_dir, void* search_start, void* page) { +int map_range_to(PHYS_ADDR page_dir, VIRT_ADDR dest, PHYS_ADDR src, uint32_t page_count, uint32_t flags) { + mount_page_dir(page_dir); + + + for (uint32_t i = 0; i < page_count; i++) { + uint32_t dir_index = PAGE_DIR_INDEX(dest + i * PAGE_SIZE); + uint32_t table_index = PAGE_TABLE_INDEX(dest + i * PAGE_SIZE); + + if (!(is_addr_available(dir_index, table_index))) { return 0; } + } + + for (uint32_t i = 0; i < page_count; i++) { + uint32_t dir_index = PAGE_DIR_INDEX(dest + i * PAGE_SIZE); + uint32_t table_index = PAGE_TABLE_INDEX(dest + i * PAGE_SIZE); + + map_page_to(src + i * PAGE_SIZE, dir_index, table_index, flags); + } +} + +void mount_page_dir(PHYS_ADDR page_dir) { + PAGE_DIR_ENTRY *cur_page_dir = PAGE_DIR_MAPPED_ADDR; + cur_page_dir[PAGE_ENTRY_COUNT - 2].entry = MAKE_PAGE_ENTRY(page_dir, PAGE_TABLE_FLAGS); +} + +VIRT_ADDR map_first_free(PHYS_ADDR page_dir, VIRT_ADDR search_start, PHYS_ADDR page, uint32_t flags) { + mount_page_dir(page_dir); uint32_t table_start_i = PAGE_TABLE_INDEX(search_start); - for (uint32_t dir_i = PAGE_DIR_INDEX(search_start); dir_i < (PAGE_ENTRY_COUNT - 1); dir_i++) { - for (uint32_t table_i = table_start_i; table_i < (PAGE_ENTRY_COUNT - 1); table_i++) { - if (map_page_to(page, )) + for (uint32_t dir_i = PAGE_DIR_INDEX(search_start); dir_i < (PAGE_ENTRY_COUNT - 2); dir_i++) { + for (uint32_t table_i = table_start_i; table_i < PAGE_ENTRY_COUNT; table_i++) { + if (map_page_to(page, dir_i, table_i, flags)) { + return PAGE_MAPPED_ADDR(dir_i, table_i); + } } table_start_i = 0;@@ -47,8 +109,21 @@
return 0; } -void* create_empty_page_dir(void) { - return 0; - #warning IMPLEMENT STH. -} -*/+PHYS_ADDR create_empty_page_dir(void) { + PHYS_ADDR page_dir_phys = get_free_page(); + mount_page_dir(page_dir_phys); + PAGE_DIR_ENTRY *page_dir = (VIRT_ADDR)0xffffe000; //PAGE_MAPPED_ADDR(PAGE_ENTRY_COUNT - 1, PAGE_ENTRY_CPAGE_MAPPED_ADDR(PAGE_ENTRY_COUNT - 1, PAGE_ENTRY_COUNT - 2)OUNT - 2); + inv_all_pages(); + + memset(page_dir, 0, PAGE_SIZE); + + // map to itself + page_dir[PAGE_ENTRY_COUNT - 1].entry = MAKE_PAGE_ENTRY(page_dir_phys, PAGE_TABLE_FLAGS); + + page_dir = PAGE_DIR_ALT_MAPPED_ADDR; + + // map kernel + page_dir[PAGE_DIR_INDEX(0xc0000000)].entry = PAGE_DIR_MAPPED_ADDR[PAGE_DIR_INDEX(0xc0000000)].entry; + + return page_dir_phys; +}
M
kernel/os_paging.h
→
kernel/os_paging.h
@@ -13,6 +13,9 @@
//! Size of a single page or page table/directory. #define PAGE_SIZE (uint32_t)(1 << 12) +typedef void* PHYS_ADDR; +typedef void* VIRT_ADDR; + //! Represents a single page entry in a page table. typedef union { uint32_t entry;@@ -66,9 +69,19 @@ return res;
} /*! + * Invalidates all pages, forces buffer reload. + */ +inline void inv_all_pages(void) { + __asm__ volatile ( "mov %cr3, %eax\n" + "mov %eax, %cr3"); +} + +int map_range_to(PHYS_ADDR page_dir, VIRT_ADDR dest, PHYS_ADDR src, uint32_t page_count, uint32_t flags); + +/*! * Uses a free page to generate a new page directory which maps its last entry to itself. * \return Address of new page directory. */ -void* create_empty_page_dir(void); +PHYS_ADDR create_empty_page_dir(void); #endif
M
kernel/os_pic.c
→
kernel/driv_pic.c
@@ -1,4 +1,4 @@
-#include "os_pic.h" +#include "driv_pic.h" #include "assembly.h" #include "common.h"
A
kernel/os_scheduler.c
@@ -0,0 +1,18 @@
+#include "os_scheduler.h" +#include "os_paging.h" +#include "driv_text.h" + +/*! + * Executes a task. + */ +ProcessID sched_exec(void) { + void* page_dir = create_empty_page_dir(); + switch_page_dir(page_dir); + + map_range_to(page_dir, (VIRT_ADDR)0x00000000, (PHYS_ADDR)0x00000000, PAGE_ENTRY_COUNT, 0b000000000011); + + // will not work because lower memory not mapped + text_write("i did it :)\n"); + while(1) {} + +}
A
kernel/os_scheduler.h
@@ -0,0 +1,16 @@
+/*! \file + * Manages the distribution of processing time among processes. + */ +#ifndef OS_SCHEDULER_H +#define OS_SCHEDULER_H + +#include <stdint.h> + +typedef uint32_t ProcessID; + +/*! + * Executes a task. + */ +ProcessID sched_exec(void); + +#endif
M
kernel/os_text.c
→
kernel/driv_text.c
@@ -124,5 +124,10 @@
enable_cursor(); set_cursor(line, column); + for (uint32_t i = 0; i < 320 * 200; i++) { + uint8_t* disp = (uint8_t*)0xA0000; + disp[i] = (uint8_t)i; + } + return 1; }
M
second_stage/paging.c
→
second_stage/paging.c
@@ -17,7 +17,7 @@ // set everything to zero
ss_memset(pdir, 0, 3 * PAGE_SIZE); // map page directory to itself - (*pdir)[PAGE_DIR_INDEX(PAGE_ENTRY_COUNT - 1)].entry = MAKE_PAGE_ENTRY(pdir, 0b000000000011); + (*pdir)[PAGE_ENTRY_COUNT - 1].entry = MAKE_PAGE_ENTRY(pdir, 0b000000000011); // map 4M of kernel to 0xC0000000 (*pdir)[PAGE_DIR_INDEX(KERNEL_VMA)].entry = MAKE_PAGE_ENTRY(kernel, 0b000000000011);
M
second_stage/paging.h
→
second_stage/paging.h
@@ -8,10 +8,10 @@
#include <stdint.h> //! Number of entries within a page table/directory. -#define PAGE_ENTRY_COUNT (1 << 10) +#define PAGE_ENTRY_COUNT (uint32_t)(1 << 10) //! Size of a single page or page table/directory. -#define PAGE_SIZE (1 << 12) +#define PAGE_SIZE (uint32_t)(1 << 12) //! Represents a single page entry in a page table. typedef union {