Skip to content

Commit 99fa0b5

Browse files
wyfcyxwangrunji0408
authored andcommitted
chk-ch8-part1
1 parent 75d4ed9 commit 99fa0b5

File tree

9 files changed

+179
-0
lines changed

9 files changed

+179
-0
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
os/target
2+
usr/rust/target
23
Cargo.lock

Diff for: usr/rust/.cargo/config

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "riscv64imac-unknown-none-elf"

Diff for: usr/rust/Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "user"
3+
version = "0.1.0"
4+
authors = ["wyfcyx <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
buddy_system_allocator = "0.3"

Diff for: usr/rust/src/bin/hello_world.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
extern crate alloc;
5+
6+
#[macro_use]
7+
extern crate user;
8+
9+
#[no_mangle]
10+
pub fn main() -> usize {
11+
for _ in 0..10 {
12+
println!("Hello world! from user mode program!");
13+
}
14+
0
15+
}

Diff for: usr/rust/src/bin/model.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
extern crate alloc;
5+
6+
#[macro_use]
7+
extern crate user;
8+
9+
#[no_mangle]
10+
pub fn main() -> usize {
11+
0
12+
}

Diff for: usr/rust/src/io.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::syscall::sys_write;
2+
use core::fmt::{self, Write};
3+
4+
pub fn putchar(ch: char) {
5+
sys_write(ch as u8);
6+
}
7+
8+
pub fn puts(s: &str) {
9+
for ch in s.chars() {
10+
putchar(ch);
11+
}
12+
}
13+
14+
#[macro_export]
15+
macro_rules! print {
16+
($($arg:tt)*) => ({
17+
$crate::io::_print(format_args!($($arg)*));
18+
});
19+
}
20+
21+
#[macro_export]
22+
macro_rules! println {
23+
() => ($crate::print!("\n"));
24+
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
25+
}
26+
27+
struct Stdout;
28+
29+
impl fmt::Write for Stdout {
30+
fn write_str(&mut self, s: &str) -> fmt::Result {
31+
puts(s);
32+
Ok(())
33+
}
34+
}
35+
36+
pub fn _print(args: fmt::Arguments) {
37+
Stdout.write_fmt(args).unwrap();
38+
}

Diff for: usr/rust/src/lang_items.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use core::panic::PanicInfo;
2+
use crate::syscall::sys_exit;
3+
use core::alloc::Layout;
4+
5+
#[linkage = "weak"]
6+
#[no_mangle]
7+
fn main() -> usize {
8+
panic!("No main() linked");
9+
}
10+
11+
use crate::DYNAMIC_ALLOCATOR;
12+
13+
fn init_heap() {
14+
const HEAP_SIZE: usize = 0x1000;
15+
static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE];
16+
unsafe {
17+
DYNAMIC_ALLOCATOR.lock().init(HEAP.as_ptr() as usize, HEAP_SIZE);
18+
}
19+
}
20+
21+
#[panic_handler]
22+
fn panic(_info: &PanicInfo) -> ! {
23+
let location = _info.location().unwrap();
24+
let message = _info.message().unwrap();
25+
println!(
26+
"\nPANIC in {} at line {} \n\t{}",
27+
location.file(),
28+
location.line(),
29+
message
30+
);
31+
loop {}
32+
}
33+
34+
#[no_mangle]
35+
pub extern "C" fn _start(_args: isize, _argv: *const u8) -> ! {
36+
init_heap();
37+
sys_exit(main())
38+
}
39+
40+
#[no_mangle]
41+
pub extern fn abort() {
42+
panic!("abort");
43+
}
44+
45+
#[lang = "oom"]
46+
fn oom(_: Layout) -> ! {
47+
panic!("out of memory!");
48+
}

Diff for: usr/rust/src/lib.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![no_std]
2+
#![feature(asm)]
3+
#![feature(lang_items)]
4+
#![feature(panic_info_message)]
5+
#![feature(linkage)]
6+
7+
extern crate alloc;
8+
9+
#[macro_use]
10+
pub mod io;
11+
12+
pub mod syscall;
13+
pub mod lang_items;
14+
15+
use buddy_system_allocator::LockedHeap;
16+
17+
#[global_allocator]
18+
static DYNAMIC_ALLOCATOR: LockedHeap = LockedHeap::empty();

Diff for: usr/rust/src/syscall.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
enum SyscallId {
2+
Write = 64,
3+
Exit = 93,
4+
}
5+
6+
#[inline(always)]
7+
fn sys_call(
8+
syscall_id: SyscallId,
9+
arg0: usize,
10+
arg1: usize,
11+
arg2: usize,
12+
arg3: usize,
13+
) -> i64 {
14+
let id = syscall_id as usize;
15+
let mut ret: i64;
16+
unsafe {
17+
asm!(
18+
"ecall"
19+
: "={x10}"(ret)
20+
: "{x17}"(id), "{x10}"(arg0), "{x11}"(arg1), "{x12}"(arg2), "{x13}"(arg3)
21+
: "memory"
22+
: "volatile"
23+
);
24+
}
25+
ret
26+
}
27+
28+
pub fn sys_write(ch: u8) -> i64 {
29+
sys_call(SyscallId::Write, ch as usize, 0, 0, 0)
30+
}
31+
32+
pub fn sys_exit(code: usize) -> ! {
33+
sys_call(SyscallId::Exit, code, 0, 0, 0);
34+
loop {}
35+
}

0 commit comments

Comments
 (0)