Operating Systems, Paging
Hello everyone, In today’s article I’m going to talk about how to set up your OS to use Virtual Memory and Paging.
Virtual memory or virtual storage is a memory management technique that provides an “idealized abstraction of the storage resources that are actually available on a given machine” which “creates the illusion to users of a very large (main) memory”.
The computer’s operating system, using a combination of hardware and software, maps memory addresses used by a program, called virtual addresses, into physical addresses in computer memory. Main storage, as seen by a process or task, appears as a contiguous address space or collection of contiguous segments. The operating system manages virtual address spaces and the assignment of real memory to virtual memory. Address translation hardware in the CPU, often referred to as a memory management unit (MMU), automatically translates virtual addresses to physical addresses. Software within the operating system may extend these capabilities to provide a virtual address space that can exceed the capacity of real memory and thus reference more memory than is physically present in the computer.
The primary benefits of virtual memory include freeing applications from having to manage a shared memory space, ability to share memory used by libraries between processes, increased security due to memory isolation, and being able to conceptually use more memory than might be physically available, using the technique of paging or segmentation.
Virtual memory makes application programming easier by hiding fragmentation of physical memory; by delegating to the kernel the burden of managing the memory hierarchy (eliminating the need for the program to handle overlays explicitly); and, when each process is run in its own dedicated address space, by obviating the need to relocate program code or to access memory with relative addressing.
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. Memory management is a crucial aspect of any computing device, and paging specifically is important to the implementation of virtual memory.
Paging works by writing data to and reading it from, secondary storage for use in primary storage. Paging is a basic function in memory management for a computer’s operating system (OS) as well — this includes Windows, Unix, Linux and macOS.
In a memory management system that takes advantage of paging, the OS reads data from secondary storage in blocks called pages, all of which have identical sizes. The physical region of memory containing a single page is called a frame. When paging is used, a frame does not have to comprise a single physically contiguous region in secondary storage. This approach offers an advantage over earlier memory management methods because it facilitates more efficient and faster use of storage.
Paging is the most common technique used in x86 to enable virtual memory. So let’s see how we can enable paging in our OS and Access virtual memory through that.
Identity paging is the simplest kind of paging we can have. It is when we map the map each virtual address onto the same physical address. This can be done by creating a page directory where each entry points to its corresponding 4 MB frame.
To enable paging you have to write the address of a page to the `cr3` and then set the 31st bit of cr0 to 1. In order to use pages the size of 4MB you have to set the PSE bit in cr4
Reasons not to Identity map the kernel
If the kernel is placed at the beginning of the virtual address space there will be issues when linking user-mode processes. During linking the linker will place the code at
0x00000000memory position by default. Bit if the kernel is mapped into the virtual address space then the user-mode processes can’t be placed at the
This can be fixed by changing the default starting position in the linker script. You simply have to place the kernel at the end of the memory. We will place the kernel at the memory address
0xC0000000 (3GB) so only user-mode processes that will take more memory than 3GB might interfere with the kernel since this is a rare occurrence it won't be a problem for us. Though this sounds simple it’s not easy. We can’t simply tell the linker to place the kernel at
0xC01000000 since we want it to be loaded at
0x00100000. The reason for this is the first MB in the memory is taken by GRUB and we can’t be sure that the computer will always have more than 3GB of physical memory. This can be solved by using both relocation (
.=0xC0100000) and the
AT instruction in the linker script.
Since the changes, we didn’t produce any outputs if the OS is booted without any errors we can assume that the paging was enabled successfully.
Helin E, Renberg A. (2015). The little book about OS development: https://littleosbook.github.io/
Os Dev Wiki https://wiki.osdev.org/Main_Page
GNU GRUB Multiboot Manual http://www.gnu.org/software/grub/manual/multiboot/
JamesM’s kernel development tutorials http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html
Thank you for reading and I will be back next week with the next article.