On x86, paging activation causes an “unconditional jump” (since EIP is now a virtual address)?

When paging is enabled by setting the paging bit in CR0 to 1, all pointers (including EIP) are now interpreted as virtual rather than physical addresses. If the memory area that the CPU is currently running on is an “identity mapping” (virtual addresses map to identical physical addresses), it looks like this will cause the CPU to do what constitutes an “unconditional jump” - this should start code execution from another (physical) address.

Is this really so? It seems to be very difficult to get the OS startup code to work reliably with this behavior. Or do all protected-mode OS identification files compose their own kernel code?

+5
source share
3 answers

Yes and no

Yes , in an informal sense, since the MMU is now translating from virtual to linear, and since the CPU is extracting virtual addresses. If we enable paging when executing a command at 4000h , assuming the next instruction is at 4003h , it is possible that 4003h translates to 8003h , so in fact there is a transition from 4000h to 8003h . Thus, we must match the page in which we are currently executing, or we will not know where the CPU code will be executed from.

No, in a technical sense, it does not jump, because the CPU does not see any transition team with all its side effects (eg, discarding instructions OoO), and, in addition, CPU accesses the memory only after the entire hierarchy of cache miss value that you you can still follow instructions from 4003h , even if the page maps to a different address.

So, is personal mapping necessary or not?

Yes, we need it. Not a complete identification card, I usually only (person), for example, displays pages 7 and 8 (corresponding to the linear range of 7000h-8fffh).

Comparing the activation of paging with the inclusion of protected mode, you can see how much they differ. Paging takes effect immediately, so you need to create all the page tables before that you activate, and you need at least one identification page to process the current current code without relying on caches.
Enabling protected mode instead is easier, you can even create GDT records after you enter protected mode, and you can control when to use it first by changing the case of segments (usually CS with jumps).

Actually, you don’t need a strictly personal page if you know what you are doing (for example, by duplicating your code or using some smoothing of the hardware memory), but this is very specific for the context in the general case, it just makes things uselessly complicated.

+3
source

This does not require a full identification card; for example, Linux actually deletes the startup code completely after it completes. The corresponding code is in pmjump.S , where the flat mode (32-bit identification card) is used, and the jump is performed immediately after the protected mode is turned on. It is noteworthy that this jump is recorded as a machine code due to switching to 32-bit mode. From there, to set up the page tables, through startup_32 . I’m not sure that unconditional transitions after status changes are completely necessary (for example, 32-bit real mode was an unplanned side effect without doing things as expected).

+3
source

The empirical answer: comment out the swap ID card setting on this minimal swap example: https://github.com/cirosantilli/x86-bare-metal-examples/blob/24988411adf10cf9f6afd1566e35472eb8ae771a/paging.S#L79 and see how. So yes, it "jumps."

0
source

All Articles