Skip to content

Commit 561b524

Browse files
committed
edit mmap
1 parent d84ea90 commit 561b524

File tree

9 files changed

+107
-68
lines changed

9 files changed

+107
-68
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ ci-user/
2020
user/
2121
os/vendor/
2222
sdcard-riscv64.img
23-
Linux1.0
23+
Linux1.0
24+
testsuits-for-oskernel

os/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ DISASM_TMP := target/$(TARGET)/$(MODE)/asm
77
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
88
APPS := ../user/src/bin/*
99
OFFLINE :=
10+
# Extra test apps to bundle into fs.img (override from CLI if needed)
11+
# Examples:
12+
# - make run TEST_APPS=../tests/musl/basic
13+
# - make run TEST_APPS=../testsuits-for-oskernel/basic
14+
TEST_APPS ?= ../tests/musl/basic
1015

1116
# BOARD
1217
BOARD := qemu
@@ -50,6 +55,14 @@ $(KERNEL_BIN): kernel
5055

5156
fs-img: $(APPS)
5257
@make -C ../user build TEST=$(TEST) CHAPTER=$(CHAPTER) BASE=$(BASE)
58+
@mkdir -p ../user/build/app/
59+
@if [ -n "$(TEST_APPS)" ]; then \
60+
if [ -e "$(TEST_APPS)" ]; then \
61+
cp -r "$(TEST_APPS)"/. ../user/build/app/; \
62+
else \
63+
echo "[fs-img] WARN: TEST_APPS '$(TEST_APPS)' not found; skipping"; \
64+
fi; \
65+
fi
5366
@rm -f $(FS_IMG)
5467
@cd ../easy-fs-fuse && cargo run --release -- -s ../user/build/app/ -t ../user/target/riscv64gc-unknown-none-elf/release/
5568

os/src/mm/memory_set.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{PTEFlags, PageTable, PageTableEntry};
33
use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
44
use super::{StepByOne, VPNRange};
55
use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT_BASE, USER_STACK_SIZE};
6-
use crate::mm::mmap::{self, MMapProt};
6+
use crate::mm::mmap;
77
use crate::sync::UPSafeCell;
88
use alloc::collections::BTreeMap;
99
use alloc::sync::Arc;
@@ -91,25 +91,23 @@ impl MemorySet {
9191
/// 检查目标地址段是否与已有的映射冲突(存在交集)
9292
fn has_conflict(&self, start: usize, len: usize) -> bool {
9393
for area in self.areas.iter() {
94-
let area_start = area.vpn_range.get_start().0 * PAGE_SIZE;
95-
let area_end = area.vpn_range.get_end().0 * PAGE_SIZE;
96-
let target_start = start;
97-
let target_end = start + len;
94+
//以下均为页号
95+
let area_start = area.vpn_range.get_start().0;
96+
let area_end = area.vpn_range.get_end().0;
97+
let target_start = start / PAGE_SIZE;
98+
let target_end = (start + len) / PAGE_SIZE +1;
9899
if target_end > area_start && target_start < area_end {
99100
return true;
100101
}
101102
}
102103
false
103104
}
104-
/// 实现mmap
105+
/// 实现mmap(只分配内存,不加载文件)
105106
pub fn mmap(
106107
&mut self,
107108
addr: usize,
108109
length: usize,
109-
prot: mmap::MMapProt,
110-
flags: mmap::MMapFlags,
111-
_fd: i32,
112-
_offset: usize,
110+
prot: mmap::MMapProt
113111
) -> Result<usize, i32> {
114112
// 检查冲突
115113
if self.has_conflict(addr, length) {
@@ -127,7 +125,7 @@ impl MemorySet {
127125
if prot.contains(mmap::MMapProt::PROT_EXEC) {
128126
permission |= MapPermission::X;
129127
}
130-
if prot != MMapProt::PROT_NONE {
128+
if prot != mmap::MMapProt::PROT_NONE {
131129
permission |= MapPermission::U;
132130
}
133131

@@ -138,13 +136,6 @@ impl MemorySet {
138136
permission,
139137
);
140138

141-
// 按类型处理映射内容
142-
if flags.contains(mmap::MMapFlags::MAP_ANONYMOUS) {
143-
// do nothing
144-
} else {
145-
// 待完成文件有关部分
146-
}
147-
148139
Ok(addr)
149140
}
150141
/// Mention that trampoline is not collected by areas.

os/src/mm/mmap.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![deny(warnings)]
22
#![allow(missing_docs)]
3+
34
use bitflags::*;
45
use crate::task::processor::PROCESSOR;
56

@@ -16,16 +17,19 @@ bitflags! {
1617
// mmap 映射类型标志
1718
bitflags! {
1819
pub struct MMapFlags: i32 {
20+
const MAP_FILE = 0;
1921
const MAP_SHARED = 1 << 0;
2022
const MAP_PRIVATE = 1 << 1;
2123
const MAP_ANONYMOUS = 1 << 2;
22-
const MAP_FILE = 1 << 3;
2324
}
2425
}
2526

26-
/// 处理mmap系统调用
27-
pub fn do_mmap(addr: usize, length: usize, prot: MMapProt, flags: MMapFlags, fd: i32, offset: usize) -> Result<usize, i32> {
27+
/// 处理mmap系统调用的分配部分
28+
pub fn do_mmap(addr: usize, length: usize, prot: MMapProt) -> Result<usize, i32> {
2829
let task = PROCESSOR.exclusive_access().current().unwrap();
2930
let mut task_inner = task.inner_exclusive_access();
30-
task_inner.mmap(addr, length, prot, flags, fd, offset)
31-
}
31+
task_inner.mmap(addr, length, prot)
32+
}
33+
34+
// 尽管文件映射在syscall中实现,但此处设置一个shared区域
35+
// unimplemented

os/src/syscall/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ use process::*;
6969

7070
use crate::{fs::Stat, task::SignalAction};
7171

72+
#[no_mangle]
7273
/// handle syscall exception with `syscall_id` and other arguments
73-
pub fn syscall(syscall_id: usize, args: [usize; 4]) -> isize {
74+
pub fn syscall(syscall_id: usize, args: [usize; 6]) -> isize {
7475
match syscall_id {
7576
SYSCALL_DUP => sys_dup(args[0]),
7677
SYSCALL_OPEN => sys_open(args[1] as *const u8, args[2] as u32),
@@ -96,7 +97,10 @@ pub fn syscall(syscall_id: usize, args: [usize; 4]) -> isize {
9697
SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize),
9798
SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
9899
SYSCALL_GET_TIME => sys_get_time(args[0] as *mut TimeVal, args[1]),
99-
SYSCALL_MMAP => sys_mmap(args[0], args[1], args[2]),
100+
SYSCALL_MMAP => sys_mmap(
101+
args[0], args[1], args[2] as i32,
102+
args[3] as i32, args[4] as i32, args[5]
103+
),
100104
SYSCALL_MUNMAP => sys_munmap(args[0], args[1]),
101105
SYSCALL_SBRK => sys_sbrk(args[0] as i32),
102106
SYSCALL_SPAWN => sys_spawn(args[0] as *const u8),

os/src/syscall/process.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
//! Process management syscalls
22
33
use crate::{
4-
fs::{open_file, OpenFlags},
5-
mm::{translated_ref, translated_refmut, translated_str, mmap},
6-
task::{
4+
fs::{*}, mm::{mmap, translated_ref, translated_refmut, translated_str}, task::{
75
add_task, current_task, current_user_token, exit_current_and_run_next, pid2task,
86
suspend_current_and_run_next, SignalAction, SignalFlags, MAX_SIG,
97
},
8+
syscall::sys_read
109
};
1110
use alloc::{string::String, sync::Arc, vec::Vec};
1211

12+
13+
1314
#[repr(C)]
1415
#[derive(Debug)]
1516
pub struct TimeVal {
@@ -142,16 +143,32 @@ pub fn sys_get_time(_ts: *mut TimeVal, _tz: usize) -> isize {
142143
}
143144

144145
/// YOUR JOB: Implement mmap.
145-
pub fn sys_mmap(_start: usize, _len: usize, _port: usize) -> isize {
146+
pub fn sys_mmap(start: usize, len: usize, port: i32, flags: i32, fd: i32, _off: usize) -> isize {
146147
trace!("kernel:pid[{}] sys_mmap NOT IMPLEMENTED", current_task().unwrap().pid.0);
147-
mmap::do_mmap(
148-
_start,
149-
_len,
150-
mmap::MMapProt::from_bits_truncate(_port as i32),
151-
mmap::MMapFlags::from_bits_truncate(_port as i32),
152-
-1,
153-
0
154-
).unwrap_or(usize::MAX) as isize
148+
let mmap_flags = mmap::MMapFlags::from_bits_truncate(flags);
149+
let mmap_prot = mmap::MMapProt::from_bits_truncate(port);
150+
if let Ok(ret) = mmap::do_mmap(
151+
start,
152+
len,
153+
mmap_prot
154+
) {
155+
match mmap_flags {
156+
mmap::MMapFlags::MAP_ANONYMOUS => {},
157+
mmap::MMapFlags::MAP_PRIVATE => {
158+
// 按目前理解,拷贝文件内容到映射区即可?
159+
sys_read(fd as usize, ret as *mut u8, len);
160+
},
161+
mmap::MMapFlags::MAP_SHARED => {
162+
//尚未实现
163+
//此此处似乎需要实现文件的同步回写
164+
},
165+
_ => {return -1;},
166+
};
167+
ret as isize
168+
}
169+
else {
170+
-1
171+
}
155172
}
156173

157174
/// YOUR JOB: Implement munmap.

os/src/task/processor.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Implementation of [`Processor`] and Intersection of control flow
1+
//!Implementation of [`Processor`] and Intersection of control flow
22
//!
33
//! Here, the continuous operation of user apps in CPU is maintained,
44
//! the current running state of CPU is recorded,
@@ -10,9 +10,12 @@ use super::{TaskContext, TaskControlBlock};
1010
use crate::sync::UPSafeCell;
1111
use crate::trap::TrapContext;
1212
use alloc::sync::Arc;
13+
use core::cell::RefMut;
1314
use lazy_static::*;
15+
use super::task::TaskControlBlockInner;
1416

1517
/// Processor management structure
18+
/// 只记录当前任务block与空闲状态下的任务上下文
1619
pub struct Processor {
1720
///The task currently executing on the current processor
1821
current: Option<Arc<TaskControlBlock>>,
@@ -42,24 +45,31 @@ impl Processor {
4245

4346
///Get current task in cloning semanteme
4447
pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
48+
//map方法传入Option<T>,对T进行处理(闭包),并返回新的Option<T'>
4549
self.current.as_ref().map(Arc::clone)
4650
}
51+
///获取当前task的访问权,但不获取其所有权
52+
pub fn _current_exclusive_access(&self) -> Option<RefMut<'_, TaskControlBlockInner>> {
53+
self.current.as_ref().map(|task| task.inner_exclusive_access())
54+
}
4755
}
4856

4957
lazy_static! {
50-
/// Global processor instance.
58+
///The global unique processor instance
5159
pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
5260
}
5361

5462
///The main part of process execution and scheduling
5563
///Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`
5664
pub fn run_tasks() {
65+
//注意,这里是一个循环
5766
loop {
5867
let mut processor = PROCESSOR.exclusive_access();
5968
if let Some(task) = fetch_task() {
6069
let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
6170
// access coming task TCB exclusively
6271
let mut task_inner = task.inner_exclusive_access();
72+
// 这玩意保存在内核堆区
6373
let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
6474
task_inner.task_status = TaskStatus::Running;
6575
// release coming task_inner manually
@@ -69,8 +79,12 @@ pub fn run_tasks() {
6979
// release processor manually
7080
drop(processor);
7181
unsafe {
82+
// 调用前,a寄存器和t寄存器已经被保存好(调用者保存)
83+
// __switch会保存s寄存器
7284
__switch(idle_task_cx_ptr, next_task_cx_ptr);
73-
}
85+
}
86+
// 一段时间后后可能会返回到这里(切回空闲状态后)
87+
// 进入下一个循环
7488
} else {
7589
warn!("no tasks available in run_tasks");
7690
}
@@ -93,15 +107,16 @@ pub fn current_user_token() -> usize {
93107
task.get_user_token()
94108
}
95109

96-
/// Get the mutable reference to trap context of current task
110+
///Get the mutable reference to trap context of current task
97111
pub fn current_trap_cx() -> &'static mut TrapContext {
98112
current_task()
99113
.unwrap()
100114
.inner_exclusive_access()
101115
.get_trap_cx()
102116
}
103117

104-
/// Return to idle control flow for new scheduling
118+
///Return to idle control flow for new scheduling
119+
///保存当前任务到传入参数地址(这时还是用户态),切换到空闲状态
105120
pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
106121
let mut processor = PROCESSOR.exclusive_access();
107122
let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();

os/src/task/task.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,13 @@ impl TaskControlBlockInner {
112112
self.fd_table.len() - 1
113113
}
114114
}
115-
pub fn mmap(
115+
pub fn mmap(//映射内存段
116116
&mut self,
117117
addr: usize,
118118
length: usize,
119-
prot: mmap::MMapProt,
120-
flags: mmap::MMapFlags,
121-
fd: i32,
122-
offset: usize,
119+
prot: mmap::MMapProt
123120
) -> Result<usize, i32> {
124-
self.memory_set.mmap(addr, length, prot, flags, fd, offset)
121+
self.memory_set.mmap(addr, length, prot)
125122
}
126123
}
127124

0 commit comments

Comments
 (0)