Building your own Operating System (Week 07)

Krishan Shamod
4 min readSep 6, 2021

This is the seventh article in this series. In this article, I’m going to talk about virtual memory and paging. In the previous article, I explained user modes. You can check it out by clicking here. For those coding and implementation staff, I’m following the guide “The little book about OS development” by Erik Helin and Adam Renberg.

Virtual Memory

Virtual memory is an abstraction of physical memory. The goal of virtual memory is to make application development easier and to allow processes to access more memory than is physically available on the computer. Due to security concerns, we don’t want apps tampering with the kernel or other applications’ memory.

Virtual memory can be handled in the x86 architecture in two ways which are segmentation and paging. The most popular and adaptable approach is paging.

Paging

Paging is a function of memory management where a computer will store and retrieve data from a device’s secondary storage to the primary storage. Segmentation translates a logical address into a linear address. Paging translates these linear addresses onto the physical address space and determines access rights and how the memory should be cached.

Paging is the most common method for enabling virtual memory in x86 processors. Virtual memory is achieved by paging, which gives each process the impression that the accessible memory range is 0x00000000 –0xFFFFFFFF, despite the fact that the real memory capacity is much smaller. It also indicates that a process will use a virtual address instead of a physical address when accessing a byte of memory.

Paging is an optional feature that certain operating systems do not use. However, paging is the best technique to make particular portions of memory available exclusively to code executing at a specific privilege level.

Enabling Paging

Paging is enabled by first writing the address of a page directory to “cr3” and then setting bit 31 of “cr0” to “1”. To use 4 MB pages, set the PSE bit of “cr4”. We can enable paging using this assembly code.

The Virtual Address for the Kernel

The kernel should ideally be put at a very high virtual memory address, such as 0xC0000000 (3 GB). The user-mode process is unlikely to be 3 GB in size, which is the only way it may now cause a kernel conflict. A higher-half kernel is one that uses virtual addresses in the range of 3 GB and up. The location 0xC0000000 is only used as an example, the kernel may be put at any address greater than 0 to get the same results. The proper address is determined by the amount of virtual memory available for the kernel and the amount of virtual memory available for the process.

Virtual Memory Through Paging

Paging allows for two benefits in virtual memory. To begin with, it enables fine-grained memory access control. Pages can be marked as read-only, read-write, or exclusively for PL0, among other options. Second, it gives the impression of a single, continuous memory. The memory may be accessed as if it were contiguous by user-mode programs and the kernel, and the contiguous memory can be expanded without moving data around in memory. We can also provide user-mode applications access to any memory under 3 GB, but we don’t need to allocate page frames to the pages unless they actually utilize it. This enables processes to contain code around 0x00000000 and a stack slightly below 0xC0000000 while still requiring only two threads.

To do paging first we need to declare functions and other things in the “paging.h” header file.

Then we can define those functions in the “paging.c” file like this.

To compile those files correctly we need to modify “makefile” like this.

Finally, you can call the paging initializing function in “kmain.c” file.

init_paging();

Now we can run the OS using the “make run” command. If you succeed then you can see “Paging enabled” in the “com1.out” file like this.

Note:- If you received an error that is saying string.h or stdint.h is missing then you need to checkObjectsand CFLAGS in Makefile. Also, you need to install gcc-multiliblibrary files using this command.

sudo apt-get install gcc-multilib

I think you all get a good idea about virtual memory and paging. You can also check my Github Repo using this link.

Thank you for reading and I will be back next week with part 08 of this article series.

--

--