All pastes #157841 Raw Edit

Miscellany

public text v1 · immutable
·published 2006-09-01 20:07 UTC
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_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);
}