void heap_free(MemoryBlock* heap, void* address) { //On recherche le bloc débutant à cette adresse et on le libère. MemoryBlock* current_block = heap; while (current_block != NULL && current_block->address != address) { current_block = current_block->next; } //Si le bloc débutant à cette adresse a été trouvé. if (current_block != NULL) { //On libère le bloc. current_block->type = FREE; //Si il y a un bloc vide avant, on fusionne les deux blocs. if (current_block->previous != NULL && current_block->previous->type == FREE) { current_block->previous->size += current_block->size; //On reconstitue les liens. current_block->previous->next = current_block->next; //Si il y a effectivement un noeud suivant. if (current_block->next != NULL) { current_block->next->previous = current_block->previous; } //On libère le bloc courant. MemoryBlock* previous_block = current_block->previous; kFree((void*)current_block, sizeof(MemoryBlock)); current_block = previous_block; } //Si il y a un bloc vide après, on fusionne les deux blocs. if (current_block->next != NULL && current_block->next->type == FREE) { current_block->size += current_block->next->size; MemoryBlock* next_block = current_block->next; current_block->next = current_block->next->next; //S'il y a un bloc après le suivant. if (current_block->next != NULL) { current_block->next->previous = current_block; } kFree((void*)next_block, sizeof(MemoryBlock)); } } }
void kFree(karbre a){ int i; if (a != NULL){ for (i=0; i<K; i++){ kFree(a->fils[i]); } } free(a); }
void heap_free_all(MemoryBlock* heap, uint32_t* page_table) { //On retient la taille totale du tas pour libérer les pages mémoire. uint32_t size = 0; //On libère toute la liste des blocs en la parcourant. MemoryBlock* next_bloc; MemoryBlock* current_block = heap; while (current_block != NULL) { next_bloc = current_block->next; size += current_block->size; kFree((void*)current_block, sizeof(MemoryBlock)); current_block = next_bloc; } //On libère les pages mémoire réservées au tas, si le tas a été alloué. if (size > 0) { vmem_free(page_table, (uint8_t*)heap->address, size); } }
s64int loadElfProgram(const char *path, struct Program *prog, struct VM *vm) { struct VNode node; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; s64int ret, n; u64int len, i, j, size, remain; char *buffer; ret = vfsOpen(path, 0, &node); if (ret!=0) return ret; ehdr = (Elf64_Ehdr *)kMalloc(sizeof(Elf64_Ehdr)); if (!ehdr) return -1; //buffer = (char*)kMallocEx(PAGE_SIZE, 1, 0); buffer = (char*)kMalloc(PAGE_SIZE); n = vfsRead(&node, sizeof(Elf64_Ehdr), ehdr); if ((n == sizeof(Elf64_Ehdr)) && isValidElfHeader(ehdr)) { prog->entry = ehdr->e_entry; len = ehdr->e_phentsize * ehdr->e_phnum; phdr = (Elf64_Phdr*)kMalloc(len); vfsSeek(&node, ehdr->e_phoff, SEEK_SET); n = vfsRead(&node, len, phdr); if (n==len) { for (i=0; i<ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_LOAD) { ret = vmAddArea(vm, phdr[i].p_vaddr, phdr[i].p_memsz, VMA_TYPE_HEAP | VMA_OWNER_USER | VMA_STATUS_USED); if (ret!=0) { break; } size = phdr[i].p_filesz; remain = size & 0xfff; size -= remain; vfsSeek(&node, phdr[i].p_offset, SEEK_SET); for (j=0; j<size; j+=PAGE_SIZE) { len = vfsRead(&node, PAGE_SIZE, buffer); if (len!=PAGE_SIZE) { ret = -1; break; } //DBG("%x,%x",vm,currentTask->vm); vmemcpy(vm, (void*)(phdr[i].p_vaddr+j), currentTask->vm, buffer, PAGE_SIZE); } if (remain) { len = vfsRead(&node, remain, buffer); if (len == remain) vmemcpy(vm, (void*)(phdr[i].p_vaddr+size), currentTask->vm, buffer, remain); else ret = -1; } if (ret!=0) break; } } } // setup stack if (ret == 0) { ret = vmAddArea(vm, USER_STACK_TOP-USER_STACK_SIZE, USER_STACK_SIZE, VMA_TYPE_STACK | VMA_OWNER_USER | VMA_STATUS_USED); } kFree(phdr); } else ret = -1; kFree(buffer); kFree(ehdr); vfsClose(&node); return ret; }