Hello,
I recently read somewhere that the XNU (Mac OS) Kernel has completely different address spaces for the kernel and the userspace programs.
All the exception handlers are only present in the kernel space (address 0x0 to 0x5000). I don't really know what happens when an interrupt or exception occours while being in usermode. The CPU switches the execution level to kernel mode but it doesn't change the page directory. Since the handlers are not available in usermode it would crash. But obviously it works. Does anybody of you know how?
Do they have some kind of trampoline which is present in all address spaces and just switches page directories? I couldn't find any section in the address layout for the userspace which could be used for something like that.
I don't know if I can post them here: Copyright 'n stuff...
I couldn't find any hint int the Book "Mac OS X Internals: A Systems Approach" about this.
I also had a look into the XNU sourcecode, but its just too much to find to relevant places without knowing each and every piece of this kernel
edit:
Yes, I know that the TLB gets trashed everytime the page directory is switched. But they really seem to do it. And it seems that it works just fine.
Interrupt Handling in XNU
Re: Interrupt Handling in XNU
Interrupt stubs begin at 0ffe00000h in every process. The function pmap_init_high_shared takes care of initializing this address range. These stubs jump to a function which sets CR3 and jumps to the handler.
Re: Interrupt Handling in XNU
Great! Thanks. I will have a look at it.
So this means they really have some kind of trampoline to switch to the kernel address space and perform the real tasks in there.
At least I wasn't totally wrong.
So this means they really have some kind of trampoline to switch to the kernel address space and perform the real tasks in there.
At least I wasn't totally wrong.
Re: Interrupt Handling in XNU
Also, it's trivial to have a separate address space for kernel mode on PowerPC, because on that architecture,
all traps shut off translation and begin execution at predefined vectors in physical memory. Generally, this is
taken care of by having a separate address space for the kernel that gets mapped back in for interrupt
handling, and then maps either pieces or all of the user mode memory back in to deal with it later in the
execution flow. This is probably what your original source was referring to.
EDIT: What was previously said about how it's done on x86 is also the same, just clarifying that I didn't
intend to correct anyone, just shedding some light on the origin of this strange technique. Also, I fixed
some terrible formatting in my post. :p
all traps shut off translation and begin execution at predefined vectors in physical memory. Generally, this is
taken care of by having a separate address space for the kernel that gets mapped back in for interrupt
handling, and then maps either pieces or all of the user mode memory back in to deal with it later in the
execution flow. This is probably what your original source was referring to.
EDIT: What was previously said about how it's done on x86 is also the same, just clarifying that I didn't
intend to correct anyone, just shedding some light on the origin of this strange technique. Also, I fixed
some terrible formatting in my post. :p
Re: Interrupt Handling in XNU
Yes. That's what the book was referring to. The first few hundret bytes in the physical space are used for the exception vectors.
What wasn't mentioned was that the CPU disables all kind of memory address translation during an interrupt.
I'm wondering how big the performance impact on x86 really is, when regularly trashing the TLB due to all these page directory switches.
My Mac OS runs pretty fast.
What wasn't mentioned was that the CPU disables all kind of memory address translation during an interrupt.
I'm wondering how big the performance impact on x86 really is, when regularly trashing the TLB due to all these page directory switches.
My Mac OS runs pretty fast.
Re: Interrupt Handling in XNU
I've actually been wondering the same. With the PowerPC specification, a TLB is actually optional, and you're
just supposed to use the TLB flush instructions whenever you might need them, and processors that don't have
one just treat them as a no-op. So on PowerPC, every OS trashes the TLB, period, at every interrupt,
because the TLB is flushed when translation is shut off. And yet, one of my PowerMacs, a 180MHz 604,
has higher performance under the same version of Debian Linux than my Pentium 233. (I haven't gotten
to play with OSX86) Also, anybody remember BeOS demos back in the day of like 16 videos being played
in real time? And that, also, was trashing the TLB every time it switched between tasks that were playing
video. Kind of challenges your reality, right?
just supposed to use the TLB flush instructions whenever you might need them, and processors that don't have
one just treat them as a no-op. So on PowerPC, every OS trashes the TLB, period, at every interrupt,
because the TLB is flushed when translation is shut off. And yet, one of my PowerMacs, a 180MHz 604,
has higher performance under the same version of Debian Linux than my Pentium 233. (I haven't gotten
to play with OSX86) Also, anybody remember BeOS demos back in the day of like 16 videos being played
in real time? And that, also, was trashing the TLB every time it switched between tasks that were playing
video. Kind of challenges your reality, right?