diff --git a/kernel/include/multiboot.h b/kernel/include/multiboot.h index 5cf26ec9..62648574 100644 --- a/kernel/include/multiboot.h +++ b/kernel/include/multiboot.h @@ -13,10 +13,12 @@ #define MULTIBOOT_FLAG_AOUT 0x010 #define MULTIBOOT_FLAG_ELF 0x020 #define MULTIBOOT_FLAG_MMAP 0x040 -#define MULTIBOOT_FLAG_CONFIG 0x080 -#define MULTIBOOT_FLAG_LOADER 0x100 -#define MULTIBOOT_FLAG_APM 0x200 -#define MULTIBOOT_FLAG_VBE 0x400 +#define MULTIBOOT_FLAG_DRIVE 0x080 +#define MULTIBOOT_FLAG_CONFIG 0x100 +#define MULTIBOOT_FLAG_LOADER 0x200 +#define MULTIBOOT_FLAG_APM 0x400 +#define MULTIBOOT_FLAG_VBE 0x800 +#define MULTIBOOT_FLAG_FB 0x1000 struct multiboot { @@ -44,6 +46,13 @@ struct multiboot uintptr_t vbe_interface_seg; uintptr_t vbe_interface_off; uintptr_t vbe_interface_len; + uintptr_t framebuffer_addr; + uintptr_t framebuffer_pitch; + uintptr_t framebuffer_width; + uintptr_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; + /* Palette stuff goes here but we don't use it */ } __attribute__ ((packed)); typedef struct { diff --git a/kernel/include/video.h b/kernel/include/video.h index 3244e54c..b70f994a 100644 --- a/kernel/include/video.h +++ b/kernel/include/video.h @@ -8,6 +8,11 @@ #define IO_VID_SET 0x5006 #define IO_VID_STRIDE 0x5007 +struct vid_size { + uint32_t width; + uint32_t height; +}; + #ifdef _KERNEL_ extern void lfb_set_resolution(uint16_t x, uint16_t y); extern uint16_t lfb_resolution_x; diff --git a/kernel/main.c b/kernel/main.c index 37a478e4..1df665b2 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -3,7 +3,7 @@ * The ToAruOS kernel is released under the terms of the * University of Illinois / NCSA License. * - * Copyright (C) 2011-2014 Kevin Lange. All rights reserved. + * Copyright (C) 2011-2018 K. Lange. All rights reserved. * Copyright (C) 2012 Markus Schober * Copyright (C) 2014 Lioncash * @@ -12,7 +12,7 @@ * 1941-2011 * * Developed by: ToAruOS Kernel Development Team - * http://github.com/klange/osdev + * http://gitlab.com/toaruos * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -25,7 +25,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the ToAruOS Kernel Development Team, Kevin Lange, + * 3. Neither the names of the ToAruOS Kernel Development Team, K. Lange, * nor the names of its contributors may be used to endorse * or promote products derived from this Software without specific prior * written permission. @@ -96,11 +96,11 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) { isrs_install(); /* Interrupt service requests */ irq_install(); /* Hardware interrupt requests */ - if (mboot_ptr->flags & (1 << 3)) { + uintptr_t last_mod = (uintptr_t)&end; + if (mboot_ptr->flags & MULTIBOOT_FLAG_MODS) { debug_print(NOTICE, "There %s %d module%s starting at 0x%x.", mboot_ptr->mods_count == 1 ? "is" : "are", mboot_ptr->mods_count, mboot_ptr->mods_count == 1 ? "" : "s", mboot_ptr->mods_addr); debug_print(NOTICE, "Current kernel heap start point would be 0x%x.", &end); if (mboot_ptr->mods_count > 0) { - uintptr_t last_mod = (uintptr_t)&end; uint32_t i; mboot_mods = (mboot_mod_t *)mboot_ptr->mods_addr; mboot_mods_count = mboot_ptr->mods_count; @@ -111,6 +111,7 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) { if ((uintptr_t)mod + sizeof(mboot_mod_t) > last_mod) { /* Just in case some silly person put this *behind* the modules... */ last_mod = (uintptr_t)mod + sizeof(mboot_mod_t); + debug_print(NOTICE, "moving forward to 0x%x", last_mod); } debug_print(NOTICE, "Module %d is at 0x%x:0x%x", i, module_start, module_end); if (last_mod < module_end) { @@ -118,12 +119,21 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) { } } debug_print(NOTICE, "Moving kernel heap start to 0x%x", last_mod); - kmalloc_startat(last_mod); } } + if ((uintptr_t)mboot_ptr > last_mod) { + last_mod = (uintptr_t)mboot_ptr + sizeof(struct multiboot); + } + while (last_mod & 0x7FF) last_mod++; + kmalloc_startat(last_mod); - paging_install(mboot_ptr->mem_upper + mboot_ptr->mem_lower); - if (mboot_ptr->flags & (1 << 6)) { + if (mboot_ptr->flags & MULTIBOOT_FLAG_MEM) { + paging_install(mboot_ptr->mem_upper + mboot_ptr->mem_lower); + } else { + debug_print(CRITICAL, "Missing MEM flag in multiboot header\n"); + } + + if (mboot_ptr->flags & MULTIBOOT_FLAG_MMAP) { debug_print(NOTICE, "Parsing memory map."); mboot_memmap_t * mmap = (void *)mboot_ptr->mmap_addr; while ((uintptr_t)mmap < mboot_ptr->mmap_addr + mboot_ptr->mmap_length) { @@ -168,40 +178,42 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) { DISABLE_EARLY_BOOT_LOG(); /* Load modules from bootloader */ - debug_print(NOTICE, "%d modules to load", mboot_mods_count); - for (unsigned int i = 0; i < mboot_ptr->mods_count; ++i ) { - mboot_mod_t * mod = &mboot_mods[i]; - uint32_t module_start = mod->mod_start; - uint32_t module_end = mod->mod_end; - size_t module_size = module_end - module_start; + if (mboot_ptr->flags & MULTIBOOT_FLAG_MODS) { + debug_print(NOTICE, "%d modules to load", mboot_mods_count); + for (unsigned int i = 0; i < mboot_ptr->mods_count; ++i ) { + mboot_mod_t * mod = &mboot_mods[i]; + uint32_t module_start = mod->mod_start; + uint32_t module_end = mod->mod_end; + size_t module_size = module_end - module_start; - int check_result = module_quickcheck((void *)module_start); - if (check_result == 1) { - debug_print(NOTICE, "Loading a module: 0x%x:0x%x", module_start, module_end); - module_data_t * mod_info = (module_data_t *)module_load_direct((void *)(module_start), module_size); - if (mod_info) { - debug_print(NOTICE, "Loaded: %s", mod_info->mod_info->name); - } - } else if (check_result == 2) { - /* Mod pack */ - debug_print(NOTICE, "Loading modpack. %x", module_start); - struct pack_header * pack_header = (struct pack_header *)module_start; - while (pack_header->region_size) { - void * start = (void *)((uintptr_t)pack_header + 4096); - int result = module_quickcheck(start); - if (result != 1) { - debug_print(WARNING, "Not actually a module?! %x", start); - } - module_data_t * mod_info = (module_data_t *)module_load_direct(start, pack_header->region_size); + int check_result = module_quickcheck((void *)module_start); + if (check_result == 1) { + debug_print(NOTICE, "Loading a module: 0x%x:0x%x", module_start, module_end); + module_data_t * mod_info = (module_data_t *)module_load_direct((void *)(module_start), module_size); if (mod_info) { debug_print(NOTICE, "Loaded: %s", mod_info->mod_info->name); } - pack_header = (struct pack_header *)((uintptr_t)start + pack_header->region_size); + } else if (check_result == 2) { + /* Mod pack */ + debug_print(NOTICE, "Loading modpack. %x", module_start); + struct pack_header * pack_header = (struct pack_header *)module_start; + while (pack_header->region_size) { + void * start = (void *)((uintptr_t)pack_header + 4096); + int result = module_quickcheck(start); + if (result != 1) { + debug_print(WARNING, "Not actually a module?! %x", start); + } + module_data_t * mod_info = (module_data_t *)module_load_direct(start, pack_header->region_size); + if (mod_info) { + debug_print(NOTICE, "Loaded: %s", mod_info->mod_info->name); + } + pack_header = (struct pack_header *)((uintptr_t)start + pack_header->region_size); + } + debug_print(NOTICE, "Done with modpack."); + } else { + debug_print(NOTICE, "Loading ramdisk: 0x%x:0x%x", module_start, module_end); + ramdisk_mount(module_start, module_size); } - debug_print(NOTICE, "Done with modpack."); - } else { - debug_print(NOTICE, "Loading ramdisk: 0x%x:0x%x", module_start, module_end); - ramdisk_mount(module_start, module_size); } } diff --git a/modules/lfbvideo.c b/modules/lfbvideo.c index 808ff6b5..f702e50a 100644 --- a/modules/lfbvideo.c +++ b/modules/lfbvideo.c @@ -46,11 +46,6 @@ void lfb_set_resolution(uint16_t x, uint16_t y); */ uint8_t * lfb_vid_memory = (uint8_t *)0xE0000000; -struct vid_size { - uint32_t width; - uint32_t height; -}; - static int ioctl_vid(fs_node_t * node, int request, void * argp) { /* TODO: Make this actually support multiple video devices */ @@ -205,7 +200,8 @@ static uint16_t bochs_current_scroll(void) { static void bochs_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra) { if ((v == 0x1234 && d == 0x1111) || - (v == 0x80EE && d == 0xBEEF)) { + (v == 0x80EE && d == 0xBEEF) || + (v == 0x10de && d == 0x0a20)) { uintptr_t t = pci_read_field(device, PCI_BAR0, 4); if (t > 0) { *((uint8_t **)extra) = (uint8_t *)(t & 0xFFFFFFF0); @@ -329,6 +325,20 @@ static void graphics_install_preset(uint16_t w, uint16_t h) { debug_print(NOTICE, "Graphics were pre-configured (thanks, bootloader!), locating video memory..."); uint16_t b = 32; /* If you are 24 bit, go away, we really do not support you. */ + if (mboot_ptr && (mboot_ptr->flags & (1 << 12))) { + /* hello world */ + lfb_vid_memory = (void *)mboot_ptr->framebuffer_addr; + w = mboot_ptr->framebuffer_width; + h = mboot_ptr->framebuffer_height; + + debug_print(WARNING, "Mode was set by bootloader: %dx%d bpp should be 32, framebuffer is at 0x%x", w, h, (uintptr_t)lfb_vid_memory); + + for (uintptr_t i = (uintptr_t)lfb_vid_memory; i <= (uintptr_t)lfb_vid_memory + w * h * 4; i += 0x1000) { + dma_frame(get_page(i, 1, kernel_directory), 0, 1, i); + } + goto mem_found; + } + /* XXX: Massive hack */ uint32_t * herp = (uint32_t *)0xA0000; herp[0] = 0xA5ADFACE; @@ -475,7 +485,8 @@ static void auto_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra) struct disp_mode * mode = extra; if (mode->set) return; if ((v == 0x1234 && d == 0x1111) || - (v == 0x80EE && d == 0xBEEF)) { + (v == 0x80EE && d == 0xBEEF) || + (v == 0x10de && d == 0x0a20)) { mode->set = 1; graphics_install_bochs(mode->x, mode->y); } else if ((v == 0x15ad && d == 0x0405)) {