#include /* Note to self: * size of byte || char = 1 byte * '' '' short = 2 * '' '' int || long = 4 */ extern void write_cr0(long value); extern void write_cr3(long value); extern long read_cr0(); extern long read_cr3(); //memory unit conversion macros #define bytesToKB(bytes) (bytes / 1024) #define bytesToMB(bytes) ((bytes / 1024) / 1024) #define bytesToGB(bytes) (((bytes / 1024) / 1024) / 1024) //--- #define KBtoBytes(kb) (kb * 1024) #define KBtoMB(kb) (kb / 1024) #define KBtoGB(kb) ((kb / 1024) / 1024) //--- #define MBtoBytes(mb) (mb * 1024 * 1024) #define MBtoKB(mb) (mb * 1024) #define MBtoGB(mb) (mb / 1024) //--- #define GBtoBytes(gb) (gb * 1024 * 1024 * 1024) #define GBtoKB(gb) (gb * 1024 * 1024) #define GBtoMB(gb) (gb * 1024) //--- #define get_bit_from_number(bit, number) (number >> bit) & 1 // kernel page directory unsigned long kpage_dir[256] __attribute__ ((aligned (4096))); unsigned long kpage_tables[262144] __attribute__ ((aligned (4096))); //32 bits in each long * 8192 longs = 262144 pages mapped (1GB) unsigned long allocation_map[8192] __attribute__ ((aligned (4096))); void mm_init(uint_32 memsize) { unsigned long *page_directory = kpage_dir; unsigned long *page_table = kpage_tables; int pagedir; uint_32 address = 0; for (pagedir = 0; pagedir < (memsize / 4); pagedir++) { int page; for (page = 0; page < 1024; page++) { page_table[page] = address | 3; address = address + 4096; // 4096 = 4kb } page_directory[pagedir] = (uint_32)page_table; page_directory[pagedir] = page_directory[pagedir] | 3; page_table += 1024; } page_directory[0] = page_directory[0] | 3; write_cr3((unsigned long)page_directory); // put that page directory address into CR3 write_cr0(read_cr0() | 0x80000000); // set the paging bit in CR0 to 1 // now allocate some pages for the kernel (up to 2MB for now) int i; for (i = 0; i < 768; i++) allocate_page(i); } boolean is_page_allocated(uint_32 page) { uint_32 alloc_map_section = (page / 32); uint_8 bit = page % 32; return get_bit_from_number(bit, allocation_map[alloc_map_section]); } // What about the other one void allocate_page(uint_32 page) { if (is_page_allocated(page)) { panic_msg("Trying to allocate an allocated page"); } uint_32 alloc_map_section = (page / 32); uint_8 bit = page % 32; allocation_map[alloc_map_section] = allocation_map[alloc_map_section] | (1 << bit); } void unallocate_page(uint_32 page) { if (is_page_unallocated(page)) { panic_msg("Trying to unallocate an unallocated page"); } uint_32 unalloc_map_section = (page); // Is this bit needed? Plus do we need anything after (page)? // uint_8 bit = page % 32; // Anything here? allocation_map[alloc_map_section] = allocation_map[alloc_map_section] | (1 << bit); }