From 4b56b72576909b81509cea100ebaa005342102fa Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Thu, 23 May 2019 17:11:47 +0300 Subject: [PATCH] Multiboot support refactoring --- src/boot/include/multiboot_info.hpp | 145 ++++++++++++++++++++++------ src/platform/pagetable.cpp | 39 ++++---- src/process/modules.cpp | 6 +- 3 files changed, 142 insertions(+), 48 deletions(-) diff --git a/src/boot/include/multiboot_info.hpp b/src/boot/include/multiboot_info.hpp index d279798..678f87e 100644 --- a/src/boot/include/multiboot_info.hpp +++ b/src/boot/include/multiboot_info.hpp @@ -7,42 +7,133 @@ class Multiboot { public: enum Flags: uint32_t { - MB_FLAG_MEM = (1 << 0), - MB_FLAG_BOOTDEV = (1 << 1), - MB_FLAG_CMDLINE = (1 << 2), - MB_FLAG_MODS = (1 << 3), - MB_FLAG_SYMTAB = (1 << 4), - MB_FLAG_ELFSYMTAB = (1 << 5), - MB_FLAG_MEMMAP = (1 << 6), - MB_FLAG_DRIVEMAP = (1 << 7), - MB_FLAG_CONFTAB = (1 << 8), - MB_FLAG_BLNAME = (1 << 9), - MB_FLAG_APMTAB = (1 << 10), - MB_FLAG_VBETAB = (1 << 11) + FLAG_MEM = (1 << 0), + FLAG_BOOTDEV = (1 << 1), + FLAG_CMDLINE = (1 << 2), + FLAG_MODS = (1 << 3), + FLAG_SYMTAB = (1 << 4), + FLAG_ELFSYMTAB = (1 << 5), + FLAG_MEMMAP = (1 << 6), + FLAG_DRIVEMAP = (1 << 7), + FLAG_CONFTAB = (1 << 8), + FLAG_BLNAME = (1 << 9), + FLAG_APMTAB = (1 << 10), + FLAG_VBETAB = (1 << 11), + FLAG_FBTAB = (1 << 12), + }; + enum MemoryType: uint32_t { + MEMORY_AVAILABLE = 1, + MEMORY_RESERVED = 2, + MEMORY_ACPI_RECLAIMABLE = 3, + MEMORY_NVS = 4, + MEMORY_BADRAM = 5, + }; + enum FramebufferType: uint8_t { + FRAMEBUFFER_TYPE_INDEXED = 0, + FRAMEBUFFER_TYPE_RGB = 1, + FRAMEBUFFER_TYPE_EGA_TEXT = 2, }; struct Payload { Flags flags; - size_t mem_lower:32, mem_upper:32; + struct { + size_t lower:32, upper:32; + } PACKED mem; uint32_t boot_device; - uint32_t pcmdline; - uint32_t mods_count; - uint32_t pmods_addr; - uint32_t syms[3]; - uint32_t mmap_length; - uint32_t pmmap_addr; - uint32_t drives_length; - uint32_t pdrives_addr; - uint32_t pconfig_table; - uint32_t pboot_loader_name; - uint32_t papm_table; - uint64_t pvbe_control_info, pvbe_mode_info, pvbe_mode, pvbe_interface_seg, - pvbe_interface_off, pvbe_interface_len; + uintptr_t pcmdline:32; + struct { uint32_t count; uintptr_t paddr:32; } PACKED mods; + union { + struct { uint32_t tabsize, strsize, addr, rsvd; } PACKED aout; + struct { uint32_t num, size, addr, shndx; } PACKED elf; + } PACKED syms; + struct { size_t size:32; uintptr_t paddr:32; } PACKED mmap; + struct { size_t size:32; uintptr_t paddr:32; } PACKED drives; + uintptr_t pconfig_table:32; + uintptr_t pboot_loader_name:32; + uintptr_t papm_table:32; + struct { + uintptr_t pcontrol_info:32; + uintptr_t pmode_info:32; + uint16_t mode, interface_seg, interface_off, interface_len; + } PACKED vbe; + struct { + uintptr_t paddr; + uint32_t pitch, width, height; + uint8_t bpp; + FramebufferType type; + union { + struct { + uint32_t paddr; + uint16_t num_colors; + } PACKED palette; + struct { + uint8_t red_field_position; + uint8_t red_mask_size; + uint8_t green_field_position; + uint8_t green_mask_size; + uint8_t blue_field_position; + uint8_t blue_mask_size; + } PACKED rgb; + } PACKED; + } PACKED fb; + } PACKED; + struct VBEInfo { + uint32_t signature; + uint16_t version; + uintptr_t vendor_string:32; + uint32_t capabilities; + uintptr_t video_mode_ptr:32; + uint16_t total_memory; + + uint16_t oem_software_rev; + uintptr_t oem_vendor_name_ptr:32; + uintptr_t oem_product_name_ptr:32; + uintptr_t oem_product_rev_ptr:32; + + uint8_t reserved[222]; + uint8_t oem_data[256]; + } PACKED; + struct VBEModeInfo { + uint16_t mode_attr; + uint8_t win_attr[2]; + uint16_t win_grain; + uint16_t win_size; + uint16_t win_seg[2]; + uintptr_t win_scheme:32; + uint16_t logical_scan; + + uint16_t h_res; + uint16_t v_res; + uint8_t char_width; + uint8_t char_height; + uint8_t memory_planes; + uint8_t bpp; + uint8_t banks; + uint8_t memory_layout; + uint8_t bank_size; + uint8_t image_pages; + uint8_t page_function; + + uint8_t rmask; + uint8_t rpos; + uint8_t gmask; + uint8_t gpos; + uint8_t bmask; + uint8_t bpos; + uint8_t resv_mask; + uint8_t resv_pos; + uint8_t dcm_info; + + uintptr_t lfb_ptr:32; + uintptr_t offscreen_ptr:32; + uint16_t offscreen_size; + + uint8_t reserved[206]; } PACKED; struct MmapEnt { uint32_t size; void *base; size_t length; - uint32_t type; + MemoryType type; } PACKED; struct Module { uint32_t start; diff --git a/src/platform/pagetable.cpp b/src/platform/pagetable.cpp index d1ff5cf..2d9705e 100644 --- a/src/platform/pagetable.cpp +++ b/src/platform/pagetable.cpp @@ -297,29 +297,29 @@ void Pagetable::init() { map(multiboot); uintptr_t bss_end; asm volatile("lea __bss_end__(%%rip), %q0":"=r"(bss_end)); - if (multiboot->flags & Multiboot::MB_FLAG_MEM) { - max_page = ((uintptr_t(multiboot->mem_upper) * 1024) + 0x100000lu) >> 12; + if (multiboot->flags & Multiboot::FLAG_MEM) { + max_page = ((multiboot->mem.upper * 1024) + 0x100000lu) >> 12; } - if (multiboot->flags & Multiboot::MB_FLAG_CMDLINE) { + if (multiboot->flags & Multiboot::FLAG_CMDLINE) { if (multiboot->pcmdline < 0x80000) multiboot->pcmdline += bss_end; map(reinterpret_cast(uintptr_t(multiboot->pcmdline))); } - if (multiboot->flags & Multiboot::MB_FLAG_MODS) { - if (multiboot->pmods_addr < 0x80000) - multiboot->pmods_addr += bss_end; + if (multiboot->flags & Multiboot::FLAG_MODS) { + if (multiboot->mods.paddr < 0x80000) + multiboot->mods.paddr += bss_end; - uintptr_t low = uintptr_t(multiboot->pmods_addr) & 0xFFFFFFFFFFFFF000; + uintptr_t low = uintptr_t(multiboot->mods.paddr) & 0xFFFFFFFFFFFFF000; uintptr_t top = klib::__align( - uintptr_t(multiboot->pmods_addr) + - multiboot->mods_count * sizeof(Multiboot::Module), + uintptr_t(multiboot->mods.paddr) + + multiboot->mods.count * sizeof(Multiboot::Module), 0x1000); for (uintptr_t addr = low; addr < top; addr += 0x1000) map(reinterpret_cast(addr)); const Multiboot::Module *mods = - reinterpret_cast(uintptr_t(multiboot->pmods_addr)); - for (uint32_t i = 0; i < multiboot->mods_count; i++) { + reinterpret_cast(uintptr_t(multiboot->mods.paddr)); + for (uint32_t i = 0; i < multiboot->mods.count; i++) { uintptr_t low = mods[i].start; uintptr_t top = klib::__align(mods[i].end, 0x1000); for (uintptr_t addr = low; addr < top; addr += 0x1000) @@ -327,20 +327,23 @@ void Pagetable::init() { } } - if (multiboot->flags & Multiboot::MB_FLAG_MEMMAP) { - if (multiboot->pmmap_addr < 0x80000) - multiboot->pmmap_addr += bss_end; + if (multiboot->flags & Multiboot::FLAG_MEMMAP) { + if (multiboot->mmap.paddr < 0x80000) + multiboot->mmap.paddr += bss_end; - const char *mmap = reinterpret_cast(uintptr_t(multiboot->pmmap_addr)); - const char *mmap_top = mmap + multiboot->mmap_length; + max_page = 0; + const char *mmap = reinterpret_cast(uintptr_t(multiboot->mmap.paddr)); + const char *mmap_top = mmap + multiboot->mmap.size; while (mmap < mmap_top) { const Multiboot::MmapEnt *ent = reinterpret_cast(mmap); map(ent); + uintptr_t low = uintptr_t(ent->base) & 0xFFFFFFFFFFFFF000; + uintptr_t top = klib::__align(uintptr_t(ent->base) + ent->length, 0x1000); if (ent->type != 1) { - uintptr_t low = uintptr_t(ent->base) & 0xFFFFFFFFFFFFF000; - uintptr_t top = klib::__align(uintptr_t(ent->base) + ent->length, 0x1000); for (uintptr_t addr = low; addr < top; addr += 0x1000) map(reinterpret_cast(addr)); + } else { + max_page = klib::max(max_page, top >> 12); } mmap += ent->size + sizeof(ent->size); } diff --git a/src/process/modules.cpp b/src/process/modules.cpp index 969d2a0..6d47358 100644 --- a/src/process/modules.cpp +++ b/src/process/modules.cpp @@ -172,10 +172,10 @@ void ModuleManager::parseInternal() { } void ModuleManager::parseInitRD() { Multiboot::Payload *multiboot = Multiboot::getPayload(); - if (!multiboot || (multiboot->flags & Multiboot::MB_FLAG_MODS) == 0) return; + if (!multiboot || (multiboot->flags & Multiboot::FLAG_MODS) == 0) return; const Multiboot::Module *mods = - reinterpret_cast(uintptr_t(multiboot->pmods_addr)); - for (uint32_t i = 0; i < multiboot->mods_count; i++) { + reinterpret_cast(uintptr_t(multiboot->mods.paddr)); + for (uint32_t i = 0; i < multiboot->mods.count; i++) { const char *base = reinterpret_cast(uintptr_t(mods[i].start)); const char *top = reinterpret_cast(uintptr_t(mods[i].end)); size_t length = size_t(top - base);