Disable paging on x86 32bit

I'm trying to write directly to a physical memory location, so I use the build function to first turn off paging, write a value, and then turn on paging again, but for some reason, the page error still fails when I try to write the value.

As I understand it, in x86-32bit paging is turned on and off, flipping bit 32 to cr0, so here is my build function:

mov 4(%esp), %ecx //address mov 8(%esp), %edx //value mov %cr0, %eax and $0x7fffffff, %eax mov %eax, %cr0 mov %edx, (%ecx) //this line still triggers a page fault somehow or $0x80000000, %eax mov %eax, %cr0 ret 

Is this the right way to achieve what I want to do? If so, why is the page error still running when the bit in cr0 flipped over?

+5
source share
2 answers

A change in the CR0 register will become active when the jump instruction is executed (only for direct jump?).

Disabling paging, however, is not a good idea: you must ensure that the code is in 1: 1 mapped memory and that interrupts are disabled.

If you are using a stack, you must also ensure that the stack is 1: 1 mapped.

It is much easier to change the page tables so that the physical address in ecx is mapped to the virtual address, and then written to the virtual address.

+3
source

Intel 64 and IA-32 Software Developer's Guide System Programming Guide describes how to disable paging as part of the switch from protected mode to return to real mode:

9.9.2 Switching to real address mode

The processor switches from protected mode back to real address mode if the software clears the PE bit in CR0 register in the MOV CR0 instruction. The procedure that returns the real address mode must perform the following steps:

  • Disable interrupts. The CLI command disables masked hardware interrupts. NMI interrupts can be disabled using external circuits.
  • If paging is enabled, do the following:

    • Transfer software control to linear addresses that are identical for physical addresses (i.e. linear addresses of equal physical addresses).
    • Verify that the GDT and IDT are on identical pages.
    • Clear PG bit in register CR0.
    • Move 0H to register CR3 to clear the TLB.

You seem to have missed the last step. TLB (translation viewing buffer) is where the CPU caches entries in the page table and is still active after clearing the PG bit. You need to clear the TLB, or the processor will continue to use it.

Note that you will have to restart CR3 before setting the PG bit again. Also, due to the fact that you are doing very unusual, you may encounter errors and compatibility issues with your emulator. It can only handle disabling paging correctly as part of the real-time switching process, as this is probably the only scenario in which it has been tested. Even physical processors can have problems in this area.

+2
source

Source: https://habr.com/ru/post/1236491/


All Articles