Also, here's my paging code.
I haven't found good tutorials/examples on how to set paging up, so I've did it myself.
Code: Select all
/*
* paging.c
*
* Created on: Oct 26, 2015
* Author: awe2k
*/
#define MAPPED_TABLES 32
// I mapped (64 tables)*(1024 pages)*(4096 bytes)=128MB
#if !MAPPED_TABLES||MAPPED_TABLES>128*1024*1024/4096/1024
#error "Too much tables would be mapped. We don't have enough RAM"
#endif
#define HAVEFUN 0
// Maps video memory (0xB8000) to (0x0)
unsigned int dirn(unsigned int virt) {
return virt >> 22;
}
unsigned int tabn(unsigned int virt) {
return (virt >> 12) % 1024;
}
// Array of pointers to my page tables
unsigned int* page_directory[1024] __attribute__((aligned(4096)));
// Array of my tables, where pages are stored
unsigned int page_tables[MAPPED_TABLES][1024] __attribute__((aligned(4096)));
void map_addr(unsigned int* virt, unsigned int* phys, unsigned int flags) {
// Both virt and phys MUST BE 0x1000 ALIGNED!
// I don't care of aligning them, as they're aligned (i*0x1000) in cycle
unsigned int table_index = (unsigned int) virt / 0x1000 % 1024;
unsigned int directory_index = (unsigned int) virt / 0x1000 / 1024;
page_tables[directory_index][table_index] = (unsigned int) phys | 3;
}
extern void loadPageDirectory(unsigned int*);
extern void enablePaging();
void paging() {
int i, j;
for (i = 0; i < 1024; i++) {
// Supervisor, not present, R/W
page_directory[i] = 0x00000002;
}
// For every table that should be mapped
for (i = 0; i < MAPPED_TABLES; i++)
// Tell that it's present, R/W, supervisor and leave ptr to it
page_directory[i] = (unsigned int) page_tables[i] | 3;
// Size in pages to be mapped
int sz = MAPPED_TABLES * 1024;
// Map every page
for (i = 0; i < sz; i++) {
map_addr(i * 0x1000, i * 0x1000, 3);
}
#if HAVEFUN
page_tables[0][0]=0xB8000|3;
page_directory[0]=(unsigned int)page_tables[0]|3;
#endif
// Obviously, loads pagedir
loadPageDirectory(page_directory);
put_string("CR0=");
put_hex(read_cr0());
put_char('\n');
// Obviously, enables paging
enablePaging();
put_string("CR0=");
put_hex(read_cr0());
put_char('\n');
}