From 391ed256d21a6ae2e2456d1809f357e6e96e15d1 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Mon, 20 Jan 2020 23:12:54 +0100 Subject: Added pure awesomeness Actually quite some days of work but ok --- src/kernel/graphics/vesa.c | 89 ++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 58 deletions(-) (limited to 'src/kernel/graphics/vesa.c') diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index a9b7f4c..d941413 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -1,11 +1,13 @@ #include #include #include -#include #include #include -#include #include +#include +#include + +extern page_directory_t *kernel_directory; void switch_to_vga() { @@ -32,7 +34,7 @@ struct edid_data get_edid() struct edid_data *edid = (struct edid_data *) 0x7E00; - return *(struct edid_data *) edid; + return *edid; } void vbe_set_mode(unsigned short mode) @@ -68,7 +70,7 @@ uint16_t *vbe_get_modes() size_t number_modes = 1; for (uint16_t *p = mode_ptr; *p != 0xFFFF; p++) number_modes++; - uint16_t *ret = kmalloc(sizeof(uint16_t) * number_modes); + uint16_t *ret = (uint16_t *) kmalloc(sizeof(uint16_t) * number_modes); for (size_t i = 0; i < number_modes; i++) ret[i] = ((uint16_t *) info->video_modes)[i]; @@ -154,7 +156,7 @@ void set_optimal_resolution() }; for (size_t i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { - mode_info = vbe_get_mode_info(modes[i]); + mode_info = vbe_get_mode_info((uint16_t) modes[i]); if (mode_info == 0 || (mode_info->attributes & 0x90) != 0x90 || (mode_info->memory_model != 4 && mode_info->memory_model != 6)) { kfree(mode_info); @@ -162,7 +164,7 @@ void set_optimal_resolution() } if ((mode_info->width > vbe_width || (mode_info->width == vbe_width && (mode_info->bpp >> 3) > vbe_bpl))) { - highest = modes[i]; + highest = (uint16_t) modes[i]; vbe_width = mode_info->width; vbe_height = mode_info->height; vbe_pitch = mode_info->pitch; @@ -180,11 +182,10 @@ void set_optimal_resolution() vbe_set_mode(highest); uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; - cursor_buffer = umalloc(fb_size); - for (uint32_t z = 0; z < fb_size; z += 4096) { - paging_set_user((uint32_t) fb + z, 1); - paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED | PT_ALL_PRIV); - paging_map((uint32_t) cursor_buffer + z, (uint32_t) cursor_buffer + z, PT_PRESENT | PT_RW | PT_USED); + cursor_buffer = (unsigned char *) kmalloc(fb_size); + for (uint32_t z = 0; z < fb_size; z += 0x1000) { + alloc_frame(get_page((uint32_t) fb + z, 1, kernel_directory), 0, 1); + alloc_frame(get_page((uint32_t) cursor_buffer + z, 1, kernel_directory), 0, 1); } if (vbe_height > 1440) vesa_set_font(32); @@ -220,9 +221,9 @@ void vesa_set_font(int height) void vesa_convert_color(uint32_t *color_array, uint32_t color) { - uint8_t red = (color >> 16) & 255; - uint8_t green = (color >> 8) & 255; - uint8_t blue = color & 255; + uint8_t red = (uint8_t) ((color >> 16) & 255); + uint8_t green = (uint8_t) ((color >> 8) & 255); + uint8_t blue = (uint8_t) (color & 255); if ((vbe_bpl << 3) == 8) { uint32_t new_color = ((red * 7 / 255) << 5) + ((green * 7 / 255) << 2) + (blue * 3 / 255); @@ -245,11 +246,11 @@ void vesa_convert_color(uint32_t *color_array, uint32_t color) void vesa_set_pixel(uint16_t x, uint16_t y, const uint32_t color[3]) { - unsigned pos = x * vbe_bpl + y * vbe_pitch; + unsigned pos = (unsigned int) (x * vbe_bpl + y * vbe_pitch); char *draw = (char *) &fb[pos]; - draw[pos] = color[2]; - draw[pos + 1] = color[1]; - draw[pos + 2] = color[0]; + draw[pos] = (char) color[2]; + draw[pos + 1] = (char) color[1]; + draw[pos + 2] = (char) color[0]; } void vesa_draw_rectangle(int x1, int y1, int x2, int y2, const uint32_t color[3]) @@ -258,9 +259,9 @@ void vesa_draw_rectangle(int x1, int y1, int x2, int y2, const uint32_t color[3] char *draw = (char *) &fb[pos1]; for (int i = 0; i <= y2 - y1; i++) { for (int j = 0; j <= x2 - x1; j++) { - draw[vbe_bpl * j] = color[2]; - draw[vbe_bpl * j + 1] = color[1]; - draw[vbe_bpl * j + 2] = color[0]; + draw[vbe_bpl * j] = (char) color[2]; + draw[vbe_bpl * j + 1] = (char) color[1]; + draw[vbe_bpl * j + 2] = (char) color[0]; } draw += vbe_pitch; } @@ -286,13 +287,13 @@ void vesa_draw_char(char ch) else if (font_height == 32) bitmap = font->font_32[ch - 32][cy]; for (int cx = 0; cx <= font_width + 1; cx++) { if (bitmap & ((1 << font_width) >> cx)) { // Side effect: Smoothness factor! - draw[vbe_bpl * cx] = terminal_color[2]; - draw[vbe_bpl * cx + 1] = terminal_color[1]; - draw[vbe_bpl * cx + 2] = terminal_color[0]; + draw[vbe_bpl * cx] = (char) terminal_color[2]; + draw[vbe_bpl * cx + 1] = (char) terminal_color[1]; + draw[vbe_bpl * cx + 2] = (char) terminal_color[0]; } else { - draw[vbe_bpl * cx] = terminal_background[2]; - draw[vbe_bpl * cx + 1] = terminal_background[1]; - draw[vbe_bpl * cx + 2] = terminal_background[0]; + draw[vbe_bpl * cx] = (char) terminal_background[2]; + draw[vbe_bpl * cx + 1] = (char) terminal_background[1]; + draw[vbe_bpl * cx + 2] = (char) terminal_background[0]; } } draw += vbe_pitch; @@ -312,34 +313,6 @@ void vesa_draw_char(char ch) } } -void vesa_keyboard_char(char ch) -{ - vesa_draw_rectangle(terminal_x, terminal_y, terminal_x + font_width, terminal_y + font_height, - terminal_background); - - if (ch == 0x08) { - if (terminal_x != 0) terminal_x -= font_width; - text[strlen(text) - 1] = '\0'; - } else if (ch == 0x09) { - terminal_x += 4 * font_width; - } else if (ch == '\r') { - terminal_x = 0; - } else if (ch == '\n') { - writec(ch); - exec_command(text); - memset(text, 0, sizeof(text)); - // terminal_scroll(); - } else if (ch >= ' ') { - writec(ch); - char tmp[2] = {ch}; - strcat(text, tmp); - } - - // terminal_scroll(); - vesa_draw_rectangle(terminal_x, terminal_y, terminal_x + font_width, terminal_y + font_height, - terminal_color); -} - int prev_coords[2] = {}; int first = 1; // TODO: Better initial cursor buffer solution void vesa_draw_cursor(int x, int y) @@ -372,9 +345,9 @@ void vesa_draw_cursor(int x, int y) prev[vbe_bpl * cx + 1] = draw[vbe_bpl * cx + 1]; prev[vbe_bpl * cx + 2] = draw[vbe_bpl * cx + 2]; if (font->cursor[cy] & ((1 << 12) >> cx)) { - draw[vbe_bpl * cx] = terminal_color[2]; - draw[vbe_bpl * cx + 1] = terminal_color[1]; - draw[vbe_bpl * cx + 2] = terminal_color[0]; + draw[vbe_bpl * cx] = (char) terminal_color[2]; + draw[vbe_bpl * cx + 1] = (char) terminal_color[1]; + draw[vbe_bpl * cx + 2] = (char) terminal_color[0]; } } draw += vbe_pitch; -- cgit v1.2.3 From 3fa449276364389137a7154a9971594816d86362 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Tue, 21 Jan 2020 22:10:16 +0100 Subject: Naming scheme and page fault improvements --- src/kernel/graphics/vesa.c | 6 +++--- src/kernel/interrupts/isr.c | 8 +++++++- src/kernel/memory/kheap.c | 8 ++++---- src/kernel/memory/paging.c | 43 ++++++++++++++++++++++--------------------- src/kernel/memory/paging.h | 12 +++++------- 5 files changed, 41 insertions(+), 36 deletions(-) (limited to 'src/kernel/graphics/vesa.c') diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index d941413..15d953a 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -7,7 +7,7 @@ #include #include -extern page_directory_t *kernel_directory; +extern page_directory_t *current_directory; void switch_to_vga() { @@ -184,9 +184,9 @@ void set_optimal_resolution() uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; cursor_buffer = (unsigned char *) kmalloc(fb_size); for (uint32_t z = 0; z < fb_size; z += 0x1000) { - alloc_frame(get_page((uint32_t) fb + z, 1, kernel_directory), 0, 1); - alloc_frame(get_page((uint32_t) cursor_buffer + z, 1, kernel_directory), 0, 1); + paging_alloc_frame(paging_get_page((uint32_t) fb + z, 1, current_directory), 0, 1); } + serial_printf("0x%x", fb); if (vbe_height > 1440) vesa_set_font(32); else if (vbe_height > 720) vesa_set_font(24); diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c index eb932b2..d89f581 100644 --- a/src/kernel/interrupts/isr.c +++ b/src/kernel/interrupts/isr.c @@ -3,6 +3,7 @@ #include #include #include +#include // Install ISRs in IDT void isrs_install() @@ -119,6 +120,11 @@ void fault_handler(struct regs *r) // halt_loop(); // Idk loop? char *message = (char *) exception_messages[r->int_no]; strcat(message, " Exception"); - panic(message); + + // Show message if there wasn't an error in video memory + if (faulting_address != (uint32_t) fb) + panic(message); + else + halt_loop(); } } \ No newline at end of file diff --git a/src/kernel/memory/kheap.c b/src/kernel/memory/kheap.c index def9ca2..40551bc 100644 --- a/src/kernel/memory/kheap.c +++ b/src/kernel/memory/kheap.c @@ -12,7 +12,7 @@ uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys) if (kheap != 0) { void *addr = alloc(sz, (uint8_t) align, kheap); if (phys != 0) { - page_t *page = get_page((uint32_t) addr, 0, kernel_directory); + page_t *page = paging_get_page((uint32_t) addr, 0, kernel_directory); *phys = page->frame * 0x1000 + ((uint32_t) addr & 0xFFF); } return (uint32_t) addr; @@ -70,8 +70,8 @@ static void expand(uint32_t new_size, heap_t *heap) uint32_t i = old_size; while (i < new_size) { - alloc_frame(get_page(heap->start_address + i, 1, kernel_directory), - (heap->supervisor) ? 1 : 0, (heap->readonly) ? 0 : 1); + paging_alloc_frame(paging_get_page(heap->start_address + i, 1, kernel_directory), + (heap->supervisor) ? 1 : 0, (heap->readonly) ? 0 : 1); i += 0x1000; } heap->end_address = heap->start_address + new_size; @@ -92,7 +92,7 @@ static uint32_t contract(uint32_t new_size, heap_t *heap) uint32_t old_size = heap->end_address - heap->start_address; uint32_t i = old_size - 0x1000; while (new_size < i) { - free_frame(get_page(heap->start_address + i, 0, kernel_directory)); + paging_free_frame(paging_get_page(heap->start_address + i, 0, kernel_directory)); i -= 0x1000; } diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index e050861..ad19091 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -2,6 +2,7 @@ #include #include #include +#include int paging_enabled = 0; @@ -19,7 +20,7 @@ extern void copy_page_physical(); #define INDEX_FROM_BIT(a) (a/(8*4)) #define OFFSET_FROM_BIT(a) (a%(8*4)) -static void set_frame(uint32_t frame_addr) +static void paging_set_frame(uint32_t frame_addr) { uint32_t frame = frame_addr / 0x1000; uint32_t idx = INDEX_FROM_BIT(frame); @@ -27,7 +28,7 @@ static void set_frame(uint32_t frame_addr) frames[idx] |= (0x1 << off); } -static void clear_frame(uint32_t frame_addr) +static void paging_clear_frame(uint32_t frame_addr) { uint32_t frame = frame_addr / 0x1000; uint32_t idx = INDEX_FROM_BIT(frame); @@ -35,7 +36,7 @@ static void clear_frame(uint32_t frame_addr) frames[idx] &= ~(0x1 << off); } -static uint32_t first_frame() +static uint32_t paging_first_frame() { uint32_t i, j; for (i = 0; i < INDEX_FROM_BIT(nframes); i++) { @@ -51,15 +52,15 @@ static uint32_t first_frame() return 0; } -void alloc_frame(page_t *page, int is_kernel, int is_writeable) +void paging_alloc_frame(page_t *page, int is_kernel, int is_writeable) { if (page->frame != 0) { return; } else { - uint32_t idx = first_frame(); + uint32_t idx = paging_first_frame(); if (idx == (uint32_t) -1) panic("No free frames!"); - set_frame(idx * 0x1000); + paging_set_frame(idx * 0x1000); page->present = 1; page->rw = (is_writeable == 1) ? 1 : 0; page->user = (is_kernel == 1) ? 0 : 1; @@ -67,13 +68,13 @@ void alloc_frame(page_t *page, int is_kernel, int is_writeable) } } -void free_frame(page_t *page) +void paging_free_frame(page_t *page) { uint32_t frame; if (!(frame = page->frame)) { return; } else { - clear_frame(frame); + paging_clear_frame(frame); page->frame = 0x0; } } @@ -91,27 +92,27 @@ void paging_install() kernel_directory->physicalAddr = (uint32_t) kernel_directory->tablesPhysical; for (uint32_t i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000) - get_page((uint32_t) i, 1, kernel_directory); + paging_get_page((uint32_t) i, 1, kernel_directory); int i = 0; while (i < 0x400000) { - alloc_frame(get_page((uint32_t) i, 1, kernel_directory), 0, 0); + paging_alloc_frame(paging_get_page((uint32_t) i, 1, kernel_directory), 0, 0); i += 0x1000; } for (i = KHEAP_START; i < (int) (KHEAP_START + KHEAP_INITIAL_SIZE); i += 0x1000) - alloc_frame(get_page((uint32_t) i, 1, kernel_directory), 0, 0); + paging_alloc_frame(paging_get_page((uint32_t) i, 1, kernel_directory), 0, 0); - switch_page_directory(kernel_directory); + paging_switch_directory(kernel_directory); kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0); - current_directory = clone_directory(kernel_directory); - switch_page_directory(current_directory); + current_directory = paging_clone_directory(kernel_directory); + paging_switch_directory(current_directory); vga_log("Installed Paging"); } -void switch_page_directory(page_directory_t *dir) +void paging_switch_directory(page_directory_t *dir) { current_directory = dir; asm volatile("mov %0, %%cr3"::"r"(dir->physicalAddr)); @@ -123,7 +124,7 @@ void switch_page_directory(page_directory_t *dir) void paging_enable() { - switch_page_directory(kernel_directory); + paging_switch_directory(kernel_directory); paging_enabled = 1; } @@ -136,7 +137,7 @@ void paging_disable() paging_enabled = 0; } -page_t *get_page(uint32_t address, int make, page_directory_t *dir) +page_t *paging_get_page(uint32_t address, int make, page_directory_t *dir) { address /= 0x1000; uint32_t table_idx = address / 1024; @@ -154,7 +155,7 @@ page_t *get_page(uint32_t address, int make, page_directory_t *dir) } } -static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) +static page_table_t *paging_clone_table(page_table_t *src, uint32_t *physAddr) { page_table_t *table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), physAddr); memset(table, 0, sizeof(page_directory_t)); @@ -163,7 +164,7 @@ static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) if (!src->pages[i].frame) continue; - alloc_frame(&table->pages[i], 0, 0); + paging_alloc_frame(&table->pages[i], 0, 0); if (src->pages[i].present) table->pages[i].present = 1; if (src->pages[i].rw) table->pages[i].rw = 1; @@ -176,7 +177,7 @@ static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) return table; } -page_directory_t *clone_directory(page_directory_t *src) +page_directory_t *paging_clone_directory(page_directory_t *src) { uint32_t phys; page_directory_t *dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys); @@ -195,7 +196,7 @@ page_directory_t *clone_directory(page_directory_t *src) dir->tablesPhysical[i] = src->tablesPhysical[i]; } else { uint32_t phys; - dir->tables[i] = clone_table(src->tables[i], &phys); + dir->tables[i] = paging_clone_table(src->tables[i], &phys); dir->tablesPhysical[i] = phys | 0x07; } } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 285cb6f..bb6ee4f 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -26,22 +26,20 @@ typedef struct page_directory { int paging_enabled; -void alloc_frame(page_t *page, int is_kernel, int is_writeable); +void paging_alloc_frame(page_t *page, int is_kernel, int is_writeable); -void free_frame(page_t *page); +void paging_free_frame(page_t *page); void paging_install(); -void switch_page_directory(page_directory_t *new); +void paging_switch_directory(page_directory_t *dir); void paging_enable(); void paging_disable(); -page_t *get_page(uint32_t address, int make, page_directory_t *dir); +page_t *paging_get_page(uint32_t address, int make, page_directory_t *dir); -void page_fault(struct regs *regs); - -page_directory_t *clone_directory(page_directory_t *src); +page_directory_t *paging_clone_directory(page_directory_t *src); #endif -- cgit v1.2.3 From b8630d78a15a69f50dac747e41e84b143dd99b08 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 25 Jan 2020 23:39:17 +0100 Subject: Hehe fixed video bug :) Took around 5 days. --- src/kernel/graphics/vesa.c | 11 +++++++++-- src/kernel/memory/paging.c | 6 +++--- src/kernel/memory/paging.h | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/kernel/graphics/vesa.c') diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 15d953a..e2b0036 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -183,8 +183,15 @@ void set_optimal_resolution() uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; cursor_buffer = (unsigned char *) kmalloc(fb_size); - for (uint32_t z = 0; z < fb_size; z += 0x1000) { - paging_alloc_frame(paging_get_page((uint32_t) fb + z, 1, current_directory), 0, 1); + uint32_t j = (uint32_t) fb; + while ((unsigned char *) j < fb + (vbe_width * vbe_height * 4)) { + paging_set_frame(j); + page_t *page = paging_get_page(j, 1, current_directory); + page->present = 1; + page->rw = 1; + page->user = 1; + page->frame = j / 0x1000; + j += 0x1000; } serial_printf("0x%x", fb); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index ad19091..861cdcb 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -20,7 +20,7 @@ extern void copy_page_physical(); #define INDEX_FROM_BIT(a) (a/(8*4)) #define OFFSET_FROM_BIT(a) (a%(8*4)) -static void paging_set_frame(uint32_t frame_addr) +void paging_set_frame(uint32_t frame_addr) { uint32_t frame = frame_addr / 0x1000; uint32_t idx = INDEX_FROM_BIT(frame); @@ -28,7 +28,7 @@ static void paging_set_frame(uint32_t frame_addr) frames[idx] |= (0x1 << off); } -static void paging_clear_frame(uint32_t frame_addr) +void paging_clear_frame(uint32_t frame_addr) { uint32_t frame = frame_addr / 0x1000; uint32_t idx = INDEX_FROM_BIT(frame); @@ -36,7 +36,7 @@ static void paging_clear_frame(uint32_t frame_addr) frames[idx] &= ~(0x1 << off); } -static uint32_t paging_first_frame() +uint32_t paging_first_frame() { uint32_t i, j; for (i = 0; i < INDEX_FROM_BIT(nframes); i++) { diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index bb6ee4f..77258b7 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -26,6 +26,8 @@ typedef struct page_directory { int paging_enabled; +void paging_set_frame(uint32_t frame_addr); + void paging_alloc_frame(page_t *page, int is_kernel, int is_writeable); void paging_free_frame(page_t *page); -- cgit v1.2.3 From bb2a6b4d93512e8afc1b1999eb58f1f506cc27ae Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 26 Jan 2020 18:38:36 +0100 Subject: Magic commit Some things work, others don't. --- src/kernel/boot.asm | 9 +- src/kernel/fs/install.c | 2 +- src/kernel/fs/load.c | 34 ++++++ src/kernel/fs/load.h | 19 +++ src/kernel/graphics/font.c | 26 ---- src/kernel/graphics/font.h | 19 --- src/kernel/graphics/vesa.c | 2 +- src/kernel/graphics/vesa.h | 2 - src/kernel/kernel.c | 36 ++---- src/kernel/syscall/actions/sys_get_pointers.c | 2 +- src/kernel/syscall/syscall.c | 2 - src/kernel/system.c | 2 + src/kernel/system.h | 2 +- src/kernel/tasks/process.asm | 48 ++++++++ src/kernel/tasks/task.c | 168 ++++++++++++++++++++++++++ src/kernel/tasks/task.h | 30 +++++ src/kernel/timer/timer.c | 2 + src/userspace/syscall.c | 4 +- src/userspace/syscall.h | 95 +++++++-------- 19 files changed, 367 insertions(+), 137 deletions(-) create mode 100644 src/kernel/fs/load.c create mode 100644 src/kernel/fs/load.h delete mode 100644 src/kernel/graphics/font.c delete mode 100644 src/kernel/graphics/font.h create mode 100644 src/kernel/tasks/process.asm create mode 100644 src/kernel/tasks/task.c create mode 100644 src/kernel/tasks/task.h (limited to 'src/kernel/graphics/vesa.c') diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 85d4254..58ee8d6 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -15,16 +15,11 @@ section .text global _start extern kernel_main _start: - mov esp, STACK_TOP - push ebx - push eax + push esp cli call kernel_main cli - - hlt_L: - hlt - jmp hlt_L + jmp $ global jump_userspace jump_userspace: diff --git a/src/kernel/fs/install.c b/src/kernel/fs/install.c index daeb91b..f7e2489 100644 --- a/src/kernel/fs/install.c +++ b/src/kernel/fs/install.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include void install_melvix() { diff --git a/src/kernel/fs/load.c b/src/kernel/fs/load.c new file mode 100644 index 0000000..be7d5b8 --- /dev/null +++ b/src/kernel/fs/load.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include + +void load_binaries() +{ + userspace = kmalloc(10000); + font = (struct font *) kmalloc(100000);; // High quality shit + + uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); + if (boot_drive_id != 0xE0) { + struct ata_interface *primary_master = new_ata(1, 0x1F0); + marfs_init(primary_master); + marfs_read_whole_file(4, (uint8_t *) userspace); + marfs_read_whole_file(5, (uint8_t *) font); + } else { + char *font_p[] = {"FONT.BIN"}; + struct iso9660_entity *font_e = ISO9660_get(font_p, 1); + if (!font_e) panic("Font not found!"); + ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, (uint8_t *) font); + kfree(font_e); + + char *user_p[] = {"USER.BIN"}; + struct iso9660_entity *user_e = ISO9660_get(user_p, 1); + if (!user_e) panic("Userspace binary not found!"); + ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) userspace); + kfree(user_e); + } + vga_log("Successfully loaded binaries"); +} \ No newline at end of file diff --git a/src/kernel/fs/load.h b/src/kernel/fs/load.h new file mode 100644 index 0000000..7a0ec06 --- /dev/null +++ b/src/kernel/fs/load.h @@ -0,0 +1,19 @@ +#ifndef MELVIX_LOAD_H +#define MELVIX_LOAD_H + +#include + +uint32_t userspace; + +struct font *font; + +struct font { + uint16_t font_32[758][32]; + uint16_t font_24[758][24]; + uint8_t font_16[758][16]; + uint16_t cursor[19]; +}; + +void load_binaries(); + +#endif diff --git a/src/kernel/graphics/font.c b/src/kernel/graphics/font.c deleted file mode 100644 index 10372b3..0000000 --- a/src/kernel/graphics/font.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -void font_install() -{ - font = (struct font *) kmalloc(100000);; // High quality shit - - uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); - if (boot_drive_id != 0xE0) { - struct ata_interface *primary_master = new_ata(1, 0x1F0); - marfs_init(primary_master); - marfs_read_whole_file(5, (uint8_t *) font); - } else { - char *font_p[] = {"FONT.BIN"}; - struct iso9660_entity *font_e = ISO9660_get(font_p, 1); - if (!font_e) panic("Font not found!"); - ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, (uint8_t *) font); - kfree(font_e); - } - vga_log("Successfully loaded font"); -} \ No newline at end of file diff --git a/src/kernel/graphics/font.h b/src/kernel/graphics/font.h deleted file mode 100644 index 7778979..0000000 --- a/src/kernel/graphics/font.h +++ /dev/null @@ -1,19 +0,0 @@ -// Generated using the Spleen font and the bdf2c converter (modified using the conv.sh script) -// Spleen font: (c) 2018-2019, Frederic Cambus, License: MIT -// bdf2c: (c) 2009-2010 Lutz Sammer, License: AGPLv3 - -#ifndef MELVIX_FONT_H -#define MELVIX_FONT_H - -#include - -struct font *font; - -struct font { - uint16_t font_32[758][32]; - uint16_t font_24[758][24]; - uint8_t font_16[758][16]; - uint16_t cursor[19]; -}; - -#endif diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index e2b0036..576fc18 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/kernel/graphics/vesa.h b/src/kernel/graphics/vesa.h index 2288760..22590de 100644 --- a/src/kernel/graphics/vesa.h +++ b/src/kernel/graphics/vesa.h @@ -185,8 +185,6 @@ void vesa_draw_cursor(int x, int y); */ void vesa_set_color(uint32_t color); -void font_install(); - /** * An enum with vesa colors * From https://github.com/joshdick/onedark.vim/ License: MIT diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index efa6ca0..91206a2 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,18 +9,15 @@ #include #include #include -#include -#include -#include #include #include -#include #include +#include +#include -extern void jump_userspace(); - -void kernel_main() +void kernel_main(uint32_t initial_stack) { + initial_esp = initial_stack; vga_log("Installing basic features of Melvix..."); // Install features @@ -28,13 +25,13 @@ void kernel_main() gdt_install(); init_serial(); acpi_install(); - paging_install(); idt_install(); isrs_install(); irq_install(); - font_install(); - serial_printf("%d", memory_get_all()); + paging_install(); + load_binaries(); set_optimal_resolution(); + serial_printf("%d", memory_get_all()); // Install drivers asm ("cli"); @@ -51,30 +48,17 @@ void kernel_main() // Print total memory info("Total memory found: %dMiB", (memory_get_all() >> 10) + 1); - uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); - #ifdef INSTALL_MELVIX #include serial_printf("Install flag given!"); - if (boot_drive_id == 0xE0) + if ((*((uint8_t *) 0x9000)) == 0xE0) install_melvix(); #endif - info("Switching to user mode..."); + tasking_install(); syscalls_install(); tss_flush(); - uint32_t userspace = (uint32_t) kmalloc(8096); - if (boot_drive_id == 0xE0) { - char *user_p[] = {"USER.BIN"}; - struct iso9660_entity *user_e = ISO9660_get(user_p, 1); - if (!user_e) panic("Userspace binary not found!"); - ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) (userspace + 4096)); - kfree(user_e); - jump_userspace(userspace + 4096, userspace + 4096); - } else { - marfs_read_whole_file(4, (uint8_t *) (userspace + 4096)); - jump_userspace(userspace + 4096, userspace + 4096); - } + switch_to_usermode(userspace); panic("This should NOT happen!"); diff --git a/src/kernel/syscall/actions/sys_get_pointers.c b/src/kernel/syscall/actions/sys_get_pointers.c index 8e34ddd..bc00b3b 100644 --- a/src/kernel/syscall/actions/sys_get_pointers.c +++ b/src/kernel/syscall/actions/sys_get_pointers.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include struct userspace_pointers { diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c index 367fe30..7ca7f99 100644 --- a/src/kernel/syscall/syscall.c +++ b/src/kernel/syscall/syscall.c @@ -6,8 +6,6 @@ typedef uint32_t (*syscall_func)(unsigned int, ...); -extern void jump_userspace(); - uint32_t (*syscalls[])() = { [0] = (uint32_t (*)()) halt_loop, // DEBUG! [1] = sys_write, diff --git a/src/kernel/system.c b/src/kernel/system.c index 85cadc2..ae2e524 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -7,6 +7,8 @@ #include #include +uint32_t initial_esp; + char *vga_buffer = (char *) 0x500; void vga_clear() diff --git a/src/kernel/system.h b/src/kernel/system.h index 9c3ae80..8d124de 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -9,7 +9,7 @@ extern void ASM_KERNEL_END(); /** * The initial stack pointer */ -extern uint32_t STACK_TOP; +uint32_t initial_esp; /** * Initialize the basic features of the OS diff --git a/src/kernel/tasks/process.asm b/src/kernel/tasks/process.asm new file mode 100644 index 0000000..a46ac3d --- /dev/null +++ b/src/kernel/tasks/process.asm @@ -0,0 +1,48 @@ +[GLOBAL read_eip] +read_eip: + pop eax + jmp eax + +[GLOBAL copy_page_physical] +copy_page_physical: + push ebx + pushf + + cli + + mov ebx, [esp+12] + mov ecx, [esp+16] + + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx + + mov edx, 1024 + +.loop: + mov eax, [ebx] + mov [ecx], eax + add ebx, 4 + add ecx, 4 + dec edx + jnz .loop + + mov edx, cr0 + or edx, 0x80000000 + mov cr0, edx + + popf + pop ebx + ret + +[GLOBAL perform_task_switch] +perform_task_switch: + cli + mov ecx, [esp+4] + mov eax, [esp+8] + mov ebp, [esp+12] + mov esp, [esp+16] + mov cr3, eax + mov eax, 0x12345 + sti + jmp ecx \ No newline at end of file diff --git a/src/kernel/tasks/task.c b/src/kernel/tasks/task.c new file mode 100644 index 0000000..e6caf9a --- /dev/null +++ b/src/kernel/tasks/task.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include +#include +#include + +volatile task_t *current_task; +volatile task_t *ready_queue; + +extern page_directory_t *kernel_directory; +extern page_directory_t *current_directory; + +extern uint32_t read_eip(); + +uint32_t next_pid = 1; + +void tasking_install() +{ + asm ("cli"); + move_stack((void *) 0xE0000000, 0x2000); + + current_task = ready_queue = (task_t *) kmalloc(sizeof(task_t)); + current_task->id = (int) next_pid++; + current_task->esp = current_task->ebp = 0; + current_task->eip = 0; + current_task->page_directory = current_directory; + current_task->next = 0; + current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); + + vga_log("Installed Tasking"); + asm ("sti"); +} + +void move_stack(void *new_stack_start, uint32_t size) +{ + for (uint32_t i = (uint32_t) new_stack_start; + i >= ((uint32_t) new_stack_start - size); + i -= 0x1000) { + paging_alloc_frame(paging_get_page(i, 1, current_directory), 0, 1); + } + + uint32_t pd_addr; + asm volatile ("mov %%cr3, %0" : "=r" (pd_addr)); + asm volatile ("mov %0, %%cr3" : : "r" (pd_addr)); + + uint32_t old_stack_pointer; asm volatile ("mov %%esp, %0" : "=r" (old_stack_pointer)); + uint32_t old_base_pointer; asm volatile ("mov %%ebp, %0" : "=r" (old_base_pointer)); + + uint32_t offset = (uint32_t) new_stack_start - initial_esp; + + uint32_t new_stack_pointer = old_stack_pointer + offset; + uint32_t new_base_pointer = old_base_pointer + offset; + + memcpy((void *) new_stack_pointer, (void *) old_stack_pointer, initial_esp - old_stack_pointer); + + for (uint32_t i = (uint32_t) new_stack_start; i > (uint32_t) new_stack_start - size; i -= 4) { + uint32_t tmp = *(uint32_t *) i; + if ((old_stack_pointer < tmp) && (tmp < initial_esp)) { + tmp = tmp + offset; + uint32_t *tmp2 = (uint32_t *) i; + *tmp2 = tmp; + } + } + + asm volatile ("mov %0, %%esp" : : "r" (new_stack_pointer)); + asm volatile ("mov %0, %%ebp" : : "r" (new_base_pointer)); +} + +extern void perform_task_switch(uint32_t, uint32_t, uint32_t, uint32_t); + +void switch_task() +{ + if (!current_task) + return; + + uint32_t esp, ebp, eip; + asm volatile ("mov %%esp, %0" : "=r"(esp)); + asm volatile ("mov %%ebp, %0" : "=r"(ebp)); + + eip = read_eip(); + + if (eip == 0x12345) + return; + + current_task->eip = eip; + current_task->esp = esp; + current_task->ebp = ebp; + + current_task = current_task->next; + if (!current_task) current_task = ready_queue; + + eip = current_task->eip; + esp = current_task->esp; + ebp = current_task->ebp; + + current_directory = current_task->page_directory; + + set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE); + + perform_task_switch(eip, current_directory->physicalAddr, ebp, esp); +} + +int fork() +{ + asm ("cli"); + + task_t *parent_task = (task_t *) current_task; + + page_directory_t *directory = paging_clone_directory(current_directory); + + task_t *new_task = (task_t *) kmalloc(sizeof(task_t)); + new_task->id = (int) next_pid++; + new_task->esp = new_task->ebp = 0; + new_task->eip = 0; + new_task->page_directory = directory; + current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); + new_task->next = 0; + + task_t *tmp_task = (task_t *) ready_queue; + while (tmp_task->next) + tmp_task = tmp_task->next; + tmp_task->next = new_task; + + uint32_t eip = read_eip(); + + if (current_task == parent_task) { + uint32_t esp; asm volatile ("mov %%esp, %0" : "=r"(esp)); + uint32_t ebp; asm volatile ("mov %%ebp, %0" : "=r"(ebp)); + new_task->esp = esp; + new_task->ebp = ebp; + new_task->eip = eip; + asm volatile ("sti"); + + return new_task->id; + } else { + return 0; + } +} + +int getpid() +{ + return current_task->id; +} + +void switch_to_usermode(uint32_t binary) +{ + set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE); + + info("Switching to user mode..."); + + asm volatile ("\ + cli; \ + mov $0x23, %%ax; \ + mov %%ax, %%ds; \ + mov %%ax, %%es; \ + mov %%ax, %%fs; \ + mov %%ax, %%gs; \ + mov %%esp, %%eax; \ + pushl $0x23; \ + pushl %%esp; \ + pushf; \ + pushl $0x1B; \ + push %0; \ + iret; \ + 1: \ + " : : "r" (binary)); +} \ No newline at end of file diff --git a/src/kernel/tasks/task.h b/src/kernel/tasks/task.h new file mode 100644 index 0000000..97aeb15 --- /dev/null +++ b/src/kernel/tasks/task.h @@ -0,0 +1,30 @@ +#ifndef MELVIX_TASK_H +#define MELVIX_TASK_H + +#include +#include + +#define KERNEL_STACK_SIZE 2048 + +typedef struct task { + int id; + uint32_t esp, ebp; + uint32_t eip; + page_directory_t *page_directory; + uint32_t kernel_stack; + struct task *next; +} task_t; + +void tasking_install(); + +void switch_task(); + +int fork(); + +void move_stack(void *new_stack_start, uint32_t size); + +int getpid(); + +void switch_to_usermode(uint32_t); + +#endif diff --git a/src/kernel/timer/timer.c b/src/kernel/timer/timer.c index cc98bc4..9bf6014 100644 --- a/src/kernel/timer/timer.c +++ b/src/kernel/timer/timer.c @@ -1,6 +1,7 @@ #include #include #include +#include unsigned long timer_ticks = 0; @@ -16,6 +17,7 @@ void timer_phase(int hz) void timer_handler(struct regs *r) { timer_ticks++; + // switch_task(); } // "Delay" function with CPU sleep diff --git a/src/userspace/syscall.c b/src/userspace/syscall.c index 132cd49..9462b10 100644 --- a/src/userspace/syscall.c +++ b/src/userspace/syscall.c @@ -5,9 +5,9 @@ */ DEFN_SYSCALL0(halt, 0); -DEFN_SYSCALL1(write, 1, char *); +DEFN_SYSCALL1(write, 1, const char *); -DEFN_SYSCALL1(read, 2, char *); +DEFN_SYSCALL1(read, 2, const char *); DEFN_SYSCALL1(writec, 3, char); diff --git a/src/userspace/syscall.h b/src/userspace/syscall.h index e46f453..bd402a1 100644 --- a/src/userspace/syscall.h +++ b/src/userspace/syscall.h @@ -3,72 +3,69 @@ #include -#define DECL_SYSCALL0(fn) int syscall_##fn() -#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1) -#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2) -#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3) -#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4) -#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5) +#define DECL_SYSCALL0(fn) int syscall_##fn(); +#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1); +#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2); +#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3); +#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4); +#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5); #define DEFN_SYSCALL0(fn, num) \ - int syscall_##fn() { \ - int a; __asm__ __volatile__("int $0x80" : "=a" (a) : "0" (num)); \ - return a; \ - } +int syscall_##fn() \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num)); \ + return a; \ +} #define DEFN_SYSCALL1(fn, num, P1) \ - int syscall_##fn(P1 p1) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "r" ((int)(p1)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1)); \ + return a; \ +} #define DEFN_SYSCALL2(fn, num, P1, P2) \ - int syscall_##fn(P1 p1, P2 p2) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "r" ((int)(p1)), "c"((int)(p2)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2)); \ + return a; \ +} #define DEFN_SYSCALL3(fn, num, P1, P2, P3) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((p2)), "d"((int)(p3)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2, P3 p3) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d"((int)p3)); \ + return a; \ +} #define DEFN_SYSCALL4(fn, num, P1, P2, P3, P4) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((int)(p2)), "d"((int)(p3)), "S"((int)(p4)) \ - : "memory"); \ - return __res; \ - } - -#define DEFN_SYSCALL5(fn, num, P1, P2, P3, P4, P5) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((int)(p2)), "d"((int)(p3)), "S"((int)(p4)), "D"((int)(p5)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4)); \ + return a; \ +} + +#define DEFN_SYSCALL5(fn, num) \ +int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4), "D" ((int)p5)); \ + return a; \ +} /** * DECLARATIONS */ DECL_SYSCALL0(halt); -DECL_SYSCALL1(write, char *); +DECL_SYSCALL1(write, const char *); -DECL_SYSCALL1(read, char *); +DECL_SYSCALL1(read, const char *); DECL_SYSCALL1(writec, char); -- cgit v1.2.3