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); } }
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); }
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; }
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; }