Basically, for memory allocating, I save the information into a struct which I can go back and free it later.
I think it is the unmapping which goes wrong:
My tests:
Code: Select all
int *a = (int *)malloc(4);
*a = 5;
free(a);
*a = 5; // NO PAGE FAULT!! why? :O im unmapping it!
putdec((unsigned int)a)); // it prints a's old address while i changed in in free() to 0xFFFFFFFF...why?! but anyways, while i holds the previous address of a, it should be giving me a page fault!
Code: Select all
#include <common.h>
#include <list.h>
#include <screen.h>
#include <page.h>
extern unsigned int *kernel_directory;
unsigned int page_list_num_nodes = 0, malloc_recorder_num_nodes = 0;
unsigned int current_addr, first_page_marked = 0;
extern void mark_page_in_bitmap(unsigned int addr);
struct node current_page_head, *page_indexer;
struct node malloc_records_head, *malloc_r_indexer;
void initialize_new_list(void)
{
current_page_head.size = 0;
current_page_head.next = 0;
current_page_head.addr = 0;
page_list_num_nodes = 0;
page_indexer = (struct node *)¤t_page_head;
}
void initialize_malloc_recorder(void)
{
malloc_records_head.size = 0;
malloc_records_head.next = 0;
malloc_records_head.addr = 0;
malloc_recorder_num_nodes = 0;
malloc_r_indexer = (struct node *)&malloc_records_head;
}
struct node *find_addr_in_malloc_recorder(unsigned int addr)
{
struct node *tmp = (struct node *)&malloc_records_head;
unsigned int i = 0;
while(i <= malloc_recorder_num_nodes)
{
if(tmp->addr == addr)
return tmp;
tmp = tmp->next;
i++;
}
return 0;
}
int is_current_page_full(struct node *current_page_head, unsigned int size_to_be_added) // 1 == full, 0 == not full
{
unsigned int sum = 0, counter = 0;
struct node *tmp = current_page_head;
while(counter <= page_list_num_nodes)
{
sum += tmp->size;
tmp = tmp->next;
counter++;
}
return ((sum + size_to_be_added) > PAGE_SIZE)?1:0;
}
void *malloc(unsigned int size)
{
if(first_page_marked == 0)
{
current_addr = 0xC0000000; // starting to allocate from this address
initialize_malloc_recorder();
initialize_new_list();
if(is_page_free(current_addr))
mark_page_in_bitmap(current_addr);
first_page_marked = 1;
}
if(is_current_page_full(¤t_page_head, size))
{
initialize_new_list();
unsigned int num_pages = size/PAGE_SIZE;
unsigned int i = 0, k;
if(current_addr & 0xFFF/*if a page aligment is needed*/)
{
PAGE_ALIGN(¤t_addr);
k = current_addr;
}
else
k = current_addr += 0x1000;
for(;i<num_pages;i++, k += 0x1000) // allocate and map a new page/s (depends on how big is `size`) for the next malloc calls
{
mark_page_in_bitmap(k);
unsigned int *pt = (unsigned int *)((unsigned int)kernel_directory[k/(PAGE_SIZE*1024)] & ~KPAGE_ENTRY_ATTR);
pt[(k/PAGE_SIZE)%1024] = k | KPAGE_ENTRY_ATTR;
}
add_to_list(¤t_page_head, page_indexer, (size-((int)(size/PAGE_SIZE))*PAGE_SIZE), 0, &page_list_num_nodes);
}
else
{
unsigned int *pt = (unsigned int *)((unsigned int)kernel_directory[current_addr/(PAGE_SIZE*1024)] & ~KPAGE_ENTRY_ATTR);
pt[(current_addr/PAGE_SIZE)%1024] = current_addr | KPAGE_ENTRY_ATTR;
putdec((unsigned int)(pt[(current_addr/PAGE_SIZE)%1024] & ~KPAGE_ENTRY_ATTR));
add_to_list(¤t_page_head, page_indexer, size, 0, &malloc_recorder_num_nodes);
}
add_to_list(&malloc_records_head, malloc_r_indexer, size, current_addr, &malloc_recorder_num_nodes);
malloc_r_indexer = malloc_r_indexer->next;
page_indexer = page_indexer->next;
enable_paging(kernel_directory);
// allocate new space now:
unsigned int ret = current_addr;
current_addr += size;
return (void *)ret;
}
void free(void *ptr)
{
if(is_page_free((unsigned int)ptr)) // it is not allocated
return;
struct node *mem_to_del = find_addr_in_malloc_recorder((unsigned int)ptr);
if(mem_to_del == (struct node *)0)
return;
unsigned int num_pages = (mem_to_del->size/PAGE_SIZE+1), i = 0, page = mem_to_del->addr;
unsigned int *pt;
while(i < num_pages)
{
pt = (unsigned int *)((unsigned int)kernel_directory[page/(PAGE_SIZE*1024)] & ~KPAGE_ENTRY_ATTR);
pt[(page/PAGE_SIZE)%1024] = 0; // unmap the address
delete_page_from_bitmap(page);
page += 0x1000;
i++;
}
remove_from_list(&malloc_records_head, mem_to_del, &malloc_recorder_num_nodes);
ptr = (void *)0xFFFFFFFF;
enable_paging(kernel_directory);
}