diff options
author | Marvin Borner | 2019-11-23 01:02:19 +0100 |
---|---|---|
committer | Marvin Borner | 2019-11-23 01:02:19 +0100 |
commit | 945d1c9eb7a6520429ebf2f988ac6cc1d12ec75d (patch) | |
tree | 04907ea20b6965b610fa7d01b5f63787a7b37221 | |
parent | 45d9495e77dba212551ae9bc8e09b51e9ed6d324 (diff) |
Fixed almost every vesa memory bug
-rw-r--r-- | src/kernel/graphics/vesa.c | 42 | ||||
-rw-r--r-- | src/kernel/graphics/vesa.h | 12 | ||||
-rw-r--r-- | src/kernel/io/io.c | 3 | ||||
-rw-r--r-- | src/kernel/lib/memory.c | 2 |
4 files changed, 43 insertions, 16 deletions
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index 9048469..becc5ff 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -64,6 +64,10 @@ 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); + for (size_t i = 0; i < number_modes; i++) + ret[i] = ((uint16_t *) info->video_modes)[i]; + return mode_ptr; } @@ -74,12 +78,20 @@ struct vbe_mode_info *vbe_get_mode_info(uint16_t mode) { regs.es = 0; regs.di = 0x7E00; v86(0x10, ®s); + if (regs.ax != 0x004f) return 0; - struct vbe_mode_info *mode_info = (struct vbe_mode_info *) 0x7E00; + struct vbe_mode_info_all *mode_info = (struct vbe_mode_info_all *) 0x7E00; - if (regs.ax != 0x004f) return 0; + struct vbe_mode_info *ret = (struct vbe_mode_info *) kmalloc(sizeof(struct vbe_mode_info)); + ret->attributes = mode_info->attributes; + ret->pitch = mode_info->pitch; + ret->width = mode_info->width; + ret->height = mode_info->height; + ret->bpp = mode_info->bpp; + ret->memory_model = mode_info->memory_model; + ret->framebuffer = mode_info->framebuffer; - return mode_info; + return ret; } void set_optimal_resolution() { @@ -94,8 +106,10 @@ void set_optimal_resolution() { struct vbe_mode_info *mode_info = vbe_get_mode_info(*mode); if (mode_info == 0 || (mode_info->attributes & 0x90) != 0x90 || - (mode_info->memory_model != 4 && mode_info->memory_model != 6)) + (mode_info->memory_model != 4 && mode_info->memory_model != 6)) { + kfree(mode_info); continue; + } serial_write("Found mode: ("); serial_write_hex(*mode); @@ -117,8 +131,11 @@ void set_optimal_resolution() { vbe_bpl = mode_info->bpp >> 3; fb = (unsigned char *) mode_info->framebuffer; } + kfree(mode_info); } + kfree(video_modes); + if (highest == 0) { serial_write("Mode detection failed!\nTrying common modes...\n"); vga_log("Mode detection failed!", 11); @@ -142,11 +159,12 @@ void set_optimal_resolution() { for (size_t i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { mode_info = vbe_get_mode_info(modes[i]); if (mode_info == 0 || (mode_info->attributes & 0x90) != 0x90 || - (mode_info->memory_model != 4 && mode_info->memory_model != 6)) + (mode_info->memory_model != 4 && mode_info->memory_model != 6)) { + kfree(mode_info); continue; + } - if ((mode_info->width > vbe_width || - (mode_info->width == vbe_width && (mode_info->bpp >> 3) > vbe_bpl))) { + if ((mode_info->width > vbe_width || (mode_info->width == vbe_width && (mode_info->bpp >> 3) > vbe_bpl))) { highest = modes[i]; vbe_width = mode_info->width; vbe_height = mode_info->height; @@ -154,6 +172,7 @@ void set_optimal_resolution() { vbe_bpl = mode_info->bpp >> 3; fb = (unsigned char *) mode_info->framebuffer; } + kfree(mode_info); } // Everything else failed :( @@ -163,6 +182,10 @@ void set_optimal_resolution() { vbe_set_mode(highest); + uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; + for (uint32_t z = 0; z < fb_size; z += 4096) + paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED); + if (vbe_height > 1440) vesa_set_font(32); else if (vbe_height > 720) vesa_set_font(24); else vesa_set_font(16); @@ -183,11 +206,6 @@ void set_optimal_resolution() { vesa_draw_number(vbe_height); vesa_draw_string("x"); vesa_draw_number(vbe_bpl << 3); - - uint32_t fb_size = vbe_width * vbe_height * vbe_bpl; - for (uint32_t z = 0; z < fb_size; z += 4096) - paging_map((uint32_t) fb + z, (uint32_t) fb + z, PT_PRESENT | PT_RW | PT_USED); - } const uint32_t default_text_color = vesa_white; diff --git a/src/kernel/graphics/vesa.h b/src/kernel/graphics/vesa.h index 1e49cd0..c2a0501 100644 --- a/src/kernel/graphics/vesa.h +++ b/src/kernel/graphics/vesa.h @@ -54,7 +54,7 @@ struct vbe_info { * The CPUs response to the 0x4F01 call * Used to get information about a specific video mode code */ -struct vbe_mode_info { +struct vbe_mode_info_all { uint16_t attributes; uint8_t window_a; uint8_t window_b; @@ -92,6 +92,16 @@ struct vbe_mode_info { uint8_t reserved1[206]; } __attribute__ ((packed)); +struct vbe_mode_info { + uint16_t attributes; + uint16_t pitch; + uint16_t width; + uint16_t height; + uint8_t bpp; + uint8_t memory_model; + uint32_t framebuffer; +} __attribute__ ((packed)); + /** * Get the monitors EDID information * TODO: Add EDID/VBE resolution mode verification diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c index 1ee76a0..3abbb18 100644 --- a/src/kernel/io/io.c +++ b/src/kernel/io/io.c @@ -90,6 +90,5 @@ void serial_write_hex(int n) { } void serial_write_dec(int n) { - char *text = itoa(n); - serial_write(text); + serial_write(itoa(n)); } diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index 0659406..a80309e 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -53,7 +53,7 @@ void memory_init() { } uint32_t memory_get_free() { - return (total_memory) - paging_get_used_pages() * 4; + return total_memory - paging_get_used_pages() * 4; } uint32_t memory_get_all() { return total_memory; }
\ No newline at end of file |