1
0
mirror of https://github.com/rcore-os/rCore.git synced 2025-01-19 01:07:05 +04:00

Merge branch 'dev' of github.com:rcore-os/rCore into dev

This commit is contained in:
Jackey-Huo 2019-05-03 11:40:06 +08:00
commit 6ec65b3c1d
41 changed files with 261 additions and 160 deletions

View File

@ -41,11 +41,11 @@ pub trait FrameAllocator: Debug + Clone + Send + Sync + 'static {
mod byframe;
mod delay;
mod linear;
mod file;
mod linear;
//mod swap;
pub use self::byframe::ByFrame;
pub use self::delay::Delay;
pub use self::linear::Linear;
pub use self::file::{File, Read};
pub use self::linear::Linear;

22
kernel/Cargo.lock generated
View File

@ -85,7 +85,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitvec"
version = "0.11.0"
source = "git+https://github.com/myrrlyn/bitvec.git#ed2aec38bfb5b1116e3585b1574c50655b9c85ec"
source = "git+https://github.com/myrrlyn/bitvec.git#8ab20a3e33fe068fc3a4a05eda1211d5fcc1237b"
[[package]]
name = "bootloader"
@ -102,7 +102,7 @@ dependencies = [
[[package]]
name = "buddy_system_allocator"
version = "0.1.2"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -248,11 +248,6 @@ name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "once"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "os_bootinfo"
version = "0.2.1"
@ -372,7 +367,7 @@ dependencies = [
"bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)",
"bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)",
"bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)",
"buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)",
@ -381,7 +376,6 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pc-keyboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pci 0.0.1 (git+https://github.com/rcore-os/pci-rs)",
@ -402,12 +396,15 @@ dependencies = [
[[package]]
name = "rcore-fs"
version = "0.1.0"
source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221"
source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707"
dependencies = [
"spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rcore-fs-sfs"
version = "0.1.0"
source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221"
source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707"
dependencies = [
"bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -667,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)" = "<none>"
"checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b"
"checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)" = "<none>"
"checksum buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed828f1e227d6e32b998d6375b67fd63ac5389d50b23f258ce151d22b6cc595"
"checksum buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "94a6c0143a07fea0db2f4b43cb9540dcc7c17af8a7beafdf2184e5e4e35aae91"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
@ -689,7 +686,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6"
"checksum mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4cbf449a63e4db77af9f662d6b42068c0925e779a3a7c70ad02f191cf1e6c802"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "931fb7a4cf34610cf6cbe58d52a8ca5ef4c726d4e2e178abd0dc13a6551c6d73"
"checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a"
"checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79"
"checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6"

View File

@ -50,7 +50,6 @@ opt-level = 2
[dependencies]
log = "0.4"
spin = "0.5"
once = "0.3"
xmas-elf = "0.6"
bitflags = "1.0"
bit_field = "0.9"
@ -58,7 +57,7 @@ volatile = "0.2"
heapless = "0.4"
bitvec = { git = "https://github.com/myrrlyn/bitvec.git", default-features = false, features = ["alloc"] }
console-traits = "0.3"
buddy_system_allocator = "0.1"
buddy_system_allocator = "0.3"
pci = { git = "https://github.com/rcore-os/pci-rs" }
device_tree = { git = "https://github.com/rcore-os/device_tree-rs" }
isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers" }

View File

@ -2,7 +2,6 @@
use alloc::string::String;
use bcm2837::atags::Atags;
use once::*;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
@ -18,10 +17,7 @@ pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000;
/// Initialize serial port before other initializations.
pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once");
serial::init();
println!("Hello Raspberry Pi!");
}

View File

@ -1,7 +1,6 @@
use bcm2837::mini_uart::{MiniUart, MiniUartInterruptId};
use core::fmt;
use lazy_static::lazy_static;
use once::*;
use spin::Mutex;
/// Struct to get a global SerialPort interface
@ -23,8 +22,6 @@ impl SerialPort {
/// Init a newly created SerialPort, can only be called once.
fn init(&mut self) {
assert_has_not_been_called!("SerialPort::init must be called only once");
self.mu.init();
super::irq::register_irq(super::irq::Interrupt::Aux, handle_serial_irq);
}

View File

@ -1,7 +1,6 @@
//! ARM64 drivers
use super::board;
use once::*;
pub use self::board::fb;
pub use self::board::serial;
@ -10,8 +9,6 @@ pub mod console;
/// Initialize ARM64 common drivers
pub fn init() {
assert_has_not_been_called!("driver::init must be called only once");
board::init_driver();
console::init();
}

View File

@ -1,7 +1,6 @@
use crate::drivers::bus::pci;
use alloc::string::String;
use mips::registers::cp0;
use once::*;
#[path = "../../../../drivers/console/mod.rs"]
pub mod console;
@ -17,7 +16,6 @@ use fb::FramebufferInfo;
/// Initialize serial port first
pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once");
// initialize serial driver
serial::init(0xbf000900);
// Enable serial interrupt

View File

@ -1,5 +1,4 @@
use alloc::string::String;
use once::*;
#[path = "../../../../drivers/console/mod.rs"]
pub mod console;
@ -11,7 +10,6 @@ pub mod serial;
/// Initialize serial port first
pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once");
serial::init(0xbfd003f8);
println!("Hello QEMU MIPSSIM!");
}

View File

@ -1,5 +1,4 @@
use alloc::string::String;
use once::*;
#[path = "../../../../drivers/console/mod.rs"]
pub mod console;
@ -14,7 +13,6 @@ use fb::FramebufferResult;
/// Initialize serial port first
pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once");
serial::init(0xa3000000);
println!("Hello ThinPad!");
}

View File

@ -1,7 +1,6 @@
//! mipsel drivers
use super::board;
use once::*;
pub use self::board::fb;
pub use self::board::serial;
@ -10,7 +9,6 @@ pub mod console;
/// Initialize common drivers
pub fn init() {
assert_has_not_been_called!("driver::init must be called only once");
board::init_driver();
console::init();
}

View File

@ -1,5 +1,3 @@
use once::*;
pub mod ide;
pub mod keyboard;
pub mod pic;
@ -9,8 +7,6 @@ pub mod serial;
pub mod vga;
pub fn init() {
assert_has_not_been_called!();
// Use IOAPIC instead of PIC
pic::disable();

View File

@ -1,7 +1,6 @@
// Copy from Redox
use log::*;
use once::*;
use spin::Mutex;
use x86_64::instructions::port::Port;
@ -18,8 +17,6 @@ pub fn disable() {
}
pub unsafe fn init() {
assert_has_not_been_called!("pic::init must be called only once");
let mut master = MASTER.lock();
let mut slave = SLAVE.lock();

View File

@ -1,9 +1,7 @@
use log::*;
use once::*;
use x86_64::instructions::port::Port;
pub fn init() {
assert_has_not_been_called!("pit::init must be called only once");
Pit::new(0x40).init(100);
info!("pit: init end");
}

View File

@ -1,4 +1,3 @@
use once::*;
use spin::Mutex;
use uart_16550::SerialPort;
use x86_64::instructions::port::Port;
@ -9,8 +8,6 @@ pub static COM1: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8)
pub static COM2: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x2F8) });
pub fn init() {
assert_has_not_been_called!("serial::init must be called only once");
COM1.lock().init();
COM2.lock().init();
enable_irq(consts::COM1);

View File

@ -4,12 +4,10 @@ use bitmap_allocator::BitAlloc;
use super::{BootInfo, MemoryRegionType};
use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR};
use log::*;
use once::*;
use rcore_memory::paging::*;
use rcore_memory::PAGE_SIZE;
pub fn init(boot_info: &BootInfo) {
assert_has_not_been_called!("memory::init must be called only once");
init_frame_allocator(boot_info);
init_device_vm_map();
init_heap();

View File

@ -48,8 +48,6 @@ pub fn init(_irq: Option<u32>, header: usize, size: usize) -> Arc<AHCIDriver> {
let ahci = AHCI::new(header, size);
let driver = Arc::new(AHCIDriver(Mutex::new(ahci)));
DRIVERS.write().push(driver.clone());
BLK_DRIVERS
.write()
.push(Arc::new(BlockDriver(driver.clone())));
BLK_DRIVERS.write().push(driver.clone());
driver
}

View File

@ -222,5 +222,5 @@ pub fn virtio_blk_init(node: &Node) {
let driver = Arc::new(driver);
DRIVERS.write().push(driver.clone());
BLK_DRIVERS.write().push(Arc::new(BlockDriver(driver)));
BLK_DRIVERS.write().push(driver);
}

View File

@ -5,7 +5,6 @@ use crate::drivers::{Driver, DRIVERS, NET_DRIVERS};
use crate::memory::active_table;
use alloc::collections::BTreeMap;
use alloc::sync::Arc;
use core::cmp::Ordering;
use pci::*;
use rcore_memory::{paging::PageTable, PAGE_SIZE};
use spin::Mutex;

View File

@ -4,7 +4,6 @@ use alloc::string::String;
use core::fmt;
use lazy_static::lazy_static;
use log::*;
use once::*;
use spin::Mutex;
/// Framebuffer information
@ -134,8 +133,6 @@ impl fmt::Debug for Framebuffer {
impl Framebuffer {
fn new(width: u32, height: u32, depth: u32) -> Result<Framebuffer, String> {
assert_has_not_been_called!("Framebuffer::new must be called only once");
let probed_info = super::probe_fb_info(width, height, depth);
match probed_info {

View File

@ -7,7 +7,7 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use spin::RwLock;
use crate::sync::Condvar;
use rcore_fs::dev::BlockDevice;
use rcore_fs::dev::{self, BlockDevice, DevError};
#[allow(dead_code)]
pub mod block;
@ -95,19 +95,29 @@ lazy_static! {
// NOTE: RwLock only write when initializing drivers
pub static ref DRIVERS: RwLock<Vec<Arc<Driver>>> = RwLock::new(Vec::new());
pub static ref NET_DRIVERS: RwLock<Vec<Arc<Driver>>> = RwLock::new(Vec::new());
pub static ref BLK_DRIVERS: RwLock<Vec<Arc<BlockDriver>>> = RwLock::new(Vec::new());
pub static ref BLK_DRIVERS: RwLock<Vec<Arc<Driver>>> = RwLock::new(Vec::new());
}
pub struct BlockDriver(Arc<Driver>);
pub struct BlockDriver(pub Arc<Driver>);
impl BlockDevice for BlockDriver {
const BLOCK_SIZE_LOG2: u8 = 9; // 512
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool {
self.0.read_block(block_id, buf)
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> dev::Result<()> {
match self.0.read_block(block_id, buf) {
true => Ok(()),
false => Err(DevError),
}
}
fn write_at(&self, block_id: usize, buf: &[u8]) -> bool {
self.0.write_block(block_id, buf)
fn write_at(&self, block_id: usize, buf: &[u8]) -> dev::Result<()> {
match self.0.write_block(block_id, buf) {
true => Ok(()),
false => Err(DevError),
}
}
fn sync(&self) -> dev::Result<()> {
Ok(())
}
}

View File

@ -19,34 +19,42 @@ impl MemBuf {
}
impl Device for MemBuf {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option<usize> {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
let slice = self.0.read();
let len = buf.len().min(slice.len() - offset);
buf[..len].copy_from_slice(&slice[offset..offset + len]);
Some(len)
Ok(len)
}
fn write_at(&self, offset: usize, buf: &[u8]) -> Option<usize> {
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
let mut slice = self.0.write();
let len = buf.len().min(slice.len() - offset);
slice[offset..offset + len].copy_from_slice(&buf[..len]);
Some(len)
Ok(len)
}
fn sync(&self) -> Result<()> {
Ok(())
}
}
#[cfg(target_arch = "x86_64")]
impl BlockDevice for ide::IDE {
const BLOCK_SIZE_LOG2: u8 = 9;
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool {
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> Result<()> {
use core::slice;
assert!(buf.len() >= ide::BLOCK_SIZE);
let buf =
unsafe { slice::from_raw_parts_mut(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) };
self.read(block_id as u64, 1, buf).is_ok()
self.read(block_id as u64, 1, buf).map_err(|_| DevError)?;
Ok(())
}
fn write_at(&self, block_id: usize, buf: &[u8]) -> bool {
fn write_at(&self, block_id: usize, buf: &[u8]) -> Result<()> {
use core::slice;
assert!(buf.len() >= ide::BLOCK_SIZE);
let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) };
self.write(block_id as u64, 1, buf).is_ok()
self.write(block_id as u64, 1, buf).map_err(|_| DevError)?;
Ok(())
}
fn sync(&self) -> Result<()> {
Ok(())
}
}

View File

@ -1,6 +1,7 @@
//! File handle for process
use alloc::{string::String, sync::Arc};
use core::fmt;
use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result};
@ -9,6 +10,7 @@ pub struct FileHandle {
inode: Arc<INode>,
offset: u64,
options: OpenOptions,
path: String,
}
#[derive(Debug, Clone)]
@ -27,12 +29,13 @@ pub enum SeekFrom {
}
impl FileHandle {
pub fn new(inode: Arc<INode>, options: OpenOptions) -> Self {
FileHandle {
pub fn new(inode: Arc<INode>, options: OpenOptions, path: String) -> Self {
return FileHandle {
inode,
offset: 0,
options,
}
path,
};
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
@ -121,3 +124,14 @@ impl FileHandle {
self.inode.clone()
}
}
impl fmt::Debug for FileHandle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
return f
.debug_struct("FileHandle")
.field("offset", &self.offset)
.field("options", &self.options)
.field("path", &self.path)
.finish();
}
}

View File

@ -5,6 +5,7 @@ use crate::net::Socket;
use crate::syscall::{SysError, SysResult};
use alloc::boxed::Box;
use rcore_fs::vfs::PollStatus;
use super::ioctl::*;
// TODO: merge FileLike to FileHandle ?
// TODO: fix dup and remove Clone
@ -30,13 +31,19 @@ impl FileLike {
Ok(len)
}
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
match self {
FileLike::File(file) => file.io_control(request as u32, arg1)?,
FileLike::Socket(socket) => {
socket.ioctl(request, arg1, arg2, arg3)?;
match request {
// TODO: place flags & path in FileLike in stead of FileHandle/Socket
FIOCLEX => Ok(0),
_ => {
match self {
FileLike::File(file) => file.io_control(request as u32, arg1)?,
FileLike::Socket(socket) => {
socket.ioctl(request, arg1, arg2, arg3)?;
}
}
Ok(0)
}
}
Ok(0)
}
pub fn poll(&self) -> Result<PollStatus, SysError> {
let status = match self {
@ -53,8 +60,8 @@ impl FileLike {
impl fmt::Debug for FileLike {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FileLike::File(_) => write!(f, "File"),
FileLike::Socket(_) => write!(f, "Socket"),
FileLike::File(file) => write!(f, "File({:?})", file),
FileLike::Socket(socket) => write!(f, "Socket({:?})", socket),
}
}
}

36
kernel/src/fs/ioctl.rs Normal file
View File

@ -0,0 +1,36 @@
// for IOR and IOW:
// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits
// higher 2 bits: 01 = write, 10 = read
#[cfg(not(target_arch = "mips"))]
pub const TCGETS: usize = 0x5401;
#[cfg(target_arch = "mips")]
pub const TCGETS: usize = 0x540D;
#[cfg(not(target_arch = "mips"))]
pub const TIOCGPGRP: usize = 0x540F;
// _IOR('t', 119, int)
#[cfg(target_arch = "mips")]
pub const TIOCGPGRP: usize = 0x4_004_74_77;
#[cfg(not(target_arch = "mips"))]
pub const TIOCSPGRP: usize = 0x5410;
// _IOW('t', 118, int)
#[cfg(target_arch = "mips")]
pub const TIOCSPGRP: usize = 0x8_004_74_76;
#[cfg(not(target_arch = "mips"))]
pub const TIOCGWINSZ: usize = 0x5413;
// _IOR('t', 104, struct winsize)
#[cfg(target_arch = "mips")]
pub const TIOCGWINSZ: usize = 0x4_008_74_68;
#[cfg(not(target_arch = "mips"))]
pub const FIONCLEX: usize = 0x5450;
#[cfg(target_arch = "mips")]
pub const FIOCLEX: usize = 0x6602;
#[cfg(not(target_arch = "mips"))]
pub const FIOCLEX: usize = 0x5451;
#[cfg(target_arch = "mips")]
pub const FIOCLEX: usize = 0x6601;

View File

@ -1,23 +1,24 @@
use alloc::{sync::Arc, vec::Vec};
use rcore_fs::vfs::*;
use rcore_fs::dev::block_cache::BlockCache;
use rcore_fs_sfs::SimpleFileSystem;
#[cfg(target_arch = "x86_64")]
use crate::arch::driver::ide;
use crate::drivers::BlockDriver;
pub use self::file::*;
pub use self::file_like::*;
pub use self::pipe::Pipe;
pub use self::stdio::{STDIN, STDOUT};
pub use self::pseudo::*;
pub use self::stdio::{STDIN, STDOUT};
mod device;
mod file;
mod file_like;
mod pipe;
mod stdio;
mod pseudo;
mod stdio;
mod ioctl;
/// Hard link user programs
#[cfg(feature = "link_user")]
@ -41,9 +42,15 @@ lazy_static! {
let device = {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "x86_64"))]
{
crate::drivers::BLK_DRIVERS.read().iter()
.next().expect("Block device not found")
.clone()
let driver = BlockDriver(
crate::drivers::BLK_DRIVERS
.read().iter()
.next().expect("Block device not found")
.clone()
);
// enable block cache
Arc::new(BlockCache::new(driver, 0x100))
// Arc::new(driver)
}
#[cfg(target_arch = "aarch64")]
{

View File

@ -57,7 +57,6 @@ impl Pipe {
// TODO: better way to provide default impl?
macro_rules! impl_inode {
() => {
fn poll(&self) -> Result<PollStatus> { Err(FsError::NotSupported) }
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
fn sync_all(&self) -> Result<()> { Ok(()) }
@ -104,5 +103,41 @@ impl INode for Pipe {
Ok(0)
}
}
fn poll(&self) -> Result<PollStatus> {
let data = self.data.lock();
match self.direction {
PipeEnd::Read => {
if data.buf.len() > 0 {
Ok(PollStatus {
read: true,
write: false,
error: false,
})
} else {
Ok(PollStatus {
read: false,
write: false,
error: false,
})
}
}
PipeEnd::Write => {
if data.buf.len() > 0 {
Ok(PollStatus {
read: false,
write: true,
error: false,
})
} else {
Ok(PollStatus {
read: false,
write: false,
error: false,
})
}
}
}
}
impl_inode!();
}

View File

@ -14,7 +14,7 @@ impl Pseudo {
pub fn new(s: &str, type_: FileType) -> Self {
Pseudo {
content: Vec::from(s.as_bytes()),
type_
type_,
}
}
}

View File

@ -7,6 +7,7 @@ use rcore_fs::vfs::*;
use crate::sync::Condvar;
use crate::sync::SpinNoIrqLock as Mutex;
use super::ioctl::*;
#[derive(Default)]
pub struct Stdin {
@ -37,10 +38,12 @@ impl Stdin {
}
#[cfg(not(any(feature = "board_k210", feature = "board_rocket_chip")))]
loop {
let ret = self.buf.lock().pop_front();
match ret {
let mut buf_lock = self.buf.lock();
match buf_lock.pop_front() {
Some(c) => return c,
None => self.pushed._wait(),
None => {
self.pushed.wait(buf_lock);
}
}
}
}
@ -62,32 +65,6 @@ lazy_static! {
pub static ref STDOUT: Arc<Stdout> = Arc::new(Stdout::default());
}
// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits
// higher 2 bits: 01 = write, 10 = read
#[cfg(not(target_arch = "mips"))]
const TCGETS: u32 = 0x5401;
#[cfg(target_arch = "mips")]
const TCGETS: u32 = 0x540D;
#[cfg(not(target_arch = "mips"))]
const TIOCGPGRP: u32 = 0x540F;
// _IOR('t', 119, int)
#[cfg(target_arch = "mips")]
const TIOCGPGRP: u32 = 0x4_004_74_77;
#[cfg(not(target_arch = "mips"))]
const TIOCSPGRP: u32 = 0x5410;
// _IOW('t', 118, int)
#[cfg(target_arch = "mips")]
const TIOCSPGRP: u32 = 0x8_004_74_76;
#[cfg(not(target_arch = "mips"))]
const TIOCGWINSZ: u32 = 0x5413;
// _IOR('t', 104, struct winsize)
#[cfg(target_arch = "mips")]
const TIOCGWINSZ: u32 = 0x4_008_74_68;
// TODO: better way to provide default impl?
macro_rules! impl_inode {
() => {
@ -103,7 +80,7 @@ macro_rules! impl_inode {
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
fn io_control(&self, cmd: u32, data: usize) -> Result<()> {
match cmd {
match cmd as usize {
TCGETS | TIOCGWINSZ | TIOCSPGRP => {
// pretend to be tty
Ok(())

View File

@ -18,7 +18,7 @@ extern crate log;
extern crate lazy_static;
pub use crate::process::{new_kernel_context, processor};
use buddy_system_allocator::LockedHeap;
use buddy_system_allocator::LockedHeapWithRescue;
use rcore_thread::std_thread as thread;
#[macro_use] // print!
@ -65,4 +65,5 @@ pub fn kmain() -> ! {
///
/// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod.
#[global_allocator]
static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
static HEAP_ALLOCATOR: LockedHeapWithRescue =
LockedHeapWithRescue::new(crate::memory::enlarge_heap);

View File

@ -14,14 +14,16 @@
use super::HEAP_ALLOCATOR;
pub use crate::arch::paging::*;
use crate::consts::MEMORY_OFFSET;
use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET};
use crate::process::process_unsafe;
use crate::sync::SpinNoIrqLock;
use alloc::boxed::Box;
use bitmap_allocator::BitAlloc;
use buddy_system_allocator::LockedHeap;
use buddy_system_allocator::Heap;
use lazy_static::*;
use log::*;
pub use rcore_memory::memory_set::{handler::*, MemoryArea, MemoryAttr};
use rcore_memory::paging::PageTable;
use rcore_memory::*;
pub type MemorySet = rcore_memory::memory_set::MemorySet<InactivePageTable0>;
@ -145,5 +147,37 @@ pub fn init_heap() {
info!("heap init end");
}
/// Allocator for the rest memory space on NO-MMU case.
pub static MEMORY_ALLOCATOR: LockedHeap = LockedHeap::empty();
pub fn enlarge_heap(heap: &mut Heap) {
info!("Enlarging heap to avoid oom");
let mut page_table = active_table();
let mut addrs = [(0, 0); 32];
let mut addr_len = 0;
#[cfg(target_arch = "x86_64")]
let va_offset = KERNEL_OFFSET + 0xe0000000;
#[cfg(not(target_arch = "x86_64"))]
let va_offset = KERNEL_OFFSET + 0x00e00000;
for i in 0..16384 {
let page = alloc_frame().unwrap();
let va = va_offset + page;
if addr_len > 0 {
let (ref mut addr, ref mut len) = addrs[addr_len - 1];
if *addr - PAGE_SIZE == va {
*len += PAGE_SIZE;
*addr -= PAGE_SIZE;
continue;
}
}
addrs[addr_len] = (va, PAGE_SIZE);
addr_len += 1;
}
for (addr, len) in addrs[..addr_len].into_iter() {
for va in (*addr..(*addr + *len)).step_by(PAGE_SIZE) {
page_table.map(va, va - va_offset).update();
}
info!("Adding {:#X} {:#X} to heap", addr, len);
unsafe {
heap.init(*addr, *len);
}
}
}

View File

@ -4,6 +4,7 @@ use crate::sync::SpinNoIrqLock as Mutex;
use crate::syscall::*;
use crate::util;
use alloc::boxed::Box;
use alloc::fmt::Debug;
use alloc::sync::Arc;
use alloc::vec::Vec;
use bitflags::*;
@ -50,7 +51,7 @@ pub enum Endpoint {
}
/// Common methods that a socket must have
pub trait Socket: Send + Sync {
pub trait Socket: Send + Sync + Debug {
fn read(&self, data: &mut [u8]) -> (SysResult, Endpoint);
fn write(&self, data: &[u8], sendto_endpoint: Option<Endpoint>) -> SysResult;
fn poll(&self) -> (bool, bool, bool); // (in, out, err)
@ -265,9 +266,8 @@ impl Socket for TcpSocketState {
TcpState::SynSent => {
// still connecting
drop(socket);
drop(sockets);
debug!("poll for connection wait");
SOCKET_ACTIVITY._wait();
SOCKET_ACTIVITY.wait(sockets);
}
TcpState::Established => {
break Ok(0);
@ -357,10 +357,8 @@ impl Socket for TcpSocketState {
return Ok((new_socket, Endpoint::Ip(remote_endpoint)));
}
// avoid deadlock
drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait();
SOCKET_ACTIVITY.wait(sockets);
}
}
@ -447,9 +445,8 @@ impl Socket for UdpSocketState {
);
}
// avoid deadlock
drop(socket);
SOCKET_ACTIVITY._wait()
SOCKET_ACTIVITY.wait(sockets);
}
}
@ -626,10 +623,8 @@ impl Socket for RawSocketState {
);
}
// avoid deadlock
drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait()
SOCKET_ACTIVITY.wait(sockets);
}
}

View File

@ -13,7 +13,7 @@ use xmas_elf::{
};
use crate::arch::interrupt::{Context, TrapFrame};
use crate::fs::{FileHandle, FileLike, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH};
use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH};
use crate::memory::{
ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read,
};
@ -255,6 +255,7 @@ impl Thread {
write: false,
append: false,
},
String::from("stdin"),
)),
);
files.insert(
@ -266,6 +267,7 @@ impl Thread {
write: true,
append: false,
},
String::from("stdout"),
)),
);
files.insert(
@ -277,6 +279,7 @@ impl Thread {
write: true,
append: false,
},
String::from("stderr"),
)),
);

View File

@ -1,7 +1,6 @@
//! Kernel shell
use crate::drivers::CMDLINE;
use crate::fs::{INodeExt, ROOT_INODE};
use crate::fs::ROOT_INODE;
use crate::process::*;
use alloc::string::String;
use alloc::vec::Vec;
@ -44,6 +43,7 @@ pub fn add_user_shell() {
#[cfg(feature = "run_cmdline")]
pub fn add_user_shell() {
use crate::drivers::CMDLINE;
let cmdline = CMDLINE.read();
let inode = ROOT_INODE.lookup(&cmdline).unwrap();
println!("not use the fucking up busybox");

View File

@ -15,6 +15,7 @@ impl Condvar {
}
/// Park current thread and wait for this condvar to be notified.
#[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")]
pub fn _wait(&self) {
// The condvar might be notified between adding to queue and thread parking.
// So park current thread before wait queue lock is freed.
@ -25,6 +26,7 @@ impl Condvar {
});
}
#[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")]
pub fn wait_any(condvars: &[&Condvar]) {
let token = Arc::new(thread::current());
// Avoid racing in the same way as the function above
@ -40,19 +42,23 @@ impl Condvar {
});
}
pub fn add_to_wait_queue(&self) -> MutexGuard<VecDeque<Arc<thread::Thread>>, SpinNoIrq> {
fn add_to_wait_queue(&self) -> MutexGuard<VecDeque<Arc<thread::Thread>>, SpinNoIrq> {
let mut lock = self.wait_queue.lock();
lock.push_back(Arc::new(thread::current()));
return lock;
}
/// Park current thread and wait for this condvar to be notified.
pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S>
where
S: MutexSupport,
{
let mutex = guard.mutex;
drop(guard);
self._wait();
let lock = self.add_to_wait_queue();
thread::park_action(move || {
drop(lock);
drop(guard);
});
mutex.lock()
}
@ -80,7 +86,4 @@ impl Condvar {
}
count
}
pub fn _clear(&self) {
self.wait_queue.lock().clear();
}
}

View File

@ -156,6 +156,11 @@ pub fn sys_select(
// infinity
1 << 31
};
// for debugging
if cfg!(debug_assertions) {
debug!("files before select {:#?}", proc.files);
}
drop(proc);
let begin_time_ms = crate::trap::uptime_msec();
@ -273,7 +278,13 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) ->
proc.lookup_inode_at(dir_fd, &path, true)?
};
let file = FileHandle::new(inode, flags.to_options());
let mut file = FileHandle::new(inode, flags.to_options(), String::from(path));
// for debugging
if cfg!(debug_assertions) {
debug!("files before open {:#?}", proc.files);
}
let fd = proc.add_file(FileLike::File(file));
Ok(fd)
}
@ -281,6 +292,12 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) ->
pub fn sys_close(fd: usize) -> SysResult {
info!("close: fd: {:?}", fd);
let mut proc = process();
// for debugging
if cfg!(debug_assertions) {
debug!("files before close {:#?}", proc.files);
}
proc.files.remove(&fd).ok_or(SysError::EBADF)?;
Ok(0)
}
@ -635,6 +652,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
write: false,
append: false,
},
String::from("pipe_r:[]"),
)));
let write_fd = proc.add_file(FileLike::File(FileHandle::new(
@ -644,6 +662,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult {
write: true,
append: false,
},
String::from("pipe_w:[]"),
)));
fds[0] = read_fd as u32;

View File

@ -1,4 +1,4 @@
use rcore_memory::memory_set::handler::{ByFrame, Delay, File};
use rcore_memory::memory_set::handler::{Delay, File};
use rcore_memory::memory_set::MemoryAttr;
use rcore_memory::paging::PageTable;
use rcore_memory::Page;

View File

@ -91,6 +91,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
return Err(SysError::EAGAIN);
}
// FIXME: support timeout
// FIXME: fix racing
queue._wait();
Ok(0)
}

View File

@ -31,8 +31,8 @@ mod net;
mod proc;
mod time;
use spin::Mutex;
use alloc::collections::BTreeMap;
use spin::Mutex;
#[cfg(feature = "profile")]
lazy_static! {
@ -45,9 +45,7 @@ lazy_static! {
#[deny(unreachable_patterns)]
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
#[cfg(feature = "profile")]
let begin_time = unsafe {
core::arch::x86_64::_rdtsc()
};
let begin_time = unsafe { core::arch::x86_64::_rdtsc() };
let cid = cpu::id();
let pid = process().pid.clone();
let tid = processor().tid();
@ -268,9 +266,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
}
#[cfg(feature = "profile")]
{
let end_time = unsafe {
core::arch::x86_64::_rdtsc()
};
let end_time = unsafe { core::arch::x86_64::_rdtsc() };
*SYSCALL_TIMING.lock().entry(id).or_insert(0) += end_time - begin_time;
if end_time % 1000 == 0 {
let timing = SYSCALL_TIMING.lock();

View File

@ -2,7 +2,6 @@
use super::fs::IoVecs;
use super::*;
use crate::drivers::SOCKET_ACTIVITY;
use crate::fs::FileLike;
use crate::net::{
Endpoint, LinkLevelEndpoint, NetlinkEndpoint, NetlinkSocketState, PacketSocketState,

View File

@ -120,8 +120,7 @@ pub fn sys_wait4(pid: isize, wstatus: *mut i32) -> SysResult {
target
);
let condvar = proc.child_exit.clone();
drop(proc); // must release lock of current process
condvar._wait();
condvar.wait(proc);
}
}

2
user

@ -1 +1 @@
Subproject commit 8dbc0edb935a62d748aaac39258d4a985de0ae17
Subproject commit b6a347750531be125583107b6d0fc307366fdcc9