Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the kernel stack movable #61

Closed
Darksecond opened this issue Jul 3, 2019 · 5 comments · Fixed by #71
Closed

Make the kernel stack movable #61

Darksecond opened this issue Jul 3, 2019 · 5 comments · Fixed by #71
Assignees
Labels
help wanted Extra attention is needed

Comments

@Darksecond
Copy link
Contributor

Right now the kernel stack is always fixed in memory. If I want to make my kernel higher-half the kernel will need to move. This can be done by providing a custom linker script to the kernel target. This works fine. The stack that is setup by the bootloader however is always fixed in memory and will not move with the kernel.

I suggest making the stack location configurable like the physical memory offset already is. A more elegant solution would be to switch to an offset and automatically calculate the stack location.

@phil-opp
Copy link
Member

phil-opp commented Jul 6, 2019

Thank you for opening this issue!

I suggest making the stack location configurable like the physical memory offset already is. A more elegant solution would be to switch to an offset and automatically calculate the stack location.

I completely agree! I think it's best to support both variants: Dynamically calculate a sensible stack location by default and allow the user to override it through an environment variable.

I don't have the time to implement it myself right now, but I'd be happy to merge a pull request. Adding the environment variable can be done as in #58. For the dynamic calculation, I think the easiest way is something like the following (in pseudo code):

struct UsedLevel4Entries {
    entry_state: [bool; 512], // whether an entry is in use by the kernel
}

impl UsedLevel4Entries {
    fn get_free_entry(&mut self) -> Page<Size1GiB> {
        let entry = self.iter_mut().find(|b| b == false).unwrap();
        entry.set(true);
        entry.page();
    }
}

fn used_level_4_entries(kernel_elf: &KernelElfFile) -> UsedLevel4Entries {
    let mut used = UsedLevel4Entries { entry_state: [false; 512], };
    for program_segment in kernel_elf {
        for level_4_page in program_segment.level_4_page_range() {
            used[level_4_page.index()] = true;
        }
    }
    used
}

Then we can use get_free_entry for selecting a free level 4 entry for the kernel stack, the physical memory offset, the recursive mapping, and the boot info.

@phil-opp phil-opp added the help wanted Extra attention is needed label Jul 6, 2019
@64
Copy link
Contributor

64 commented Jul 30, 2019

Going to take a stab at this at some point over the next few days

@64 64 self-assigned this Jul 30, 2019
@64
Copy link
Contributor

64 commented Aug 1, 2019

I have a minimal working version which does most of these things.

I think ideally we should avoid taking up four different p4 entries, if possible. Kernel stack and boot info can definitely be put in the same entry.

It would also be good to pass the kernel some kind of structure which can be used to easily unmap the boot info and bootloader mappings when the user wishes, and I think this might be a good opportunity to do it.

@phil-opp
Copy link
Member

phil-opp commented Aug 1, 2019

@64 Sounds good!

bors bot added a commit that referenced this issue Aug 1, 2019
71: Dynamically map kernel stack, boot info, physical memory and recursive table r=phil-opp a=64

Fixes #61. This provides a way for the user to set the kernel stack address through an environment variable, or calculate it dynamically, making sure that it does not interfere with any other mappings. We also calculate space for the recursive page table, boot info and physical memory offset, with the small optimisation that the boot info and kernel stack are placed adjacently if possible to save a few extra page table allocations.

Going to punt on a way to unmap these things for now. Reclaiming memory from unused page tables is a bit tricky and it would be nice to do it right.

Co-authored-by: Matt Taylor <mstaveleytaylor@gmail.com>
@bors bors bot closed this as completed in #71 Aug 1, 2019
@64
Copy link
Contributor

64 commented Aug 1, 2019

Note: I am planning to document this when I write up a guide on making higher-half kernels, which should be in the next week or so (but for now this is usable through the BOOTLOADER_KERNEL_STACK_ADDRESS environment variable).

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants