Skip to content

Commit 94f084c

Browse files
committed
update
1 parent e6a0721 commit 94f084c

File tree

12 files changed

+526
-108
lines changed

12 files changed

+526
-108
lines changed

os/Makefile

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,23 @@
22
TARGET := riscv64gc-unknown-none-elf
33
MODE := release
44
KERNEL_ELF := target/$(TARGET)/$(MODE)/os
5-
KERNEL_BIN := $(KERNEL_ELF).bin
6-
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
7-
OFFLINE :=
85

96
# BOARD
10-
BOARD := qemu
7+
BOARD ?= qemu
118
SBI ?= rustsbi
129
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
1310

14-
# Building mode argument
15-
ifeq ($(MODE), release)
16-
MODE_ARG := --release
17-
endif
18-
19-
# KERNEL ENTRY
20-
KERNEL_ENTRY_PA := 0x80200000
21-
22-
# Binutils
23-
OBJDUMP := rust-objdump --arch-name=riscv64
24-
OBJCOPY := rust-objcopy --binary-architecture=riscv64
25-
26-
CHAPTER ?= $(shell git rev-parse --abbrev-ref HEAD | sed -E 's/ch([0-9])/\1/')
27-
TEST ?= $(CHAPTER)
28-
BASE ?= 1
29-
30-
# Disassembly
31-
DISASM ?= -x
32-
33-
build: env $(KERNEL_BIN)
34-
35-
env:
36-
ifeq ($(OFFLINE),)
37-
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET)
38-
cargo install cargo-binutils
39-
rustup component add rust-src
40-
rustup component add llvm-tools-preview
41-
endif
42-
43-
$(KERNEL_BIN): kernel
44-
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
45-
4611
kernel:
47-
@make -C ../user build TEST=$(TEST) CHAPTER=$(CHAPTER) BASE=$(BASE)
48-
@echo Platform: $(BOARD)
49-
@cargo build $(MODE_ARG)
12+
cargo build --release
5013

5114
clean:
52-
@cargo clean
53-
54-
disasm: kernel
55-
@$(OBJDUMP) $(DISASM) $(KERNEL_ELF) | less
56-
57-
disasm-vim: kernel
58-
@$(OBJDUMP) $(DISASM) $(KERNEL_ELF) > $(DISASM_TMP)
59-
@vim $(DISASM_TMP)
60-
@rm $(DISASM_TMP)
61-
62-
run: run-inner
15+
cargo clean
6316

64-
run-inner: build
65-
@qemu-system-riscv64 \
17+
run: kernel
18+
timeout --foreground 30s qemu-system-riscv64 \
6619
-machine virt \
6720
-nographic \
6821
-bios $(BOOTLOADER) \
69-
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA)
70-
71-
debug: build
72-
@tmux new-session -d \
73-
"qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S" && \
74-
tmux split-window -h "riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'" && \
75-
tmux -2 attach-session -d
76-
77-
gdbserver: build
78-
@qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S
79-
80-
gdbclient:
81-
@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'
22+
-kernel $(KERNEL_ELF)
8223

83-
.PHONY: build env kernel clean disasm disasm-vim run-inner gdbserver gdbclient
24+
.PHONY: build kernel clean run

os/build.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
//! Building applications linker
2-
3-
use std::fs::{read_dir, File};
41
use std::io::{Result, Write};
2+
use std::fs::{File, read_dir};
53

64
fn main() {
7-
println!("cargo:rerun-if-changed=../user/src/");
5+
println!("cargo:rerun-if-changed=../ci-user/user/src/");
86
println!("cargo:rerun-if-changed={}", TARGET_PATH);
97
insert_app_data().unwrap();
108
}
119

12-
static TARGET_PATH: &str = "../user/build/elf/";
10+
static TARGET_PATH: &str = "../ci-user/user/build/elf/";
1311

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

28-
writeln!(
29-
f,
30-
r#"
25+
writeln!(f, r#"
3126
.align 3
3227
.section .data
3328
.global _num_app
3429
_num_app:
35-
.quad {}"#,
36-
apps.len()
37-
)?;
30+
.quad {}"#, apps.len())?;
3831

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

37+
writeln!(f, r#"
38+
.global _app_names
39+
_app_names:"#)?;
40+
for app in apps.iter() {
41+
writeln!(f, r#" .string "{}""#, app)?;
42+
}
43+
4444
for (idx, app) in apps.iter().enumerate() {
4545
println!("app_{}: {}", idx, app);
46-
writeln!(
47-
f,
48-
r#"
46+
writeln!(f, r#"
4947
.section .data
5048
.global app_{0}_start
5149
.global app_{0}_end
5250
.align 3
5351
app_{0}_start:
5452
.incbin "{2}{1}.elf"
55-
app_{0}_end:"#,
56-
idx, app, TARGET_PATH
57-
)?;
53+
app_{0}_end:"#, idx, app, TARGET_PATH)?;
5854
}
5955
Ok(())
6056
}

os/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
//! We then call [`task::run_first_task()`] and for the first time go to
1616
//! userspace.
1717
18-
#![deny(missing_docs)]
1918
#![deny(warnings)]
2019
#![no_std]
2120
#![no_main]

os/src/mm/memory_set.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,39 @@ impl MemorySet {
5151
pub fn token(&self) -> usize {
5252
self.page_table.token()
5353
}
54+
/// Check whether there is overlap with already mapped pages
55+
pub fn check_mmap_area(&self, start_vpn: VirtPageNum, end_vpn: VirtPageNum) -> bool {
56+
for area in &self.areas {
57+
if !(end_vpn <= area.vpn_range.get_start()
58+
|| start_vpn >= area.vpn_range.get_end())
59+
{
60+
return true;
61+
}
62+
}
63+
false
64+
}
65+
/// Remove
66+
pub fn remove_framed_area(
67+
&mut self,
68+
start_va: VirtAddr,
69+
end_va:VirtAddr,
70+
) -> isize {
71+
if let Some(pos) = self
72+
.areas
73+
.iter()
74+
.position(|area| {
75+
area.vpn_range.get_start() == start_va.floor()
76+
&& area.vpn_range.get_end() == end_va.ceil()
77+
})
78+
{
79+
let mut area = self.areas.remove(pos);
80+
area.unmap(&mut self.page_table);
81+
0
82+
} else {
83+
-1
84+
}
85+
}
86+
5487
/// Assume that no conflicts.
5588
pub fn insert_framed_area(
5689
&mut self,
@@ -63,13 +96,24 @@ impl MemorySet {
6396
None,
6497
);
6598
}
66-
fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
99+
pub fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
67100
map_area.map(&mut self.page_table);
68101
if let Some(data) = data {
69102
map_area.copy_data(&mut self.page_table, data);
70103
}
71104
self.areas.push(map_area);
72105
}
106+
pub fn remove_area(&mut self, start_vpn: VirtPageNum, end_vpn: VirtPageNum) -> isize {
107+
if let Some(pos) = self.areas.iter().position(|area| {
108+
area.vpn_range.get_start() == start_vpn && area.vpn_range.get_end() == end_vpn
109+
}) {
110+
let mut area = self.areas.remove(pos);
111+
area.unmap(&mut self.page_table);
112+
0
113+
} else {
114+
-1
115+
}
116+
}
73117
/// Mention that trampoline is not collected by areas.
74118
fn map_trampoline(&mut self) {
75119
self.page_table.map(
@@ -262,6 +306,20 @@ impl MemorySet {
262306
false
263307
}
264308
}
309+
310+
pub fn unmap_range(&mut self, start_vpn: VirtPageNum, end_vpn: VirtPageNum) -> isize {
311+
312+
for vpn in VPNRange::new(start_vpn, end_vpn) {
313+
if let Some(area) = self.areas.iter_mut().find(|area| {
314+
vpn >= area.vpn_range.get_start() && end_vpn < area.vpn_range.get_end()
315+
}){
316+
area.unmap_one(&mut self.page_table, vpn);
317+
area.data_frames.remove(&vpn);
318+
319+
}
320+
}
321+
0
322+
}
265323
}
266324
/// map area structure, controls a contiguous piece of virtual memory
267325
pub struct MapArea {
@@ -409,4 +467,4 @@ pub fn remap_test() {
409467
.unwrap()
410468
.executable(),);
411469
println!("remap_test passed!");
412-
}
470+
}

os/src/mm/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
//!
77
//! Every task or process has a memory_set to control its virtual memory.
88
9-
mod address;
10-
mod frame_allocator;
11-
mod heap_allocator;
12-
mod memory_set;
13-
mod page_table;
9+
pub mod address;
10+
pub mod frame_allocator;
11+
pub mod heap_allocator;
12+
pub mod memory_set;
13+
pub mod page_table;
1414

15-
pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
16-
use address::{StepByOne, VPNRange};
15+
pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum,VPNRange,StepByOne};
1716
pub use frame_allocator::{frame_alloc, FrameTracker};
1817
pub use memory_set::remap_test;
19-
pub use memory_set::{kernel_stack_position, MapPermission, MemorySet, KERNEL_SPACE};
20-
pub use page_table::{translated_byte_buffer, PageTableEntry};
18+
pub use memory_set::{kernel_stack_position, MapPermission, MemorySet, KERNEL_SPACE,MapArea,MapType};
19+
pub use page_table::{translated_byte_buffer, translated_ref, translated_refmut, PageTableEntry};
2120
pub use page_table::{PTEFlags, PageTable};
2221

22+
2323
/// initiate heap allocator, frame allocator and kernel space
2424
pub fn init() {
2525
heap_allocator::init_heap();

os/src/mm/page_table.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,25 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&
179179
}
180180
v
181181
}
182+
/// Translate&Copy a ptr[T] to a immutable reference through page table
183+
pub fn translated_ref<T>(token: usize, ptr: *const T) -> Option<&'static T> {
184+
let ptr =ptr as * const u8;
185+
let len = core::mem::size_of::<T>();
186+
let buffers = translated_byte_buffer(token, ptr, len);
187+
188+
if buffers.len() != 1 || buffers[0].len() != len {
189+
return None;
190+
}
191+
Some(unsafe { &*(buffers[0].as_ptr() as *const T) })
192+
}
193+
/// Translate&Copy a ptr[T] to a mutable reference through page table
194+
pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> Option<&'static mut T> {
195+
let ptr =ptr as * mut u8;
196+
let len = core::mem::size_of::<T>();
197+
let mut buffers = translated_byte_buffer(token, ptr, len);
198+
199+
if buffers.len() != 1 || buffers[0].len() != len {
200+
return None;
201+
}
202+
Some(unsafe { &mut *(buffers[0].as_mut_ptr() as *mut T) })
203+
}

os/src/syscall/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ mod process;
3030

3131
use fs::*;
3232
use process::*;
33+
use crate::mm::{translated_byte_buffer};
34+
// use crate::task::TASK_MANAGER;
3335

3436
/// handle syscall exception with `syscall_id` and other arguments
3537
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
38+
crate::task::set_nr_syscall(syscall_id);
39+
// TASK_MANAGER.increase_current_syscall_count(syscall_id);
3640
match syscall_id {
3741
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
3842
SYSCALL_EXIT => sys_exit(args[0] as i32),
@@ -45,3 +49,26 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
4549
_ => panic!("Unsupported syscall_id: {}", syscall_id),
4650
}
4751
}
52+
53+
54+
pub fn translated_ref<T>(token: usize, ptr: *const T) -> Option<&'static T> {
55+
let ptr =ptr as * const u8;
56+
let len = core::mem::size_of::<T>();
57+
let buffers = translated_byte_buffer(token, ptr, len);
58+
59+
if buffers.len() != 1 || buffers[0].len() != len {
60+
return None;
61+
}
62+
Some(unsafe { &*(buffers[0].as_ptr() as *const T) })
63+
}
64+
65+
pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> Option<&'static mut T> {
66+
let ptr =ptr as * mut u8;
67+
let len = core::mem::size_of::<T>();
68+
let mut buffers = translated_byte_buffer(token, ptr, len);
69+
70+
if buffers.len() != 1 || buffers[0].len() != len {
71+
return None;
72+
}
73+
Some(unsafe { &mut *(buffers[0].as_mut_ptr() as *mut T) })
74+
}

0 commit comments

Comments
 (0)