Implement proc_unmap ()
This commit is contained in:
1
kernel/.gitignore
vendored
1
kernel/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
*.json
|
*.json
|
||||||
|
.cache
|
||||||
|
|||||||
@@ -38,9 +38,13 @@ static bool proc_check_elf (uint8_t* elf) {
|
|||||||
return true;
|
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) {
|
uint32_t flags) {
|
||||||
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
||||||
|
|
||||||
|
if (mapping == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
mapping->paddr = start_paddr;
|
mapping->paddr = start_paddr;
|
||||||
mapping->vaddr = start_vaddr;
|
mapping->vaddr = start_vaddr;
|
||||||
mapping->size = pages * PAGE_SIZE;
|
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);
|
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) {
|
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ struct proc {
|
|||||||
|
|
||||||
void proc_sched (void);
|
void proc_sched (void);
|
||||||
void proc_kill (struct proc* proc);
|
void proc_kill (struct proc* proc);
|
||||||
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);
|
uint32_t flags);
|
||||||
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
|
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
|
||||||
void proc_init (void);
|
void proc_init (void);
|
||||||
|
|||||||
Reference in New Issue
Block a user