XyrisOS / xyris

The Xyris Kernel
https://xyr.is
MIT License
154 stars 11 forks source link

Fix Bootloader Handoff Memory Conflict #278

Closed Kfeavel closed 3 years ago

Kfeavel commented 3 years ago

Panix has an issue that prevents progress from being made when it comes to the memory management refactors. There exists a "chicken / egg" problem in the kernel where the boot-loader information needs to be mapped into memory for the kernel to be able to access it, but in order to map memory properly (in the refactored design), the memory manager needs information about the memory layout from the boot-loader, which creates a circular dependency.

The offending code is located at kernel/boot/Handoff.cpp:L83 for the Stivale2 parser

void Handoff::parseStivale2(Handoff* that, void* handoff)
{
    ...
    while (tag)
    {
        // TODO: Find a way around this when the new memory manager code is done.
        uintptr_t page = ((uintptr_t)tag & PAGE_ALIGN);
        map_kernel_page(VADDR(page), page);
        // Follows the tag list order in stivale2.h
        switch(tag->identifier)
        {
    ...
}

and like wise at kernel/boot/Handoff.cpp:L166 for the Multiboot2 parser.

void Handoff::parseMultiboot2(Handoff* that, void* handoff)
{
    ...
    // TODO: Find a way around this when the new memory manager code is done.
    for (uintptr_t page = ((uintptr_t)handoff & PAGE_ALIGN) + PAGE_SIZE;
         page <= (((uintptr_t)handoff + fixed->total_size) & PAGE_ALIGN);
         page += PAGE_SIZE) {
        rs232::printf("Mapping bootinfo at 0x%08x\n", page);
        map_kernel_page(VADDR(page), page);
    }
    ...
}

These two functions should not be required to map in the boot-loader information, especially considering kernel/arch/i386/boot/boot.s:L67 has to setup and enable paging in order to boot the kernel, considering it is a high-half kernel.

_start.lowmem:
    ...
    ; create virtual mappings for the kernel in the higher-half
    mov edx, _KERNEL_START
    shr edx, 22       ; find which directory entry we need to use

        ; the first page table
    mov eax, kernel_pt
    mov [edx * 4 + page_directory], eax
    or dword [edx * 4 + page_directory], PAGE_PERM
    ...
_start.higher:
    ; compute the page table offset
    ; this only works because the two page tables are adjacent
    ...

An ideal solution is as follows: Remove as much paging code out of boot.s (either by converting as much of boot.s to C as possible or creating basic C paging functions that can be accessed by boot.s ) and mapping in the bootloader information at the same time the kernel is mapped into higher-half memory.

Kfeavel commented 3 years ago

This would also be a huge step toward resolving #211.

the-grue commented 3 years ago

Please see PR #289

Kfeavel commented 3 years ago

Resolved by #289, but leaving open until @the-grue finishes refactoring the assembly into C.

Kfeavel commented 3 years ago

Resolved by #289, but leaving open until @the-grue finishes refactoring the assembly into C.

Going to close since this issue is resolved and converting assembly to C is its own, separate goal.