ComputerPsi wrote:
okay.. If in the GDT, if I allocate and use 4 GB for something when I only have 1 GB of memory, what happens?
A general protection fault occurs (GPF).
The standard method to implement paging is using virtual memory aka paging, and giving each process it's own address space. There are also multiple ways you can store a swap file: partition, whole disk, or file. The most straight forward and apparently the most widely used mechanism for detecting when to swap memory to disk is by waiting for the amount of used memory to exceed a threshold (say ninety-percent for a example). In Linux for example a thread is woken which will start to find pages that are cold (or have not been accessed recently by a process). These threads are written to disk, the page is unmapped, and a special flag could be set to remember that this page was swapped to disk (for later when it is accessed again and becomes less cold).
They way you implement disk swapping is by using virtual memory. The idea is to create a separate virtual memory directory and associated tables for every process. Each time you switch to another process you switch to it's page directory by (re)loading the processor register CR3. You do not change the CR3 when switching between the threads of a process.
When paging is enabled and a valid directory is loaded any memory access will reference a entry in this directory and the correct table linked in the directory. The entry will hold a physical address in RAM.
A common method is to map the kernel to the exact same place in all of the processes' virtual memory. So that each time a CR3 is reloaded the kernel still remains in at the exact same (virtual) memory address.
So if you only had one gigabyte of RAM then:
- It would take a while to fill this RAM up as the system loaded, or you used the system and started working with applications.
- If a threshold of used RAM was reached (lets say ninety percent), then you would immediately start looking for pages in the system that have not been accessed recently or ever, but allocated by the processes. By not being accessed I mean a flag is not set in the table entry for the virtual memory map.
You would then open a file on the hard disk, or use a partition, and write that page (4096 bytes) to disk. Then unmap it from that process, store some information pertaining to the fact that you swapped that page to disk, and finally add that page to the list, stack, or whatever mechanism you use to represent free pages so that you maintain a system that never reaches one-hundred percent RAM usage until you run out of hard disk space (file or partition space).
If you
swap a page from a process to disk and that process goes to access that page; Lets say five minutes later. Then what happens is a page fault is generated, and when handling this page fault exception you check if the page was swapped or if the application is just accessing memory it never had (bugs). If you swapped it to disk then you simply read and write that page back into memory and remap it back to the application. You might not use the same physical page when remapping. Of course the general idea is that simultaneously during this you are also keeping the system's used memory under a threshold (ninety percent given in a example above).
You come down to having two seperate systems in your kernel.
A periodic thread or routine to swap memory to disk.- check used memory is below set threshold (maybe ninety-percent); check could be performed during system calls for memory allocation or you might schedule this as a thread or call this as routine.
- search for pages when memory is above set threshold that have their accessed flag not set, which hopefully means the process allocated these but never had the chance to use them, or is not using them often or has recently.
- unmap pages found during search from the process they are mapped in.
- write unmaped pages to disk and add physical page to list of free pages.
The page fault exception handler.- check if address is a or inside a page that was swapped to disk.
- if page was swapped to disk, then grab a free page from the free page list in the memory manager. read and write data from disk back to this page and remap page into process.
- if page was not swapped, then do normal error routine for a program trying to access memory that did not exist (was not allocated).
You might use a more
advanced routine for searching (detecting pages that are not used often) rather than simply checking the accessed bit for a entry in a page directory.
You also might set a
flag on the process that just tried to access a swapped page if you are inside the page fault exception handler, since most likely you have blocked the scheduler from running at this moment. You might then assigned the job to your
periodic checking thread (above). Once the periodic checking thread loads and maps the page that was a access was attempted on, because it was swapped, then you can unset the flag and the scheduler can starting running this process when it's turn comes up.
1. Move cold (unused but allocated) pages to disk, and free the page into the system's free memory list.
2. When a swapped page is accessed allocate a new page, load the data from disk back onto the page, and map the page back into the process and continue like normal.