Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


When a valid fixmap address is referenced, the comparison in theifquery yields a positive value. Since
both comparison objects are constants, the query need not be executed and is therefore removed.

__fix_to_virtis defined as a macro. Owing to theinlineproperty offix_to_virt, it is copied directly
to the point in the code where the fixmap address query is executed. This macro is defined as follows:

include/asm-x86/fixmap_32.h
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))

Startingat the top(and not from the bottom as usual), the kernel goes backnpages to determine the virtual
address of then-th fixmap entry. As, once again, only constants are used in this calculation, the compiler
is able to compute the result at compilation time. Theaddress in RAM at which the corresponding virtual
address is located has not yet been occupied as a result of the above division of memory.

The association between the fixmap address and physical page in memory is established by
set_fixmap(fixmap, page_nr)andset_fixmap_nocache(whose implementation is not discussed).
They simply associate the corresponding entry in the page tables with a page in RAM. Unlike
set_fixmap,set_fixmap_nocachedisables hardware caching for the page involved as this is sometimes
necessary.

Notice that some other architectures also provide fixmaps, including AMD64.

Alternative Allocators


Dividing virtual address space in a 3 : 1 ratio is not the only option. Relatively little effort is needed to
select a different division because all bounds are defined by constants in the sources. For some purposes
it may be better to split the address space symmetrically, 2 GiB for user address space and 2 GiB for
kernel address space.__PAGE_OFFSETmust then be set to0x80000000instead of the typical default of
0xC0000000. This division is useful when the system performs tasks that require a large amount of mem-
ory for the kernel but little for the user processes (such tasks are rare). As any change to how memory
is divided requires recompilation of all userspace applications, the configuration statements include no
option to split memory differently, although this would be easy to do in principle.

Basically, it is possible to split memory by manually modifying the kernel sources, but the kernel offers
some default splitting ratios.__PAGE_OFFSETis then defined as follows:

include/asm-x86/page_32.h
#define __PAGE_OFFSET # ((unsigned long)CONFIG_PAGE_OFFSET)

Table 3-6 collects all possibilities for splitting the virtual address space and the resulting maximal amount
of RAM that can be mapped.

Splitting the kernel in ratios other than 3 : 1 can make sense in specific scenarios, for instance, for
machines that mainly run code in the kernel — think about network routers. The general case, however,
is best served with a 3 : 1 ratio.

Splitting the Virtual Address Space


paging_initis invoked on IA-32 systems during the boot process to split the virtual address space as
described above. The code flow diagram is shown in Figure 3-16.
Free download pdf