From cb349ae620b3684b7e8d646bbb6f91d3c462eb4d Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 18 Oct 2022 21:16:12 +0300 Subject: [PATCH] x32 still not working (TODO: do 1:1 page mapping, except for kernel) --- Architecture/i686/Multiboot2.cpp | 338 ++++++++++++++++++ Architecture/i686/boot.asm | 16 +- Core/CrashHandler.cpp | 30 +- Core/Memory/Memory.cpp | 56 ++- Core/Memory/PhysicalMemoryManager.cpp | 23 +- Core/PeripheralComponentInterconnect.cpp | 2 +- Core/Symbols.cpp | 2 +- Core/SystemCalls.cpp | 4 +- ...iversalAsynchronousReceiverTransmitter.cpp | 2 +- Kernel.cpp | 36 -- Makefile | 2 +- include/boot/binfo.h | 4 +- include/display.hpp | 2 +- include/memory.hpp | 45 ++- include/vector.hpp | 12 +- 15 files changed, 480 insertions(+), 94 deletions(-) create mode 100644 Architecture/i686/Multiboot2.cpp diff --git a/Architecture/i686/Multiboot2.cpp b/Architecture/i686/Multiboot2.cpp new file mode 100644 index 0000000..066c09f --- /dev/null +++ b/Architecture/i686/Multiboot2.cpp @@ -0,0 +1,338 @@ +#include + +#include +#include + +#include "../../kernel.h" + +enum VideoType +{ + VIDEO_TYPE_NONE = 0x00, + VIDEO_TYPE_COLOUR = 0x20, + VIDEO_TYPE_MONOCHROME = 0x30, +}; + +uint16_t GetBiosAreaHardware() +{ + const uint16_t *BIOSDataAreaDetectedHardware = (const uint16_t *)0x410; + return *BIOSDataAreaDetectedHardware; +} + +enum VideoType GetVideoType() { return (enum VideoType)(GetBiosAreaHardware() & 0x30); } + +void GetSMBIOS() +{ + unsigned char *SMBIOSAddress = (unsigned char *)0xF0000; + while ((unsigned int)(unsigned long)SMBIOSAddress < 0x100000) + { + if (SMBIOSAddress[0] == '_' && + SMBIOSAddress[1] == 'S' && + SMBIOSAddress[2] == 'M' && + SMBIOSAddress[3] == '_') + { + unsigned char Checksum = 0; + int Length = SMBIOSAddress[5]; + for (int i = 0; i < Length; i++) + Checksum += SMBIOSAddress[i]; + + if (Checksum == 0) + break; + } + SMBIOSAddress += 16; + } + + if ((unsigned int)(unsigned long)SMBIOSAddress == 0x100000) + { + // No SMBIOS found + } +} + +struct multiboot_info +{ + multiboot_uint32_t Size; + multiboot_uint32_t Reserved; + struct multiboot_tag *Tag; +}; + +EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic) +{ + if (Info == NULL || Magic == NULL) + { + if (Magic == NULL) + error("Multiboot magic is NULL"); + if (Info == NULL) + error("Multiboot info is NULL"); + CPU::Stop(); + } + else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) + { + error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC); + trace("Hello, World!"); + CPU::Stop(); + } + + uint64_t div = 1193180 / 1000; + outb(0x43, 0xB6); + outb(0x42, (uint8_t)div); + outb(0x42, (uint8_t)(div >> 8)); + uint8_t tmp = inb(0x61); + if (tmp != (tmp | 3)) + outb(0x61, tmp | 3); + + BootInfo binfo; + uint32_t Itr = 0; + + for (uint32_t i = 8; i < Info->Size; i += Itr) + { + multiboot_tag *Tag = (multiboot_tag *)((uint8_t *)Info + i); + if (Tag->type == MULTIBOOT_TAG_TYPE_END) + break; + + switch (Tag->type) + { + case MULTIBOOT_TAG_TYPE_CMDLINE: + { + strcpy(binfo.Kernel.CommandLine, ((multiboot_tag_string *)Tag)->string); + break; + } + case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: + { + strcpy(binfo.Bootloader.Name, ((multiboot_tag_string *)Tag)->string); + break; + } + case MULTIBOOT_TAG_TYPE_MODULE: + { + multiboot_tag_module *module = (multiboot_tag_module *)Tag; + static int module_count = 0; + binfo.Modules[module_count++].Address = (void *)module->mod_start; + binfo.Modules[module_count++].Size = module->size; + strcpy(binfo.Modules[module_count++].Path, "(null)"); + strcpy(binfo.Modules[module_count++].CommandLine, module->cmdline); + break; + } + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + { + multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag; + fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]", + meminfo->mem_lower, meminfo->mem_upper); + break; + } + case MULTIBOOT_TAG_TYPE_BOOTDEV: + { + multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag; + fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]", + bootdev->biosdev, bootdev->slice, bootdev->part); + break; + } + case MULTIBOOT_TAG_TYPE_MMAP: + { + multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag; + uint32_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry); + + binfo.Memory.Entries = EntryCount; + for (uint32_t i = 0; i < EntryCount; i++) + { + if (EntryCount > MAX_MEMORY_ENTRIES) + { + warn("Too many memory entries, skipping the rest..."); + break; + } + + multiboot_mmap_entry entry = mmap->entries[i]; + binfo.Memory.Size += entry.len; + switch (entry.type) + { + case MULTIBOOT_MEMORY_AVAILABLE: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = Usable; + break; + case MULTIBOOT_MEMORY_RESERVED: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = Reserved; + break; + case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = ACPIReclaimable; + break; + case MULTIBOOT_MEMORY_NVS: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = ACPINVS; + break; + case MULTIBOOT_MEMORY_BADRAM: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = BadMemory; + break; + default: + binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + binfo.Memory.Entry[i].Length = entry.len; + binfo.Memory.Entry[i].Type = Unknown; + break; + } + } + break; + } + case MULTIBOOT_TAG_TYPE_VBE: + { + multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag; + fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]", + vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len); + break; + } + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag; + static int fb_count = 0; + + binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr; + binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width; + binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; + binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; + binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; + binfo.Framebuffer[fb_count].MemoryModel = fb->common.framebuffer_type; + + switch (fb->common.framebuffer_type) + { + case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: + { + fixme("indexed"); + break; + } + case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: + { + binfo.Framebuffer[fb_count].RedMaskSize = fb->framebuffer_red_mask_size; + binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position; + binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size; + binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position; + binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size; + binfo.Framebuffer[fb_count].BlueMaskShift = fb->framebuffer_blue_field_position; + break; + } + case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: + { + fixme("ega_text"); + break; + } + } + debug("Framebuffer %d: %dx%d %d bpp", i, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp); + debug("More info:\nAddress: %p\nPitch: %lld\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d", + fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type, + fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size, + fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position); + + fb_count++; + break; + } + case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + { + multiboot_tag_elf_sections *elf = (multiboot_tag_elf_sections *)Tag; + fixme("elf_sections->[num=%d, size=%d, entsize=%d, shndx=%d]", + elf->num, elf->size, elf->entsize, elf->shndx); + break; + } + case MULTIBOOT_TAG_TYPE_APM: + { + multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag; + fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]", + apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32: + { + multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag; + fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64: + { + multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag; + fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size); + break; + } + case MULTIBOOT_TAG_TYPE_SMBIOS: + { + multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag; + fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor); + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_OLD: + { + binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp; + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_NEW: + { + binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp; + break; + } + case MULTIBOOT_TAG_TYPE_NETWORK: + { + multiboot_tag_network *net = (multiboot_tag_network *)Tag; + fixme("network->[dhcpack: %p]", net->dhcpack); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_MMAP: + { + multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag; + fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]", + efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_BS: + { + fixme("efi_bs->[%p] (unknown structure)", Tag); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32_IH: + { + multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag; + fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64_IH: + { + multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag; + fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: + { + multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; + binfo.Kernel.PhysicalBase = (void *)load_base_addr->load_base_addr; + binfo.Kernel.VirtualBase = (void *)(load_base_addr->load_base_addr + 0xC0000000); + break; + } + } + Itr = Tag->size; + if ((Itr % 8) != 0) + Itr += (8 - Itr % 8); + } + + tmp = inb(0x61) & 0xFC; + outb(0x61, tmp); + + int *vm = (int *)0xb8000; + // "Not supported yet" + vm[0] = 0x054E; + vm[1] = 0x056F; + vm[2] = 0x0574; + vm[3] = 0x0520; + vm[4] = 0x0573; + vm[5] = 0x0575; + vm[6] = 0x0570; + vm[7] = 0x0570; + vm[8] = 0x0572; + vm[9] = 0x056F; + vm[10] = 0x0574; + vm[11] = 0x0520; + vm[12] = 0x0579; + vm[13] = 0x0565; + vm[14] = 0x0574; + + CPU::Stop(); + // Entry(&binfo); +} diff --git a/Architecture/i686/boot.asm b/Architecture/i686/boot.asm index 16d7477..4697ef5 100644 --- a/Architecture/i686/boot.asm +++ b/Architecture/i686/boot.asm @@ -18,19 +18,29 @@ KERNEL_VIRTUAL_BASE equ 0xC0000000 ; 3GB KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; 768 KERNEL_STACK_SIZE equ 0x4000 ; 16KB -extern x32Entry +extern x32Multiboot2Entry global _start section .data align 0x1000 BootPageTable: dd 0x00000083 - times (KERNEL_PAGE_NUMBER - 1) dd 0 + times ((KERNEL_PAGE_NUMBER) - 1) dd 0 dd 0x00000083 times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0 section .text _start: + mov word [0xb8000], 0x074C ; L + mov word [0xb8002], 0x076F ; o + mov word [0xb8004], 0x0761 ; a + mov word [0xb8006], 0x0764 ; d + mov word [0xb8008], 0x0769 ; i + mov word [0xb800a], 0x076E ; n + mov word [0xb800c], 0x0767 ; g + mov word [0xb800e], 0x072E ; . + mov word [0xb8010], 0x072E ; . + mov word [0xb8012], 0x072E ; . mov ecx, (BootPageTable - KERNEL_VIRTUAL_BASE) mov cr3, ecx mov ecx, cr4 @@ -48,7 +58,7 @@ HigherHalfStart: push eax ; Multiboot2 Magic add ebx, KERNEL_VIRTUAL_BASE push ebx ; Multiboot2 Header - call x32Entry + call x32Multiboot2Entry Loop: hlt jmp Loop diff --git a/Core/CrashHandler.cpp b/Core/CrashHandler.cpp index 12893d0..38cf1ba 100644 --- a/Core/CrashHandler.cpp +++ b/Core/CrashHandler.cpp @@ -59,7 +59,7 @@ namespace CrashHandler { #if defined(__amd64__) CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data; - error("Exception: %#lx", Frame->InterruptNumber); + error("Exception: %#llx", Frame->InterruptNumber); if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA) { @@ -215,18 +215,18 @@ namespace CrashHandler } } - EHPrint("\e7981FCTechnical Informations on CPU %ld:\n", + EHPrint("\e7981FCTechnical Informations on CPU %lld:\n", CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE)); - EHPrint("FS=%#lx GS=%#lx SS=%#lx CS=%#lx DS=%#lx\n", + EHPrint("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n", CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), Frame->ss, Frame->cs, Frame->ds); - EHPrint("R8=%#lx R9=%#lx R10=%#lx R11=%#lx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11); - EHPrint("R12=%#lx R13=%#lx R14=%#lx R15=%#lx\n", Frame->r12, Frame->r13, Frame->r14, Frame->r15); - EHPrint("RAX=%#lx RBX=%#lx RCX=%#lx RDX=%#lx\n", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); - EHPrint("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx\n", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); - EHPrint("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx\n", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); - EHPrint("CR0=%#lx CR2=%#lx CR3=%#lx CR4=%#lx CR8=%#lx\n", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); - EHPrint("DR0=%#lx DR1=%#lx DR2=%#lx DR3=%#lx DR6=%#lx DR7=%#lx\n", dr0, dr1, dr2, dr3, dr6, dr7.raw); + EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11); + EHPrint("R12=%#llx R13=%#llx R14=%#llx R15=%#llx\n", Frame->r12, Frame->r13, Frame->r14, Frame->r15); + EHPrint("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx\n", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); + EHPrint("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx\n", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); + EHPrint("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); + EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); + EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", dr0, dr1, dr2, dr3, dr6, dr7.raw); EHPrint("\eFC797BCR0: PE:%s MP:%s EM:%s TS:%s\n ET:%s NE:%s WP:%s AM:%s\n NW:%s CD:%s PG:%s\n R0:%#x R1:%#x R2:%#x\n", cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False", @@ -234,10 +234,10 @@ namespace CrashHandler cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False", cr0._reserved0, cr0._reserved1, cr0._reserved2); - EHPrint("\eFCBD79CR2: PFLA: %#lx\n", + EHPrint("\eFCBD79CR2: PFLA: %#llx\n", cr2.PFLA); - EHPrint("\e79FC84CR3: PWT:%s PCD:%s PDBR:%#lx\n", + EHPrint("\e79FC84CR3: PWT:%s PCD:%s PDBR:%#llx\n", cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); EHPrint("\eBD79FCCR4: VME:%s PVI:%s TSD:%s DE:%s\n PSE:%s PAE:%s MCE:%s PGE:%s\n PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s\n LA57:%s VMXE:%s SMXE:%s PCIDE:%s\n OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s\n R0:%#x R1:%#x R2:%#x\n", @@ -410,7 +410,7 @@ void StackFaultExceptionHandler(CPU::x64::TrapFrame *Frame) break; } debug("external:%d table:%d idx:%#x", SelCode.External, SelCode.Table, SelCode.Idx); - sprintf_(descbuf, "Stack segment fault at address %#lx", Frame->rip); + sprintf_(descbuf, "Stack segment fault at address %#llx", Frame->rip); CrashHandler::EHPrint(descbuf); sprintf_(desc_ext, "External: %d", SelCode.External); CrashHandler::EHPrint(desc_ext); @@ -452,7 +452,7 @@ void GeneralProtectionExceptionHandler(CPU::x64::TrapFrame *Frame) // SET_PRINT_MID((char *)"System crashed!", FHeight(6)); // CurrentDisplay->ResetPrintColor(); // SET_PRINT_MID((char *)"More info about the exception:", FHeight(4)); - // sprintf_(descbuf, "Kernel performed an illegal operation at address %#lx", RIP); + // sprintf_(descbuf, "Kernel performed an illegal operation at address %#llx", RIP); // SET_PRINT_MID((char *)descbuf, FHeight(5)); // sprintf_(desc_ext, "External: %d", SelCode.External); // SET_PRINT_MID((char *)desc_ext, FHeight(3)); @@ -477,7 +477,7 @@ void PageFaultExceptionHandler(CPU::x64::TrapFrame *Frame) staticbuffer(page_sgx); CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); - sprintf_(ret_err, "An exception occurred at %#lx by %#lx\n", CPU::x64::readcr2().PFLA, Frame->rip); + sprintf_(ret_err, "An exception occurred at %#llx by %#llx\n", CPU::x64::readcr2().PFLA, Frame->rip); CrashHandler::EHPrint(ret_err); sprintf_(page_present, "Page: %s\n", params.P ? "Present" : "Not Present"); CrashHandler::EHPrint(page_present); diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 74cc6f1..d3ba21e 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -27,8 +27,9 @@ void tracepagetable(PageTable *pt) { for (int i = 0; i < 512; i++) { +#if defined(__amd64__) if (pt->Entries[i].Value.Present) - debug("Entry %03d: %x %x %x %x %x %x %x %x %x %x %x %p-%#lx", i, + debug("Entry %03d: %x %x %x %x %x %x %x %x %x %x %x %p-%#llx", i, pt->Entries[i].Value.Present, pt->Entries[i].Value.ReadWrite, pt->Entries[i].Value.UserSupervisor, pt->Entries[i].Value.WriteThrough, pt->Entries[i].Value.CacheDisable, pt->Entries[i].Value.Accessed, @@ -36,16 +37,63 @@ void tracepagetable(PageTable *pt) pt->Entries[i].Value.Global, pt->Entries[i].Value.PageAttributeTable, pt->Entries[i].Value.ExecuteDisable, pt->Entries[i].GetAddress(), pt->Entries[i].Value); +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif } } #endif void InitializeMemoryManagement(BootInfo *Info) { + for (uint64_t i = 0; i < Info->Memory.Entries; i++) + { + uint64_t Base = reinterpret_cast(Info->Memory.Entry[i].BaseAddress); + uint64_t Length = Info->Memory.Entry[i].Length; + uint64_t End = Base + Length; + const char *Type = "Unknown"; + + switch (Info->Memory.Entry[i].Type) + { + case Usable: + Type = "Usable"; + break; + case Reserved: + Type = "Reserved"; + break; + case ACPIReclaimable: + Type = "ACPI Reclaimable"; + break; + case ACPINVS: + Type = "ACPI NVS"; + break; + case BadMemory: + Type = "Bad Memory"; + break; + case BootloaderReclaimable: + Type = "Bootloader Reclaimable"; + break; + case KernelAndModules: + Type = "Kernel and Modules"; + break; + case Framebuffer: + Type = "Framebuffer"; + break; + default: + break; + } + + trace("%lld: %#016llx-%#016llx %s", + i, + Base, + End, + Type); + } + trace("Initializing Physical Memory Manager"); KernelAllocator = Physical(); KernelAllocator.Init(Info); - debug("Memory Info: %dMB / %dMB (%dMB reserved)", + debug("Memory Info: %lldMB / %lldMB (%lldMB reserved)", TO_MB(KernelAllocator.GetUsedMemory()), TO_MB(KernelAllocator.GetTotalMemory()), TO_MB(KernelAllocator.GetReservedMemory())); @@ -207,8 +255,8 @@ void HeapFree(void *Address) } } -void *operator new(uint64_t Size) { return HeapMalloc(Size); } -void *operator new[](uint64_t Size) { return HeapMalloc(Size); } +void *operator new(size_t Size) { return HeapMalloc(Size); } +void *operator new[](size_t Size) { return HeapMalloc(Size); } void operator delete(void *Pointer) { HeapFree(Pointer); } void operator delete[](void *Pointer) { HeapFree(Pointer); } void operator delete(void *Pointer, long unsigned int Size) { HeapFree(Pointer); } diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index 4654131..5569b5d 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -237,27 +237,40 @@ namespace Memory if (Info->Memory.Entry[i].Type == Usable) if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize) { + // We don't want to use 0 as a memory address. + if (Info->Memory.Entry[i].BaseAddress == nullptr) + continue; LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; - debug("Largest free memory segment: %p (%dKB)", + debug("Largest free memory segment: %llp (%lldMB)", (void *)Info->Memory.Entry[i].BaseAddress, - TO_KB(Info->Memory.Entry[i].Length)); + TO_MB(Info->Memory.Entry[i].Length)); } TotalMemory = MemorySize; FreeMemory = MemorySize; - uint64_t BitmapSize = ALIGN_UP((MemorySize / 0x1000) / 8, 0x1000); - trace("Initializing Bitmap (%p %dKB)", LargestFreeMemorySegment, TO_KB(BitmapSize)); + if (LargestFreeMemorySegment == nullptr) + { + error("No free memory found!"); + CPU::Stop(); + } + + uint64_t BitmapSize = ALIGN_UP((MemorySize / PAGE_SIZE) / 8, PAGE_SIZE); + trace("Initializing Bitmap at %llp-%llp (%lld Bytes)", + LargestFreeMemorySegment, + (void *)((uint64_t)LargestFreeMemorySegment + BitmapSize), + BitmapSize); PageBitmap.Size = BitmapSize; PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment; for (uint64_t i = 0; i < BitmapSize; i++) *(uint8_t *)(PageBitmap.Buffer + i) = 0; + trace("Reserving pages..."); this->ReservePages(0, MemorySize / PAGE_SIZE + 1); for (uint64_t i = 0; i < Info->Memory.Entries; i++) if (Info->Memory.Entry[i].Type == Usable) this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1); - this->ReservePages(0, 0x100); // Reserve between 0 and 0x100000 + this->ReservePages(0, 0x100); // Reserve between 0 and 0x100000. this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1); } diff --git a/Core/PeripheralComponentInterconnect.cpp b/Core/PeripheralComponentInterconnect.cpp index 61e5bb7..8fb445e 100644 --- a/Core/PeripheralComponentInterconnect.cpp +++ b/Core/PeripheralComponentInterconnect.cpp @@ -850,7 +850,7 @@ namespace PCI { DeviceConfig *NewDeviceConfig = (DeviceConfig *)((uint64_t)((ACPI::ACPI *)PowerManager->GetACPI())->MCFG + sizeof(ACPI::ACPI::MCFGHeader) + (sizeof(DeviceConfig) * t)); Memory::Virtual().Map((void *)NewDeviceConfig->BaseAddress, (void *)NewDeviceConfig->BaseAddress, Memory::PTFlag::RW); - trace("PCI Entry %d Address:%#lx BUS:%#lx-%#lx", t, NewDeviceConfig->BaseAddress, + trace("PCI Entry %d Address:%#llx BUS:%#llx-%#llx", t, NewDeviceConfig->BaseAddress, NewDeviceConfig->StartBus, NewDeviceConfig->EndBus); for (uint64_t Bus = NewDeviceConfig->StartBus; Bus < NewDeviceConfig->EndBus; Bus++) EnumerateBus(NewDeviceConfig->BaseAddress, Bus); diff --git a/Core/Symbols.cpp b/Core/Symbols.cpp index ef9bb18..792b134 100644 --- a/Core/Symbols.cpp +++ b/Core/Symbols.cpp @@ -57,7 +57,7 @@ namespace SymbolResolver Symbols::Symbols(uint64_t Address) { - debug("Solving symbols for address: %#lx", Address); + debug("Solving symbols for address: %#llx", Address); Elf64_Ehdr *Header = (Elf64_Ehdr *)Address; if (Header->e_ident[0] != 0x7F && Header->e_ident[1] != 'E' && diff --git a/Core/SystemCalls.cpp b/Core/SystemCalls.cpp index 93ba66d..9e5ba2b 100644 --- a/Core/SystemCalls.cpp +++ b/Core/SystemCalls.cpp @@ -5,9 +5,9 @@ extern "C" uint64_t SystemCallsHandler(SyscallsRegs *regs) { #if defined(__amd64__) - fixme("System call %ld", regs->rax); + fixme("System call %lld", regs->rax); #elif defined(__i386__) - fixme("System call %ld", regs->eax); + fixme("System call %lld", regs->eax); #elif defined(__aarch64__) fixme("System call"); #endif diff --git a/Core/UniversalAsynchronousReceiverTransmitter.cpp b/Core/UniversalAsynchronousReceiverTransmitter.cpp index e8618bb..14dbc67 100644 --- a/Core/UniversalAsynchronousReceiverTransmitter.cpp +++ b/Core/UniversalAsynchronousReceiverTransmitter.cpp @@ -39,7 +39,7 @@ namespace UniversalAsynchronousReceiverTransmitter { static int once = 0; if (!once++) - warn("Serial port %#lx is faulty.", Port); + warn("Serial port %#llx is faulty.", Port); // serialports[Port] = false; // ignore for now // return; } diff --git a/Kernel.cpp b/Kernel.cpp index c881906..1d8ab3e 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -91,39 +91,3 @@ EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x while (1) CPU::Halt(); } - -struct multiboot_info -{ - multiboot_uint32_t Size; - multiboot_uint32_t Reserved; - struct multiboot_tag *Tag; -}; - -EXTERNC void x32Entry(multiboot_info *Info, unsigned int Magic) -{ - trace("Hello, World!"); - - if (Info == NULL || Magic == NULL) - { - if (Magic == NULL) - { - error("Multiboot magic is NULL"); - } - if (Info == NULL) - { - error("Multiboot info is NULL"); - } - CPU::Stop(); - } - else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) - { - error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC); - trace("Hello, World!"); - CPU::Stop(); - } - - ((unsigned char *)0xb8000)[2 * (80) * (25) - 2] = 'M'; - ((unsigned char *)0xb8000)[2 * (80) * (25) - 1] = 4; - - CPU::Stop(); -} diff --git a/Makefile b/Makefile index 32cbb3b..74a43ec 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ else ifeq ($(OSARCH), i686) CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \ -mno-red-zone -mno-sse -mno-sse2 \ - -march=i686 -pipe -msoft-float -fno-builtin -fpermissive + -march=i686 -pipe -msoft-float -fno-builtin CFLAG_STACK_PROTECTOR := -fstack-protector-all LDFLAGS += -TArchitecture/i686/linker.ld \ -fno-pic -fno-pie \ diff --git a/include/boot/binfo.h b/include/boot/binfo.h index d346abd..ffcbc2d 100644 --- a/include/boot/binfo.h +++ b/include/boot/binfo.h @@ -3,6 +3,7 @@ enum MemoryType { + Unknown, Usable, Reserved, ACPIReclaimable, @@ -10,8 +11,7 @@ enum MemoryType BadMemory, BootloaderReclaimable, KernelAndModules, - Framebuffer, - Unknown + Framebuffer }; #define MAX_FRAMEBUFFERS 16 diff --git a/include/display.hpp b/include/display.hpp index a4980a8..f0a3a19 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -104,7 +104,7 @@ namespace Video { Width = this->framebuffer.Width; Height = this->framebuffer.Height; - debug("No width and height specified, using %ldx%ld", Width, Height); + debug("No width and height specified, using %ldx%lld", Width, Height); } uint64_t Size = this->framebuffer.Pitch * Height; diff --git a/include/memory.hpp b/include/memory.hpp index f4cafb2..49009e5 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -137,6 +137,7 @@ namespace Memory { struct { +#if defined(__amd64__) bool Present : 1; bool ReadWrite : 1; bool UserSupervisor : 1; @@ -152,6 +153,18 @@ namespace Memory uint32_t Available2 : 7; uint16_t ProtectionKey : 4; bool ExecuteDisable : 1; +#elif defined(__i386__) + bool Present : 1; + bool ReadWrite : 1; + bool UserSupervisor : 1; + bool Accessed : 1; + bool Dirty : 1; + uint8_t Available : 7; + uint32_t Frame : 20; +// TODO: i386 PDEData is not tested +#elif defined(__aarch64__) +// TODO: aarch64 PDEData not implemented +#endif }; uint64_t raw; } PDEData; @@ -338,26 +351,26 @@ namespace Memory class PageMapIndexer { public: - uint64_t PDP_i; - uint64_t PD_i; - uint64_t PT_i; - uint64_t P_i; + uint64_t PDP_i = 0; + uint64_t PD_i = 0; + uint64_t PT_i = 0; + uint64_t P_i = 0; PageMapIndexer(uint64_t VirtualAddress) { #if defined(__amd64__) - PDP_i = (VirtualAddress & ((uint64_t)0x1FF << 39)) >> 39; - PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30; - PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21; - P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12; + this->PDP_i = (VirtualAddress & ((uint64_t)0x1FF << 39)) >> 39; + this->PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30; + this->PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21; + this->P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12; #elif defined(__i386__) - PD_i = (VirtualAddress & ((uint64_t)0x3FF << 22)) >> 22; - PT_i = (VirtualAddress & ((uint64_t)0x3FF << 12)) >> 12; - P_i = (VirtualAddress & ((uint64_t)0xFFF << 0)) >> 0; + this->PD_i = (VirtualAddress & ((uint64_t)0x3FF << 22)) >> 22; + this->PT_i = (VirtualAddress & ((uint64_t)0x3FF << 12)) >> 12; + this->P_i = (VirtualAddress & ((uint64_t)0xFFF)) >> 0; #elif defined(__aarch64__) - PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30; - PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21; - P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12; + this->PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30; + this->PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21; + this->P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12; #endif } }; @@ -409,8 +422,8 @@ namespace Memory void InitializeMemoryManagement(BootInfo *Info); -void *operator new(uint64_t Size); -void *operator new[](uint64_t Size); +void *operator new(size_t Size); +void *operator new[](size_t Size); void operator delete(void *Pointer); void operator delete[](void *Pointer); void operator delete(void *Pointer, long unsigned int Size); diff --git a/include/vector.hpp b/include/vector.hpp index b1feff6..910d8a6 100644 --- a/include/vector.hpp +++ b/include/vector.hpp @@ -25,7 +25,7 @@ public: VectorCapacity = Size; VectorSize = Size; #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: Vector( %ld )", Size); + debug("VECTOR ALLOCATION: Vector( %lld )", Size); #endif VectorBuffer = new T[Size]; } @@ -35,7 +35,7 @@ public: VectorSize = Size; VectorCapacity = Size; #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: Vector( %ld %llx )", Size, Initial); + debug("VECTOR ALLOCATION: Vector( %lld %llx )", Size, Initial); #endif VectorBuffer = new T[Size]; for (uint64_t i = 0; i < Size; i++) @@ -47,7 +47,7 @@ public: VectorSize = Vector.VectorSize; VectorCapacity = Vector.VectorCapacity; #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: Vector( )->Size: %ld", VectorSize); + debug("VECTOR ALLOCATION: Vector( )->Size: %lld", VectorSize); #endif VectorBuffer = new T[VectorSize]; for (uint64_t i = 0; i < VectorSize; i++) @@ -117,7 +117,7 @@ public: VectorCapacity = 0; } #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: reverse( %ld )", Capacity); + debug("VECTOR ALLOCATION: reverse( %lld )", Capacity); #endif T *Newbuffer = new T[Capacity]; uint64_t _Size = Capacity < VectorSize ? Capacity : VectorSize; @@ -125,7 +125,7 @@ public: Newbuffer[i] = VectorBuffer[i]; VectorCapacity = Capacity; #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: reverse( )->Buffer:~%ld", VectorBuffer); + debug("VECTOR ALLOCATION: reverse( )->Buffer:~%lld", VectorBuffer); #endif delete[] VectorBuffer; VectorBuffer = Newbuffer; @@ -145,7 +145,7 @@ public: VectorSize = Vector.VectorSize; VectorCapacity = Vector.VectorCapacity; #ifdef DEBUG_MEM_ALLOCATION - debug("VECTOR ALLOCATION: operator=( )->Size:%ld", VectorSize); + debug("VECTOR ALLOCATION: operator=( )->Size:%lld", VectorSize); #endif VectorBuffer = new T[VectorSize]; for (uint64_t i = 0; i < VectorSize; i++)