Kernel is now able to boot from mb2

This commit is contained in:
Alex 2023-05-08 00:27:12 +03:00
parent c4798a69b1
commit 7811c21971
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
10 changed files with 558 additions and 400 deletions

View File

@ -1,3 +1,4 @@
; https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html
section .multiboot2 section .multiboot2
align 4096 align 4096
HEADER_START: HEADER_START:
@ -33,6 +34,28 @@ MB2_INFO_REQUEST_TAG_START:
dd 21 ; Load Base Address dd 21 ; Load Base Address
MB2_INFO_REQUEST_TAG_END: MB2_INFO_REQUEST_TAG_END:
align 8 align 8
MB2_FRAMEBUFFER_TAG_START:
dw 5
dw 1
dd MB2_FRAMEBUFFER_TAG_END - MB2_FRAMEBUFFER_TAG_START
dd 0
dd 0
dd 32
MB2_FRAMEBUFFER_TAG_END:
align 8
MB2_EGA_SUPPORT_TAG_START:
dw 4
dw 0
dd MB2_EGA_SUPPORT_TAG_END - MB2_EGA_SUPPORT_TAG_START
dd 1 ; https://www.gnu.org/software/grub/manual/multiboot2/html_node/Console-header-tags.html
MB2_EGA_SUPPORT_TAG_END:
align 8
MB2_MODULE_ALIGN_TAG_START:
dw 6
dw 0
dd MB2_MODULE_ALIGN_TAG_END - MB2_MODULE_ALIGN_TAG_START
MB2_MODULE_ALIGN_TAG_END:
align 8
MB2_TAG_START: MB2_TAG_START:
dw 0 dw 0
dw 0 dw 0

View File

@ -22,6 +22,12 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
CPU::Stop(); CPU::Stop();
} }
BootInfo mb2binfo{};
// Clear the BSS
// memset_unsafe(&_kernel_rodata_end, 0, &_kernel_end - &_kernel_rodata_end);
{
uint64_t div = 1193180 / 1000; uint64_t div = 1193180 / 1000;
outb(0x43, 0xB6); outb(0x43, 0xB6);
outb(0x42, (uint8_t)div); outb(0x42, (uint8_t)div);
@ -30,7 +36,6 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
if (tmp != (tmp | 3)) if (tmp != (tmp | 3))
outb(0x61, tmp | 3); outb(0x61, tmp | 3);
BootInfo mb2binfo;
int pos = 0; int pos = 0;
auto InfoAddress = Info; auto InfoAddress = Info;
for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8); for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8);
@ -65,12 +70,13 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
{ {
multiboot_tag_module *module = (multiboot_tag_module *)Tag; multiboot_tag_module *module = (multiboot_tag_module *)Tag;
static int module_count = 0; static int module_count = 0;
mb2binfo.Modules[module_count++].Address = (void *)(uint64_t)module->mod_start; mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start;
mb2binfo.Modules[module_count++].Size = module->size; mb2binfo.Modules[module_count].Size = module->size;
strncpy(mb2binfo.Modules[module_count++].Path, "(null)", 6); strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6);
strncpy(mb2binfo.Modules[module_count++].CommandLine, module->cmdline, strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline,
strlen(module->cmdline)); strlen(module->cmdline));
debug("Module: %s", mb2binfo.Modules[module_count++].Path); debug("Module: %s", mb2binfo.Modules[module_count].Path);
module_count++;
break; break;
} }
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
@ -90,7 +96,7 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
case MULTIBOOT_TAG_TYPE_MMAP: case MULTIBOOT_TAG_TYPE_MMAP:
{ {
multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag; multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag;
uint32_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry); size_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry);
mb2binfo.Memory.Entries = EntryCount; mb2binfo.Memory.Entries = EntryCount;
for (uint32_t i = 0; i < EntryCount; i++) for (uint32_t i = 0; i < EntryCount; i++)
{ {
@ -180,6 +186,11 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
mb2binfo.Framebuffer[fb_count].Type = EGA; mb2binfo.Framebuffer[fb_count].Type = EGA;
break; break;
} }
default:
{
mb2binfo.Framebuffer[fb_count].Type = Unknown_Framebuffer_Type;
break;
}
} }
debug("Framebuffer %d: %dx%d %d bpp", fb_count, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp); debug("Framebuffer %d: %dx%d %d bpp", fb_count, 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", debug("More info:\nAddress: %p\nPitch: %lld\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d",
@ -268,7 +279,7 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag;
mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr; mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr;
mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000); mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000);
mb2binfo.Kernel.Size = &_kernel_end - &_kernel_start; mb2binfo.Kernel.Size = ((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start);
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase); debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
break; break;
} }
@ -282,6 +293,7 @@ EXTERNC void multiboot_main(uint64_t Magic, uint64_t Info)
tmp = inb(0x61) & 0xFC; tmp = inb(0x61) & 0xFC;
outb(0x61, tmp); outb(0x61, tmp);
}
Entry(&mb2binfo); Entry(&mb2binfo);
} }

View File

@ -33,7 +33,7 @@ union __attribute__((packed)) PageTableEntry
struct __attribute__((packed)) PageTableEntryPtr struct __attribute__((packed)) PageTableEntryPtr
{ {
PageTableEntry Entries[511]; PageTableEntry Entries[512];
}; };
union __attribute__((packed)) PageDirectoryEntry union __attribute__((packed)) PageDirectoryEntry
@ -67,7 +67,7 @@ union __attribute__((packed)) PageDirectoryEntry
struct __attribute__((packed)) PageDirectoryEntryPtr struct __attribute__((packed)) PageDirectoryEntryPtr
{ {
PageDirectoryEntry Entries[511]; PageDirectoryEntry Entries[512];
}; };
union __attribute__((packed)) PageDirectoryPointerTableEntry union __attribute__((packed)) PageDirectoryPointerTableEntry
@ -101,7 +101,7 @@ union __attribute__((packed)) PageDirectoryPointerTableEntry
struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr
{ {
PageDirectoryPointerTableEntry Entries[511]; PageDirectoryPointerTableEntry Entries[512];
}; };
union __attribute__((packed)) PageMapLevel4 union __attribute__((packed)) PageMapLevel4
@ -135,7 +135,7 @@ union __attribute__((packed)) PageMapLevel4
struct PageTable4 struct PageTable4
{ {
PageMapLevel4 Entries[511]; PageMapLevel4 Entries[512];
} __attribute__((aligned(0x1000))); } __attribute__((aligned(0x1000)));
extern "C" char BootPageTable[]; extern "C" char BootPageTable[];
@ -177,7 +177,7 @@ public:
} }
}; };
__always_inline inline SafeFunction NIF void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags) __attribute__((section(".bootstrap.text"))) SafeFunction NIF void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
{ {
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress); PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only // Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
@ -188,9 +188,11 @@ __always_inline inline SafeFunction NIF void Map(void *VirtualAddress, void *Phy
if (!PML4.Present) if (!PML4.Present)
{ {
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage(); PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage();
if (PDPTEPtr == nullptr)
return;
{ {
void *ptr = PDPTEPtr; void *ptr = PDPTEPtr;
int value = 0; uint8_t value = 0;
size_t num = 0x1000; size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr; uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++) for (size_t i = 0; i < num; i++)
@ -209,9 +211,11 @@ __always_inline inline SafeFunction NIF void Map(void *VirtualAddress, void *Phy
if (!PDPTE.Present) if (!PDPTE.Present)
{ {
PDEPtr = (PageDirectoryEntryPtr *)RequestPage(); PDEPtr = (PageDirectoryEntryPtr *)RequestPage();
if (PDEPtr == nullptr)
return;
{ {
void *ptr = PDEPtr; void *ptr = PDEPtr;
int value = 0; uint8_t value = 0;
size_t num = 0x1000; size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr; uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++) for (size_t i = 0; i < num; i++)
@ -230,9 +234,11 @@ __always_inline inline SafeFunction NIF void Map(void *VirtualAddress, void *Phy
if (!PDE.Present) if (!PDE.Present)
{ {
PTEPtr = (PageTableEntryPtr *)RequestPage(); PTEPtr = (PageTableEntryPtr *)RequestPage();
if (PTEPtr == nullptr)
return;
{ {
void *ptr = PTEPtr; void *ptr = PTEPtr;
int value = 0; uint8_t value = 0;
size_t num = 0x1000; size_t num = 0x1000;
uint8_t *p = (uint8_t *)ptr; uint8_t *p = (uint8_t *)ptr;
for (size_t i = 0; i < num; i++) for (size_t i = 0; i < num; i++)
@ -262,14 +268,14 @@ EXTERNC __attribute__((section(".bootstrap.text"))) SafeFunction NIF __attribute
BPTable = (PageTable4 *)BootPageTable; BPTable = (PageTable4 *)BootPageTable;
// for (size_t i = 0; i < 0x10000000; i += 0x1000) // for (size_t i = 0; i < 0x10000000; i += 0x1000)
// Map((void *)i, (void *)i, 0x3); // MB2_64_Map((void *)i, (void *)i, 0x3);
uintptr_t KernelStart = (uintptr_t)&_kernel_start; uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelEnd = (uintptr_t)&_kernel_end; uintptr_t KernelEnd = (uintptr_t)&_kernel_end;
uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000; uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000;
for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000) for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000)
{ {
Map((void *)i, (void *)PhysicalStart, 0x3); MB2_64_Map((void *)i, (void *)PhysicalStart, 0x3);
PhysicalStart += 0x1000; PhysicalStart += 0x1000;
} }

View File

@ -57,8 +57,6 @@ SECTIONS
{ {
*(.rodata .rodata.*) *(.rodata .rodata.*)
} }
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE);
.init_array : AT(ADDR(.init_array) - KERNEL_VMA) .init_array : AT(ADDR(.init_array) - KERNEL_VMA)
{ {
@ -75,6 +73,7 @@ SECTIONS
KEEP(*(.fini_array .dtors)) KEEP(*(.fini_array .dtors))
PROVIDE_HIDDEN (__fini_array_end = .); PROVIDE_HIDDEN (__fini_array_end = .);
} }
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
. += CONSTANT(MAXPAGESIZE); . += CONSTANT(MAXPAGESIZE);
.bss : AT(ADDR(.bss) - KERNEL_VMA) .bss : AT(ADDR(.bss) - KERNEL_VMA)

View File

@ -146,6 +146,7 @@ NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info)
NIF void MapKernel(PageTable4 *PT, BootInfo *Info) NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
{ {
debug("Mapping Kernel"); debug("Mapping Kernel");
uintptr_t BootstrapStart = (uintptr_t)&_bootstrap_start;
uintptr_t KernelStart = (uintptr_t)&_kernel_start; uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelTextEnd = (uintptr_t)&_kernel_text_end; uintptr_t KernelTextEnd = (uintptr_t)&_kernel_text_end;
uintptr_t KernelDataEnd = (uintptr_t)&_kernel_data_end; uintptr_t KernelDataEnd = (uintptr_t)&_kernel_data_end;
@ -154,6 +155,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
uintptr_t KernelFileStart = (uintptr_t)Info->Kernel.FileBase; uintptr_t KernelFileStart = (uintptr_t)Info->Kernel.FileBase;
uintptr_t KernelFileEnd = KernelFileStart + Info->Kernel.Size; uintptr_t KernelFileEnd = KernelFileStart + Info->Kernel.Size;
debug("Kernel physical address: %#lx - %#lx", Info->Kernel.PhysicalBase, (uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size);
debug("Kernel file base: %#lx - %#lx", KernelFileStart, KernelFileEnd);
debug("File size: %ld KB", TO_KB(Info->Kernel.Size)); debug("File size: %ld KB", TO_KB(Info->Kernel.Size));
debug(".text size: %ld KB", TO_KB(KernelTextEnd - KernelStart)); debug(".text size: %ld KB", TO_KB(KernelTextEnd - KernelStart));
debug(".data size: %ld KB", TO_KB(KernelDataEnd - KernelTextEnd)); debug(".data size: %ld KB", TO_KB(KernelDataEnd - KernelTextEnd));
@ -164,9 +168,23 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
uintptr_t k; uintptr_t k;
Virtual va = Virtual(PT); Virtual va = Virtual(PT);
/* Bootstrap section */
for (k = BootstrapStart; k < KernelStart - KERNEL_VMA_OFFSET; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
/* Text section */ /* Text section */
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE) for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
{ {
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
@ -175,6 +193,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* Data section */ /* Data section */
for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
{ {
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
@ -183,6 +204,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* Read only data section */ /* Read only data section */
for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
{ {
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
@ -191,12 +215,18 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* BSS section */ /* BSS section */
for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
{ {
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
} }
debug("BaseKernelMapAddress: %#lx - %#lx", Info->Kernel.PhysicalBase, BaseKernelMapAddress);
/* Kernel file */ /* Kernel file */
if (KernelFileStart != 0)
for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE) for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)k, PTFlag::G); va.Map((void *)k, (void *)k, PTFlag::G);
@ -304,6 +334,7 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
trace("Initializing Virtual Memory Manager"); trace("Initializing Virtual Memory Manager");
KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1)); KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1));
debug("Page table allocated at %#lx", KernelPageTable);
memset(KernelPageTable, 0, PAGE_SIZE); memset(KernelPageTable, 0, PAGE_SIZE);
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)

View File

@ -22,6 +22,8 @@
#include <uart.hpp> #include <uart.hpp>
#endif #endif
#include "../../Architecture/amd64/acpi.hpp"
#include "../../kernel.h" #include "../../kernel.h"
extern "C" char BootPageTable[]; // 0x10000 in length extern "C" char BootPageTable[]; // 0x10000 in length
@ -379,6 +381,7 @@ namespace Memory
TotalMemory = MemorySize; TotalMemory = MemorySize;
FreeMemory = MemorySize; FreeMemory = MemorySize;
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1;
void *LargestFreeMemorySegment = nullptr; void *LargestFreeMemorySegment = nullptr;
uint64_t LargestFreeMemorySegmentSize = 0; uint64_t LargestFreeMemorySegmentSize = 0;
@ -395,39 +398,54 @@ namespace Memory
continue; continue;
} }
if (Info->Memory.Entry[i].Length > BitmapSize + 0x1000)
{
LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
debug("Largest free memory segment: %llp (%lldMB)",
(void *)Info->Memory.Entry[i].BaseAddress,
TO_MB(Info->Memory.Entry[i].Length));
}
}
}
#define ROUND_UP(N, S) ((((N) + (S)-1) / (S)) * (S)) #define ROUND_UP(N, S) ((((N) + (S)-1) / (S)) * (S))
if (LargestFreeMemorySegment >= Info->Kernel.PhysicalBase && if (LargestFreeMemorySegment >= Info->Kernel.PhysicalBase &&
LargestFreeMemorySegment <= (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size)) LargestFreeMemorySegment <= (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size))
{ {
debug("Kernel range: %#lx-%#lx", Info->Kernel.PhysicalBase, (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size));
void *NewLargestFreeMemorySegment = (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size); void *NewLargestFreeMemorySegment = (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size);
void *RoundNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewLargestFreeMemorySegment, PAGE_SIZE); void *RoundNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewLargestFreeMemorySegment, PAGE_SIZE);
RoundNewLargestFreeMemorySegment = (void *)((uintptr_t)RoundNewLargestFreeMemorySegment + PAGE_SIZE); /* Leave a page between the kernel and the bitmap */
debug("Rounding %p to %p", NewLargestFreeMemorySegment, RoundNewLargestFreeMemorySegment); debug("Rounding %p to %p", NewLargestFreeMemorySegment, RoundNewLargestFreeMemorySegment);
info("Largest free memory segment is in the kernel, moving it to %p", RoundNewLargestFreeMemorySegment); info("Memory bitmap's memory segment is in the kernel, moving it to %p", RoundNewLargestFreeMemorySegment);
LargestFreeMemorySegmentSize = (uintptr_t)LargestFreeMemorySegmentSize - ((uintptr_t)RoundNewLargestFreeMemorySegment - (uintptr_t)LargestFreeMemorySegment);
LargestFreeMemorySegment = RoundNewLargestFreeMemorySegment; LargestFreeMemorySegment = RoundNewLargestFreeMemorySegment;
if (RoundNewLargestFreeMemorySegment >= &_bootstrap_start &&
RoundNewLargestFreeMemorySegment <= (void *)((uintptr_t)&_bootstrap_end + &_bootstrap_start))
{
void *NewNewLargestFreeMemorySegment = (void *)((uintptr_t)&_bootstrap_end + &_bootstrap_start);
void *RoundNewNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewNewLargestFreeMemorySegment, PAGE_SIZE);
debug("Rounding %p to %p", NewNewLargestFreeMemorySegment, RoundNewNewLargestFreeMemorySegment);
info("Largest free memory segment is in the bootstrap, moving it to %p", RoundNewNewLargestFreeMemorySegment);
LargestFreeMemorySegment = RoundNewNewLargestFreeMemorySegment;
}
} }
#undef ROUND_UP #undef ROUND_UP
if (LargestFreeMemorySegmentSize < BitmapSize + 0x1000)
{
trace("Largest free memory segment is too small (%lld bytes), skipping...",
LargestFreeMemorySegmentSize);
continue;
}
debug("Found a memory segment of %lld bytes (%lldMB) at %llp (out segment is %lld bytes (%lldKB)))",
LargestFreeMemorySegmentSize,
TO_MB(LargestFreeMemorySegmentSize),
LargestFreeMemorySegment,
BitmapSize,
TO_KB(BitmapSize));
break;
}
// LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
// LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
// debug("Largest free memory segment: %llp (%lldMB)",
// (void *)Info->Memory.Entry[i].BaseAddress,
// TO_MB(Info->Memory.Entry[i].Length));
}
}
}
if (LargestFreeMemorySegment == nullptr) if (LargestFreeMemorySegment == nullptr)
{ {
error("No free memory found!"); error("No free memory found!");
@ -435,7 +453,6 @@ namespace Memory
} }
/* TODO: Read swap config and make the configure the bitmap size correctly */ /* TODO: Read swap config and make the configure the bitmap size correctly */
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1;
debug("Initializing Bitmap at %llp-%llp (%lld Bytes)", debug("Initializing Bitmap at %llp-%llp (%lld Bytes)",
LargestFreeMemorySegment, LargestFreeMemorySegment,
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize), (void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
@ -460,12 +477,63 @@ namespace Memory
this->ReservePage((void *)0x0); /* Trampoline stack, gdt, idt, etc... */ this->ReservePage((void *)0x0); /* Trampoline stack, gdt, idt, etc... */
this->ReservePages((void *)0x2000, 4); /* TRAMPOLINE_START */ this->ReservePages((void *)0x2000, 4); /* TRAMPOLINE_START */
debug("Reserving bitmap pages..."); debug("Reserving bitmap region %#lx-%#lx...", PageBitmap.Buffer, (void *)((uintptr_t)PageBitmap.Buffer + PageBitmap.Size));
this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size));
debug("Reserving kernel..."); // debug("Reserving page table...");
this->ReservePages(BootPageTable, TO_PAGES(0x10000)); // this->ReservePages(BootPageTable, TO_PAGES(0x10000)); << in the bootstrap region
debug("Reserving kernel bootstrap region %#lx-%#lx...", &_bootstrap_start, &_bootstrap_end);
this->ReservePages(&_bootstrap_start, TO_PAGES((uintptr_t)&_bootstrap_end - (uintptr_t)&_bootstrap_start)); this->ReservePages(&_bootstrap_start, TO_PAGES((uintptr_t)&_bootstrap_end - (uintptr_t)&_bootstrap_start));
this->ReservePages(&_kernel_start, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start)); void *KernelPhysicalStart = (void *)(((uintptr_t)&_kernel_start - KERNEL_VMA_OFFSET));
void *KernelPhysicalEnd = (void *)(((uintptr_t)&_kernel_end - KERNEL_VMA_OFFSET));
debug("Reserving kernel region %#lx-%#lx...", KernelPhysicalStart, KernelPhysicalEnd);
this->ReservePages((void *)KernelPhysicalStart, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start));
ACPI::ACPI::ACPIHeader *hdr = nullptr;
bool XSDT = false;
if (Info->RSDP->Revision >= 2 && Info->RSDP->XSDTAddress)
{
hdr = (ACPI::ACPI::ACPIHeader *)(Info->RSDP->XSDTAddress);
XSDT = true;
}
else
{
hdr = (ACPI::ACPI::ACPIHeader *)(uintptr_t)Info->RSDP->RSDTAddress;
}
debug("Reserving RSDT...");
this->ReservePages((void*)Info->RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo)));
debug("Reserving ACPI tables...");
uint64_t TableSize = ((hdr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / (XSDT ? 8 : 4));
debug("Table size: %lld", TableSize);
for (uint64_t t = 0; t < TableSize; t++)
{
// TODO: Should I be concerned about unaligned memory access?
ACPI::ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDT)
SDTHdr = (ACPI::ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)hdr + sizeof(ACPI::ACPI::ACPIHeader) + (t * 8)));
else
SDTHdr = (ACPI::ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)hdr + sizeof(ACPI::ACPI::ACPIHeader) + (t * 4)));
this->ReservePages(SDTHdr, TO_PAGES(SDTHdr->Length));
}
debug("Reserving kernel modules...");
for (uint64_t i = 0; i < MAX_MODULES; i++)
{
if (Info->Modules[i].Address == 0x0)
continue;
debug("Reserving module %s (%#lx-%#lx)...", Info->Modules[i].CommandLine,
Info->Modules[i].Address, (void *)((uintptr_t)Info->Modules[i].Address + Info->Modules[i].Size));
this->ReservePages((void *)Info->Modules[i].Address, TO_PAGES(Info->Modules[i].Size));
}
} }
Physical::Physical() {} Physical::Physical() {}

View File

@ -28,6 +28,13 @@ namespace SymbolResolver
Symbols::Symbols(uintptr_t ImageAddress) Symbols::Symbols(uintptr_t ImageAddress)
{ {
debug("Solving symbols for address: %#llx", ImageAddress); debug("Solving symbols for address: %#llx", ImageAddress);
if (ImageAddress == 0)
{
error("Invalid image address");
return;
}
Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress; Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress;
if (Header->e_ident[0] != 0x7F && if (Header->e_ident[0] != 0x7F &&
Header->e_ident[1] != 'E' && Header->e_ident[1] != 'E' &&

View File

@ -255,9 +255,6 @@ EXTERNC void KPrint(const char *Format, ...)
EXTERNC NIF void Main(BootInfo *Info) EXTERNC NIF void Main(BootInfo *Info)
{ {
memcpy(&bInfo, Info, sizeof(BootInfo));
debug("BootInfo structure is at %p", bInfo);
Display = new Video::Display(bInfo.Framebuffer[0]); Display = new Video::Display(bInfo.Framebuffer[0]);
KPrint("%s - %s [\e058C19%s\eFFFFFF]", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); KPrint("%s - %s [\e058C19%s\eFFFFFF]", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT);
KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", CPU::Hypervisor(), CPU::Vendor(), CPU::Name()); KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", CPU::Hypervisor(), CPU::Vendor(), CPU::Name());
@ -270,7 +267,7 @@ EXTERNC NIF void Main(BootInfo *Info)
Interrupts::Initialize(0); Interrupts::Initialize(0);
KPrint("Loading Kernel Symbols"); KPrint("Loading Kernel Symbols");
KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase); KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)bInfo.Kernel.FileBase);
KPrint("Reading Kernel Parameters"); KPrint("Reading Kernel Parameters");
ParseConfig((char *)bInfo.Kernel.CommandLine, &Config); ParseConfig((char *)bInfo.Kernel.CommandLine, &Config);
@ -496,8 +493,23 @@ EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info)
TestMemoryAllocation(); TestMemoryAllocation();
#endif #endif
/* This is allocated in RAM. */
static BootInfo *bootInfo_temp = nullptr;
bootInfo_temp = Info; /* Info will be lost after changing the rsp and bsp. */
/* NO RETURN BEYOND THIS POINT */
void *KernelStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));
asmv("mov %0, %%rsp"
:
: "r"(KernelStack)
: "memory");
asmv("mov $0, %rbp");
memcpy(&bInfo, bootInfo_temp, sizeof(BootInfo));
debug("BootInfo structure is at %p", &bInfo);
EnableProfiler = true; EnableProfiler = true;
Main(Info); Main(bootInfo_temp);
} }
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"

View File

@ -25,7 +25,6 @@
#include "../syscalls.h" #include "../syscalls.h"
#include "../kernel.h" #include "../kernel.h"
#include "../../Userspace/libs/include/sysbase.h"
#include "../ipc.h" #include "../ipc.h"
using InterProcessCommunication::IPC; using InterProcessCommunication::IPC;
@ -111,124 +110,125 @@ static int sys_detach_address(SyscallsFrame *Frame, uintptr_t Address)
return SYSCALL_OK; return SYSCALL_OK;
} }
static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4) static uintptr_t sys_kernelctl(SyscallsFrame *Frame, uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED; return SYSCALL_ACCESS_DENIED;
switch (Command) return SYSCALL_NOT_IMPLEMENTED;
{
case KCTL_GET_PID:
return TaskManager->GetCurrentThread()->Parent->ID;
case KCTL_GET_TID:
return TaskManager->GetCurrentThread()->ID;
case KCTL_GET_PAGE_SIZE:
return PAGE_SIZE;
case KCTL_IS_CRITICAL:
return TaskManager->GetCurrentThread()->Security.IsCritical;
case KCTL_REGISTER_ELF_LIB:
{
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char *Identifier = (char *)Arg1;
const char *Path = (const char *)Arg2;
if (!Identifier || !Path) // switch (Command)
return SYSCALL_INVALID_ARGUMENT; // {
// case KCTL_GET_PID:
// return TaskManager->GetCurrentThread()->Parent->ID;
// case KCTL_GET_TID:
// return TaskManager->GetCurrentThread()->ID;
// case KCTL_GET_PAGE_SIZE:
// return PAGE_SIZE;
// case KCTL_IS_CRITICAL:
// return TaskManager->GetCurrentThread()->Security.IsCritical;
// case KCTL_REGISTER_ELF_LIB:
// {
// if (!CheckTrust(TrustedByKernel | Trusted))
// return SYSCALL_ACCESS_DENIED;
// char *Identifier = (char *)Arg1;
// const char *Path = (const char *)Arg2;
std::string FullPath = Path; // if (!Identifier || !Path)
int retries = 0; // return SYSCALL_INVALID_ARGUMENT;
RetryReadPath:
debug("KCTL_REGISTER_ELF_LIB: Trying to open %s", FullPath.c_str());
VirtualFileSystem::File f = vfs->Open(FullPath.c_str());
if (!f.IsOK()) // std::string FullPath = Path;
{ // int retries = 0;
FullPath.clear(); // RetryReadPath:
switch (retries) // debug("KCTL_REGISTER_ELF_LIB: Trying to open %s", FullPath.c_str());
{ // VirtualFileSystem::File f = vfs->Open(FullPath.c_str());
case 0:
FullPath = "/system/lib/";
break;
case 1:
FullPath = "/system/lib64/";
break;
case 2:
FullPath = "/system/";
break;
case 3:
{
// TODO: Check process binary path
break;
}
default:
{
vfs->Close(f);
return SYSCALL_INVALID_ARGUMENT;
}
}
FullPath += Path;
vfs->Close(f);
retries++;
goto RetryReadPath;
}
vfs->Close(f); // if (!f.IsOK())
if (Execute::AddLibrary(Identifier, (void *)f.node->Address, f.node->Length)) // {
return SYSCALL_OK; // FullPath.clear();
else // switch (retries)
return SYSCALL_INTERNAL_ERROR; // {
} // case 0:
case KCTL_GET_ELF_LIB_FILE: // FullPath = "/system/lib/";
{ // break;
if (!CheckTrust(TrustedByKernel | Trusted)) // case 1:
return SYSCALL_ACCESS_DENIED; // FullPath = "/system/lib64/";
char *Identifier = (char *)Arg1; // break;
if (!Identifier) // case 2:
return 0; // FullPath = "/system/";
// break;
// case 3:
// {
// // TODO: Check process binary path
// break;
// }
// default:
// {
// vfs->Close(f);
// return SYSCALL_INVALID_ARGUMENT;
// }
// }
// FullPath += Path;
// vfs->Close(f);
// retries++;
// goto RetryReadPath;
// }
Execute::SharedLibraries lib = Execute::GetLibrary(Identifier); // vfs->Close(f);
if (!lib.Address) // if (Execute::AddLibrary(Identifier, (void *)f.node->Address, f.node->Length))
{ // return SYSCALL_OK;
debug("Failed to get library address %#lx", (uintptr_t)lib.Address); // else
} // return SYSCALL_INTERNAL_ERROR;
// }
// case KCTL_GET_ELF_LIB_FILE:
// {
// if (!CheckTrust(TrustedByKernel | Trusted))
// return SYSCALL_ACCESS_DENIED;
// char *Identifier = (char *)Arg1;
// if (!Identifier)
// return 0;
debug("Returning library address %#lx (%s)", (uintptr_t)lib.Address, Identifier); // Execute::SharedLibraries lib = Execute::GetLibrary(Identifier);
return (uintptr_t)lib.Address; // if (!lib.Address)
} // {
case KCTL_GET_ELF_LIB_MEMORY_IMAGE: // debug("Failed to get library address %#lx", (uintptr_t)lib.Address);
{ // }
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char *Identifier = (char *)Arg1;
if (!Identifier)
return 0;
Execute::SharedLibraries lib = Execute::GetLibrary(Identifier); // debug("Returning library address %#lx (%s)", (uintptr_t)lib.Address, Identifier);
// return (uintptr_t)lib.Address;
// }
// case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
// {
// if (!CheckTrust(TrustedByKernel | Trusted))
// return SYSCALL_ACCESS_DENIED;
// char *Identifier = (char *)Arg1;
// if (!Identifier)
// return 0;
if (!lib.MemoryImage) // Execute::SharedLibraries lib = Execute::GetLibrary(Identifier);
{
debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage);
}
debug("Returning memory image %#lx (%s)", (uintptr_t)lib.MemoryImage, Identifier); // if (!lib.MemoryImage)
return (uintptr_t)lib.MemoryImage; // {
} // debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage);
case KCTL_GET_FRAMEBUFFER_BUFFER: // }
return r_cst(uint64_t, Display->GetBuffer(0)->Buffer);
case KCTL_GET_FRAMEBUFFER_WIDTH:
return Display->GetBuffer(0)->Width;
case KCTL_GET_FRAMEBUFFER_HEIGHT:
return Display->GetBuffer(0)->Height;
case KCTL_GET_FRAMEBUFFER_SIZE:
return Display->GetBuffer(0)->Size;
default: // debug("Returning memory image %#lx (%s)", (uintptr_t)lib.MemoryImage, Identifier);
{ // return (uintptr_t)lib.MemoryImage;
warn("KernelCTL: Unknown command: %lld", Command); // }
return SYSCALL_INVALID_ARGUMENT; // case KCTL_GET_FRAMEBUFFER_BUFFER:
} // return r_cst(uint64_t, Display->GetBuffer(0)->Buffer);
} // case KCTL_GET_FRAMEBUFFER_WIDTH:
// return Display->GetBuffer(0)->Width;
// case KCTL_GET_FRAMEBUFFER_HEIGHT:
// return Display->GetBuffer(0)->Height;
// case KCTL_GET_FRAMEBUFFER_SIZE:
// return Display->GetBuffer(0)->Size;
// default:
// {
// warn("KernelCTL: Unknown command: %lld", Command);
// return SYSCALL_INVALID_ARGUMENT;
// }
// }
UNUSED(Arg1); UNUSED(Arg1);
UNUSED(Arg2); UNUSED(Arg2);

View File

@ -229,7 +229,7 @@ namespace Memory
struct __packed PageTableEntryPtr struct __packed PageTableEntryPtr
{ {
PageTableEntry Entries[511]; PageTableEntry Entries[512];
}; };
union __packed PageDirectoryEntry union __packed PageDirectoryEntry
@ -305,7 +305,7 @@ namespace Memory
struct __packed PageDirectoryEntryPtr struct __packed PageDirectoryEntryPtr
{ {
PageDirectoryEntry Entries[511]; PageDirectoryEntry Entries[512];
}; };
union __packed PageDirectoryPointerTableEntry union __packed PageDirectoryPointerTableEntry
@ -381,7 +381,7 @@ namespace Memory
struct __packed PageDirectoryPointerTableEntryPtr struct __packed PageDirectoryPointerTableEntryPtr
{ {
PageDirectoryPointerTableEntry Entries[511]; PageDirectoryPointerTableEntry Entries[512];
}; };
union __packed PageMapLevel4 union __packed PageMapLevel4
@ -436,7 +436,7 @@ namespace Memory
struct PageTable4 struct PageTable4
{ {
PageMapLevel4 Entries[511]; PageMapLevel4 Entries[512];
/** /**
* @brief Update CR3 with this PageTable4 * @brief Update CR3 with this PageTable4
@ -458,7 +458,7 @@ namespace Memory
struct PageTable5 struct PageTable5
{ {
PageMapLevel5 Entries[511]; PageMapLevel5 Entries[512];
} __aligned(0x1000); } __aligned(0x1000);
class Physical class Physical