Memory Mappings Overview & Mapping Types

 

Chapter 49: Memory Mappings
Part 1 of 5 โ€” Overview & Mapping Types
๐Ÿ“„ Topic
mmap Overview
๐ŸŽฏ Level
Intermediate
๐Ÿ“š Source
TLPI Ch49
๐Ÿ’ผ Target
TI / ST / Qualcomm

What is a Memory Mapping?

A memory mapping is a region of a process’s virtual address space that is backed by either a file on disk or by anonymous (zero-filled) memory. The kernel manages this mapping so that reading/writing to that virtual address range actually reads/writes the underlying backing store โ€” without the process manually calling read() or write().

Memory mappings are created using the mmap() system call. They are widely used for:

  • Loading program text and data segments (the OS does this automatically)
  • Memory-mapped file I/O (fast alternative to read/write)
  • Inter-process communication (IPC) between related or unrelated processes
  • Dynamic memory allocation (glibc malloc() uses this internally)
  • Sharing code between processes via shared libraries

Key Terms in This Part:

mmap() File Mapping Anonymous Mapping MAP_PRIVATE MAP_SHARED Copy-on-Write Virtual Address Space Page Table IPC

The Two Dimensions of a Mapping

Every mapping created by mmap() has exactly two independent attributes. Think of them as two separate on/off switches:

Dimension 1: Backing Store
Type Backed By
File Mapping A region of a file on disk
Anonymous Mapping Zero-initialized RAM (no file)

Dimension 2: Visibility
Flag Modifications
MAP_PRIVATE Private to process (copy-on-write)
MAP_SHARED Visible to all sharers + written to file

These two dimensions combine to produce 4 types of mappings (covered in the next section).

The 4 Types of Memory Mappings

The combination of file/anonymous ร— private/shared gives four distinct mapping types, each used for a different purpose:

Combination Primary Use Case Writes visible to others? Written to file?
Private + File Load program text/data, read-only file init No (copy-on-write) No
Private + Anonymous Memory allocation (malloc large blocks) No (copy-on-write) N/A
Shared + File Memory-mapped I/O, IPC between unrelated processes Yes Yes
Shared + Anonymous IPC between related processes (parent/child) Yes N/A

How Processes Share the Same Physical Pages

Two processes can end up pointing to the same physical RAM pages in two ways:

Way 1: Same File Region
Process A
Virtual Pages โ†’ Physical RAM page X
โ‡…
Process B
Virtual Pages โ†’ Physical RAM page X
Both mmap the same file region โ†’ kernel maps them to same physical pages.

Way 2: fork() Inheritance
Parent Process
Virtual Pages โ†’ Physical RAM page Y
fork() โ†“
Child Process
Virtual Pages โ†’ Physical RAM page Y
Child inherits parent’s page table entries. Both point to same RAM.

Whether these processes actually see each other’s writes depends on MAP_PRIVATE vs MAP_SHARED.

MAP_PRIVATE: Copy-on-Write (COW) Explained

With MAP_PRIVATE, modifications are not visible to other processes. The kernel achieves this through the copy-on-write mechanism:

COW Step-by-Step
1
Both processes map the same page โ€” page tables of both point to same RAM page. Page is marked read-only.
2
Process A tries to write to the page โ†’ hardware raises a page fault.
3
Kernel allocates a new private RAM page for Process A, copies data from original page into it, updates Process A’s page table.
4
Process A continues writing to its own private copy. Process B still sees the original page โ€” fully isolated.

This is exactly the same mechanism used by fork() for the process’s heap and stack pages.

MAP_SHARED: Shared Mappings

With MAP_SHARED, all processes that map the same region share the same physical pages. There is no copy-on-write. A write by one process is immediately visible to all others sharing that mapping.

For file-backed shared mappings, writes are also propagated back to the underlying file on disk (though potentially with a delay โ€” the kernel’s page cache handles this). This is the basis of memory-mapped I/O.

Key Difference Summary:

Attribute MAP_PRIVATE MAP_SHARED
Writes visible to others No Yes
Copy-on-Write Yes (kernel handles) No
File changes propagated No Yes (for file mappings)
Survives exec() No (mappings lost) No (mappings lost)
Inherited by fork() Yes Yes

Viewing Process Mappings: /proc/PID/maps

Linux exposes every mapping of a process in /proc/PID/maps. Each line shows: address range, permissions, offset, device, inode, and pathname (if file-backed).

/* Read and print your own process's memory map */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    char path[64];
    char line[256];
    FILE *fp;

    /* /proc/self/maps is shorthand for /proc/<our-PID>/maps */
    snprintf(path, sizeof(path), "/proc/self/maps");

    fp = fopen(path, "r");
    if (fp == NULL) {
        perror("fopen /proc/self/maps");
        exit(EXIT_FAILURE);
    }

    printf("%-40s %-6s %-8s %s\n",
           "Address Range", "Perms", "Offset", "Pathname");
    printf("%s\n", "-----------------------------------------------------------");

    while (fgets(line, sizeof(line), fp) != NULL) {
        printf("%s", line);
    }

    fclose(fp);
    return 0;
}

Sample output fields:

7f8a3c000000-7f8a3c021000 r--p 00000000 08:01 12345   /lib/x86_64-linux-gnu/libc.so.6
7f8a3c021000-7f8a3c176000 r-xp 00021000 08:01 12345   /lib/x86_64-linux-gnu/libc.so.6
7fff3b400000-7fff3b421000 rw-p 00000000 00:00 0       [stack]

Notice: r-xp = read + execute + private (code), rw-p = read + write + private (stack/heap), r--s would be read + shared.

๐ŸŽฏ Interview Questions โ€” Overview & Mapping Types
Q1. What is a memory mapping and why is it useful?
A memory mapping creates a direct correspondence between a region of a process’s virtual address space and either a file on disk or anonymous (zero-filled) RAM. It is useful because it avoids explicit read()/write() system calls for file I/O, enables efficient IPC by sharing pages between processes, and allows the OS to lazily load program segments from disk.
Q2. What is the difference between MAP_PRIVATE and MAP_SHARED?
MAP_PRIVATE gives each process its own copy-on-write view โ€” writes are not visible to other processes and not propagated to any backing file. MAP_SHARED means all processes sharing the mapping see each other’s writes, and for file-backed mappings, writes are also flushed to the file.
Q3. What is copy-on-write (COW) and how does the kernel implement it for MAP_PRIVATE?
COW is a lazy copying technique. Initially all processes sharing a private mapping point to the same physical pages, which are marked read-only in their page tables. When any process attempts a write, the hardware raises a page fault. The kernel handles the fault by allocating a new private page, copying the original content into it, updating the faulting process’s page table to point to the new page, then allowing the write to proceed. Other processes retain their pointers to the original page.
Q4. Name the four types of memory mappings and give one use case for each.
(1) Private + File: Loading a program’s text and initialized data segments from the ELF binary. (2) Private + Anonymous: malloc() allocating large memory blocks. (3) Shared + File: Memory-mapped I/O and IPC between unrelated processes via a file. (4) Shared + Anonymous: IPC between a parent and child process created by fork().
Q5. Are memory mappings preserved across exec() and fork()?
On fork(): Yes โ€” the child inherits all of the parent’s mappings (both MAP_PRIVATE and MAP_SHARED), including the mapping type. On exec(): No โ€” all mappings are destroyed (the process image is replaced). The new program gets its own fresh mappings created by the kernel when loading the ELF.
Q6. How does two processes mapping the same file end up sharing physical RAM pages?
The kernel’s page cache (also called the buffer cache) holds disk pages in RAM. When Process A maps a file region, the kernel brings those pages into the page cache. When Process B maps the same region, the kernel checks the page cache first โ€” if the pages are already there, it simply maps the same physical frames into Process B’s page table. No data is duplicated.

Chapter 49 Series

Part 1 of 5 โ€” Overview & Types

Next: mmap() System Call โ†’ ๐Ÿ  Home

Leave a Reply

Your email address will not be published. Required fields are marked *