From f0706b802bc48144857870f9299bb4f60d203d14 Mon Sep 17 00:00:00 2001 From: fef Date: Thu, 21 Oct 2021 23:21:56 +0200 Subject: [PATCH] boot: ignore unaddressable RAM areas on i386 We don't support PAE or any other fancy hack to get past the 4 GB limit on 32-bit, so we have to clip areas that would fall outside that range --- arch/x86/boot/boot.c | 45 ++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/arch/x86/boot/boot.c b/arch/x86/boot/boot.c index 2e609fb..5c19566 100644 --- a/arch/x86/boot/boot.c +++ b/arch/x86/boot/boot.c @@ -4,10 +4,10 @@ #include #include +#include #include #include -#include #include #include #include @@ -81,7 +81,7 @@ static const char *mmap_type_name(u32 type); extern int main(int argc, char *argv[]); -__asmlink void _boot(u32 magic, uintptr_t phys_address) /* NOLINT */ +__asmlink void _boot(u32 magic, uintptr_t phys_address) { kprintf_set_printer(&fb_kprintf_printer); fb_init(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); @@ -142,20 +142,32 @@ static inline int handle_mmap_tag(struct mb2_tag_mmap *tag) struct mb2_mmap_entry *entry = &tag->entries[0]; while ((void *)entry < (void *)tag + tag->tag.size) { - kprintf(" [%p-%p] %s\n", - (void *)entry->addr, - (void *)entry->addr + entry->len - 1, + kprintf(" [0x%016llx-0x%016llx] %s\n", + entry->addr, + entry->addr + entry->len - 1, mmap_type_name(entry->type)); - if (entry->type == 1 && entry->len > region_len) { + usize safe_len; +# ifdef __x86_64__ + safe_len = entry->safe_len; +# else + if (entry->addr >= (1llu << 32)) + safe_len = 0; /* we can't handle 64-bit pointers */ + else if (entry->len > (1llu << 32) - entry->addr) + safe_len = (1llu << 32) - entry->addr; /* clip to 32-bit */ + else + safe_len = entry->len; +# endif + + if (entry->type == MB2_MEMORY_AVAILABLE && safe_len > region_len) { region = entry->addr; - region_len = entry->len; + region_len = safe_len; } entry = (void *)entry + tag->entry_size; } - if (region == 0) { + if (region == 0 || region_len == 0) { kprintf("No memory available! Aborting.\n"); return 1; } @@ -182,9 +194,9 @@ static void fb_newline(void) fb_col = 0; if (fb_line == FB_LINES - 1) { - u8 *first_row = (u8 *)cell_at(0, 0); - u8 *second_row = (u8 *)cell_at(1, 0); - u8 *last_row_end = (u8 *)cell_at(FB_LINES, FB_COLS); + void *first_row = (void *)cell_at(0, 0); + void *second_row = (void *)cell_at(1, 0); + void *last_row_end = (void *)cell_at(FB_LINES, FB_COLS); memmove(first_row, second_row, last_row_end - second_row); } else { fb_line++; @@ -227,7 +239,7 @@ static void fb_clear(void) { for (unsigned int l = 0; l < FB_LINES; l++) { for (unsigned int c = 0; c < FB_COLS; c++) { - cell_at(l, c)->c = '\0'; + cell_at(l, c)->c = ' '; cell_at(l, c)->fg = fb_foreground; cell_at(l, c)->bg = fb_background; } @@ -241,6 +253,10 @@ static void fb_init(enum vga_color fg, enum vga_color bg) fb_foreground = fg; fb_background = bg; + /* disable cursor */ + x86_outb(0x3D4, 0x0A); + x86_outb(0x3D5, 0x20); + fb_clear(); } @@ -254,13 +270,14 @@ static void print_gay_propaganda(void) VGA_COLOR_BLUE, VGA_COLOR_MAGENTA, }; + static char line[FB_COLS]; + memset(line, ' ', FB_COLS); enum vga_color bg_before = fb_background; enum vga_color fg_before = fb_foreground; for (int i = 0; i < ARRAY_SIZE(rainbow); i++) { fb_background = rainbow[i]; - for (int j = 0; j < FB_COLS; j++) - fb_write(NULL, " ", 1); + fb_write(NULL, line, FB_COLS); } fb_background = bg_before;