Figure 316 Code flow diagram for paginginit

pagetable_init first initializes the page tables of the system using swapper_pg_dir as a basic (this variable was previously used to hold the provisional data). Two extensions available on all modern IA-32 variants are then enabled (only a few very old Pentium implementations do not support these).

□ Support for large memory pages. The size of specially marked pages is 4 MiB instead of the usual 4 KiB. This option is used for kernel pages because they are never swapped out. Increasing the page size means that fewer page table entries are needed, and this has a positive impact on the translation lookaside buffers (TLBs), which are then less burdened with kernel data.

□ If possible, kernel pages are provided with a further attribute (_PAGE_GLOBAL) that is why the _page_global bit is activated in the_page_kernel and_page_kernel_exec variables. These variables specify the flags set for the kernel itself when pages are allocated; these settings are therefore automatically transferred to the kernel pages.

The TLB entries of pages with a set _page_global bit are not flushed from the TLBs during context switches. Since the kernel is always present at the same location in the virtual address space, this enhances system performance, a welcome effect as kernel data must be made available as quickly as possible.

Mapping of the physical pages (or of the first 896 MiB, as discussed above) into virtual address space as of PAGE_OFFSET is done with the help of kernel_physical_mapping_init. The kernel successively scans all relevant entries of the various page directories and sets the pointers to the correct values.

Then the areas for fixmap entries and the persistent kernel mappings are set up. Again, this equates to filling the page tables with appropriate values.

Once page table initialization with pagetable_init has been concluded, the cr3 register is supplied with a pointer to the page global directory used (swapper_pg_dir). This is necessary to activate the new page tables. Reassigning the cr3 register has exactly this effect on IA-32 machines.

The TLB entries must also be flushed because they still contain boot memory allocation data.

_flush_all_tlb does the necessary work. In contrast to TLB flushes during context switches, pages with a _page_global bit are also flushed.

kmap_init initializes the global variable kmap_pte. The kernel uses this variable to store the page table entry for the area later used to map pages from the highmem zone into kernel address space. Besides, the address of the first fixmap area for highmem kernel mappings is stored in the global variable kmem_vstart.

Continue reading here: Initialization of the Hotn Cold Cache

Was this article helpful?

0 0