mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 09:26:26 +04:00
Load app from sdcard on K210, but panicked on qemu.
This commit is contained in:
parent
ea515323d3
commit
ae9eecf97b
@ -8,6 +8,5 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
spin = "0.7.0"
|
spin = "0.7.0"
|
||||||
#lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
||||||
lazy_static = "1.4.0"
|
#rand = "0.8.0"
|
||||||
rand = "0.8.0"
|
|
@ -79,6 +79,7 @@ fn easy_fs_pack() -> std::io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn efs_test() -> std::io::Result<()> {
|
fn efs_test() -> std::io::Result<()> {
|
||||||
let block_file = Arc::new(BlockFile(Mutex::new(
|
let block_file = Arc::new(BlockFile(Mutex::new(
|
||||||
@ -145,4 +146,5 @@ fn efs_test() -> std::io::Result<()> {
|
|||||||
random_str_test((12 + 128) * BLOCK_SZ);
|
random_str_test((12 + 128) * BLOCK_SZ);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
16
os/Makefile
16
os/Makefile
@ -5,6 +5,8 @@ KERNEL_ELF := target/$(TARGET)/$(MODE)/os
|
|||||||
KERNEL_BIN := $(KERNEL_ELF).bin
|
KERNEL_BIN := $(KERNEL_ELF).bin
|
||||||
KERNEL_ENTRY_PA := 0x80020000
|
KERNEL_ENTRY_PA := 0x80020000
|
||||||
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
|
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
|
||||||
|
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
|
||||||
|
SDCARD := /dev/sdb
|
||||||
|
|
||||||
# BOARD
|
# BOARD
|
||||||
BOARD ?= qemu
|
BOARD ?= qemu
|
||||||
@ -22,11 +24,19 @@ OBJCOPY := rust-objcopy --binary-architecture=riscv64
|
|||||||
# Disassembly
|
# Disassembly
|
||||||
DISASM ?= -x
|
DISASM ?= -x
|
||||||
|
|
||||||
build: $(KERNEL_BIN)
|
build: $(KERNEL_BIN) $(FS_IMG)
|
||||||
|
|
||||||
|
sdcard: $(FS_IMG)
|
||||||
|
@sudo dd if=/dev/zero of=$(SDCARD) bs=1M count=16
|
||||||
|
@sudo dd if=$(FS_IMG) of=$(SDCARD)
|
||||||
|
|
||||||
$(KERNEL_BIN): kernel
|
$(KERNEL_BIN): kernel
|
||||||
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
|
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
|
||||||
|
|
||||||
|
$(FS_IMG):
|
||||||
|
@echo "hello, world!"
|
||||||
|
@cd ../easy-fs && cargo run --release
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
@cd ../user && make build
|
@cd ../user && make build
|
||||||
@cargo build --release --features "board_$(BOARD)"
|
@cargo build --release --features "board_$(BOARD)"
|
||||||
@ -51,8 +61,8 @@ ifeq ($(BOARD),qemu)
|
|||||||
-nographic \
|
-nographic \
|
||||||
-bios $(BOOTLOADER) \
|
-bios $(BOOTLOADER) \
|
||||||
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) \
|
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) \
|
||||||
-drive file=fs.img,if=none,format=raw,id=x0 \
|
-drive file=$(FS_IMG),if=none,format=raw,id=x0 \
|
||||||
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
||||||
else
|
else
|
||||||
@cp $(BOOTLOADER) $(BOOTLOADER).copy
|
@cp $(BOOTLOADER) $(BOOTLOADER).copy
|
||||||
@dd if=$(KERNEL_BIN) of=$(BOOTLOADER).copy bs=128K seek=1
|
@dd if=$(KERNEL_BIN) of=$(BOOTLOADER).copy bs=128K seek=1
|
||||||
|
52
os/build.rs
52
os/build.rs
@ -1,56 +1,6 @@
|
|||||||
use std::io::{Result, Write};
|
static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/";
|
||||||
use std::fs::{File, read_dir};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=../user/src/");
|
println!("cargo:rerun-if-changed=../user/src/");
|
||||||
println!("cargo:rerun-if-changed={}", TARGET_PATH);
|
println!("cargo:rerun-if-changed={}", TARGET_PATH);
|
||||||
insert_app_data().unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/";
|
|
||||||
|
|
||||||
fn insert_app_data() -> Result<()> {
|
|
||||||
let mut f = File::create("src/link_app.S").unwrap();
|
|
||||||
let mut apps: Vec<_> = read_dir("../user/src/bin")
|
|
||||||
.unwrap()
|
|
||||||
.into_iter()
|
|
||||||
.map(|dir_entry| {
|
|
||||||
let mut name_with_ext = dir_entry.unwrap().file_name().into_string().unwrap();
|
|
||||||
name_with_ext.drain(name_with_ext.find('.').unwrap()..name_with_ext.len());
|
|
||||||
name_with_ext
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
apps.sort();
|
|
||||||
|
|
||||||
writeln!(f, r#"
|
|
||||||
.align 4
|
|
||||||
.section .data
|
|
||||||
.global _num_app
|
|
||||||
_num_app:
|
|
||||||
.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 "{}\n""#, app)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (idx, app) in apps.iter().enumerate() {
|
|
||||||
println!("app_{}: {}", idx, app);
|
|
||||||
writeln!(f, r#"
|
|
||||||
.section .data
|
|
||||||
.global app_{0}_start
|
|
||||||
.global app_{0}_end
|
|
||||||
.align 12
|
|
||||||
app_{0}_start:
|
|
||||||
.incbin "{2}{1}"
|
|
||||||
app_{0}_end:"#, idx, app, TARGET_PATH)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@ -16,7 +16,7 @@ pub const CLOCK_FREQ: usize = 12500000;
|
|||||||
|
|
||||||
#[cfg(feature = "board_qemu")]
|
#[cfg(feature = "board_qemu")]
|
||||||
pub const MMIO: &[(usize, usize)] = &[
|
pub const MMIO: &[(usize, usize)] = &[
|
||||||
(0x10001000, 0x10000),
|
(0x10000000, 0x10000),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(feature = "board_k210")]
|
#[cfg(feature = "board_k210")]
|
||||||
|
@ -4,11 +4,7 @@ mod sdcard;
|
|||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
use easy_fs::BlockDevice;
|
||||||
pub trait BlockDevice : Send + Sync + Any {
|
|
||||||
fn read_block(&self, block_id: usize, buf: &mut [u8]);
|
|
||||||
fn write_block(&self, block_id: usize, buf: &[u8]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "board_qemu")]
|
#[cfg(feature = "board_qemu")]
|
||||||
type BlockDeviceImpl = virtio_blk::VirtIOBlock;
|
type BlockDeviceImpl = virtio_blk::VirtIOBlock;
|
||||||
|
@ -717,7 +717,7 @@ lazy_static! {
|
|||||||
fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
|
fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
|
||||||
// wait previous output
|
// wait previous output
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
let peripherals = Peripherals::take().unwrap();
|
let peripherals = unsafe { Peripherals::steal() };
|
||||||
sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap();
|
sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap();
|
||||||
sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap();
|
sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap();
|
||||||
sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap();
|
sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap();
|
||||||
|
@ -23,9 +23,12 @@ lazy_static! {
|
|||||||
|
|
||||||
impl BlockDevice for VirtIOBlock {
|
impl BlockDevice for VirtIOBlock {
|
||||||
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
|
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
|
||||||
|
//println!("read block {}", block_id);
|
||||||
self.0.lock().read_block(block_id, buf).expect("Error when reading VirtIOBlk");
|
self.0.lock().read_block(block_id, buf).expect("Error when reading VirtIOBlk");
|
||||||
|
//println!("read block OK!");
|
||||||
}
|
}
|
||||||
fn write_block(&self, block_id: usize, buf: &[u8]) {
|
fn write_block(&self, block_id: usize, buf: &[u8]) {
|
||||||
|
//println!("write block {}", block_id);
|
||||||
self.0.lock().write_block(block_id, buf).expect("Error when writing VirtIOBlk");
|
self.0.lock().write_block(block_id, buf).expect("Error when writing VirtIOBlk");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,6 +47,7 @@ pub extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr {
|
|||||||
for i in 0..pages {
|
for i in 0..pages {
|
||||||
let frame = frame_alloc().unwrap();
|
let frame = frame_alloc().unwrap();
|
||||||
if i == 0 { ppn_base = frame.ppn; }
|
if i == 0 { ppn_base = frame.ppn; }
|
||||||
|
println!("virtio_dma_alloc {:?}", frame.ppn);
|
||||||
assert_eq!(frame.ppn.0, ppn_base.0 + i);
|
assert_eq!(frame.ppn.0, ppn_base.0 + i);
|
||||||
QUEUE_FRAMES.lock().push(frame);
|
QUEUE_FRAMES.lock().push(frame);
|
||||||
}
|
}
|
||||||
|
104
os/src/fs/inode.rs
Normal file
104
os/src/fs/inode.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use easy_fs::{
|
||||||
|
EasyFileSystem,
|
||||||
|
Inode,
|
||||||
|
};
|
||||||
|
use crate::drivers::BLOCK_DEVICE;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use lazy_static::*;
|
||||||
|
use bitflags::*;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use spin::Mutex;
|
||||||
|
|
||||||
|
pub struct OSInode {
|
||||||
|
readable: bool,
|
||||||
|
writable: bool,
|
||||||
|
inner: Mutex<OSInodeInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OSInodeInner {
|
||||||
|
offset: usize,
|
||||||
|
inode: Arc<Inode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OSInode {
|
||||||
|
pub fn new(
|
||||||
|
readable: bool,
|
||||||
|
writable: bool,
|
||||||
|
inode: Arc<Inode>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
readable,
|
||||||
|
writable,
|
||||||
|
inner: Mutex::new(OSInodeInner {
|
||||||
|
offset: 0,
|
||||||
|
inode,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn read_all(&self) -> Vec<u8> {
|
||||||
|
let mut inner = self.inner.lock();
|
||||||
|
let mut buffer = [0u8; 512];
|
||||||
|
let mut v: Vec<u8> = Vec::new();
|
||||||
|
loop {
|
||||||
|
let len = inner.inode.read_at(inner.offset, &mut buffer);
|
||||||
|
if len == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inner.offset += len;
|
||||||
|
v.extend_from_slice(&buffer[..len]);
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref ROOT_INODE: Arc<Inode> = {
|
||||||
|
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
|
||||||
|
Arc::new(EasyFileSystem::root_inode(&efs))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_apps() {
|
||||||
|
println!("/**** APPS ****");
|
||||||
|
for app in ROOT_INODE.ls() {
|
||||||
|
println!("{}", app);
|
||||||
|
}
|
||||||
|
println!("**************/")
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct OpenFlags: u32 {
|
||||||
|
const RDONLY = 0;
|
||||||
|
const WRONLY = 1 << 0;
|
||||||
|
const RDWR = 1 << 1;
|
||||||
|
const CREATE = 1 << 9;
|
||||||
|
const TRUNC = 1 << 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpenFlags {
|
||||||
|
/// Do not check validity for simplicity
|
||||||
|
/// Return (readable, writable)
|
||||||
|
pub fn read_write(&self) -> (bool, bool) {
|
||||||
|
if self.is_empty() {
|
||||||
|
(true, false)
|
||||||
|
} else if self.contains(Self::WRONLY) {
|
||||||
|
(false, true)
|
||||||
|
} else {
|
||||||
|
(true, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
|
||||||
|
let (readable, writable) = flags.read_write();
|
||||||
|
// TODO: do not support CREATE or TRUNC flags now
|
||||||
|
ROOT_INODE.find(name)
|
||||||
|
.map(|inode| {
|
||||||
|
Arc::new(OSInode::new(
|
||||||
|
readable,
|
||||||
|
writable,
|
||||||
|
inode
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
mod pipe;
|
mod pipe;
|
||||||
mod stdio;
|
mod stdio;
|
||||||
|
mod inode;
|
||||||
|
|
||||||
use crate::mm::UserBuffer;
|
use crate::mm::UserBuffer;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
|
||||||
pub trait File : Any + Send + Sync {
|
pub trait File : Any + Send + Sync {
|
||||||
|
fn readable(&self) -> bool;
|
||||||
|
fn writable(&self) -> bool;
|
||||||
fn read(&self, buf: UserBuffer) -> usize;
|
fn read(&self, buf: UserBuffer) -> usize;
|
||||||
fn write(&self, buf: UserBuffer) -> usize;
|
fn write(&self, buf: UserBuffer) -> usize;
|
||||||
fn as_any_ref(&self) -> &dyn Any;
|
fn as_any_ref(&self) -> &dyn Any;
|
||||||
@ -18,4 +21,5 @@ impl dyn File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use pipe::{Pipe, make_pipe};
|
pub use pipe::{Pipe, make_pipe};
|
||||||
pub use stdio::{Stdin, Stdout};
|
pub use stdio::{Stdin, Stdout};
|
||||||
|
pub use inode::{OSInode, open_file, OpenFlags, list_apps};
|
@ -114,8 +114,10 @@ pub fn make_pipe() -> (Arc<Pipe>, Arc<Pipe>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl File for Pipe {
|
impl File for Pipe {
|
||||||
|
fn readable(&self) -> bool { self.readable }
|
||||||
|
fn writable(&self) -> bool { self.writable }
|
||||||
fn read(&self, buf: UserBuffer) -> usize {
|
fn read(&self, buf: UserBuffer) -> usize {
|
||||||
assert_eq!(self.readable, true);
|
assert_eq!(self.readable(), true);
|
||||||
let mut buf_iter = buf.into_iter();
|
let mut buf_iter = buf.into_iter();
|
||||||
let mut read_size = 0usize;
|
let mut read_size = 0usize;
|
||||||
loop {
|
loop {
|
||||||
@ -141,7 +143,7 @@ impl File for Pipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn write(&self, buf: UserBuffer) -> usize {
|
fn write(&self, buf: UserBuffer) -> usize {
|
||||||
assert_eq!(self.writable, true);
|
assert_eq!(self.writable(), true);
|
||||||
let mut buf_iter = buf.into_iter();
|
let mut buf_iter = buf.into_iter();
|
||||||
let mut write_size = 0usize;
|
let mut write_size = 0usize;
|
||||||
loop {
|
loop {
|
||||||
|
@ -9,6 +9,8 @@ pub struct Stdin;
|
|||||||
pub struct Stdout;
|
pub struct Stdout;
|
||||||
|
|
||||||
impl File for Stdin {
|
impl File for Stdin {
|
||||||
|
fn readable(&self) -> bool { true }
|
||||||
|
fn writable(&self) -> bool { false }
|
||||||
fn read(&self, mut user_buf: UserBuffer) -> usize {
|
fn read(&self, mut user_buf: UserBuffer) -> usize {
|
||||||
assert_eq!(user_buf.len(), 1);
|
assert_eq!(user_buf.len(), 1);
|
||||||
// busy loop
|
// busy loop
|
||||||
@ -33,6 +35,8 @@ impl File for Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl File for Stdout {
|
impl File for Stdout {
|
||||||
|
fn readable(&self) -> bool { false }
|
||||||
|
fn writable(&self) -> bool { true }
|
||||||
fn read(&self, _user_buf: UserBuffer) -> usize{
|
fn read(&self, _user_buf: UserBuffer) -> usize{
|
||||||
panic!("Cannot read from stdout!");
|
panic!("Cannot read from stdout!");
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
pub fn get_num_app() -> usize {
|
|
||||||
extern "C" { fn _num_app(); }
|
|
||||||
unsafe { (_num_app as usize as *const usize).read_volatile() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_app_data(app_id: usize) -> &'static [u8] {
|
|
||||||
extern "C" { fn _num_app(); }
|
|
||||||
let num_app_ptr = _num_app as usize as *const usize;
|
|
||||||
let num_app = get_num_app();
|
|
||||||
let app_start = unsafe {
|
|
||||||
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1)
|
|
||||||
};
|
|
||||||
assert!(app_id < num_app);
|
|
||||||
unsafe {
|
|
||||||
core::slice::from_raw_parts(
|
|
||||||
app_start[app_id] as *const u8,
|
|
||||||
app_start[app_id + 1] - app_start[app_id]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn get_app_data_by_name(name: &str) -> Option<&'static [u8]> {
|
|
||||||
let num_app = get_num_app();
|
|
||||||
let app_names = app_names();
|
|
||||||
(0..num_app)
|
|
||||||
.find(|&i| app_names[i] == name)
|
|
||||||
.map(|i| get_app_data(i))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
fn app_names() -> Vec<&'static str> {
|
|
||||||
let num_app = get_num_app();
|
|
||||||
extern "C" { fn _app_names(); }
|
|
||||||
let mut start = _app_names as usize as *const u8;
|
|
||||||
let mut v = Vec::new();
|
|
||||||
unsafe {
|
|
||||||
for _ in 0..num_app {
|
|
||||||
let mut end = start;
|
|
||||||
while end.read_volatile() != '\n' as u8 {
|
|
||||||
end = end.add(1);
|
|
||||||
}
|
|
||||||
let slice = core::slice::from_raw_parts(start, end as usize - start as usize);
|
|
||||||
let str = core::str::from_utf8(slice).unwrap();
|
|
||||||
v.push(str);
|
|
||||||
// Mention that there is a extra char between names
|
|
||||||
start = end.add(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_apps() {
|
|
||||||
let apps = app_names();
|
|
||||||
println!("/**** APPS ****");
|
|
||||||
for app in apps {
|
|
||||||
println!("{}", app);
|
|
||||||
}
|
|
||||||
println!("**************/")
|
|
||||||
}
|
|
@ -17,7 +17,6 @@ mod lang_items;
|
|||||||
mod sbi;
|
mod sbi;
|
||||||
mod syscall;
|
mod syscall;
|
||||||
mod trap;
|
mod trap;
|
||||||
mod loader;
|
|
||||||
mod config;
|
mod config;
|
||||||
mod task;
|
mod task;
|
||||||
mod timer;
|
mod timer;
|
||||||
@ -26,7 +25,6 @@ mod fs;
|
|||||||
mod drivers;
|
mod drivers;
|
||||||
|
|
||||||
global_asm!(include_str!("entry.asm"));
|
global_asm!(include_str!("entry.asm"));
|
||||||
global_asm!(include_str!("link_app.S"));
|
|
||||||
|
|
||||||
fn clear_bss() {
|
fn clear_bss() {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -44,11 +42,21 @@ pub fn rust_main() -> ! {
|
|||||||
println!("[kernel] Hello, world!");
|
println!("[kernel] Hello, world!");
|
||||||
mm::init();
|
mm::init();
|
||||||
mm::remap_test();
|
mm::remap_test();
|
||||||
task::add_initproc();
|
|
||||||
trap::init();
|
trap::init();
|
||||||
trap::enable_timer_interrupt();
|
trap::enable_timer_interrupt();
|
||||||
timer::set_next_trigger();
|
timer::set_next_trigger();
|
||||||
loader::list_apps();
|
fs::list_apps();
|
||||||
|
//println!("after listing apps");
|
||||||
|
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!");
|
||||||
}
|
}
|
@ -10,6 +10,9 @@ pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if let Some(file) = &inner.fd_table[fd] {
|
if let Some(file) = &inner.fd_table[fd] {
|
||||||
|
if !file.writable() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
let file = file.clone();
|
let file = file.clone();
|
||||||
// release Task lock manually to avoid deadlock
|
// release Task lock manually to avoid deadlock
|
||||||
drop(inner);
|
drop(inner);
|
||||||
@ -30,6 +33,9 @@ pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
|
|||||||
}
|
}
|
||||||
if let Some(file) = &inner.fd_table[fd] {
|
if let Some(file) = &inner.fd_table[fd] {
|
||||||
let file = file.clone();
|
let file = file.clone();
|
||||||
|
if !file.readable() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// release Task lock manually to avoid deadlock
|
// release Task lock manually to avoid deadlock
|
||||||
drop(inner);
|
drop(inner);
|
||||||
file.read(
|
file.read(
|
||||||
|
@ -10,7 +10,11 @@ use crate::mm::{
|
|||||||
translated_str,
|
translated_str,
|
||||||
translated_refmut,
|
translated_refmut,
|
||||||
};
|
};
|
||||||
use crate::loader::get_app_data_by_name;
|
use crate::fs::{
|
||||||
|
OSInode,
|
||||||
|
open_file,
|
||||||
|
OpenFlags,
|
||||||
|
};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
pub fn sys_exit(exit_code: i32) -> ! {
|
pub fn sys_exit(exit_code: i32) -> ! {
|
||||||
@ -48,9 +52,10 @@ pub fn sys_fork() -> isize {
|
|||||||
pub fn sys_exec(path: *const u8) -> isize {
|
pub fn sys_exec(path: *const u8) -> isize {
|
||||||
let token = current_user_token();
|
let token = current_user_token();
|
||||||
let path = translated_str(token, path);
|
let path = translated_str(token, path);
|
||||||
if let Some(data) = get_app_data_by_name(path.as_str()) {
|
if let Some(app_inode) = open_file(path.as_str(), OpenFlags::RDONLY) {
|
||||||
|
let all_data = app_inode.read_all();
|
||||||
let task = current_task().unwrap();
|
let task = current_task().unwrap();
|
||||||
task.exec(data);
|
task.exec(all_data.as_slice());
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
|
@ -5,14 +5,14 @@ mod manager;
|
|||||||
mod processor;
|
mod processor;
|
||||||
mod pid;
|
mod pid;
|
||||||
|
|
||||||
use crate::loader::{get_app_data_by_name};
|
use crate::fs::{open_file, OpenFlags};
|
||||||
use switch::__switch;
|
use switch::__switch;
|
||||||
use task::{TaskControlBlock, TaskStatus};
|
use task::{TaskControlBlock, TaskStatus};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use manager::fetch_task;
|
use manager::fetch_task;
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
|
|
||||||
pub use context::TaskContext;
|
pub use context::TaskContext;
|
||||||
|
|
||||||
pub use processor::{
|
pub use processor::{
|
||||||
run_tasks,
|
run_tasks,
|
||||||
current_task,
|
current_task,
|
||||||
@ -76,9 +76,11 @@ pub fn exit_current_and_run_next(exit_code: i32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new(
|
pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new({
|
||||||
TaskControlBlock::new(get_app_data_by_name("initproc").unwrap())
|
let inode = open_file("initproc", OpenFlags::RDONLY).unwrap();
|
||||||
);
|
let v = inode.read_all();
|
||||||
|
TaskControlBlock::new(v.as_slice())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_initproc() {
|
pub fn add_initproc() {
|
||||||
|
@ -61,6 +61,7 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_tasks() {
|
pub fn run_tasks() {
|
||||||
|
println!("into Processor::run_tasks!");
|
||||||
PROCESSOR.run();
|
PROCESSOR.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user