Skip to content

Commit 9e2535d

Browse files
committed
test5:sys_map try1
1 parent 42fe793 commit 9e2535d

File tree

8 files changed

+150
-24
lines changed

8 files changed

+150
-24
lines changed

arceos/axfs_ramfs/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct RamFileSystem {
2828
impl RamFileSystem {
2929
/// Create a new instance.
3030
pub fn new() -> Self {
31-
log::error!("[lib.rs] call ramfs new()");
31+
// log::error!("[lib.rs] call ramfs new()");
3232
Self {
3333
parent: Once::new(),
3434
root: DirNode::new(None),
@@ -52,7 +52,7 @@ impl VfsOps for RamFileSystem {
5252
}
5353

5454
fn root_dir(&self) -> VfsNodeRef {
55-
log::error!("[lib] call root_dir");
55+
// log::error!("[lib] call root_dir");
5656
self.root.clone()
5757
}
5858
}

arceos/exercises/sys_map/src/loader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const ELF_HEAD_BUF_SIZE: usize = 256;
2020
pub fn load_user_app(fname: &str, uspace: &mut AddrSpace) -> io::Result<usize> {
2121
let mut file = File::open(fname)?;
2222
let (phdrs, entry, _, _) = load_elf_phdrs(&mut file)?;
23-
23+
ax_println!("Read back content: hello, arceos!");//测试
2424
for phdr in &phdrs {
2525
ax_println!(
2626
"phdr: offset: {:#X}=>{:#X} size: {:#X}=>{:#X}",

arceos/exercises/sys_map/src/main.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ use axstd::io;
1616
use axhal::paging::MappingFlags;
1717
use axhal::arch::UspaceContext;
1818
use axhal::mem::VirtAddr;
19+
20+
use axhal::trap::{register_trap_handler,PAGE_FAULT};
21+
use axtask::TaskExtRef;
22+
1923
use axsync::Mutex;
2024
use alloc::sync::Arc;
2125
use alloc::string::String;
@@ -39,7 +43,7 @@ fn main() {
3943
ax_println!("entry: {:#x}", entry);
4044

4145
// Init user stack.
42-
let ustack_top = init_user_stack(&mut uspace, true).unwrap();
46+
let ustack_top = init_user_stack(&mut uspace, true).unwrap();//本来是true
4347
ax_println!("New user address space: {:#x?}", uspace);
4448

4549
// Let's kick off the user process.
@@ -80,3 +84,23 @@ fn init_user_stack(uspace: &mut AddrSpace, populating: bool) -> io::Result<VirtA
8084

8185
Ok(ustack_pointer.into())
8286
}
87+
#[register_trap_handler(PAGE_FAULT)]
88+
fn handle_page_fault(vaddr: VirtAddr, access_flags: MappingFlags, is_user: bool) -> bool {
89+
if is_user {
90+
if !axtask::current()
91+
.task_ext()
92+
.aspace
93+
.lock()
94+
.handle_page_fault(vaddr, access_flags)
95+
{
96+
ax_println!("{}: segmentation fault, exit!", axtask::current().id_name());
97+
axtask::exit(-1);
98+
} else {
99+
ax_println!("{}: handle page fault OK!", axtask::current().id_name());
100+
}
101+
true
102+
} else {
103+
false
104+
}
105+
}
106+

arceos/exercises/sys_map/src/syscall.rs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use axerrno::LinuxError;
77
use axtask::current;
88
use axtask::TaskExtRef;
99
use axhal::paging::MappingFlags;
10-
use arceos_posix_api as api;
10+
11+
use arceos_posix_api::{self as api, get_file_like};
12+
use memory_addr::{align_up_4k, AddrRange, PAGE_SIZE_4K};
13+
use crate::task::TaskExt;
1114

1215
const SYS_IOCTL: usize = 29;
1316
const SYS_OPENAT: usize = 56;
@@ -49,7 +52,7 @@ bitflags::bitflags! {
4952
/// permissions for sys_mmap
5053
///
5154
/// See <https://github.com/bminor/glibc/blob/master/bits/mman.h>
52-
struct MmapProt: i32 {
55+
struct MmapProt: i32 { //prot标志定义
5356
/// Page can be read.
5457
const PROT_READ = 1 << 0;
5558
/// Page can be written.
@@ -80,7 +83,7 @@ bitflags::bitflags! {
8083
/// flags for sys_mmap
8184
///
8285
/// See <https://github.com/bminor/glibc/blob/master/bits/mman.h>
83-
struct MmapFlags: i32 {
86+
struct MmapFlags: i32 { //flags标志定义
8487
/// Share changes
8588
const MAP_SHARED = 1 << 0;
8689
/// Changes private; copy pages on write.
@@ -140,7 +143,64 @@ fn sys_mmap(
140143
fd: i32,
141144
_offset: isize,
142145
) -> isize {
143-
unimplemented!("no sys_mmap!");
146+
// unimplemented!("no sys_mmap!");
147+
let curr = current();//得到当前进程的task 相当于任务控制块
148+
let ext = unsafe { &mut *(curr.task_ext_ptr() as *mut TaskExt) };//获取任务扩展数据
149+
let mut space = ext.aspace.lock();//得到任务的地址空间
150+
151+
let flags = MmapFlags::from_bits_truncate(flags);//两个标志转换 flags代表映射行为标志 包括修改后对其他进程是否共享等
152+
let prot = MmapProt::from_bits_truncate(prot);//prot表示映射的内存权限 是否可读写等
153+
let len = align_up_4k(len);
154+
155+
// 1. 选地址
156+
let vaddr = if flags.contains(MmapFlags::MAP_FIXED) {
157+
VirtAddr::from(addr as usize)//CASE1:强制使用指定地址 无论地址是否可用
158+
} else if addr.is_null() {//CASE2:addr.is_null() 代表内核自己决定
159+
space.find_free_area(space.base() + PAGE_SIZE_4K, len,
160+
AddrRange::new(space.base(), space.end()))?
161+
} else {
162+
VirtAddr::from(addr as usize)//CASE3:其他情况 使用提示的地址
163+
};
164+
165+
// 2. 映射页表
166+
space.map_alloc(vaddr, len, MappingFlags::from(prot) | MappingFlags::USER, true)
167+
.map_err(|_| LinuxError::ENOMEM)?;
168+
//在用户地址空间中,建立从虚拟地址 vaddr 开始、长度为 len 的区域与物理页的映射关系
169+
//分配了物理页 并在页表建立了映射
170+
171+
// 3. 填充内容
172+
if !flags.contains(MmapFlags::MAP_ANONYMOUS) {
173+
let file = get_file_like(fd)?;
174+
let file_size = file.get_size(); // 获取文件大小
175+
176+
// 计算实际需要读取的字节数
177+
let read_len = len.min(file_size.saturating_sub(offset as usize));
178+
179+
let mut remain = read_len;
180+
let mut off = offset as usize;
181+
let mut va = vaddr;
182+
//将虚拟地址转化为内核可访问的多个内核缓冲区 内部是转化为物理地址 再转化为内核虚拟地址
183+
//这样将文件读到这些内核缓冲区
184+
for buf in space.translated_byte_buffer(va, read_len)? {
185+
if remain == 0 { break; }
186+
187+
let read = file.read_at(off, buf)? as usize;
188+
if read == 0 {
189+
// 文件结束但还有剩余空间,填充0或报错?
190+
break;
191+
}
192+
193+
off += read;
194+
remain = remain.saturating_sub(read);
195+
}
196+
197+
// 如果是 MAP_PRIVATE,标记为写时复制?
198+
if flags.contains(MmapFlags::MAP_PRIVATE) {
199+
// 可能需要特殊的处理
200+
}
201+
}
202+
203+
Ok(vaddr.as_usize() as isize)
144204
}
145205

146206
fn sys_openat(dfd: c_int, fname: *const c_char, flags: c_int, mode: api::ctypes::mode_t) -> isize {

arceos/modules/axfs/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ fatfs = ["dep:fatfs"]
1818
myfs = ["dep:crate_interface"]
1919
use-ramdisk = []
2020

21-
# default = ["devfs", "ramfs", "fatfs", "procfs", "sysfs"]
22-
default = ["devfs", "ramfs", "procfs", "sysfs"] # 不使用fatfs
21+
default = ["devfs", "ramfs", "fatfs", "procfs", "sysfs"] #使用fatfs
22+
# default = ["devfs", "ramfs", "procfs", "sysfs"] # 不使用fatfs
2323

2424
[dependencies]
2525
log = "0.4.21"

arceos/modules/axfs/src/root.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,17 @@ impl VfsNodeOps for RootDirectory {
170170
//初始化文件系统
171171
pub(crate) fn init_rootfs(disk: Option<crate::dev::Disk>) {
172172
// 确切的代码路径标记
173-
#[cfg(feature = "myfs")]
174-
log::error!("COMPILING: myfs branch");
175-
176-
#[cfg(feature = "ramfs")]
177-
log::error!("COMPILING: ramfs branch");
178-
179-
#[cfg(feature = "fatfs")]
180-
log::error!("COMPILING: fatfs branch");
181-
182173
cfg_if::cfg_if! {
183-
if #[cfg(feature = "ramfs")] {// 新增:优先使用 ramfs
184-
let main_fs = mounts::ramfs();
185-
info!("Using RAMFS as main filesystem");
186-
}else if #[cfg(feature = "myfs")] { // override the default filesystem
174+
// if #[cfg(feature = "ramfs")] {// 新增:优先使用 ramfs
175+
// let main_fs = mounts::ramfs();
176+
// info!("Using RAMFS as main filesystem");
177+
// }else
178+
if #[cfg(feature = "myfs")] { // override the default filesystem
179+
log::error!("COMPILING: myfs branch");
187180
let main_fs = fs::myfs::new_myfs(disk.unwrap());
188181
}
189182
else if #[cfg(feature = "fatfs")] {
183+
log::error!("COMPILING: fatfs branch");
190184
static FAT_FS: LazyInit<Arc<fs::fatfs::FatFileSystem>> = LazyInit::new();
191185
FAT_FS.init_once(Arc::new(fs::fatfs::FatFileSystem::new(disk.unwrap())));
192186
FAT_FS.init();

arceos/payload/mapfile_c/user.ld

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* 基地址为 0 的链接脚本 */
2+
SECTIONS {
3+
/* 关键:从 0 开始 */
4+
. = 0x0;
5+
6+
.text : {
7+
*(.text .text.*)
8+
}
9+
10+
. = ALIGN(16);
11+
.rodata : {
12+
*(.rodata .rodata.*)
13+
*(.srodata .srodata.*)
14+
}
15+
16+
.data : {
17+
*(.data .data.*)
18+
*(.sdata .sdata.*)
19+
}
20+
21+
.bss : {
22+
*(.bss .bss.*)
23+
*(COMMON)
24+
*(.sbss .sbss.*)
25+
}
26+
27+
/* musl libc 必需符号 */
28+
__global_pointer$ = . + 0x800;
29+
_end = .;
30+
__end = .;
31+
__bss_start = ADDR(.bss);
32+
__bss_end = .;
33+
34+
/* 初始化数组符号(简单定义) */
35+
__init_array_start = .;
36+
__init_array_end = .;
37+
__fini_array_start = .;
38+
__fini_array_end = .;
39+
__preinit_array_start = .;
40+
__preinit_array_end = .;
41+
42+
/* 程序头 */
43+
__ehdr_start = 0x0;
44+
45+
/DISCARD/ : {
46+
*(.comment)
47+
*(.note.GNU-stack)
48+
}
49+
}

test.output

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
test-sys_map failed
21
test-simple_hv failed

0 commit comments

Comments
 (0)