Skip to content

Commit

Permalink
完成了除munmap以外的其他所有代码,且只有munmap的一个测试点没有通过,其他测试点全部通过
Browse files Browse the repository at this point in the history
reports所涉及的文档也完善好了,问答题全部写完了
要提交的变更:
      修改:     src/config.rs
      修改:     src/mm/memory_set.rs
      修改:     src/mm/mod.rs
      修改:     src/mm/page_table.rs
      修改:     src/syscall/mod.rs
      修改:     src/syscall/process.rs
      修改:     src/task/mod.rs
      修改:     src/task/task.rs
      修改:     src/trap/mod.rs
      新文件:   ../reports/lab1.md
      新文件:   ../reports/lab2.md
  • Loading branch information
Eternal60f3 committed May 11, 2024
1 parent 5cd43bc commit ef3743b
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 43 deletions.
3 changes: 3 additions & 0 deletions os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ BASE ?= 1
# Disassembly
DISASM ?= -x

# Run usertests or usershell
TEST ?=

build: env $(KERNEL_BIN)

env:
Expand Down
34 changes: 15 additions & 19 deletions os/build.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
//! Building applications linker
use std::fs::{read_dir, File};
use std::io::{Result, Write};
use std::fs::{File, read_dir};

fn main() {
println!("cargo:rerun-if-changed=../user/src/");
println!("cargo:rerun-if-changed=../ci-user/user/src/");
println!("cargo:rerun-if-changed={}", TARGET_PATH);
insert_app_data().unwrap();
}

static TARGET_PATH: &str = "../user/build/elf/";
static TARGET_PATH: &str = "../ci-user/user/build/elf/";

/// get app data and build linker
fn insert_app_data() -> Result<()> {
let mut f = File::create("src/link_app.S").unwrap();
let mut apps: Vec<_> = read_dir("../user/build/elf/")
let mut apps: Vec<_> = read_dir("../ci-user/user/build/elf")
.unwrap()
.into_iter()
.map(|dir_entry| {
Expand All @@ -25,36 +22,35 @@ fn insert_app_data() -> Result<()> {
.collect();
apps.sort();

writeln!(
f,
r#"
writeln!(f, r#"
.align 3
.section .data
.global _num_app
_num_app:
.quad {}"#,
apps.len()
)?;
.quad {}"#, apps.len())?;

for i in 0..apps.len() {
writeln!(f, r#" .quad app_{}_start"#, i)?;
}
writeln!(f, r#" .quad app_{}_end"#, apps.len() - 1)?;

writeln!(f, r#"
.global _app_names
_app_names:"#)?;
for app in apps.iter() {
writeln!(f, r#" .string "{}""#, app)?;
}

for (idx, app) in apps.iter().enumerate() {
println!("app_{}: {}", idx, app);
writeln!(
f,
r#"
writeln!(f, r#"
.section .data
.global app_{0}_start
.global app_{0}_end
.align 3
app_{0}_start:
.incbin "{2}{1}.elf"
app_{0}_end:"#,
idx, app, TARGET_PATH
)?;
app_{0}_end:"#, idx, app, TARGET_PATH)?;
}
Ok(())
}
4 changes: 3 additions & 1 deletion os/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/// user app's stack size
pub const USER_STACK_SIZE: usize = 4096 * 2;
/// kernel stack size
pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
pub const KERNEL_STACK_SIZE: usize = 4096 * 20;
/// kernel heap size
pub const KERNEL_HEAP_SIZE: usize = 0x200_0000;

Expand All @@ -15,6 +15,8 @@ pub const PAGE_SIZE: usize = 0x1000;
pub const PAGE_SIZE_BITS: usize = 0xc;
/// the max number of syscall
pub const MAX_SYSCALL_NUM: usize = 500;
/// current the count of syscall
pub const SYSCALL_CNT: usize = 8;
/// the virtual addr of trapoline
pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1;
/// the virtual addr of trap context
Expand Down
5 changes: 5 additions & 0 deletions os/src/mm/memory_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ impl MemorySet {
false
}
}

/// check a vpn whether has been mapped
pub fn vpn_ismap(&self, vpn: VirtPageNum) -> bool {
self.page_table.is_map(vpn)
}
}
/// map area structure, controls a contiguous piece of virtual memory
pub struct MapArea {
Expand Down
6 changes: 3 additions & 3 deletions os/src/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ mod heap_allocator;
mod memory_set;
mod page_table;

pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
use address::{StepByOne, VPNRange};
pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum, VPNRange};
use address::StepByOne;
pub use frame_allocator::{frame_alloc, FrameTracker};
pub use memory_set::remap_test;
pub use memory_set::{kernel_stack_position, MapPermission, MemorySet, KERNEL_SPACE};
pub use page_table::{translated_byte_buffer, PageTableEntry};
pub use page_table::{translated_byte_buffer, PageTableEntry, va_var2pa_mut};
use page_table::{PTEFlags, PageTable};

/// initiate heap allocator, frame allocator and kernel space
Expand Down
33 changes: 32 additions & 1 deletion os/src/mm/page_table.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Implementation of [`PageTableEntry`] and [`PageTable`].
use super::{frame_alloc, FrameTracker, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
use super::{frame_alloc, FrameTracker, PhysPageNum, StepByOne, VirtAddr, VirtPageNum, PhysAddr};
use crate::config::PAGE_SIZE;
use _core::{mem, panic};
use alloc::vec;
use alloc::vec::Vec;
use bitflags::*;
Expand Down Expand Up @@ -143,6 +145,25 @@ impl PageTable {
pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
self.find_pte(vpn).map(|pte| *pte)
}
pub fn va_var2pa_mut<T>(&self, ptr: *mut T) -> Option<&'static mut T> {
let va = VirtAddr::from(ptr as usize);
let vpn = va.floor();
if let Some(pte) = self.translate(vpn) {
let ppn = pte.ppn();
let pa = PhysAddr::from(PhysAddr::from(ppn).0 + va.page_offset());
if PAGE_SIZE - pa.page_offset() >= mem::size_of::<T>() {
return Some(pa.get_mut());
}
}
return None;
}
pub fn is_map(&self, vpn: VirtPageNum) -> bool {
if let Some(_) = self.find_pte(vpn) {
true
} else {
false
}
}
/// get the token from the page table
pub fn token(&self) -> usize {
8usize << 60 | self.root_ppn.0
Expand Down Expand Up @@ -171,3 +192,13 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&
}
v
}

/// get mut var by pa
pub fn va_var2pa_mut<T>(token: usize, ptr: *mut T) -> &'static mut T {
let page_table = PageTable::from_token(token);
if let Some(quote) = page_table.va_var2pa_mut(ptr) {
quote
} else {
panic!("the ptr not map or it is splited by two pages");
}
}
16 changes: 16 additions & 0 deletions os/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,27 @@ const SYSCALL_MMAP: usize = 222;
/// taskinfo syscall
const SYSCALL_TASK_INFO: usize = 410;

/// syscall tong
pub const SYSCALL_TONG: [usize; SYSCALL_CNT] = [
SYSCALL_WRITE,
SYSCALL_EXIT,
SYSCALL_YIELD,
SYSCALL_GET_TIME,
SYSCALL_TASK_INFO,
SYSCALL_SBRK,
SYSCALL_MUNMAP,
SYSCALL_MMAP,
];

mod fs;
mod process;

use fs::*;
use process::*;
use crate::config::SYSCALL_CNT;

pub use process::TaskInfo;

/// handle syscall exception with `syscall_id` and other arguments
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id {
Expand Down
37 changes: 22 additions & 15 deletions os/src/syscall/process.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Process management syscalls
use crate::{
config::MAX_SYSCALL_NUM,
task::{
change_program_brk, exit_current_and_run_next, suspend_current_and_run_next, TaskStatus,
},
config::MAX_SYSCALL_NUM, mm::va_var2pa_mut, task::{
change_program_brk, curr_mmap, current_user_token, exit_current_and_run_next, get_current_info, suspend_current_and_run_next, TaskStatus
}, timer::get_time_us
};

#[repr(C)]
Expand All @@ -17,11 +16,11 @@ pub struct TimeVal {
#[allow(dead_code)]
pub struct TaskInfo {
/// Task status in it's life cycle
status: TaskStatus,
pub status: TaskStatus,
/// The numbers of syscall called by task
syscall_times: [u32; MAX_SYSCALL_NUM],
pub syscall_times: [u32; MAX_SYSCALL_NUM],
/// Total running time of task
time: usize,
pub time: usize,
}

/// task exits and submit an exit code
Expand All @@ -41,23 +40,31 @@ pub fn sys_yield() -> isize {
/// YOUR JOB: get time with second and microsecond
/// HINT: You might reimplement it with virtual memory management.
/// HINT: What if [`TimeVal`] is splitted by two pages ?
pub fn sys_get_time(_ts: *mut TimeVal, _tz: usize) -> isize {
pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize {
trace!("kernel: sys_get_time");
-1
let us = get_time_us();
let tmp = va_var2pa_mut(current_user_token(), ts);
*tmp = TimeVal {
sec: us / 1_000_000,
usec: us % 1_000_000,
};
0
}

/// YOUR JOB: Finish sys_task_info to pass testcases
/// HINT: You might reimplement it with virtual memory management.
/// HINT: What if [`TaskInfo`] is splitted by two pages ?
pub fn sys_task_info(_ti: *mut TaskInfo) -> isize {
trace!("kernel: sys_task_info NOT IMPLEMENTED YET!");
-1
pub fn sys_task_info(ti: *mut TaskInfo) -> isize {
trace!("kernel: sys_task_info");
let tmp = va_var2pa_mut(current_user_token(), ti);
get_current_info(tmp);
0
}

// YOUR JOB: Implement mmap.
pub fn sys_mmap(_start: usize, _len: usize, _port: usize) -> isize {
trace!("kernel: sys_mmap NOT IMPLEMENTED YET!");
-1
pub fn sys_mmap(start: usize, len: usize, port: usize) -> isize {
trace!("kernel: sys_mmap");
curr_mmap(start, len, port)
}

// YOUR JOB: Implement munmap.
Expand Down
Loading

0 comments on commit ef3743b

Please sign in to comment.