DEV Community

Cover image for Stop Wondering How Virtual Memory Works!!!
Bhushitha Hashan
Bhushitha Hashan

Posted on

Stop Wondering How Virtual Memory Works!!!

It’s 9:45 PM on a Tuesday. The office lights are dimmed, and the only thing illuminating Arjun’s face is the harsh white glare of a terminal filled with a nasty kernel backtrace. He’s slumped in his chair, hands over his face, looking like he’s about to lose it.

Maya, a Senior SRE who lives off black coffee and complex systems, walks by his desk on her way to the breakroom. She stops, seeing the "I’m fucked" energy radiating off him.


The Scene: Late Night at the SRE Lab

Maya: Yo, Arjun. You still here? You look like you just watched a server rack fall over. What’s up?

Arjun: (Groans) Maya, man... I’m losing my mind. I’ve been trying to debug this C program for four hours. I keep getting a SIGSEGV at an address that looks like 0x0000800000001234. I thought I understood memory, but this just looks like a random number. My pointers are tripping, and I don't even know where this data is actually going.

Maya: (Leans over, looking at the screen) Ah, the classic "I think I know pointers" crisis. Don't sweat it. everyone hits this wall. You’re looking at a virtual address, but you’re stressed because you can’t see the "real" memory, right?

Arjun: Exactly. It feels like magic. I know the CPU does something with page tables and the MMU, but it feels like a black box.

Maya: Alright, pull up a chair. Let’s strip the magic away. Think about it like this: your program is a spoiled brat. It thinks it owns the entire memory space,yes from zero to the max. That’s the Virtual Address Space. But the actual RAM (the Physical Address) is a shared resource the OS manages.

Arjun: So the CPU translates them on the fly?

Maya: Yeah, via the MMU (Memory Management Unit). But it doesn't translate byte by byte.that would be insane. It does it in 4KB chunks called Pages.

Arjun: Okay, so a virtual address is just an index?

Maya: Sort of. Look at your 64-bit address. Even though we call it 64-bit, x86_64 CPUs usually only use 48 bits for addressing right now.

Arjun: Wait, why only 48?

Maya: Because 48 bits gives you 256 Terabytes of RAM. We don't exactly have that sitting in the server room yet. But here’s the kicker: bits 48 through 63 must be a copy of bit 47. If bit 47 is 0, the top bits must be 0. If it's 1, the top bits must be 1. This is called Canonical Form.

Arjun: (Looking at his code) Wait... bit 47 in my address 0x000080... is 0, but bit 48 is a 1.

Maya: Bingo. That’s why you’re fucked. You broke the canonical rule. The CPU didn't even look at the page table; it just saw that bit 48 didn't match bit 47 and threw a General Protection Fault. SIGSEGV. Game over.

Arjun: Holy shit. So the address space is basically split in half?

Maya: Exactly.

  • Lower half (bit 47=0): User space (0x0000...)
  • Upper half (bit 47=1): Kernel space (0xffff...) Anything in that "hole" in the middle is radioactive.

Arjun: Okay, so if I fix my pointer math and stay in the lower half, how does it get to the actual RAM chip?

Maya: This is where it gets cool. The MMU takes your virtual address and splits it. The lowest 12 bits (bits 0–11) are the Offset. Since 2 to the power 12 = 4096, that offset points to the exact byte inside a 4KB page. The rest of the bits are the Virtual Page Number (VPN).

Arjun: And the MMU uses that VPN to "walk" the page table?

Maya: Right. It’s a 4 level tree. It’s like a scavenger hunt. The CPU starts at a base address in the CR3 register, uses bits from your address to find the next level, and finally lands on a PTE (Page Table Entry).

Arjun: (Squinting) So the PTE is the final answer?

Maya: Yes, you’ve got it exactly right. But the PTE is a compact little structure, not just a plain address. Look at this:

  • Bits 0–11: These are your Permission and Status Flags.
  • Bits 12–51: This is the PFN (Physical Frame Number).
  • Bit 63: This is the NX (No Execute) bit.

Arjun: Wait, so you’re saying the first 12 bits are just used for permissions and shit, and the other bits do the actual pointing?

Maya: Yes, exactly! The PTE contains the physical frame number (PFN) , which is the real, physical address of the page in RAM, but it's shifted right by 12 bits to save space.

When the CPU confirms you have permission (checking those flags in bits 0-11 like "is it writable?" or "is it user-accessible?"), it takes that PFN, shifts it left by 12 bits (which is just adding twelve zeros at the end) to get the base physical address, and then it adds the offset from your original virtual address.

Arjun: So: Virtual address -> PTE -> PFN (real physical page address) -> + offset -> real physical byte address.

Maya: Exactly. No more indirection. That’s the final translation. The address that comes out of that math is what goes out on the memory bus to actually grab the data from the RAM stick.

Arjun: Man, that bit shifting is clever. It’s like they reused the 12 bits of the offset to store the permissions in the PTE because they knew the physical frame address would always end in twelve zeros anyway.

Maya: Spot on. You’ve mastered the PTE layout. Now, what happens if the Present bit (bit 0) is 0?

Arjun: The MMU can’t find the page?

Maya: Right. Page Fault. The CPU stops what it's doing and screams for the OS. The kernel's page fault handler looks at the CR2 register to see where you were trying to go. If you were just trying to access a page that got swapped to the SSD, the kernel quietly loads it into RAM, updates the PTE, and lets your program continue like nothing happened.

Arjun: But if I’m trying to write to a read-only page or a null pointer?

Maya: Then the kernel realizes you’re doing something illegal and sends you a SIGSEGV. Which is exactly what happened to you tonight.

Arjun: (Laughs) Because I was hitting a non-canonical address. I didn't even make it to the page table check.

Maya: Exactly. And one last thing,don't forget the TLB (Translation Lookaside Buffer). Walking a 4-level page table for every single memory access would make the computer slow as hell. The TLB is a tiny, super fast cache in the CPU that remembers recent "Virtual -> Physical" translations. It's the only reason modern computers are fast.

Arjun: So: Check TLB -> if miss, walk Page Tables -> check PTE flags ->calculate physical address -> fetch data.

Maya: You got it. Now, quit staring at that backtrace, fix your pointer math, and let's get some food. My treat.

Arjun: (Closing the laptop) Thanks, Maya. I actually feel like I know what's happening under the hood now. I’m not just "fucked",I’m "educated and fucked."

Maya: (Laughing) That’s the spirit kid. Let’s go.

Top comments (0)