Skip to content

Commit 86abde4

Browse files
wyfcyxwangrunji0408
authored andcommitted
chk-ch8-part4
1 parent 99fa0b5 commit 86abde4

File tree

17 files changed

+293
-17
lines changed

17 files changed

+293
-17
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
os/target
22
usr/rust/target
3+
os/src/link_user.S
34
Cargo.lock

os/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ edition = "2018"
1010
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
1111
spin = "0.5.2"
1212
buddy_system_allocator = "0.3"
13-
13+
xmas-elf = "0.6"

os/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ env:
1313
rustup component add llvm-tools-preview rustfmt
1414
rustup target add $(target)
1515

16+
export USER_IMG = ../usr/rust/target/$(target)/debug/hello_world
17+
1618
kernel:
1719
cargo build
1820

os/build.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use std::fs::File;
2+
use std::io::{Result, Write};
3+
4+
fn main() {
5+
println!("cargo:rerun-if-env-changed=USER_IMG");
6+
if let Ok(user_img) = std::env::var("USER_IMG") {
7+
println!("cargo:rerun-if-changed={}", user_img);
8+
}
9+
gen_link_user_asm().unwrap();
10+
}
11+
12+
/// Generate assembly file for linking user image
13+
fn gen_link_user_asm() -> Result<()> {
14+
let mut f = File::create("src/link_user.S").unwrap();
15+
let user_img = std::env::var("USER_IMG").unwrap();
16+
17+
writeln!(f, "# generated by build.rs - do not edit")?;
18+
writeln!(f, r#"
19+
.section .data
20+
.global _user_img_start
21+
.global _user_img_end
22+
_user_img_start:
23+
.incbin "{}"
24+
_user_img_end:
25+
"#, user_img)?;
26+
Ok(())
27+
}

os/src/consts.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ pub const PHYSICAL_MEMORY_OFFSET: usize = 0xffffffff40000000;
1313
pub const PAGE_SIZE: usize = 4096;
1414

1515
pub const KERNEL_STACK_SIZE: usize = 0x80000;
16+
17+
pub const USER_STACK_SIZE: usize = 0x80000;
18+
pub const USER_STACK_OFFSET: usize = 0xffffffff00000000;

os/src/context.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ impl Context {
4646
contextContent.tf.x[11] = args[1];
4747
contextContent.tf.x[12] = args[2];
4848
}
49-
49+
50+
pub unsafe fn new_user_thread(
51+
entry: usize,
52+
ustack_top: usize,
53+
kstack_top: usize,
54+
satp: usize
55+
) -> Self {
56+
ContextContent::new_user_thread(entry, ustack_top, satp).push_at(kstack_top)
57+
}
5058
}
5159

5260
#[repr(C)]
@@ -86,6 +94,28 @@ impl ContextContent {
8694
content
8795
}
8896

97+
fn new_user_thread(
98+
entry: usize,
99+
ustack_top: usize,
100+
satp: usize
101+
) -> Self {
102+
ContextContent {
103+
ra: __trapret as usize,
104+
satp,
105+
s: [0; 12],
106+
tf: {
107+
let mut tf: TrapFrame = unsafe { zeroed() };
108+
tf.x[2] = ustack_top;
109+
tf.sepc = entry;
110+
tf.sstatus = sstatus::read();
111+
tf.sstatus.set_spie(true);
112+
tf.sstatus.set_sie(false);
113+
tf.sstatus.set_spp(sstatus::SPP::User);
114+
tf
115+
}
116+
}
117+
}
118+
89119
unsafe fn push_at(self, stack_top: usize) -> Context {
90120
let ptr = (stack_top as *mut ContextContent).sub(1);
91121
*ptr = self;

os/src/init.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
global_asm!(include_str!("boot/entry64.asm"));
2+
global_asm!(include_str!("link_user.S"));
23

34
use crate::consts::*;
45
use crate::memory::{

os/src/interrupt.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub fn rust_trap(tf: &mut TrapFrame) {
4040
Trap::Exception(Exception::InstructionPageFault) => page_fault(tf),
4141
Trap::Exception(Exception::LoadPageFault) => page_fault(tf),
4242
Trap::Exception(Exception::StorePageFault) => page_fault(tf),
43+
Trap::Exception(Exception::UserEnvCall) => syscall(tf),
4344
_ => panic!("undefined trap!")
4445
}
4546
}
@@ -58,6 +59,16 @@ fn page_fault(tf: &mut TrapFrame) {
5859
panic!("page fault!");
5960
}
6061

62+
fn syscall(tf: &mut TrapFrame) {
63+
tf.sepc += 4;
64+
let ret = crate::syscall::syscall(
65+
tf.x[17],
66+
[tf.x[10], tf.x[11], tf.x[12]],
67+
tf
68+
);
69+
tf.x[10] = ret as usize;
70+
}
71+
6172
#[inline(always)]
6273
pub fn disable_and_store() -> usize {
6374
let sstatus: usize;

os/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ mod timer;
1818
mod consts;
1919
mod memory;
2020
mod process;
21+
mod syscall;

os/src/memory/memory_set/area.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,19 @@ impl MemoryArea {
3939
attr : attr,
4040
}
4141
}
42+
43+
pub fn page_copy(&self, pt: &mut PageTableImpl, src: usize, length: usize) {
44+
let mut l = length;
45+
let mut s = src;
46+
for page in PageRange::new(self.start, self.end) {
47+
self.handler.page_copy(
48+
pt,
49+
page,
50+
s,
51+
if l < PAGE_SIZE { l } else { PAGE_SIZE },
52+
);
53+
s += PAGE_SIZE;
54+
if l >= PAGE_SIZE { l -= PAGE_SIZE; }
55+
}
56+
}
4257
}

0 commit comments

Comments
 (0)