Skip to content

Commit

Permalink
Merge pull request #1 from YdrMaster/dev-uart
Browse files Browse the repository at this point in the history
Merge
  • Loading branch information
YdrMaster authored Mar 29, 2022
2 parents 69587e8 + 91a23d3 commit 4cddebe
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 59 deletions.
10 changes: 5 additions & 5 deletions linux-object/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ zircon-object = { path = "../zircon-object", features = ["elf"] }
kernel-hal = { path = "../kernel-hal", default-features = false }
downcast-rs = { version = "1.2", default-features = false }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
cfg-if = "1.0"
smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [
"alloc",
Expand Down
2 changes: 2 additions & 0 deletions linux-object/src/fs/devfs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod fbdev;
mod input;
mod random;
mod uartdev;

pub use fbdev::FbDev;
pub use input::{EventDev, MiceDev};
pub use random::RandomINode;
pub use uartdev::UartDev;
109 changes: 109 additions & 0 deletions linux-object/src/fs/devfs/uartdev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use alloc::sync::Arc;
use core::any::Any;
use rcore_fs::vfs::{make_rdev, FileType, FsError, INode, Metadata, PollStatus, Result, Timespec};
use rcore_fs_devfs::DevFS;
use zcore_drivers::{scheme::UartScheme, DeviceError};

/// Uart device.
pub struct UartDev {
index: usize,
port: Arc<dyn UartScheme>,
inode_id: usize,
}

impl UartDev {
pub fn new(index: usize, port: Arc<dyn UartScheme>) -> Self {
Self {
index,
port,
inode_id: DevFS::new_inode_id(),
}
}
}

impl INode for UartDev {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
info!(
"uart read_at: offset={:#x} buf_len={:#x}",
offset,
buf.len()
);

let mut len = 0;
for b in buf.iter_mut() {
match self.port.try_recv() {
Ok(Some(b_)) => {
*b = b_;
len += 1;
}
Ok(None) => break,
Err(e) => return Err(convert_error(e)),
}
}
Ok(len)
}

fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
info!(
"uart write_at: offset={:#x} buf_len={:#x}",
offset,
buf.len()
);

for b in buf {
self.port.send(*b).map_err(convert_error)?;
}
Ok(buf.len())
}

fn poll(&self) -> Result<PollStatus> {
Ok(PollStatus {
// TOKNOW and TODO
read: true,
write: false,
error: false,
})
}

fn metadata(&self) -> Result<Metadata> {
Ok(Metadata {
dev: 1,
inode: self.inode_id,
size: 0,
blk_size: 0,
blocks: 0,
atime: Timespec { sec: 0, nsec: 0 },
mtime: Timespec { sec: 0, nsec: 0 },
ctime: Timespec { sec: 0, nsec: 0 },
type_: FileType::CharDevice,
mode: 0o600, // owner read & write
nlinks: 1,
uid: 0,
gid: 0,
rdev: make_rdev(4, self.index),
})
}

#[allow(unsafe_code)]
fn io_control(&self, _cmd: u32, _data: usize) -> Result<usize> {
warn!("uart ioctl unimplemented");
Ok(0)
}

fn as_any_ref(&self) -> &dyn Any {
self
}
}

fn convert_error(e: DeviceError) -> FsError {
match e {
DeviceError::NotSupported => FsError::NotSupported,
DeviceError::NotReady => FsError::Busy,
DeviceError::InvalidParam => FsError::InvalidParam,
DeviceError::BufferTooSmall
| DeviceError::DmaError
| DeviceError::IoError
| DeviceError::AlreadyExists
| DeviceError::NoResources => FsError::DeviceError,
}
}
19 changes: 15 additions & 4 deletions linux-object/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ use downcast_rs::impl_downcast;

use kernel_hal::drivers;
use rcore_fs::vfs::{FileSystem, FileType, INode, PollStatus, Result};
use rcore_fs_devfs::special::{NullINode, ZeroINode};
use rcore_fs_devfs::DevFS;
use rcore_fs_devfs::{
special::{NullINode, ZeroINode},
DevFS,
};
use rcore_fs_mountfs::MountFS;
use rcore_fs_ramfs::RamFS;
use zircon_object::{object::KernelObject, vm::VmObject};

use self::{devfs::RandomINode, pseudo::Pseudo};
use crate::error::{LxError, LxResult};
use crate::process::LinuxProcess;
use devfs::RandomINode;
use pseudo::Pseudo;

pub use file::{File, OpenFlags, SeekFrom};
pub use pipe::Pipe;
Expand Down Expand Up @@ -128,7 +131,7 @@ pub fn create_root_fs(rootfs: Arc<dyn FileSystem>) -> Arc<dyn INode> {
.expect("failed to mknod /dev/urandom");

if let Some(display) = drivers::all_display().first() {
use self::devfs::{EventDev, FbDev, MiceDev};
use devfs::{EventDev, FbDev, MiceDev};

// Add framebuffer device at `/dev/fb0`
if let Err(e) = devfs_root.add("fb0", Arc::new(FbDev::new(display.clone()))) {
Expand Down Expand Up @@ -156,6 +159,14 @@ pub fn create_root_fs(rootfs: Arc<dyn FileSystem>) -> Arc<dyn INode> {
}
}

// Add uart devices at `/dev/ttyS{i}`
for (i, uart) in drivers::all_uart().as_vec().iter().enumerate() {
let fname = format!("ttyS{}", i);
if let Err(e) = devfs_root.add(&fname, Arc::new(devfs::UartDev::new(i, uart.clone()))) {
warn!("failed to mknod /dev/{}: {:?}", &fname, e);
}
}

// mount DevFS at /dev
let dev = root.find(true, "dev").unwrap_or_else(|_| {
root.create("dev", FileType::Dir, 0o666)
Expand Down
19 changes: 14 additions & 5 deletions linux-object/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,33 @@ impl TimeSpec {
}
}

impl From<Timespec> for TimeSpec {
fn from(t: Timespec) -> Self {
Self {
sec: t.sec as _,
nsec: t.nsec as _,
}
}
}

impl From<TimeSpec> for Timespec {
fn from(t: TimeSpec) -> Self {
Timespec {
sec: t.sec as i64,
nsec: t.nsec as i32,
Self {
sec: t.sec as _,
nsec: t.nsec as _,
}
}
}

impl From<TimeSpec> for Duration {
fn from(t: TimeSpec) -> Self {
Duration::new(t.sec as u64, t.nsec as u32)
Self::new(t.sec as _, t.nsec as _)
}
}

impl From<TimeSpec> for TimeVal {
fn from(t: TimeSpec) -> Self {
TimeVal {
Self {
sec: t.sec,
usec: t.nsec / 1_000,
}
Expand Down
2 changes: 1 addition & 1 deletion linux-syscall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ static_assertions = "1.1.0"
zircon-object = { path = "../zircon-object" }
linux-object = { path = "../linux-object" }
kernel-hal = { path = "../kernel-hal", default-features = false }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
bitvec = { version = "0.22", default-features = false, features = ["alloc"] }
9 changes: 1 addition & 8 deletions linux-syscall/src/file/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,7 @@ impl Syscall<'_> {
pub fn sys_fstatfs(&self, fd: FileDesc, mut buf: UserOutPtr<StatFs>) -> SysResult {
info!("statfs: fd={:?}, buf={:?}", fd, buf);

let info = self
.linux_process()
.get_file_like(fd)?
.downcast_arc::<File>()
.map_err(|_| LxError::EBADF)?
.inode()
.fs()
.info();
let info = self.linux_process().get_file(fd)?.inode().fs().info();
buf.write(info.into())?;
Ok(0)
}
Expand Down
61 changes: 29 additions & 32 deletions linux-syscall/src/file/stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ impl Syscall<'_> {
/// - `stat_ptr` – pointer to stat buffer
pub fn sys_fstat(&self, fd: FileDesc, mut stat_ptr: UserOutPtr<Stat>) -> SysResult {
info!("fstat: fd={:?}, stat_ptr={:?}", fd, stat_ptr);
let proc = self.linux_process();
let file = proc.get_file(fd)?;
let stat = Stat::from(file.metadata()?);
stat_ptr.write(stat)?;

let meta = self.linux_process().get_file(fd)?.metadata()?;
stat_ptr.write(meta.into())?;
Ok(0)
}

Expand All @@ -48,11 +47,10 @@ impl Syscall<'_> {
dirfd, path, stat_ptr, flags
);

let proc = self.linux_process();
let follow = !flags.contains(AtFlags::SYMLINK_NOFOLLOW);
let inode = proc.lookup_inode_at(dirfd, path, follow)?;
let stat = Stat::from(inode.metadata()?);
stat_ptr.write(stat)?;
let inode = self.linux_process().lookup_inode_at(dirfd, path, follow)?;
let stat = inode.metadata()?;
stat_ptr.write(stat.into())?;
Ok(0)
}

Expand All @@ -65,21 +63,21 @@ impl Syscall<'_> {
}

#[cfg(not(target_arch = "mips"))]
use linux_object::fs::vfs::Timespec;
use linux_object::time::TimeSpec;

#[cfg(target_arch = "mips")]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Timespec {
pub struct TimeSpec {
pub sec: i32,
pub nsec: i32,
}

#[cfg(target_arch = "mips")]
impl From<linux_object::fs::vfs::Timespec> for Timespec {
fn from(t: Timespec) -> Self {
Timespec {
impl From<linux_object::fs::vfs::TimeSpec> for TimeSpec {
fn from(t: TimeSpec) -> Self {
TimeSpec {
sec: t.sec as _,
nsec: t.nsec,
nsec: t.nsec as _,
}
}
}
Expand Down Expand Up @@ -113,11 +111,11 @@ pub struct Stat {
blocks: u64,

/// last access time
atime: Timespec,
atime: TimeSpec,
/// last modification time
mtime: Timespec,
mtime: TimeSpec,
/// last status change time
ctime: Timespec,
ctime: TimeSpec,
}

#[cfg(target_arch = "mips")]
Expand Down Expand Up @@ -147,11 +145,11 @@ pub struct Stat {
size: u64,

/// last access time
atime: Timespec,
atime: TimeSpec,
/// last modification time
mtime: Timespec,
mtime: TimeSpec,
/// last status change time
ctime: Timespec,
ctime: TimeSpec,

/// blocksize for filesystem I/O
blksize: u32,
Expand Down Expand Up @@ -192,27 +190,26 @@ pub struct Stat {
blocks: u64,

/// last access time
atime: Timespec,
atime: TimeSpec,
/// last modification time
mtime: Timespec,
mtime: TimeSpec,
/// last status change time
ctime: Timespec,
ctime: TimeSpec,
}

impl From<Metadata> for Stat {
#[allow(clippy::useless_conversion)]
fn from(info: Metadata) -> Self {
Stat {
dev: info.dev as u64,
ino: info.inode as u64,
mode: StatMode::from_type_mode(info.type_, info.mode as u16),
dev: info.dev as _,
ino: info.inode as _,
mode: StatMode::from_type_mode(info.type_, info.mode as _),
nlink: info.nlinks as _,
uid: info.uid as u32,
gid: info.gid as u32,
rdev: info.rdev as u64,
size: info.size as u64,
uid: info.uid as _,
gid: info.gid as _,
rdev: info.rdev as _,
size: info.size as _,
blksize: info.blk_size as _,
blocks: info.blocks as u64,
blocks: info.blocks as _,
atime: info.atime.into(),
mtime: info.mtime.into(),
ctime: info.ctime.into(),
Expand Down
2 changes: 1 addition & 1 deletion loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ libos = ["kernel-hal/libos", "zircon-object/aspace-separate"]
[dev-dependencies]
env_logger = "0.9"
async-std = { version = "1.10", features = ["attributes"] }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc" }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" }

[[example]]
name = "linux-libos"
Expand Down
6 changes: 3 additions & 3 deletions zCore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ kernel-hal = { path = "../kernel-hal", default-features = false, features = [
zcore-loader = { path = "../loader", default-features = false }
zircon-object = { path = "../zircon-object" }
linux-object = { path = "../linux-object", optional = true }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc", optional = true }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc", optional = true }
rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b", optional = true }
rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b", optional = true }

# LibOS mode
[target.'cfg(not(target_os = "none"))'.dependencies]
async-std = { version = "1.10", optional = true }
chrono = { version = "0.4", optional = true }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1ec3cdc", optional = true }
rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b", optional = true }

# Bare-metal mode
[target.'cfg(target_os = "none")'.dependencies]
Expand Down

0 comments on commit 4cddebe

Please sign in to comment.