13

If I write a program that tries to read memory at every possible address, and I run it on a "full" Unix, it will not be able to access all of the physical RAM. But how does the operating system prevent it from doing so?

I am more familiar with small CPU architectures where any piece of assembly code can access everything. I don't understand how a program (the kernel) can detect such malicious operations.

zwol
  • 7,177
nowox
  • 447

1 Answers1

14

It's not the kernel that's preventing bad memory accesses, it's the CPU. The role of the kernel is only to configure the CPU correctly.

More precisely, the hardware component that prevents bad memory accesses is the MMU. When a program accesses a memory address, the address is decoded by the CPU based on the content of the MMU. The MMU establishes a translation from virtual addresses to physical addresses: when the CPU does a load or a store at a certain virtual address, it calculates the corresponding physical address based on the MMU content. The kernel sets the MMU configuration in such a way that each program can only access memory that it's entitled to. Other programs' memory and hardware registers are not mapped at all in a program's memory: these physical addresses have no corresponding virtual address in the MMU configuration for that program.

On a context switch between different processes, the kernel modifies the MMU configuration so that it contains the desired translation for the new process.

Some virtual addresses are not mapped at all, i.e. the MMU translates them to a special “no such address” value. When the processor dereferences an unmapped address, this causes a trap: the processor branches to a predefined location in kernel code. Some traps are legitimate; for example the virtual address could correspond to a page that's in swap space, in which case the kernel code will load the page content from swap then switch back to the original program in such a way that the memory access instruction is executed again. Other traps are not legitimate, in which case the process receives a signal which by default kills the program immediately (and if not branches to the signal handler in the program: in any case the memory access instruction is not completed).

  • Could you specify a bit the statement "the address is decoded by the CPU based on the content of the MMU"? Is there an actual code in the running program which decodes addresses? Or when a CPU makes an access to an address -- the access is done to MMU, which translates/handles it properly (makes an access to the memory or cache and returns the result, or triggers a kernel procedure)?

    So, from microcontroller/assembly perspective, the MMU is new part. The CPU is not connected directly to the memory, it is connected to MMU and that is where the virtual memory abstraction is done.

    – xealits Nov 27 '15 at 15:41
  • 3
    @xealits The translation from virtual address to physical address is done inside the MMU, which is a hardware circuit. There is no code to do that in the program or in the kernel. The kernel is only invoked in exceptional cases, when the program attempts to access a virtual address for which the MMU entry says “invalid address”. The kernel also does the job of configuring the registers and the tables in RAM that the MMU uses. – Gilles 'SO- stop being evil' Nov 27 '15 at 18:23