Simple filetest passed on qemu/k210.
This commit is contained in:
parent
b68278f22e
commit
b121689d08
11 changed files with 159 additions and 24 deletions
6
easy-fs/build.rs
Normal file
6
easy-fs/build.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=../user/src/");
|
||||||
|
println!("cargo:rerun-if-changed={}", TARGET_PATH);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ KERNEL_ENTRY_PA := 0x80020000
|
||||||
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
|
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
|
||||||
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
|
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
|
||||||
SDCARD := /dev/sdb
|
SDCARD := /dev/sdb
|
||||||
|
APPS := ../user/src/bin
|
||||||
|
|
||||||
# BOARD
|
# BOARD
|
||||||
BOARD ?= qemu
|
BOARD ?= qemu
|
||||||
|
@ -33,12 +34,13 @@ sdcard: $(FS_IMG)
|
||||||
$(KERNEL_BIN): kernel
|
$(KERNEL_BIN): kernel
|
||||||
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
|
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
|
||||||
|
|
||||||
$(FS_IMG):
|
$(FS_IMG): $(APPS)
|
||||||
@echo "hello, world!"
|
@cd ../user && make build
|
||||||
@cd ../easy-fs && cargo run --release
|
@cd ../easy-fs && cargo run --release
|
||||||
|
|
||||||
|
$(APPS):
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
@cd ../user && make build
|
|
||||||
@cargo build --release --features "board_$(BOARD)"
|
@cargo build --release --features "board_$(BOARD)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -8,6 +8,9 @@ use lazy_static::*;
|
||||||
use bitflags::*;
|
use bitflags::*;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
use super::File;
|
||||||
|
use crate::mm::UserBuffer;
|
||||||
|
use core::any::Any;
|
||||||
|
|
||||||
pub struct OSInode {
|
pub struct OSInode {
|
||||||
readable: bool,
|
readable: bool,
|
||||||
|
@ -92,13 +95,67 @@ impl OpenFlags {
|
||||||
|
|
||||||
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
|
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
|
||||||
let (readable, writable) = flags.read_write();
|
let (readable, writable) = flags.read_write();
|
||||||
// TODO: do not support CREATE or TRUNC flags now
|
if flags.contains(OpenFlags::CREATE) {
|
||||||
ROOT_INODE.find(name)
|
if let Some(inode) = ROOT_INODE.find(name) {
|
||||||
.map(|inode| {
|
// clear size
|
||||||
Arc::new(OSInode::new(
|
inode.clear();
|
||||||
|
Some(Arc::new(OSInode::new(
|
||||||
readable,
|
readable,
|
||||||
writable,
|
writable,
|
||||||
inode
|
inode,
|
||||||
))
|
)))
|
||||||
})
|
} else {
|
||||||
|
// create file
|
||||||
|
ROOT_INODE.create(name)
|
||||||
|
.map(|inode| {
|
||||||
|
Arc::new(OSInode::new(
|
||||||
|
readable,
|
||||||
|
writable,
|
||||||
|
inode,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ROOT_INODE.find(name)
|
||||||
|
.map(|inode| {
|
||||||
|
if flags.contains(OpenFlags::TRUNC) {
|
||||||
|
inode.clear();
|
||||||
|
}
|
||||||
|
Arc::new(OSInode::new(
|
||||||
|
readable,
|
||||||
|
writable,
|
||||||
|
inode
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl File for OSInode {
|
||||||
|
fn readable(&self) -> bool { self.readable }
|
||||||
|
fn writable(&self) -> bool { self.writable }
|
||||||
|
fn read(&self, mut buf: UserBuffer) -> usize {
|
||||||
|
let mut inner = self.inner.lock();
|
||||||
|
let mut total_read_size = 0usize;
|
||||||
|
for slice in buf.buffers.iter_mut() {
|
||||||
|
let read_size = inner.inode.read_at(inner.offset, *slice);
|
||||||
|
if read_size == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inner.offset += read_size;
|
||||||
|
total_read_size += read_size;
|
||||||
|
}
|
||||||
|
total_read_size
|
||||||
|
}
|
||||||
|
fn write(&self, buf: UserBuffer) -> usize {
|
||||||
|
let mut inner = self.inner.lock();
|
||||||
|
let mut total_write_size = 0usize;
|
||||||
|
for slice in buf.buffers.iter() {
|
||||||
|
let write_size = inner.inode.write_at(inner.offset, *slice);
|
||||||
|
assert_eq!(write_size, slice.len());
|
||||||
|
inner.offset += write_size;
|
||||||
|
total_write_size += write_size;
|
||||||
|
}
|
||||||
|
total_write_size
|
||||||
|
}
|
||||||
|
fn as_any_ref(&self) -> &dyn Any { self }
|
||||||
}
|
}
|
|
@ -46,17 +46,7 @@ pub fn rust_main() -> ! {
|
||||||
trap::enable_timer_interrupt();
|
trap::enable_timer_interrupt();
|
||||||
timer::set_next_trigger();
|
timer::set_next_trigger();
|
||||||
fs::list_apps();
|
fs::list_apps();
|
||||||
//println!("after listing apps");
|
|
||||||
task::add_initproc();
|
task::add_initproc();
|
||||||
/*
|
|
||||||
println!("after adding initproc!");
|
|
||||||
println!("list apps again!");
|
|
||||||
fs::list_apps();
|
|
||||||
println!("test user_shell now!");
|
|
||||||
let user_shell = fs::open_file("user_shell", fs::OpenFlags::RDONLY).unwrap();
|
|
||||||
println!("user_shell size = {}", user_shell.read_all().len());
|
|
||||||
println!("before running tasks!");
|
|
||||||
*/
|
|
||||||
task::run_tasks();
|
task::run_tasks();
|
||||||
panic!("Unreachable in rust_main!");
|
panic!("Unreachable in rust_main!");
|
||||||
}
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
use crate::mm::{UserBuffer, translated_byte_buffer, translated_refmut};
|
use crate::mm::{
|
||||||
|
UserBuffer,
|
||||||
|
translated_byte_buffer,
|
||||||
|
translated_refmut,
|
||||||
|
translated_str,
|
||||||
|
};
|
||||||
use crate::task::{current_user_token, current_task};
|
use crate::task::{current_user_token, current_task};
|
||||||
use crate::fs::{make_pipe};
|
use crate::fs::{make_pipe, OpenFlags, open_file};
|
||||||
|
|
||||||
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
||||||
let token = current_user_token();
|
let token = current_user_token();
|
||||||
|
@ -46,6 +51,23 @@ pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_open(path: *const u8, flags: u32) -> isize {
|
||||||
|
let task = current_task().unwrap();
|
||||||
|
let token = current_user_token();
|
||||||
|
let path = translated_str(token, path);
|
||||||
|
if let Some(inode) = open_file(
|
||||||
|
path.as_str(),
|
||||||
|
OpenFlags::from_bits(flags).unwrap()
|
||||||
|
) {
|
||||||
|
let mut inner = task.acquire_inner_lock();
|
||||||
|
let fd = inner.alloc_fd();
|
||||||
|
inner.fd_table[fd] = Some(inode);
|
||||||
|
fd as isize
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sys_close(fd: usize) -> isize {
|
pub fn sys_close(fd: usize) -> isize {
|
||||||
let task = current_task().unwrap();
|
let task = current_task().unwrap();
|
||||||
let mut inner = task.acquire_inner_lock();
|
let mut inner = task.acquire_inner_lock();
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
const SYSCALL_OPEN: usize = 56;
|
||||||
const SYSCALL_CLOSE: usize = 57;
|
const SYSCALL_CLOSE: usize = 57;
|
||||||
const SYSCALL_PIPE: usize = 59;
|
const SYSCALL_PIPE: usize = 59;
|
||||||
const SYSCALL_READ: usize = 63;
|
const SYSCALL_READ: usize = 63;
|
||||||
|
@ -18,6 +19,7 @@ use process::*;
|
||||||
|
|
||||||
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
||||||
match syscall_id {
|
match syscall_id {
|
||||||
|
SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32),
|
||||||
SYSCALL_CLOSE => sys_close(args[0]),
|
SYSCALL_CLOSE => sys_close(args[0]),
|
||||||
SYSCALL_PIPE => sys_pipe(args[0] as *mut usize),
|
SYSCALL_PIPE => sys_pipe(args[0] as *mut usize),
|
||||||
SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
|
SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
|
||||||
|
|
|
@ -61,7 +61,6 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_tasks() {
|
pub fn run_tasks() {
|
||||||
println!("into Processor::run_tasks!");
|
|
||||||
PROCESSOR.run();
|
PROCESSOR.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,4 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
buddy_system_allocator = "0.6"
|
buddy_system_allocator = "0.6"
|
||||||
|
bitflags = "1.2.1"
|
38
user/src/bin/filetest_simple.rs
Normal file
38
user/src/bin/filetest_simple.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use user_lib::{
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
read,
|
||||||
|
write,
|
||||||
|
OpenFlags,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main() -> i32 {
|
||||||
|
let test_str = "Hello, world!";
|
||||||
|
let filea = "filea\0";
|
||||||
|
let fd = open(filea, OpenFlags::CREATE | OpenFlags::WRONLY);
|
||||||
|
assert!(fd > 0);
|
||||||
|
let fd = fd as usize;
|
||||||
|
write(fd, test_str.as_bytes());
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
let fd = open(filea, OpenFlags::RDONLY);
|
||||||
|
assert!(fd > 0);
|
||||||
|
let fd = fd as usize;
|
||||||
|
let mut buffer = [0u8; 100];
|
||||||
|
let read_len = read(fd, &mut buffer) as usize;
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
test_str,
|
||||||
|
core::str::from_utf8(&buffer[..read_len]).unwrap(),
|
||||||
|
);
|
||||||
|
println!("file_test passed!");
|
||||||
|
0
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ mod syscall;
|
||||||
mod lang_items;
|
mod lang_items;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate bitflags;
|
||||||
|
|
||||||
use syscall::*;
|
use syscall::*;
|
||||||
use buddy_system_allocator::LockedHeap;
|
use buddy_system_allocator::LockedHeap;
|
||||||
|
@ -42,6 +44,17 @@ fn main() -> i32 {
|
||||||
panic!("Cannot find main!");
|
panic!("Cannot find main!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct OpenFlags: u32 {
|
||||||
|
const RDONLY = 0;
|
||||||
|
const WRONLY = 1 << 0;
|
||||||
|
const RDWR = 1 << 1;
|
||||||
|
const CREATE = 1 << 9;
|
||||||
|
const TRUNC = 1 << 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open(path: &str, flags: OpenFlags) -> isize { sys_open(path, flags.bits) }
|
||||||
pub fn close(fd: usize) -> isize { sys_close(fd) }
|
pub fn close(fd: usize) -> isize { sys_close(fd) }
|
||||||
pub fn pipe(pipe_fd: &mut [usize]) -> isize { sys_pipe(pipe_fd) }
|
pub fn pipe(pipe_fd: &mut [usize]) -> isize { sys_pipe(pipe_fd) }
|
||||||
pub fn read(fd: usize, buf: &mut [u8]) -> isize { sys_read(fd, buf) }
|
pub fn read(fd: usize, buf: &mut [u8]) -> isize { sys_read(fd, buf) }
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
const SYSCALL_OPEN: usize = 56;
|
||||||
const SYSCALL_CLOSE: usize = 57;
|
const SYSCALL_CLOSE: usize = 57;
|
||||||
const SYSCALL_PIPE: usize = 59;
|
const SYSCALL_PIPE: usize = 59;
|
||||||
const SYSCALL_READ: usize = 63;
|
const SYSCALL_READ: usize = 63;
|
||||||
|
@ -23,6 +24,10 @@ fn syscall(id: usize, args: [usize; 3]) -> isize {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_open(path: &str, flags: u32) -> isize {
|
||||||
|
syscall(SYSCALL_OPEN, [path.as_ptr() as usize, flags as usize, 0])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sys_close(fd: usize) -> isize {
|
pub fn sys_close(fd: usize) -> isize {
|
||||||
syscall(SYSCALL_CLOSE, [fd, 0, 0])
|
syscall(SYSCALL_CLOSE, [fd, 0, 0])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue