Includeasmx86fixmap32h

static _always_inline unsigned long fix_to_virt(const unsigned int idx)

_this_fixmap_does_not_exist();

return _fix_to_virt(idx);

The if query is totally removed by compiler optimization mechanisms — this is possible because the function is defined as an inline function, 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_adresses is the last element of fixed_addresses and 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.

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

_fix_to_virt is defined as a macro. Owing to the inline property of fix_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))

Starting at the top (and not from the bottom as usual), the kernel goes back n pages to determine the virtual address of the n-th fixmap entry. As, once again, only constants are used in this calculation, the compiler is able to compute the result at compilation time. The address 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) and set_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_nocache disables hardware caching for the page involved as this is sometimes necessary.

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

Continue reading here: Alternative Division

Was this article helpful?

0 0