Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


include/asm-x86/fixmap_32.h
#define __FIXADDR_TOP 0xfffff000
#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)
#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)

The advantage of fixmap addresses is that at compilation time, the address acts like a constant whose
physical address is assigned when the kernel is booted. Addresses of this kind can be de-referenced faster
than when normal pointers are used. The kernel also ensures that the page table entries of fixmaps are
not flushed from the TLB during a context switch so that access is always made via fast cache memory.

A constant is created for each fixmap address and must appear in theenumlist calledfixed_addresses.

include/asm-x86/fixmap_32.h
enum fixed_addresses {
FIX_HOLE,
FIX_VDSO,
FIX_DBGP_BASE,
FIX_EARLYCON_MEM_BASE,
#ifdef CONFIG_X86_LOCAL_APIC
FIX_APIC_BASE, /* local (CPU) APIC) — required for SMP or not */
#endif
...
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte’s for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
...
FIX_WP_TEST,
__end_of_fixed_addresses
};

The kernel provides thefix_to_virtfunction to calculate the virtual address of a fixmap constant.

include/asm-x86/fixmap_32.h
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();

return __fix_to_virt(idx);
}

Theifquery is totally removed by compiler optimization mechanisms — this is possible because the
function is defined as aninlinefunction, and only constants are used in the query. Such optimization is
necessary because otherwise fixmap addresses would be no better than normal pointers. A formal check
is made to ensure that the required fixmap address is in the valid area.__end_of_fixed_adressesis
the last element offixed_addressesand defines the maximum possible number. The pseudo-function
__this_fixmap_does_not_exist(for which no definition exists) is invoked if the kernel accesses an
invalid address. When the kernel is linked, this leads to an error message indicating that no image can
be generated because of undefined symbols. Consequently, kernel faults of this kind are detected at
compilation time and not when the kernel is running.
Free download pdf