4

As noted in LDD the kernel virtual memory (top 1GB in IA-32 address space) is partitioned into kernel logical addresses and kernel virtual addresses. Kernel logical addresses are mapped directly which means that you can map virtual addresses to physical addresses by subtracting a certain (0xC0000000) value. For moving btwn mappings a pair of macros are defined: __pa() and __va().

My questions are: "What are the usecases for these macros?" and: "What is the benefit of direct mapping?"

I have heared that direct mapping allows using larger pages (e.g., 4MB) and consequently leads to more efficient translation. Are translations for the directly mapped region performed using page tables?

3
  • Picked from www.makelinux.net , ldd3, chp15: if you have a logical address, the macro __pa( ) (defined in <asm/page.h>) returns its associated physical address. Physical addresses can be mapped back to logical addresses with __va( ), but only for low-memory pages.
    – a.saurabh
    Commented Apr 21, 2017 at 12:14
  • If the mapping is done using the page tables why do we need these macros? If these macros are used to eliminate the access to the page tables how is it possible to have access to a physical address (returned by __pa()), directly?
    – TheAhmad
    Commented Apr 21, 2017 at 19:16
  • 1
    @TheAhmad If you have a physical address, you cannot access it directly on x86--you must map some virtual address to that physical address, and then access the virtual address. Linux sets up (or used to setup--I'm not sure if the direct map exists in its entirety anymore) the page tables so that every physical address is accessible from a virtual address. The macros give you that virtual address, if you pass in the physical address.
    – mdenton8
    Commented Apr 22, 2018 at 22:01

1 Answer 1

0

as we known, in 32 bit older days, 0 ~ 3 GB of the virtual memory address space is belonged to user space;3 GB ~ 4 GB of the virtual memory address space is belonged to kernel space;

in kernel, it usually allocated physical memory from Normal Zone which usually is under 1 GB;

for example, we allocate memory by kmalloc(100, GFP_KERNEL)

GFP_KERNEL means allocate physical memory from Zone Normal;

by that, Kernel can easily add 0xC000000(aka, 3 GB offset) to physical memory address(0 ~ 1 GB), then the physical memory address is directly mapped to kernel virtual memory address(3 ~ 4 GB);

by this way, kernel can access underneath physical memory more quickly which just subtract by 0xC0000000; (the memory access is by virtual address, need map virtual address to physical address)

Not the answer you're looking for? Browse other questions tagged or ask your own question.