Virtual Memory and MMU: when are they used and when not?

3

2

I'm wondering about how a Virtual Memory system could be managed alongside with a MMU when there's the need to mantain some "fixed" addresses in the address space.

For example, when a machine boots up, the CPU starts reading the first instruction from a fixed address (that is mapped to some kind of ROM), then gives addresses to pheriperals (if the Memory Mapped I/O system is used), and then the OS is bootstrapped. I also know that interrupt routines and such things need to be at "fixed" position in memory, and these things are loaded by the OS.

I may think that MMU is disabled in such a process and then it is enabled after the OS loaded.

I may think that the processes above uses system address space and that the system address space is not virtualized, despite the user address space actually is.

This will result in a pool of physical addresses that remains the same in order to access I/O peripherals, interrupt routines and so on, and a virtual user space managed by the MMU, where the processes can elaborate all the data they needs to elaborate, demanding to the OS the access to I/O peripherals.

But i'm not sure of these things. So I ask you, when the MMU is actually enabled? Does it deal with all the addresses, or only with the ones of the user space? Is it true that some addresses can bypass the MMU even when the system is running, in order to access fixed memory positions? Or am I missing some important clues?

iMineLink

Posted 2014-02-03T14:45:04.467

Reputation: 133

Answers

-2

x86 CPUs boot up in a "real mode" - basically, 16-bit mode where the CPU can only see the first 1MB of RAM. One of the first tasks of a BIOS bootloader (or UEFI may do this directly) is to switch the CPU into "protected" mode. Protected memory is available in this mode, and the CPU has privilege levels in this mode - generally "kernel" and "user."

I'm a bit fuzzy on this, but how the MMU maps memory is controlled by the Global Descriptor Table (GDT). Kernel mode can change the GDT, user mode cannot.

So when kernel mode is entered, it can set the GDT to a memory mapping that either identity maps all memory (i.e. acts like it's not mapped at all) or maps it in a way that gives it access to all devices, etc. When it returns to user mode, it can load more restrictive GDT before handing control back.

I might be wrong - it may be when the CPU enters kernel mode it simply disables the MMU but I do believe it can be used by kernel mode as well in this fashion.

LawrenceC

Posted 2014-02-03T14:45:04.467

Reputation: 63 487

This makes sense! So either the SO uses a "1:1" memory mapping or disables the MMU at all in kernel mode... Things like DMAs controllers, that are given a base address and a buffer size to transfer data directly from or to RAM, using therefore addresses that are sequentially, are managed in the kernel space? – iMineLink – 2014-02-03T16:02:54.293

There's some details of the Windows bootloader in http://channel9.msdn.com/Shows/Going+Deep/Inside-Windows-8-Chris-Stevens-Boot-Environment

– David Marshall – 2014-02-03T17:15:36.793

DMA probably works on the physical address level only - though newer CPUs have an IOMMU that may allow translation of device I/O addresses. – LawrenceC – 2014-02-03T17:29:32.100

@DavidMarshall thanks for the video, I've downloaded it and I will see it as soon as possible.

ultrasawblade interesting!

– iMineLink – 2014-02-03T18:04:27.260

1

Sorry but the speculation in the chosen answer is misleading, and leaves out the most important aspect, which is address translation via page tables.

It is true that when any PC-compatible machine boots it starts out in "real mode". And modern 32-bit operating systems on x86 do run in "protected mode", which includes segmented addressing as defined by the GDT. However they then also enable page table-based address translation by setting the PG (paging) bit, bit 31, in CR0. This is never turned off for the life of the OS.

Also, in most modern 32-bit operating systems, GDT-based segmented addressing is essentially bypassed: All of the commonly-used GDTEs are set up with base address 0, size 4 billion bytes. So although the MMU does go through the motions of adding the relevant segment "base address" to the "displacement" that comes from the instruction, this is effectively a no-op. A different set of GDTEs is used for ring 0 vs ring 3, but they all have the same base address and size. The "privilege level" fields (0 vs 3) are about all that is different. This enables the "privileged access" bit in the page table entries to be effective, allowing memory to be protected for kernel- mode or user+kernel mode access on a page-by-page basis. That is not possible with segment descriptors; they are far too coarse-grained.

In x64 CPUs the segmenting mechanism essentially disappears while in long mode. Page table-based address translation of course still happens as long as the PG bit is set, which it is throughout the life of the OS. The MMU is most emphatically not disabled while in kernel mode, nor does the "SO" (or anything) use 1:1 mapping between virtual and physical addresses.

Accesses to known physical addresses, like those assigned to PCI-like peripherals, is done by allocating unused virtual addresses and setting up the correspondnig page table entries with the required physical page numbers. Code in device drivers then uses the virtual addresses.

Yes, DMA primarily works on physical addresses. A dumb/cheap DMA controller indeed just transfers to a physically contiguous buffer with a given start address and length. To support such devices either the OS or device driver will allocate physically contiguous "bounce buffers" for the DMA device to access, and copy data between there and the user's buffer.

Smart/more expensive DMA controllers can handle buffers that occupy discontiguous ranges of physical addressses (referred to as "scatter-gather mapping"). These are much preferred for high-performance devices.

An IOMMU can allow stupid/cheap DMA controllers to access a physically discontiguous buffer as if it was contiguous. However, platforms with IOMMUs are not yet ubiquitous enough to say "your platform must have an IOMMU for our OS". Therefore, at present, IOMMUs are primarily used by virtual machine monitors.

Jamie Hanrahan

Posted 2014-02-03T14:45:04.467

Reputation: 19 777