http://www.aros.org AROS-Exec AROS-Exec Archives Power2People
kitty mascottop logo menu

MMU HIDD

Note

This document is currently only a draft and as such will most likely change before it is accepted as an official specification. It might also be deprecated if a better approach has been found in the mean time, and doesn't necessarily correspond precisely with the current implementations.

Characteristics

The mmu.hidd will be the hardware interface for the Memory Management devices, and should have the following characteristics:

  • Memory is divided in memory pages, and access restrictions are handled on a page-by-page basis. Page size should be adaptable to hardware used.
  • Access to a page could be set for any specific task to be unreadable, readable, or read/writeable.
  • Tasks should be able to change these access restrictions on regions of memory, both for themselves and for other tasks.
  • It should be possible, e.g. for reasons of speed or because of hardware limitation, to disable some (or all) parts of the memory management, or to decide to only partially implement the mm specification. The mmu.hidd should implement an interface that allows the OS to determine a level of supported memory management, to allow the OS(es) to adapt.
  • The mmu.hidd should be a low-level abstraction. It should not include the higher level of specific mm-based services, but it should be abstraction of the interfaces used for actual MMU implementations.

Optional features:

  • Virtual Address Scheme: Virtual addresses can be different from real addresses and the same real address can be mapped to different virtual addresses for different tasks, and vice versa. (Mapping addresses 1:n is a requirement for a real fork() or other OS emulation layers but will probably not be used by AROS itself.)
  • Virtual memory support: Gathering metrics to decide which page should be swapped. The virtual memory scheme itself, swapping pages in and out, are beyond the scope of the mmu.hidd because of the need for disk IO. Therefore it should be implemented elsewhere in the OS.
  • Security features: Through the use of the mmu.hidd the OS should be able to limit the rights of tasks to change the access restrictions of pages Thus the OS could stop malicious code from changing an unwriteable page to a writeable one in order to hack the page's contents.
  • Feature support: Providing support for the OS for special features of specific MM implementations. E.g.: Supervisor context on the Amiga 68k which provides fast switching between contexts without the need for mmu cache flushes. Similar special features may exist in other MM implementations (PowerPC, Alpha, Intel, HP, ...).
  • Support for cache control on pages and DMA support and similar, if this can be generalized. This will mostly be useful for other drivers.

Implementation

To allow room for optimization, different levels of mmu implementation can be implemented by the mmu.hidd programmer. The OS on top of the mmu.hidd (normally AROS) should be flexible enough to adapt itself to the level implemented by the mmu devices. Also, different implementations can be created for the same hardware, to allow the system administrator to decide at boot time on the type of system to run: A fast single-user system or a, slightly slower, secure multi-user system.

Level 0: No memory protection support

This is like it was in the classic OS: A single address space without any memory protection.

A basic hook can be installed, which may be called when a memory access error occurs. This is an optional feature which, on hardware that can't support it, need not be implemented, nor if the implementation would require memory pages, as those aren't supported for level 0. Since it's optional, the OS should not be based on the assumption that a memory access error results in a call to such a hook.

At all times, the mmu.hidd has to know the amount of physical memory in the system. Two mechanisms are provided to assure this:

  • During (system) initialization a list of available memory is provided.
  • HIDD methods should be implemented to allow the addition and removal of certain memory. (Such methods would be useful for PCMCIA cards, or wouldn't they?)

Also, every mmu implementation should implement and document an API to set caching policies. Drivers which need those should then be able to use this. (Ideally this API would be the domain of the abstract mmu.hidd, rather than of each specific implementation, but caching protocols appear to vary so widely that any abstraction would limit the actual implementations. This machine-dependent API will, however, be used only by machine-dependent drivers.)

Level 1: A single address space with basic access restrictions

Although the description mentioned tasks, in the implementation of the mmu.hidd they are replaced by Memory Contexts. Memory contexts originate from a proposal from Dave Haynie, and were used in the mmu.library by Thomas Richter, for the classic AmigaOS. Tasks are defined at a higher level in the OS and could also include metrics related to task switching and the like. The relation between contexts and tasks is up to the OS. Different contexts could be associated with a single task, or a single context could be shared between several tasks.

The address space is divided into memory pages. At this level there is only one address space and all addresses are physical addresses. All contexts thus have the same address space. However, a page can have different access restrictions in different contexts. A page can be either non-existent, unmapped (it exists but is not currently in use), unreadable, readable, or read-writeable. The mapped/unmapped flag is there to allow mmu.hidd page allocations to coexist with the OS memory allocation. When the OS wants to allocate a page it should select an unmapped page and mark it as mapped. A convenience method 'ReservePages' could be provided, which maps the amount of pages required and returns a list of those pages. Since these are physical addresses, the pages returned in such a list should be adjacent, as that's what the application requires.

By implementing this internally, it should be possible to minimize the required number of page tables. When creating a new context the mmu.hidd could itself Reserve Pages, for the context's page tables.

Hooks can be registered, to be called when a page's access restriction is violated. When a hook is called it should first check whether it's applicable to the reported violation. If it is, it should handle the exception and return TRUE, otherwise, it should immediately return FALSE. This allows mmu.hidd to keep a list of hooks and call each in turn until one of them handles the exception. When no (other) hook handles a certain exception the mmu.hidd will try to make the program continue by skipping the offending instruction. Of course, OS developers are urged to handle every exception generated (and AROS probably will).

When the OS wants to change something on a context it should lock the context first. Afterwards it should unlock the context again. This allows the mmu.hidd to optimize determining the page tables, by only recomputing them when a context is unlocked. (Though LockContext will keep processes from changing the settings of the same context at the same time, it does not block usage of the context in any way. You should be as quick as possible inside the lock, and check that the order of your changes will not have unintended side-effects.) Because no two LockContext()s can be executed simultaneously on the same context, functions have to be provided so the OS can keep track of which process has locked a context and a hook is called when a second lock is tried on a context. This way a deadlock can be prevented by the OS by switching back to the task which first locked the context.

Like the mmu.library on the classic AmigaOS, mmu.hidd could offer a way to lock multiple contexts at once.

Level 2: Virtual addresses

At this level an address need no longer be a physical address. Methods have to be provided for the mmu.hidd to get the amount of real memory on the system, and the segments it is divided in, and to map/unmap a real page in a certain context or contexts. For hardware drivers and DMA the real address will be needed, so methods to translate between virtual address and physical address will also have to be provided.

Level 3: Virtual memory support

This is basically the same as the previous level, but some additional flags allow virtual memory support. One flag should indicate whether a page is swapped to disk. Other flags should help the OS to decide which pages to swap out, by indicating whether a page has been read or been written to. The former can be used by the OS to decide which pages are accessed the least frequent and are a candidate to be used when a new page needs to be swapped in; the latter warns the OS that that page needs to be swapped out first before swapping in the requested page. The interpretation and clearing of these flags are part of the OS module that implements virtual memory.

An additional hook can be installed at this level which is called whenever a program tries to access a swapped memory page. By this hook the OS should perform everything needed to swap the page back in.

Maybe this level can be joined with the previous level, since an MMU that allows for virtual addresses will probably implement virtual memory support as well. On the other hand, maybe an AROS version on an FPGA may only want to implement level 2 and not level 3. Comments wanted!

Security support

The features presented so far only implement protection against accessing unprivileged pages. No measures were taken to protect against malicious code. Code that tries on purpose to mess things up, is free to do so. To prevent this some more hooks are needed. These are called whenever code tries to change a context. So, if code wants to change access restrictions, create a new context, switch contexts or something similar, the OS can intervene and disallow the change, and maybe even kill the offending program. When the kernel OS boots, it should create a context with the appropriate hooks, after which everything can be secured.

This security support can be optionally implemented on those mmu.hidd levels that implement contexts: Levels 1, 2, and 3. This means a mmu.hidd can implement the following support:

  • level 0
  • level 1 without security
  • level 1 with security
  • level 2 without security
  • level 2 with security
  • level 3 without security
  • level 3 with security

Of course, a certain level including security may be (somewhat) slower than the same level without security.


Copyright © 1995-2024, The AROS Development Team. All rights reserved.
Amiga® is a trademark of Amiga Inc. All other trademarks belong to their respective owners.