iansjack wrote: ↑Wed Nov 20, 2024 3:20 am
If I read your diagrams completely, the address space of user programs overlaps that of the kernel. Assuming that you are using paging (and why wouldn't you?), doesn't this mean that every system call involves a reload of the page tables? That doesn't seem to be very efficient. Surely it's better to use a separate kernel address space.
You read the diagrams correctly. That's the plan anyway. When coming out of user space the trampoline will install the kernel page directory and a few other tasks such as changing over to a kernel stack. Having to manually do page translation for pointers coming out of user space is not going to be great for performance as well. I'm not sure yet if this will wind up being a bad idea.
iansjack wrote: ↑Wed Nov 20, 2024 8:41 am
Was that not the point of the interrupt trampoline area?
I'm pretty sure this is in reference to 'The "public" part of the kernel must live in it's own reserved address space.' and you are correct.
Octocontrabass wrote: ↑Wed Nov 20, 2024 11:33 am
Any particular reason why you're avoiding higher-half specifically? (Not that you need a reason.)
Perhaps because I have no idea what I am doing. But really the motivation here is it absolutely feels wrong to have such a large portion of the kernel address space overlap with the user address space. I see it as a least-privilege violation even when accounting for the ability to tell the MMU to keep the kernel pages inaccessible from rings above 0.
It's good to see my sysadmin gut has at least some idea of what it is doing. Of course my trampoline design brings with it performance issues and some pain in implementation passing data to/from user space. This is going to be an interesting experiment at least.
That's probably fine if you're using legacy BIOS, but what about UEFI? UEFI doesn't guarantee available memory at any specific addresses, so you might need to load your kernel at different physical addresses on different PCs.
Thank you for the heads up here. I'm really just cutting my teeth and decided to start with targeting i686. I figured wrapping my head around a turbocharged 386 running in Qemu is a nice simple place to start. On a lark I wanted to see if my kernel would actually boot on real hardware and found out fast my spare laptop doesn't even know how to boot legacy media. It did boot on my workstation though which nicely has a more flexible bios.
Doing the transition to x86_64 and UEFI and all that I'm sure is going to wind up with my head exploding, regrets, and swearing when I eventually get around to it.
You don't need to merge everything together into one section, but if you do it anyway, the only problem it can cause is that you won't be able to assign different permissions to things that share the same page.
...
If you link position-independent code into a static executable, the linker will perform optimizations that make the code no longer position-independent.
...
If the trampoline is entirely in its own object files, you can tell the linker to treat those files specially. For example:
Ahhhhhhhhhh thank you very much for the knowledge sharing. I've never had to worry about these kinds of details before.
I also realized after asking that if I tried to use relocatable code to move the trampoline around then I'd have to maintain and calculate function pointers so the identity mapped chunk of the kernel could call into the trampoline chunk or only interface with the trampoline through interrupts. Neither of those choices sounded particularly great. I think what I might do for a first pass is ask the linker to stick the trampoline around the end of the address space minus 32 MiB. That'll definitely hold for quite a while.
Do you know how "smart" GRUB/multiboot is going to be about loading an ELF binary with sections that have a very different address than other ones? My linker script currently starts off with a 2 MiB initial offset as suggested by the barebones tutorial. If I ask the linker to put sections at the end of the address space is multiboot going to see that in the ELF binary and attempt to stick it there? I'm wondering if I'm going to have to make the trampoline it's own ELF binary and bring it in with a multiboot module.