MentOS  0.8.0
The Mentoring Operating System
paging.h
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include "mem/zone_allocator.h"
9 #include "proc_access.h"
10 #include "kernel.h"
11 #include "stddef.h"
12 #include "boot.h"
13 #include "stdint.h"
14 
16 #define PAGE_SHIFT 12
18 #define PAGE_SIZE (1 << PAGE_SHIFT)
20 #define MAX_PHY_PFN (1UL << (32 - PAGE_SHIFT))
21 
23 #define PROCAREA_START_ADDR 0x00000000
25 #define PROCAREA_END_ADDR 0xC0000000
26 
28 #define MAX_PAGE_TABLE_ENTRIES 1024
30 #define MAX_PAGE_DIR_ENTRIES 1024
31 
33 typedef struct page_dir_entry_t {
34  unsigned int present : 1;
35  unsigned int rw : 1;
36  unsigned int user : 1;
37  unsigned int w_through : 1;
38  unsigned int cache : 1;
39  unsigned int accessed : 1;
40  unsigned int reserved : 1;
41  unsigned int page_size : 1;
42  unsigned int global : 1;
43  unsigned int available : 3;
44  unsigned int frame : 20;
46 
48 typedef struct page_table_entry_t {
49  unsigned int present : 1;
50  unsigned int rw : 1;
51  unsigned int user : 1;
52  unsigned int w_through : 1;
53  unsigned int cache : 1;
54  unsigned int accessed : 1;
55  unsigned int dirty : 1;
56  unsigned int zero : 1;
57  unsigned int global : 1;
58  unsigned int kernel_cow : 1;
59  unsigned int available : 2;
60  unsigned int frame : 20;
62 
65  MM_USER = 0x1,
66  MM_GLOBAL = 0x2,
67  MM_RW = 0x4,
68  MM_PRESENT = 0x8,
69  // Kernel flags
70  MM_COW = 0x10,
71  MM_UPDADDR = 0x20,
72 };
73 
77 typedef struct page_table_t {
80 } __attribute__((aligned(PAGE_SIZE))) page_table_t;
81 
84 typedef struct page_directory_t {
90 } __attribute__((aligned(PAGE_SIZE))) page_directory_t;
91 
93 typedef struct vm_area_struct_t {
95  struct mm_struct_t *vm_mm;
101  list_head vm_list;
105  unsigned short vm_flags;
107 
109 typedef struct mm_struct_t {
111  list_head mmap_list;
119  list_head mm_list;
143  unsigned int total_vm;
145 
147 extern kmem_cache_t *pgtbl_cache;
148 
153 static inline int vm_area_compare(const list_head *vma0, const list_head *vma1)
154 {
155  // Retrieve the vm_area_struct from the list_head for vma0.
156  vm_area_struct_t *_vma0 = list_entry(vma0, vm_area_struct_t, vm_list);
157  // Retrieve the vm_area_struct from the list_head for vma1.
158  vm_area_struct_t *_vma1 = list_entry(vma1, vm_area_struct_t, vm_list);
159  // Compare the start address of vma0 with the end address of vma1.
160  return _vma0->vm_start > _vma1->vm_end;
161 }
162 
168 int paging_init(boot_info_t *info);
169 
173 
177 {
178  return (page_directory_t *)get_cr3();
179 }
180 
184 {
185  set_cr3((uintptr_t)dir);
186 }
187 
192 
197 
200 void paging_flush_tlb_single(unsigned long addr);
201 
203 static inline void paging_enable(void)
204 {
205  // Clear the PSE bit from cr4.
207  // Set the PG bit in cr0.
209 }
210 
213 static inline int paging_is_enabled(void)
214 {
215  return bitmask_check(get_cr0(), CR0_PG);
216 }
217 
220 void page_fault_handler(pt_regs *f);
221 
227 page_t *mem_virtual_to_page(page_directory_t *pgdir, uint32_t virt_start, size_t *size);
228 
236 int mem_upd_vm_area(page_directory_t *pgd, uint32_t virt_start, uint32_t phy_start, size_t size, uint32_t flags);
237 
247  page_directory_t *dst_pgd,
248  uint32_t src_start,
249  uint32_t dst_start,
250  size_t size,
251  uint32_t flags);
252 
261  uint32_t virt_start,
262  size_t size,
263  uint32_t pgflags,
264  uint32_t gfpflags);
265 
273  vm_area_struct_t *area,
274  int cow,
275  uint32_t gfpflags);
276 
282 
288 
294 int is_valid_vm_area(mm_struct_t *mm, uintptr_t vm_start, uintptr_t vm_end);
295 
301 int find_free_vm_area(mm_struct_t *mm, size_t length, uintptr_t *vm_start);
302 
306 mm_struct_t *create_blank_process_image(size_t stack_size);
307 
312 
#define bitmask_clear(V, M)
Clears the bits identified by the mask.
Definition: bitops.h:19
#define bitmask_check(V, M)
Checks if the bits identified by the mask are all 1.
Definition: bitops.h:21
#define bitmask_set(V, M)
Sets the bits identified by the mask.
Definition: bitops.h:18
Bootloader structures.
Kernel generic data structure and functions.
mm_struct_t * create_blank_process_image(size_t stack_size)
Creates the main memory descriptor.
Definition: paging.c:1182
int mem_clone_vm_area(page_directory_t *src_pgd, page_directory_t *dst_pgd, uint32_t src_start, uint32_t dst_start, size_t size, uint32_t flags)
Clones a range of pages between two distinct page tables.
Definition: paging.c:1121
int mem_upd_vm_area(page_directory_t *pgd, uint32_t virt_start, uint32_t phy_start, size_t size, uint32_t flags)
Updates the virtual memory area in a page directory.
Definition: paging.c:1076
MEMMAP_FLAGS
Flags associated with virtual memory areas.
Definition: paging.h:64
@ MM_RW
Area has read/write permissions.
Definition: paging.h:67
@ MM_UPDADDR
Update address (used for special memory mappings).
Definition: paging.h:71
@ MM_USER
Area belongs to user mode (accessible by user-level processes).
Definition: paging.h:65
@ MM_GLOBAL
Area is global (not flushed from TLB on context switch).
Definition: paging.h:66
@ MM_PRESENT
Area is present in memory.
Definition: paging.h:68
@ MM_COW
Area is copy-on-write (used for forked processes).
Definition: paging.h:70
struct mm_struct_t mm_struct_t
Memory Descriptor, used to store details about the memory of a user process.
page_t * mem_virtual_to_page(page_directory_t *pgdir, uint32_t virt_start, size_t *size)
Maps a virtual address to a corresponding physical page.
Definition: paging.c:1036
int paging_init(boot_info_t *info)
Initializes the paging system, sets up memory caches, page directories, and maps important memory reg...
Definition: paging.c:459
void paging_flush_tlb_single(unsigned long addr)
Invalidate a single tlb page (the one that maps the specified virtual address)
Definition: paging.c:111
#define MAX_PAGE_TABLE_ENTRIES
For a single page table in a 32-bit system.
Definition: paging.h:28
int is_valid_vm_area(mm_struct_t *mm, uintptr_t vm_start, uintptr_t vm_end)
Checks if the given virtual memory area range is valid.
Definition: paging.c:345
mm_struct_t * clone_process_image(mm_struct_t *mmp)
Create a Memory Descriptor.
Definition: paging.c:1242
int destroy_process_image(mm_struct_t *mm)
Free Memory Descriptor with all the memory segment contained.
Definition: paging.c:1308
struct vm_area_struct_t vm_area_struct_t
Virtual Memory Area, used to store details of a process segment.
static page_directory_t * paging_get_current_directory(void)
Provide access to the current paging directory.
Definition: paging.h:176
kmem_cache_t * pgtbl_cache
Cache used to store page tables.
Definition: paging.c:33
int find_free_vm_area(mm_struct_t *mm, size_t length, uintptr_t *vm_start)
Searches for an empty spot for a new virtual memory area.
Definition: paging.c:397
struct page_table_entry_t page_table_entry_t
An entry of a page table.
void page_fault_handler(pt_regs *f)
Handles a page fault.
Definition: paging.c:776
#define PAGE_SIZE
Size of a page (4096 bytes).
Definition: paging.h:18
int destroy_vm_area(mm_struct_t *mm, vm_area_struct_t *area)
Destroys a virtual memory area.
Definition: paging.c:266
static int paging_is_enabled(void)
Returns if paging is enabled.
Definition: paging.h:213
#define MAX_PAGE_DIR_ENTRIES
For a page directory with 1024 entries.
Definition: paging.h:30
struct page_dir_entry_t page_dir_entry_t
An entry of a page directory.
page_directory_t * paging_get_main_directory(void)
Provide access to the main page directory.
Definition: paging.c:60
int paging_switch_directory_va(page_directory_t *dir)
Switches paging directory, the pointer can be a lowmem address.
Definition: paging.c:83
static void paging_switch_directory(page_directory_t *dir)
Switches paging directory, the pointer must be a physical address.
Definition: paging.h:183
static int vm_area_compare(const list_head *vma0, const list_head *vma1)
Comparison function between virtual memory areas.
Definition: paging.h:153
int is_current_pgd(page_directory_t *pgd)
Checks if the given page directory is the current one.
Definition: paging.c:72
static void paging_enable(void)
Enables paging.
Definition: paging.h:203
uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_t gfpflags)
Clone a virtual memory area, using copy on write if specified.
Definition: paging.c:187
vm_area_struct_t * find_vm_area(mm_struct_t *mm, uint32_t vm_start)
Searches for the virtual memory area at the given address.
Definition: paging.c:322
vm_area_struct_t * create_vm_area(mm_struct_t *mm, uint32_t virt_start, size_t size, uint32_t pgflags, uint32_t gfpflags)
Create a virtual memory area.
Definition: paging.c:117
Set of functions and flags used to manage processors registers.
static uintptr_t get_cr0(void)
Reads the current cr0 value.
Definition: proc_access.h:134
static void set_cr0(uintptr_t cr0)
Sets the cr0 value.
Definition: proc_access.h:144
static uintptr_t get_cr3(void)
Reads the current cr3 value.
Definition: proc_access.h:173
static void set_cr3(uintptr_t cr3)
Sets the cr3 value.
Definition: proc_access.h:183
#define CR0_PG
Paging Enable.
Definition: proc_access.h:15
static void set_cr4(uintptr_t cr4)
Sets the cr4 value.
Definition: proc_access.h:202
static uintptr_t get_cr4(void)
Reads the current cr4 value.
Definition: proc_access.h:192
#define CR4_PSE
Page Size Extensions.
Definition: proc_access.h:31
Define basic data types.
unsigned int pgprot_t
This data-type is used to set protection bits of pages.
Definition: stddef.h:52
Standard integer data-types.
unsigned uintptr_t
Define the unsigned 32-bit pointer.
Definition: stdint.h:36
unsigned int uint32_t
Define the unsigned 32-bit integer.
Definition: stdint.h:18
Mentos structure to communicate bootloader info to the kernel.
Definition: boot.h:11
Stores the information of a cache.
Definition: slab.h:27
Memory Descriptor, used to store details about the memory of a user process.
Definition: paging.h:109
uint32_t brk
End address of the heap.
Definition: paging.h:131
uint32_t start_code
Start address of the code segment.
Definition: paging.h:121
uint32_t env_start
Start address of the environment variables.
Definition: paging.h:139
unsigned int total_vm
Total number of mapped pages.
Definition: paging.h:143
vm_area_struct_t * mmap_cache
Pointer to the last used memory area.
Definition: paging.h:113
uint32_t start_data
Start address of the data segment.
Definition: paging.h:125
uint32_t end_code
End address of the code segment.
Definition: paging.h:123
uint32_t arg_start
Start address of the arguments.
Definition: paging.h:135
uint32_t arg_end
End address of the arguments.
Definition: paging.h:137
page_directory_t * pgd
Pointer to the process's page directory.
Definition: paging.h:115
uint32_t end_data
End address of the data segment.
Definition: paging.h:127
list_head mm_list
List of mm_structs.
Definition: paging.h:119
int map_count
Number of memory areas.
Definition: paging.h:117
uint32_t env_end
End address of the environment variables.
Definition: paging.h:141
uint32_t start_stack
Start address of the stack.
Definition: paging.h:133
uint32_t start_brk
Start address of the heap.
Definition: paging.h:129
list_head mmap_list
List of memory areas (vm_area_struct references).
Definition: paging.h:111
An entry of a page directory.
Definition: paging.h:33
unsigned int available
Available for system use.
Definition: paging.h:43
unsigned int w_through
Write-through caching enabled.
Definition: paging.h:37
unsigned int frame
Frame address (shifted right 12 bits).
Definition: paging.h:44
unsigned int cache
Cache disabled.
Definition: paging.h:38
unsigned int page_size
Page size (0 = 4 KB, 1 = 4 MB).
Definition: paging.h:41
unsigned int global
Global page (not flushed by TLB).
Definition: paging.h:42
unsigned int present
Page is present in memory.
Definition: paging.h:34
unsigned int accessed
Page has been accessed.
Definition: paging.h:39
unsigned int user
User/supervisor (0 = supervisor, 1 = user).
Definition: paging.h:36
unsigned int rw
Read/write permission (0 = read-only, 1 = read/write).
Definition: paging.h:35
unsigned int reserved
Reserved.
Definition: paging.h:40
A page directory.
Definition: paging.h:84
page_dir_entry_t entries[MAX_PAGE_DIR_ENTRIES]
Array of page directory entries.
Definition: paging.h:89
Page descriptor. Use as a bitmap to understand the order of the block and if it is free or allocated.
Definition: zone_allocator.h:25
An entry of a page table.
Definition: paging.h:48
unsigned int zero
Reserved (set to 0).
Definition: paging.h:56
unsigned int kernel_cow
Kernel copy-on-write.
Definition: paging.h:58
unsigned int global
Global page (not flushed by TLB).
Definition: paging.h:57
unsigned int rw
Read/write permission (0 = read-only, 1 = read/write).
Definition: paging.h:50
unsigned int accessed
Page has been accessed.
Definition: paging.h:54
unsigned int w_through
Write-through caching enabled.
Definition: paging.h:52
unsigned int available
Available for system use.
Definition: paging.h:59
unsigned int user
User/supervisor (0 = supervisor, 1 = user).
Definition: paging.h:51
unsigned int frame
Frame address (shifted right 12 bits).
Definition: paging.h:60
unsigned int present
Page is present in memory.
Definition: paging.h:49
unsigned int cache
Cache disabled.
Definition: paging.h:53
unsigned int dirty
Page has been written to.
Definition: paging.h:55
A page table.
Definition: paging.h:77
page_table_entry_t pages[MAX_PAGE_TABLE_ENTRIES]
Array of page table entries.
Definition: paging.h:79
Interrupt stack frame.
Definition: kernel.h:24
Virtual Memory Area, used to store details of a process segment.
Definition: paging.h:93
struct mm_struct_t * vm_mm
Pointer to the memory descriptor associated with this area.
Definition: paging.h:95
list_head vm_list
Linked list of memory areas.
Definition: paging.h:101
pgprot_t vm_page_prot
Page protection flags (permissions).
Definition: paging.h:103
uint32_t vm_start
Start address of the segment, inclusive.
Definition: paging.h:97
uint32_t vm_end
End address of the segment, exclusive.
Definition: paging.h:99
unsigned short vm_flags
Flags indicating attributes of the memory area.
Definition: paging.h:105
Implementation of the Zone Allocator.