1. Overview
The virtual address space of a process in Linux consists of pages of fixed sizes. A page is the smallest unit of data used in virtual memory management.
In this tutorial, we’ll discuss the page size in the virtual address space. Firstly, we’ll discuss the virtual memory addressing and pages briefly. Then, we’ll learn how to get the page size. Finally, we’ll discuss how the page size is determined.
2. Brief Information About Virtual Addresses and Pages
In Linux, each process runs as if it owns a large and contiguous memory thanks to virtual memory addressing. The size of the virtual address space of a process depends both on the architecture of the system and on the Operating System (OS). For example, 32-bit architectures can provide access to 4 GB of memory in Linux, but the OS provides 3 GB for the user space and 1 GB for the kernel space for each process.
The virtual address space of a process is generally much larger than the actual amount of the physical memory in the system.
Virtual memory addressing has several advantages. For example, it provides process isolation as each process has its own address space, increasing security. Another advantage of it is to make application programming easier since the details of the fragmented physical memory are hidden from the application.
The hardware unit that translates virtual addresses to physical addresses is the Memory Management Unit (MMU). It’s usually located in the CPU.
MMU divides the virtual addresses into fixed-length memory chunks known as pages. It maps a page in the virtual memory to a page frame in the physical memory. Therefore, the page size depends on the hardware architecture.
The page size is typically 4096 bytes in Linux for x86-64 processors.
3. Getting the Page Size
In this section, we’ll discuss how to get the page size using different methods.
3.1. Getting the Page Size From the Command Line
We can get the page size using the getconf command:
$ uname -a
Linux centos9 5.14.0-22.el9.x86_64 #1 SMP Fri Nov 26 23:47:21 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ getconf PAGESIZE
4096
The getconf command prints the system configuration variable values. PAGESIZE is one of the system configuration variables corresponding to the page size of the virtual address space. The distro we check the page size for is CentOS Stream 9, as the output of the uname command shows. Therefore, its value is 4096 bytes.
We can also use PAGE_SIZE instead of PAGESIZE:
$ getconf PAGE_SIZE
4096
Since the page size of the virtual address space is architecture dependent, we may get a different result on a different system:
$ uname -a
SunOS server1 5.10 Generic_120011-14 sun4u sparc SUNW, Sun-Fire-V445
$ getconf PAGESIZE
8192
The page size is 8192 bytes in SunOS on UltraSPARC architecture.
3.2. Getting the Page Size Programmatically
We can also get the page size programmatically using the following C program, get_page_size.c:
#include <stdio.h>
#include <unistd.h>
void main()
{
printf("Page size (sysconf) %d\n", sysconf(_SC_PAGESIZE));
printf("Page size (getpagesize) %d\n", getpagesize());
}
The program gets the virtual memory page size using two different functions. The first one is the sysconf() function in the standard C library. The parameter we pass to sysconf() is _SC_PAGESIZE.
The other function we use is getpagesize(). getpagesize() is also in the standard C library. However, using sysconf() instead of getpagesize() is more portable in old standard C libraries.
We print the values returned by sysconf() and getpagesize() using printf().
Let’s build the program using gcc and then run it:
$ gcc -o get_page_size get_page_size.c
$ ./get_page_size
Page size (sysconf) 4096
Page size (getpagesize) 4096
The page sizes returned by sysconf() and getpagesize() are the same, 4096, as expected.
4. How Is the Page Size Determined?
The PAGE_SIZE macro defined in the Linux kernel source determines the page size. Its definition is in the kernel header file /usr/src/kernels/5.14.0-22.el9.x86_64/include/asm-generic/page.h in CentOS 9 Stream. This macro is calculated using another macro in the same header file, PAGE_SHIFT.
The value of PAGE_SHIFT is 12. The value 1 is shifted to the left PAGE_SHIFT times (1UL << PAGE_SHIFT) and assigned to PAGE_SIZE. This is equivalent to 2^12, which is 4096.
5. Conclusion
In this article, we discussed the page size in the virtual address space. Firstly, we briefly looked at virtual addressing and pages. Then, we learned that page size depends on the hardware architecture. Following, we discussed how to get the page size. Finally, we saw how the OS determines the page size.