• Aucun résultat trouvé

“Dirty” Bits)

Dans le document 0.1 Style and Limits (Page 176-181)

An operating system that provides a page for an application program to use often wants to keep track of whether that page has been modified since the OS last obtained it (perhaps from disc or network) or saved a copy of it.

Nonmodified (“clean”) pages may be quietly discarded, since they can easily be recovered from a tile system if they’re ever needed again.

In OS parlance the modified pages are called “dirty” and the OS must take care of them until the application program exits or the dirty page is cleaned by being saved away to backing store. To help out with this process it is common for CISC CPUs to maintain a bit in the memory-resident page table indicating that a write operation to the page has occurred. The MIPS CPU does not support this feature, even in the TLB entries. The D bit of the page table (found in the EntryLo register) is a write-enable and is of course used to flag read-only pages.

So here’s the trick:

• When a writable page is first loaded into memory you mark its page table entry with D clear (leaving it read-only).

• When any write is attempted to the page a trap will result; system soft-ware will recognize this as a legitimate write but will use the event to set a modified bit in the memory resident tables — which, since it’s in the EntryLo(D) position, permits feature writes to be done without an exception.

• You will also want to set the D bit in the TLB entry so that the write can proceed, but since TLB entries are randomly and unpredictably replaced this would be useless as a way of remembering the modified state.

6.9 Memory Translation and 64-Bit Pointers

When the MIPS architecture was invented, 32-bit CPUs had been around for a while and the largest programs’ data sets were already moving up toward 100MB — the address space had only 4 bits or so to spare.1 There was therefore every reason to be reasonably careful with the 32-bit space and not to reduce it by profligate fragmentation; this is why application programs (running with user privilege) keep 31 bits’ worth of addressing for themselves.

When the MIPS III instruction set introduced 64-bit registers in 1991 it was leading the industry, and as we discussed in Section 2.8.2 MIPS was probably 4-6 years ahead of real pressure on a 32-bit address boundary The doubling of register size only had to yield a few bits of extra address space to be remarkably future-proof; it’s been more important to be cautious about the potentially exploding size of OS data structures than to make efficient use of all address space.

The limitations to the practical address space resulting from the basic 64-bit memory map are not going to be reached for a while; they permit the mapped user and other spaces to grow to 61 bits without any reorganization.

However, the XContext(VPN2) field is “only” 27 bits, limiting the mappable user virtual address to 40 bits. So how do we go about implementing a 40-bit user space?

A page table compatible with the layout of XContext has 229 entries (one for each value of R/VPN2, each 16 bytes long). That’s 8GB of space, which is larger than the whole of kseg0, ksegl, and kseg2 combined. Fortunately, the R4x00 CPU and its successors have another 240-byte, kernel-privilege, mapped region starting at 0xC000 0000 0000 0000 that can be used. Most of this page table is likely to be empty, since the 40-bit user program ad-dress space (for which R == 0) has an immense gap between stack and data segments, and there’ll be even less in the privileged areas. The part of the

1Historically, application program demand for memory space seems to have gown at about 34 bit per year, and this rate appears to be currently sustained.

156 6.10. Everyday Use of the MIPS TLB

page table corresponding to the gap will never be accessed and need not be mapped to physical memory at all. Clearly it’s going to be useful to have some relatively compact data structure to map the kernel-privilege addresses, but that’s straying into the design of operating systems and is beyond the scope of this book.

6.10 Everyday Use of the MIPS TLB

If you’re using a big OS, then it will use the TLB and you’ll hardly see it. If not, you may wonder whether it’s useful. Because the MIPS TLB provides a rather general address translation service, there are a number of ways you might take advantage of it.

The TLB mechanism permits you to translate addresses (at page granu-larity) from any mapped address to any physical address and therefore to relocate regions of program space to any location in your machine’s address map. There’s no need to support a TLB refill exception or a separate memory-held page table if your mapping requirements are modest enough that you can accommodate all the translations you need in the TLB.

The TLB also allows you to define some address as temporarily or perma-nently unavailable, so that accesses to those locations will cause an excep-tion that can be used to run some operating system service routine. By us-ing user-privilege programs you can give some software access only to those addresses you want it to have, and by using address space IDs in the trans-lation entries you can efficiently manage multiple mutually inaccessible user programs. You can write-protect some parts of memory.

The applications for this are endless, but here’s a list to indicate the range:

• Accessing inconvenient physical address ranges: Hardware registers for a MIPS system are most conveniently located in the physical address range 0-512MB, where you can access them with a corresponding pointer from the ksegl region. But where the hardware can’t stay within this de-sirable area, you can map an arbitrary page of higher physical memory into a convenient mapped area such as kseg2. The TLB flags for this translation should be set to ensure uncached access, but then the pro-gram can be written exactly as though the address was in the convenient place.

• Memory resources for an exception routine: Suppose you’d like to run an exception handler without using the reserved k0/k1registers to save context. If so, you’d have trouble because a MIPS CPU normally has nowhere to save any registers without overwriting at least one of these.

You can do loads or stores using the zero register as a base address, but with a positive offset these addresses are located in the first 32KB

of kuseg, and with a negative offset they are located in the last 32KB of kseg2. Without the TLB, these go nowhere. With the TLB, you could map one or more pages in this region into readlwrite memory and then use zero-based stores to save context and rescue your exception handler.

• Extendable stacks and heaps in a non-VM system: Even when you don’t have a disk and have no intention of supporting full demand paging, it can still be useful to grow an application’s stack and heap on demand while monitoring its growth. In this case you’ll need the TLB to map the stack/heap addresses, and you’ll use TLB miss events to decide whether to allocate more memory or whether the application is out of control.

• Emulating hardware: If you have hardware that is sometimes present and sometimes not, then accessing registers through a mapped region caw connect directly to the hardware in properly equipped systems and invoke a software handler on others.

The main idea is that the TLB, with all the ingenuity of a specification that fits so well into a big OS, is a useful, straightforward general resource for programmers.

6.11 Memory Management in a Non-UNIX OS

OSs designed for use off the desktop are generally called real-time OSs (RTOSs), hijacking a term that once meant something about real time. The UNIX-style system outlined in the first part of this chapter has all the elements you’re likely to find in a smaller OS, but many RTOSs are much simpler.

This field is new enough that there are no real standards. The likely pio-neer in this area is Microsoft’s Windows/CE, and internal descriptions of that OS may not yet be freely available. So we’ll limit ourselves to a few general points.

Off-desktop systems are likely to be providing a single fairly tightly inte-grated function; without the need to support a diverse range of programs, including third-party and customer-written software, process protection is much less of an issue. We expect smaller OSs to be more permissive, since the applications writers have more influence. It’s not clear that this is actu-ally a good thing, but older RTOSs had no protection at all.

Demand paging makes a lot of sense as a way of loading a program, since you don’t have to do the work of loading parts of the program that aren’t used. Systems without a disk probably won’t page out dirty data; however, demand paging remains useful without it.

When you’re trying to understand a new memory management system, the first thing is to figure out the memory maps, both the virtual map presented

158 6.11. Memory Management in a Non-UNIX OS

to application software and the physical map of the system. It’s the simple-minded virtual address map that makes UNIX memory management relatively straightforward to describe. But operating systems targeted at embedded ap-plications do not usually have their roots in hardware with memory man-agement, and the process memory map often has the fossils of unmapped memory maps hidden inside it. The use of a pencil, paper, and patience will sort it out.

Chapter 7

Dans le document 0.1 Style and Limits (Page 176-181)