#include "paging.h" #include "libc/stdio.h" /// Use a bitmap to keep track of allocated pages char pages_status[PAGING_MAX_PAGES/8]; /// Kernel page directory (ATTENTION need to be 4096) u32 k_pd[PAGING_MAX_DIR_ENTRY] __attribute__((aligned(4096))); /// Kernel page table u32 k_pt[PAGING_MAX_DIR_ENTRY][1024] __attribute__((aligned(4096))); void paging_enable(){ // Init pages status for(int i=0;i<PAGING_MAX_PAGES/8;i++) pages_status[i]=0; // Init page directory for(int i=0;i<PAGING_MAX_DIR_ENTRY;i++){ k_pd[i]=0; } k_pd[0]=((int)&k_pt[0][0]); k_pd[0]|=7; // Permissions // Init page table 0 int addr_offset=0; for(int i=0;i<1024;i++){ k_pt[0][i]=addr_offset; k_pt[0][i]|=7; // Permission paging_set_usage(addr_offset,1); // Mark addr as used addr_offset+=PAGING_PAGE_SIZE; // 4Ko pages } // Allow access to more ram for(int i=1;i<PAGING_MAX_DIR_ENTRY;i++){ k_pd[i]=((int)&k_pt[i][0]); k_pd[i]|=7; // Permissions for(int j=0;j<1024;j++){ k_pt[i][j]=addr_offset; k_pt[i][j]|=7; // Permission addr_offset+=PAGING_PAGE_SIZE; // 4Ko pages } } // Turns on paging asm( "movl %0, %%eax \n\t" "movl %%eax, %%cr3 \n\t" // Configure page table location "movl %%cr0, %%eax \n\t" "orl %1, %%eax \n\t" "movl %%eax, %%cr0 \n\t" // Turn on paging :: "b" (k_pd), "i" (PAGING_CR0_BIT) ); } void paging_set_usage(int addr,char state){ char bytes=pages_status[addr/PAGING_PAGE_SIZE/8]; char bit=addr/PAGING_PAGE_SIZE%8; if(state=0) pages_status[addr/PAGING_PAGE_SIZE/8]=~(1<<bit)&bytes; else pages_status[addr/PAGING_PAGE_SIZE/8]=(1<<bit)|bytes; } void paging_dump(int min,int max){ for(int i=0;i<(PAGING_MAX_PAGES/8);i++){ for(int j=0;j<8;j++){ char status=(pages_status[i]>>j)&0x1; if((i*8+j)>=min){ if((i*8+j)<max || max<0) printi(status); } } } } char* paging_allocate_next_page(){ for(int i=0;i<(PAGING_MAX_PAGES/8);i++){ char bytes=pages_status[i]; for(int j=0;j<8;j++){ char state=(bytes>>j)&1; if(state!=1){ int page_id=i*8+j; int page_addr=PAGING_PAGE_SIZE*page_id; paging_set_usage(page_addr,1); return((char*)page_addr); } } } print("Could not allocate anymore pages! Stopping..."); asm("hlt"); } // TODO: Take p into account int *paging_allocate(int p){ // ----- Allow kernel access during interruption int *page_dir=(int*)paging_allocate_next_page(); int *k_page_table=(int*)paging_allocate_next_page(); // Init page directory page_dir[0]=(int)k_page_table|3; // Init page table 0 int addr_offset=0; for(int i=0;i<1024;i++){ k_page_table[i]=addr_offset; k_page_table[i]|=3; // Permission addr_offset+=PAGING_PAGE_SIZE; // 4Ko pages } // ----- Task table int *u_page_table=(int*)paging_allocate_next_page(); page_dir[1]=(int)u_page_table|7; // 1024*1024*4096/4 u_page_table[0]=(int)page_dir|7; u_page_table[1]=(int)k_page_table|7; u_page_table[2]=(int)u_page_table|7; u_page_table[3]=(int)paging_allocate_next_page()|7; return page_dir; } void paging_page_fault(){ print("Page fault!"); asm("hlt"); }