Repository navigation
Expand file tree
/
Copy pathpage.c
More file actions
154 lines (131 loc) · 4.1 KB
/
Copy pathpage.c
File metadata and controls
154 lines (131 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "page.h"
#include <stdint.h>
#include <stddef.h>
struct ppage physical_page_array[128]; //128 pages, each 2 mb in length covers 256 megs of memory
struct ppage *head;
extern int _end_kernel;
struct ppage *end_kernel_ptr = &_end_kernel;
struct page mp_pt[1024] __attribute__((aligned(0x1000)));
struct page page_table[1024] __attribute__((aligned(0x1000)));
struct page_directory_entry page_directory[1024] __attribute__((aligned(0x1000)));
void init_pfa_list(void) {
// initialize list of free physical page structures
// for size of physical page array
// struct ppage, set next pointer to i+1
// if NOT first page, set prev to i-1
// page.next = &physical_page_array[i+1];
int size = sizeof(physical_page_array)/sizeof(physical_page_array[0]);
struct ppage *current;
head = &physical_page_array[0];
for (int i = 0; i < size; i++) {
if (i == 0) {
current = &physical_page_array[i];
current->physical_addr = ((unsigned int) &_end_kernel & 0xFFFFF000);
current->next = &physical_page_array[i+1];
}
else {
current->next = &physical_page_array[i+1];
current->physical_addr = ((unsigned int) &_end_kernel & 0xFFFFF000)+ 4096*i;
current->prev = &physical_page_array[i-1];
}
current = current->next;
}
}
struct ppage *allocate_physical_pages(unsigned int npages) {
// allocate physical pages
// npages: how many pages to allocate
// unlink npages pages
// head point to page after npages
// last of npages, next = null
// page after npages, prev = null
struct ppage *current = head;
struct ppage *allocated = head;
// set freed head to first page
// point current to FIRST of NEW list
for (int i = 0; i < npages; i++) {
current = current->next;
}
// head point to first of new list, current is first of new list
head = current;
// last of npages, next = null;
current->prev->next = NULL;
// first of new list, prev = null;
current->prev = NULL;
return allocated;
}
void free_physical_pages(struct ppage *ppage_list) {
// free physical pages
struct ppage *current = ppage_list;
while (current->next != NULL) {
current = current->next;
}
current->next = head;
current->next->prev = current;
head = ppage_list;
}
void load_page_directory(struct page_directory_entry *pd) {
asm("mov %0, %%cr3"
:
:"r"(pd)
:);
}
void enable_paging(void) {
asm("mov %cr0, %eax\n"
"or $0x80000001, %eax\n"
"mov %eax, %cr0");
}
void map_pages_init(void) {
//initialize page directory
for (int i = 0; i < 1024; i++) {
page_directory[i].present = 0;
page_directory[i].rw = 0;
page_directory[i].user = 0;
page_directory[i].writethru = 0;
page_directory[i].cachedisabled = 0;
page_directory[i].accessed = 0;
page_directory[i].pagesize = 0;
page_directory[i].ignored = 0;
page_directory[i].os_specific = 0;
page_directory[i].frame = 0;
}
//initialize page table
for (int i = 0; i < 1024; i++) {
page_table[i].frame = i;
page_table[i].present = 1;
page_table[i].rw = 1;
page_table[i].user = 0;
page_table[i].accessed = 0;
page_table[i].dirty = 0;
page_table[i].unused = 0;
}
//point page_table to page_directory[0], present and rw to 1, while the others stay 0
page_directory[0].frame = (unsigned int)page_table >> 12;
page_directory[0].present = 1;
page_directory[0].rw = 1;
load_page_directory(page_directory);
enable_paging();
}
void *map_pages(void *vaddr, struct ppage *ppages, struct page_directory_entry *pd) {
// identity mapping page, where virtual address and physical addresses are the same
uint32_t pdindex = (uint32_t)vaddr >> 22;
uint32_t ptindex = (uint32_t)vaddr >> 12 & 0x3ff;
//zero out page table
for (int i = 0; i < 1024; i++) {
mp_pt[i].frame = 0;
mp_pt[i].present = 0;
mp_pt[i].rw = 0;
mp_pt[i].user = 0;
mp_pt[i].accessed = 0;
mp_pt[i].dirty = 0;
mp_pt[i].unused = 0;
}
//have the page_directory point to the page_table
page_directory[pdindex].frame = (uint32_t)mp_pt >> 12;
page_directory[pdindex].present = 1;
page_directory[pdindex].rw = 1;
//store page address to page_table entry
mp_pt[ptindex].frame = (uint32_t)ppages->physical_addr >> 12;
mp_pt[ptindex].present = 1;
mp_pt[ptindex].rw = 1;
return vaddr;
}