Before diving further into these details, it's very important to clearly understand a few key points.
Consider a small and typical code snippet from a C program:
int i = 5;
printf("address of i is 0x%x\n", &i);
The address you see the printf() emit is a virtual address and not a physical one. We distinguish between two kinds of virtual addresses:
- If you run this code in a user space process, the address of variable i that you will see is a UVA.
- If you run this code within the kernel, or a kernel module (of course, you'd then use the printk() API), the address of variable i you will see is a Kernel Virtual Address (KVA).
Next, a virtual address is not an absolute value (an offset from 0); it's actually a bitmask:
- On a 32-bit Linux OS, the 32 available bits are divided into what's called the Page Global Directory (PGD) value, the Page Table (PT) value, and the offset.
- These become indices...