Implement proc_unmap ()

This commit is contained in:
2026-01-06 17:47:21 +01:00
parent e50f8940a9
commit 9f107a1a5e
3 changed files with 69 additions and 2 deletions

1
kernel/.gitignore vendored
View File

@@ -1 +1,2 @@
*.json
.cache

View File

@@ -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) {

View File

@@ -44,7 +44,7 @@ struct proc {
void proc_sched (void);
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);
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
void proc_init (void);