Exemplo n.º 1
0
void do_kfree(void* addr)
{
	addr -= NODE_T_SIZE;
	struct kheap_node_t* ptr = addr;

	/* Mark as free */
	ptr->status = KMALLOC_FREE;

	/* Coalesce the surrounding free memory */
	if (ptr->next != NULL && ptr->next->status == KMALLOC_FREE)
		unify_fwd(ptr);
	if (ptr->prev != NULL && ptr->prev->status == KMALLOC_FREE)
	{
		ptr = ptr->prev;
		unify_fwd(ptr);
	}

	/* If this is the last node, free some of the heap */
	if (ptr->next == NULL && ptr->size > (2 * PAGE_SIZE))
	{
		void* prev_end = ksbrk(-(ptr->size));
		kheap_end = ksbrk(0);
		ptr->size -= ((size_t)prev_end - (size_t)kheap_end);
	}
}
Exemplo n.º 2
0
void *k_mem_alloc(unsigned long size)
{
	unsigned long realsize;
	struct k_mem_alloc_header *chunk;

	if ((realsize = sizeof(struct k_mem_alloc_header) + size) < KMALLOC_MINSIZE)
		realsize = KMALLOC_MINSIZE;

	// Searching for a free (size) block from the start of the heap
	chunk = (struct k_mem_alloc_header *) KERN_HEAP;
	while (chunk->used || chunk->size < realsize)
	{
		if (chunk->size == 0)
		{
			k_log(error, "arch/oldpc/paging/pages_heap_remove_page() // Corrupted chunk");;
			asm("hlt");
		}

		chunk = (struct k_mem_alloc_header*) ((char*) chunk + chunk->size);
		if (chunk == (struct k_mem_alloc_header *) kern_heap)
		{
			if (ksbrk((realsize / PAGESIZE) + 1) < 0)
			{
				k_log(error, "arch/oldpc/paging/pages_heap_remove_page() // No memory left");
				asm("hlt");
			}
		}
		else if (chunk > (struct k_mem_alloc_header *) kern_heap)
		{
			k_log(error, "arch/oldpc/paging/pages_heap_remove_page() // Chunk hout of limits");
			asm("hlt");
		}
	}

	// We found a free block, we try to set each block to the minimal size
	if (chunk->size - realsize < KMALLOC_MINSIZE)
		chunk->used = 1;
	else
	{
		struct k_mem_alloc_header *other = (struct k_mem_alloc_header *) ((char *) chunk + realsize);
		other->size = chunk->size - realsize;
		other->used = 0;
		chunk->size = realsize;
		chunk->used = 1;
	}

	k_mem_alloc_used += realsize;

	// Return a pointer to the data...
	return (char*) chunk + sizeof(struct k_mem_alloc_header);
}
Exemplo n.º 3
0
static void* do_kmalloc(size_t size, size_t align)
{
	/* Start address is aligned to [align] that is a multiple of 16.
	 * End of the block is aligned so that the entire chunk's end is
	 * aligned to 16 bytes. */

	if (size == 0)
		return NULL;

	size = round_up(size, NODE_T_SIZE);

	/* Make sure we have a heap */
	if (kheap_start == NULL)
	{
		kheap_start = ksbrk(size + PAGE_SIZE);
		if (kheap_start == (void*)-1)
		{
			errno = ENOMEM;
			return NULL;
		}

		kheap_end = ksbrk(0);
		kheap_size = kheap_end - kheap_start;
		struct kheap_node_t* start = (struct kheap_node_t*)kheap_start;
		start->size = kheap_size - NODE_T_SIZE;
		start->status = KMALLOC_FREE;
		start->next = NULL;
		start->prev = NULL;
	}

	struct kheap_node_t* startnode = (struct kheap_node_t*)kheap_start;
	struct kheap_node_t* curnode = startnode;

	void* ret = NULL;

	/* Find a decent node */
	while (curnode != NULL)
	{
		if (curnode->next == NULL)
		{
			/* Enlarge the heap. */
			if (curnode->size < size + PAGE_SIZE)
			{
				void* prev_end = ksbrk(size + PAGE_SIZE - curnode->size);
				kheap_end = ksbrk(0);
				if (prev_end == (void*)-1)
				{
					errno = ENOMEM;
					return NULL;
				}
				curnode->size += (size_t)(kheap_end - prev_end);
				kheap_size += (size_t)(kheap_end - prev_end);
			}
		}

		if (curnode->status == KMALLOC_RES)
		{
			curnode = curnode->next;
			continue;
		}

		size_t padding_amount = 0;
		if (((size_t)(curnode + NODE_T_SIZE) % align) != 0)
		{
			padding_amount = align - ((size_t)curnode % align);
		}

		if (curnode->size < (size + padding_amount))
		{
			curnode = curnode->next;
			continue;
		}

		/* If we reach this, we have found a decent node */

		struct kheap_node_t* padding = curnode;
		if (padding_amount != 0 \
		    && padding_amount != NODE_T_SIZE)
		{
			/* Set the padding node */
			curnode = (void*)curnode + padding_amount - NODE_T_SIZE;
			padding->size = padding_amount - 2 * NODE_T_SIZE;
			padding->status = KMALLOC_FREE;
			curnode->next = padding->next;
			padding->next = curnode;
			curnode->prev = padding;
			curnode->size = (size_t)curnode->next \
				- (size_t)curnode - NODE_T_SIZE;
		}

		/* Pad if we need to */
		if (curnode->size != size)
		{
			padding = (void*)curnode + NODE_T_SIZE + size;
			padding->prev = curnode;
			padding->next = curnode->next;
			if (padding->next != NULL)
			{
				padding->size = (size_t)padding->next \
					- (size_t)padding - NODE_T_SIZE;
				padding->next->prev = padding;
			}
			else
			{
				padding->size = (size_t)kheap_end
					- (size_t)padding - NODE_T_SIZE;
			}
			padding->status = KMALLOC_FREE;
			curnode->next = padding;
		}

		curnode->size = size;
		curnode->status = KMALLOC_RES;

		ret = (void*)((void*)curnode + NODE_T_SIZE);
		break;
	}

	return ret;
}
Exemplo n.º 4
0
uint64_t user_irq_handler(registers_t *regs)
{  
	int n = regs->rax;
	uint64_t ret,buf;
	int fd;
	int count;
	if(n == 0)
	{
		scheduling = 1;
		fd=regs->rdi;
		buf = regs->rsi;
		count = regs->rdx;
		if(fd==0)
		{
			kscanf((char*)buf,count);
			scheduling = 0;
			return (uint64_t)(strlen((char*)buf));
		}
		
	}

	if(n == 1)
	{
		buf=regs->rsi;
		count = regs->rdx;
		printf("%c",*(char*)buf);
		return (uint64_t)count;
	}
	else if(n==12)    //brk malloc
	{
		uint64_t ret=ksbrk((uint64_t)(regs->rdi));
		regs->rax=ret;
		return ret;
	}

	else if(n==15)    //opendir
	{
		struct files_list* dir=(struct files_list*)kopendir((char*)(regs->rdi));
		regs->rax=(uint64_t)(struct files_list*)dir;
		return (uint64_t)dir;
	}	



	else if(n==16)	  //readdir
	{
		uint64_t dent=kreaddir((uint64_t)(regs->rdi));
		regs->rax=dent;
		return dent;

	}
	if(n==79)//getcwd
	{   
		buf=regs->rdi;
		count=regs->rsi; 
		strcpy((char*)buf,pwd);
		//while(1);
		regs->rax=4;
		return 1;
	}
	
	if(n==80) //cchdir
	{  
		buf=regs->rdi;
		if(strcmp((char*)buf,"..")==0)
		{
			int len=strlen(pwd);
			int count=0;
			while(count<2)
			{ 
				if(pwd[len-1]=='/')
				count++;
				len--;
			}
			pwd[len+1]='\0'; 
			regs->rax=0;
			return 0;
		}	
		int k=strlen((char*)buf);
		if(*(char*)(buf+k-1)!='/')
		buf=(uint64_t)strcat((char*)buf,"/");
		
		if(pathlook((char*)buf))
		{	
			strcpy(pwd,(char*)buf);
			regs->rax=0;
			return 0;
		}
		char path[100];
		strcpy(path,pwd);
		buf=(uint64_t)strcat(path,(char*)buf);

		if(pathlook((char*)buf))
		{	
			strcpy(pwd,(char*)buf);
			regs->rax=0;
			return 0;
		}

		return 0;
	}
		
	/* Handler for getpid*/
	if (n == 39)
	{
		regs->rax = getpid();
	}

	/* Handler for getppid*/
	if (n == 110)
	{
		regs->rax = getppid();
	}

	/* Handler for fork*/
	if(n == 57)
	{
		 
		 int a = fork();
		regs->rax = a;
		return a;
		
	}
	/* Handler for execve*/
	if(n == 59)
	{
		uint64_t filename = regs->rdi;
		uint64_t argv = regs->rsi;
		uint64_t envp = regs->rdx;
		int a = execve((char *)filename,(char**)argv,(char**)envp);
		regs->rax = a;
		return a;
	}
	/* Handler for exit*/
	if(n == 60)
	{
		exit();
		return 1;	
	}
	/* Handler for waitpid*/
	if(n == 61)
	{
		waitpid();
		return 1;	
	}
	/* Handler for sleep*/
	if(n == 98)
	{
		uint64_t sleep = regs->rdi;
		struct task *temp = running;
		temp->task_state = WAITING;
		temp->sleep = 1;
		int pid = temp->ppid;
		temp->time_to_sleep = sleep;
		while(temp->next->pid != pid)
			temp = temp->next;
		temp->task_state = WAITING;
		temp->sleep = 1;
		temp->time_to_sleep = sleep;		
		scheduler();
	}
	/* Handler for kill*/
	if(n == 99)
	{
		uint64_t pid = regs->rdi;
		struct task *temp = running;
		while(temp->next->pid != pid)
		{	
			temp = temp->next;
		}
		temp->next = temp->next->next;
		scheduler();
		return 1; 
	}
	/* Handler for PS*/
	if(n == 100)
	{
		struct task *temp = running;
		printf("Process:%s  PID:%d\n",temp->name,temp->pid);
		while(temp->next != running)
		{	
			printf("Process:%s  PID:%d\n",temp->next->name,temp->next->pid);
			temp = temp->next;
		}
		return 1; 
	}

	ret=1;
	return (uint64_t)ret;
}