rendered paste body#include <all.h>
/* 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_allocated(page))
{
panic_msg("Trying to unallocate an unallocated 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);
}