Problems with Memory Manager

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ateno3
Member
Member
Posts: 25
Joined: Sun Oct 02, 2011 3:36 am
Location: Spain

Problems with Memory Manager

Post by ateno3 »

First, I want to apologize for my English,I know which some words and expressions are misspelled, my native language is Spanish.
I will try to translate some parts with Google Translator.

I begin to explain my problem:
I am trying to design a memory manager:
- I am using paging, although the physical adresses are the same that logical adresses.
- I divide the RAM in dynamic fragments which they relate through with nodes (MIIOS_Alloc_Node) which they are linked list.
- I emulate the 'OS' with VirtualBox with a 32MB RAM.I reserve for the system 8MB and the rest is mapped to memory request.

HEADER:

Code: Select all

#ifndef MEMORY_MANAGER_H
#define MEMORY_MANAGER_H
	#include <types.h>
	
	#define ALLOC_NODE_USED 1
	#define ALLOC_NODE_END  (1<<7)
	
	struct __attribute__((__packed__)) __alloc_node{
		struct __alloc_node* last;
		struct __alloc_node* next;
		u8 flags; // El primer bit indica si se usa.
				  // El ultimo bit indica si es la ultima pagina
	};
	
	
	typedef struct __alloc_node MIIOS_Alloc_Node;
	
	static MIIOS_Alloc_Node* MMfirst;
	
	void InitMMU();
	
	// Peticion de memoria
	void* kmalloc(u32 bytes);
	
	// Liberar memoria
	void kfree(void* ptr);
	
#endif
	
	
	
SOURCE:

Code: Select all

#include <mmu.h>
#include <types.h>
#include <paging.h>

	void InitMMU(){
		// Este el ultimo nodo , esta en el MB 32 - 15 bytes
		MIIOS_Alloc_Node* end=(MIIOS_Alloc_Node*)0x1FFFFF0;
		
		// Este es el primer nodo, esta en el MB 8
		MMfirst=(MIIOS_Alloc_Node*)0x800000;
		
		// Enlazamos los nodos
		MMfirst->last=NULL;	// No hay un nodo anterior al primero (obvio)
		MMfirst->next=end;	// El siguiente nodo, es el ultimo
		MMfirst->flags=0;	// Esta libre
		
		end->last=MMfirst;	// El anterior nodo, es el primero
		end->next=NULL;		// No hay un nodo siguiente al ultimo (obvio)
		end->flags=(1<<7)|1;// Esta usado y ademas es el ultimo nodo
		
		
	}
	
	void* kmalloc(u32 bytes){
		
		MIIOS_Alloc_Node* tmp;
		MIIOS_Alloc_Node* tmp2;
		
		for(tmp=MMfirst; tmp->next!=NULL, tmp!=NULL, (tmp->flags&(1<<7))!=(1<<7); tmp=tmp->next){
			if((tmp->flags&(1<<7))==(1<<7)) break;
			if(tmp==NULL) break;
			
			if(tmp->flags&0x01==0){	// Hay un nodo libre
				if((u32)(tmp->next-tmp)==bytes+10){	// El nodo tiene el mismo 
													//tamaño que lo que se necesita
					tmp->flags|=1;	// Ponemos el bit 0 en usado
					return (void*)(tmp+sizeof(MIIOS_Alloc_Node));
				}
				
				if((u32)(tmp->next-tmp)>bytes+10){	// El tamaño del nodo es mayor
					// Si es menos de 18 mayor que el espacio requerido
					if(((u32)(tmp->next-tmp))-(bytes+10)<18){
						tmp->flags|=1;
						return (void*)(tmp+sizeof(MIIOS_Alloc_Node));
					}
					// Sino...
					tmp2=(MIIOS_Alloc_Node*)tmp+bytes+10;
					
					// Creamos otro nodo que vaya donde termine el que
					// vamos a usar y lo enlazamos con los demas
					tmp2->next=tmp->next;
					tmp2->last=tmp;
					tmp2->flags=0;
					
					tmp->next->last=tmp2;
					
					tmp->next=tmp2;
					tmp->flags=1;
					return (void*)(tmp+sizeof(MIIOS_Alloc_Node));
				}
			}
		}
		return NULL;
	}
	
	void kfree(void* ptr){
		if(ptr==NULL) return;
		// Obtenemos el nodo al que corresponde la direccion
		MIIOS_Alloc_Node* node=ptr-sizeof(MIIOS_Alloc_Node);
		if(node==NULL) return;
		if(node->flags==0) return;	// El nodo no esta usado
		if((node->flags&(1<<7))==(1<<7)) return;	// El ultimo nodo
		
		node->flags=0;	// Ponemos el bit 0 en libre
		// Vamos a comprobar si hay nodo libres delante...
		MIIOS_Alloc_Node* tmp;
		for(tmp=node->next; tmp!=NULL, tmp->flags&1!=1, (tmp->flags&(1<<7))!=(1<<7); tmp=tmp->next){
			if(node->flags&1==1) break;
			if((node->flags&(1<<7))==(1<<7)) break;
			if(tmp==NULL) break;
		}
		// si los hay los unimos todos en uno solo
		node->next=tmp;
		tmp->last=node;
		
		// Vamos a ver si hay nodos libres detras...
		for(tmp=node->last; tmp!=NULL, tmp->flags&1!=1, (tmp->flags&(1<<7))!=(1<<7); tmp=tmp->last){
			if(node->flags&1==1) break;
			if((node->flags&(1<<7))==(1<<7)) break;
			if(tmp==NULL) break;
		}
		// si los hay los unimos todos
		tmp=tmp->next;
		
		tmp->next=node->next;
		node->next->last=tmp;
		
		return;
	}
	
- This is piece of code, but it isn't mean that the protected mode isn't started. Moreover, the GDT and IDT is also started.
MAIN:

Code: Select all

extern void __enable_a20();
 
	void _init(){
		ScreenClear();
		// LoadDefaultGDT();      This is started in bootloader.asm
		// RunProtectedMode();  This is started in bootloader.asm 
		PIC_ReMap(0x20,0x28);
		// __enable_a20();        This is started in bootloader.asm
		//LoadDefaultIDT();       This is started in bootloader.asm
		InstallExceptionINT();
	        printf("Iniciando paginacion....\n");
		Identy_PagingInit();
		printf("[OK]\nIniciando Gestor de Memoria...\n");
		InitMMU();
		printf("[OK]\n");
		printf("Realizando Test de alojacion con kmalloc\n");
		s8* test=(s8*) kmalloc (40);
		memset(test, 0, 40);
		strcpy(test, "Prueba de malloc\n");
		printf("%x\n", (u32)test);
		printf("%s\n", test);
		printf("Liberando memoria...\n");
		kfree(test);
		while(1) hlt();
	}
- After starting the memory manager, I try to do a memory request, but it always return NULL. Can someone help me?
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Problems with Memory Manager

Post by turdus »

What do you want to achieve? I think your problem is you do not know what you're doing. I suggest to get a pencil and paper, and do not code a single line until you're absolutely certain about what's under the hood. As soon as you get clear about the algorithm, coding will not be an issue any more.
Questions to ask yourself:
1. what kind of memory manager are you designing? Physical? Virtual? Userland heap? Kernel heap?
2. what's the basic unit of allocation?
3. how does it fit in pmm->vmm->heap trinity?
Post Reply