Thereafter, setup_arch() calls paging_init() in arch/i386/mm/init.c.
This function does several things. First, it calls pagetable_init() to map the
entire physical memory, or as much of it as will fit between PAGE_OFFSET and
4GB, starting at PAGE_OFFSET.
In pagetable_init(), we actually build the kernel page tables in swapper_pg_dir
that map the entire physical memory range to PAGE_OFFSET. This is simply a
matter of doing the arithmetic and stuffing the correct values into the page directory and page tables. This
mapping is created in swapper_pg_dir, the kernel page directory; this is also
the page directory used to initiate paging. (Virtual addresses up to the next
4MB boundary past the end of memory are actually mapped here when using 4MB page
tables, but "that's OK as we won't use that memory anyway"). If there is
physical memory left unmapped here - that is, memory with physical address
greater than 4GB-PAGE_OFFSET - that memory is unusable unless the CONFIG_HIGHMEM
option is set.
Near the end of pagetable_init() we call fixrange_init() to reserve pagetables (but
not populate them) for compile-time-fixed virtual-memory mappings. These tables
map virtual addresses that are hard-coded into the kernel, but which are not
part of the loaded kernel data. The fixmap tables are mapped to physical pages
allocated at run time, using the set_fixmap() call.
After initializing the fixmaps, if CONFIG_HIGHMEM is set, we also allocate some
pagetables for the kmap() allocator. kmap() allows the
kernel to map any page of physical memory into the kernel virtual address space
for temporary use. It's used, for example, to provide mappings on an
as-needed basis for physical pages that aren't directly mappable during
pagetable_init().
The fixmap and kmap pagetables occupy a
portion of the top of kernel virtual space - addresses which therefore
cannot be used to permanently map physical pages in the PAGE_OFFSET
mapping. For this reason, 128MB at the top of kernel VM is reserved
(the vmalloc allocator also uses
addresses in this range). Any physical pages that would otherwise be
mapped into the PAGE_OFFSET mapping in the 4GB-128MB range are instead
(if CONFIG_HIGHMEM is specified) included in the high memory zone,
accessible to the kernel only via kmap(). If
CONFIG_HIGMEM is not true, those pages are completely unusable. This
becomes an issue only on machines with a large amount of RAM (900-odd
MB or more). For example, if PAGE_OFFSET==3GB and the machine has 2GB
of RAM, only the first physical 1GB-128MB can be mapped between
PAGE_OFFSET and the beginning of the fixmap/kmap address range. The
remaining pages are still usable - in fact for user-process mappings
they act the same as direct-mapped pages - but the kernel cannot
access them directly.
Back in paging_init(), we possibly initialize the kmap() system
further by calling kmap_init(), which simply caches the first kmap
pagetable [in the TLB?]. Then, we initialize the zone allocator by computing the zone sizes
and calling free_area_init() to build the mem_map and initialize the
freelists
. All freelists are initialized empty and all pages are
marked "reserved" (not accessible to the VM system); this situation is
rectified later.