Implement proc_unmap ()
This commit is contained in:
@@ -38,9 +38,13 @@ static bool proc_check_elf (uint8_t* elf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
||||
bool proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
||||
uint32_t flags) {
|
||||
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
||||
|
||||
if (mapping == NULL)
|
||||
return false;
|
||||
|
||||
mapping->paddr = start_paddr;
|
||||
mapping->vaddr = start_vaddr;
|
||||
mapping->size = pages * PAGE_SIZE;
|
||||
@@ -57,6 +61,68 @@ void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr,
|
||||
}
|
||||
|
||||
spin_unlock (&proc->pd.lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool proc_unmap (struct proc* proc, uintptr_t start_vaddr, size_t pages) {
|
||||
size_t unmap_size = pages * PAGE_SIZE;
|
||||
uintptr_t end_vaddr = start_vaddr + unmap_size;
|
||||
struct list_node_link *mapping_link, *mapping_link_tmp;
|
||||
bool used_tail_mapping = false;
|
||||
|
||||
struct proc_mapping* tail_mapping = malloc (sizeof (*tail_mapping));
|
||||
if (tail_mapping == NULL)
|
||||
return false;
|
||||
|
||||
spin_lock (&proc->pd.lock);
|
||||
|
||||
list_foreach (proc->mappings, mapping_link, mapping_link_tmp) {
|
||||
struct proc_mapping* mapping =
|
||||
list_entry (mapping_link, struct proc_mapping, proc_mappings_link);
|
||||
|
||||
uintptr_t m_end = mapping->vaddr + mapping->size;
|
||||
|
||||
/* check overlap */
|
||||
if ((start_vaddr < m_end) && (end_vaddr > mapping->vaddr)) {
|
||||
/* split in the middle */
|
||||
if ((start_vaddr > mapping->vaddr) && (end_vaddr < m_end)) {
|
||||
tail_mapping->vaddr = end_vaddr;
|
||||
tail_mapping->paddr = mapping->paddr + (end_vaddr - mapping->vaddr);
|
||||
tail_mapping->size = m_end - end_vaddr;
|
||||
|
||||
mapping->size = start_vaddr - mapping->vaddr;
|
||||
|
||||
list_insert_after (proc->mappings, &mapping->proc_mappings_link,
|
||||
&tail_mapping->proc_mappings_link);
|
||||
|
||||
used_tail_mapping = true;
|
||||
|
||||
break;
|
||||
} else if ((start_vaddr <= mapping->vaddr) && (end_vaddr < m_end)) { /* shrink left */
|
||||
size_t diff = end_vaddr - mapping->vaddr;
|
||||
mapping->vaddr += diff;
|
||||
mapping->paddr += diff;
|
||||
mapping->size -= diff;
|
||||
} else if ((start_vaddr > mapping->vaddr) && (end_vaddr >= m_end)) { /* shrink right */
|
||||
mapping->size = start_vaddr - mapping->vaddr;
|
||||
} else { /* full overlap */
|
||||
list_remove (proc->mappings, &mapping->proc_mappings_link);
|
||||
free (mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!used_tail_mapping)
|
||||
free (tail_mapping);
|
||||
|
||||
for (uintptr_t vpage = start_vaddr; vpage < end_vaddr; vpage += PAGE_SIZE) {
|
||||
mm_unmap_page (&proc->pd, vpage, 0);
|
||||
}
|
||||
|
||||
spin_unlock (&proc->pd.lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) {
|
||||
|
||||
Reference in New Issue
Block a user