Skip to content

Commit a944a74

Browse files
committed
feat: impl sys_munmap
1 parent eb435ea commit a944a74

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

os/src/mm/memory_set.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,25 @@ impl MemorySet {
262262
false
263263
}
264264
}
265+
266+
/// Remove a MapArea that exactly matches [start_va, end_va)
267+
/// Returns true if successfully removed, false if not found or range doesn't match exactly
268+
pub fn remove_area_with_range(&mut self, start_va: VirtAddr, end_va: VirtAddr) -> bool {
269+
let start_vpn = start_va.floor();
270+
let end_vpn = end_va.ceil();
271+
272+
// Find the area that exactly matches this range
273+
if let Some(idx) = self.areas.iter().position(|area| {
274+
area.vpn_range.get_start() == start_vpn && area.vpn_range.get_end() == end_vpn
275+
}) {
276+
// Remove the area and unmap it
277+
let mut area = self.areas.remove(idx);
278+
area.unmap(&mut self.page_table);
279+
true
280+
} else {
281+
false
282+
}
283+
}
265284
}
266285
/// map area structure, controls a contiguous piece of virtual memory
267286
pub struct MapArea {

os/src/syscall/process.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,37 @@ pub fn sys_mmap(start: usize, len: usize, prot: usize) -> isize {
160160
}
161161
}
162162

163-
// YOUR JOB: Implement munmap.
164-
pub fn sys_munmap(_start: usize, _len: usize) -> isize {
165-
trace!("kernel: sys_munmap NOT IMPLEMENTED YET!");
166-
-1
163+
/// 取消到 [start, start + len) 虚存的映射
164+
/// 参数和返回值请参考 mmap
165+
/// 为了简单,参数错误时不考虑内存的恢复和回收。
166+
/// 可能的错误:
167+
/// - [start, start + len) 中存在未被映射的虚存。
168+
/// - [start, start + len) 和调用mmap时提供的不一致
169+
/// - [start, start + len) 中存在未被映射的虚存。
170+
pub fn sys_munmap(start: usize, len: usize) -> isize {
171+
trace!("kernel: sys_munmap start={:#x}, len={:#x}", start, len);
172+
173+
// 检查 len 为 0 的情况
174+
if len == 0 {
175+
return 0;
176+
}
177+
178+
let start_va = crate::mm::VirtAddr::from(start);
179+
180+
let end_va = crate::mm::VirtAddr::from(start + len);
181+
182+
// 调用新的接口来取消映射
183+
if crate::task::munmap_for_current_task(start_va, end_va) {
184+
trace!(
185+
"sys_munmap: successfully unmapped [{:#x}, {:#x})",
186+
start,
187+
start + len
188+
);
189+
0
190+
} else {
191+
trace!("sys_munmap: failed to unmap, address range not fully mapped");
192+
-1
193+
}
167194
}
168195

169196
/// change data segment size

os/src/task/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,29 @@ impl TaskManager {
190190
memory_set.insert_framed_area(start_va, end_va, map_perm);
191191
true
192192
}
193+
194+
/// Unmap memory area for the current task
195+
fn munmap_for_current_task(
196+
&self,
197+
start_va: crate::mm::VirtAddr,
198+
end_va: crate::mm::VirtAddr,
199+
) -> bool {
200+
let mut inner = self.inner.exclusive_access();
201+
let current = inner.current_task;
202+
let memory_set = &mut inner.tasks[current].memory_set;
203+
204+
// 检查地址范围是否完全被映射
205+
let start_vpn = start_va.floor();
206+
let end_vpn = end_va.ceil();
207+
for vpn in crate::mm::VPNRange::new(start_vpn, end_vpn) {
208+
if memory_set.translate(vpn).is_none() {
209+
return false; // 有未映射的页
210+
}
211+
}
212+
213+
// 移除对应的 MapArea
214+
memory_set.remove_area_with_range(start_va, end_va)
215+
}
193216
}
194217

195218
/// Run the first task in task list.
@@ -258,3 +281,13 @@ pub fn mmap_for_current_task(
258281
) -> bool {
259282
TASK_MANAGER.mmap_for_current_task(start_va, end_va, map_perm)
260283
}
284+
285+
/// Unmap memory area for the current task
286+
pub fn munmap_for_current_task(
287+
start_va: crate::mm::VirtAddr,
288+
end_va: crate::mm::VirtAddr,
289+
) -> bool {
290+
TASK_MANAGER.munmap_for_current_task(start_va, end_va)
291+
}
292+
293+

0 commit comments

Comments
 (0)