diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/graphics/vesa.c | 68 | ||||
-rw-r--r-- | src/kernel/kernel.c | 4 | ||||
-rw-r--r-- | src/kernel/paging/paging.c | 12 | ||||
-rw-r--r-- | src/kernel/paging/paging.h | 12 |
4 files changed, 72 insertions, 24 deletions
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index d19e7d8..b6aca1a 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -5,6 +5,7 @@ #include "../paging/kheap.h" #include "../io/io.h" #include "font.h" +#include "../paging/paging.h" void switch_to_vga() { serial_write("Force switch to VGA!\n"); @@ -31,30 +32,39 @@ struct edid_data get_edid() { struct vbe_mode_info *vbe_set_mode(unsigned short mode) { serial_write("Setting VBE mode!\n"); + serial_write_hex(mode); vesa_available = 0; regs16_t regs; regs.ax = 0x4F02; regs.bx = mode | (1 << 14); + disable_paging(); int32(0x10, ®s); + enable_paging(); if (regs.ax == 0x004F) { - regs.ax = 0x4F01; - regs.cx = mode; - regs.es = 0xA000; - regs.di = 0x0000; - int32(0x10, ®s); - if (regs.ax != 0x004F) { + struct vbe_mode_info *vbe_info = (struct vbe_mode_info *) 0x7E00; + regs16_t regs2; + regs2.ax = 0x4F01; + regs2.cx = mode; + regs2.es = 0; + regs2.di = 0x7E00; + disable_paging(); + int32(0x10, ®s2); + enable_paging(); + + if (regs2.ax != 0x004F) { switch_to_vga(); return ((void *) 0); } - struct vbe_mode_info *vbe_info = (struct vbe_mode_info *) 0xA0000; + struct vbe_mode_info *vbe_info_final = (struct vbe_mode_info *) kmalloc(sizeof(vbe_info)); + memory_copy(vbe_info_final, vbe_info, sizeof(vbe_info)); - vbe_width = vbe_info->width; - vbe_height = vbe_info->height; - vbe_bpp = vbe_info->bpp / 8; - vbe_pitch = vbe_info->pitch; - fb = (char *) vbe_info->framebuffer; + vbe_width = vbe_info_final->width; + vbe_height = vbe_info_final->height; + vbe_bpp = vbe_info_final->bpp / 8; + vbe_pitch = vbe_info_final->pitch; + fb = (char *) vbe_info_final->framebuffer; /*for (int i = 0; i < vbe_width * vbe_height * vbe_bpp; i++) { fb[i] = 100; @@ -71,37 +81,53 @@ struct vbe_mode_info *vbe_set_mode(unsigned short mode) { } } -void set_optimal_resolution() { +uint16_t *vbe_get_modes() { vesa_available = 0; - struct vbe_info *info = (struct vbe_info *) 0x2000; - struct vbe_mode_info *mode_info = (struct vbe_mode_info *) 0x3000; + struct vbe_info *info = (struct vbe_info *) 0x7E00; memory_copy(info->signature, "VBE2", 4); regs16_t regs; regs.ax = 0x4F00; regs.es = 0; - regs.di = 0x2000; + regs.di = 0x7E00; + disable_paging(); int32(0x10, ®s); + enable_paging(); if (regs.ax != 0x004F || strcmp(info->signature, "VESA") != 0) { switch_to_vga(); - return; + return ((void *) 0); } uint16_t *mode_ptr = get_ptr(info->video_modes); + int number_modes = 1; + for (uint16_t *p = mode_ptr; *p != 0xFFFF; p++) number_modes++; + + uint16_t *video_modes = (uint16_t *) kmalloc(sizeof(uint16_t) * number_modes); + for (int i = 0; i < number_modes; i++) video_modes[i] = mode_ptr[i]; + + return video_modes; +} + +void set_optimal_resolution() { + uint16_t *video_modes = vbe_get_modes(); uint16_t mode; uint16_t highest = 0x11B; uint16_t highest_width = 0; - while ((mode = *mode_ptr++) != 0xFFFF) { + while ((mode = *video_modes++) != 0xFFFF) { mode &= 0x1FF; regs16_t regs2; regs2.ax = 0x4F01; regs2.cx = mode; - regs2.es = get_segment(mode_info); - regs2.di = get_offset(mode_info); + regs2.es = 0; + regs2.di = 0x7E00; + disable_paging(); int32(0x10, ®s2); + enable_paging(); + + struct vbe_mode_info *mode_info = (struct vbe_mode_info *) 0x7E00; if ((mode_info->attributes & 0x90) != 0x90) continue; @@ -114,7 +140,7 @@ void set_optimal_resolution() { highest_width = mode_info->width; } } - + serial_write("Reached set mode!\n"); vbe_set_mode(highest); } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index da0b18b..d96ea00 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,20 +9,20 @@ #include "paging/kheap.h" void init() { - initialise_paging(); timer_install(); gdt_install(); idt_install(); isrs_install(); irq_install(); + initialise_paging(); init_serial(); // terminal_initialize(); // TODO: Replace VGA functions with VESA asm volatile ("sti"); } void kernel_main(void) { - set_optimal_resolution(); init(); + set_optimal_resolution(); // vesa_draw_string("This is a testing text!"); diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c index 4bb69d0..1712f7e 100644 --- a/src/kernel/paging/paging.c +++ b/src/kernel/paging/paging.c @@ -105,6 +105,18 @@ void initialise_paging() { switch_page_directory(current_directory); } +void disable_paging() { + uint32_t cr0; + asm volatile("mov %%cr0, %0": "=r"(cr0)); + cr0 &= 0x7fffffff; + asm volatile("mov %0, %%cr0"::"r"(cr0)); +} + +void enable_paging() { + switch_page_directory(kernel_directory); + switch_page_directory(current_directory); +} + void switch_page_directory(page_directory_t *dir) { current_directory = dir; asm volatile("mov %0, %%cr3"::"r"(dir->physicalAddr)); diff --git a/src/kernel/paging/paging.h b/src/kernel/paging/paging.h index 51f407f..681b84e 100644 --- a/src/kernel/paging/paging.h +++ b/src/kernel/paging/paging.h @@ -25,11 +25,21 @@ typedef struct page_directory { } page_directory_t; /** - * Initialize the environment and enables paging + * Initialize the environment and enable paging */ void initialise_paging(); /** + * Enable paging bit in CR0 (without initializing) + */ +void enable_paging(); + +/** + * Disable paging bit in CR0 + */ +void disable_paging(); + +/** * Load the page directory into the CR3 register * @param new The page directory */ |