Skip to content

Commit

Permalink
Merge pull request #1 from LearningOS/working
Browse files Browse the repository at this point in the history
Use ref implementation for os8 & fix os8-ref cargo.toml
  • Loading branch information
kxxt authored Dec 8, 2022
2 parents a427c64 + 9a442e8 commit 1e6c91c
Show file tree
Hide file tree
Showing 44 changed files with 3,938 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/chatgpt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ jobs:
name: Let chatgpt comment on your PR.
steps:
- name: ChatGPT comment
uses: kxxt/chatgpt-action@v0.2
uses: kxxt/chatgpt-action@HEAD
id: chatgpt
with:
number: ${{ github.event.pull_request.number }}
sessionToken: ${{ secrets.CHATGPT_SESSION_TOKEN }}
split: 'yolo' # Use true to enable the unstable split feature.
split: 'true' # Use true to enable the unstable split feature.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion os8-ref/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ log = "0.4"
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
lock_api = "=0.4.6"
xmas-elf = "0.7.0"
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers" }
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "93f821c" }
easy-fs = { path = "../easy-fs" }

[profile.release]
Expand Down
12 changes: 5 additions & 7 deletions os8/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,9 @@ macro_rules! println {
}
}

/*
以下代码提供了与颜色相关的 ANSI 转义字符,以及彩色输出可以使用的函数与宏。
可以使用它们,甚至扩展它们,来提升开发体验和显示效果。
*/

// 使用 ANSI 转义字符来加上颜色
/// 以下代码提供了与颜色相关的 ANSI 转义字符,以及彩色输出可以使用的函数与宏。
/// 可以使用它们,甚至扩展它们,来提升开发体验和显示效果。
/// 使用 ANSI 转义字符来加上颜色
#[macro_export]
macro_rules! colorize {
($content: ident, $foreground_color: ident) => {
Expand All @@ -66,13 +62,15 @@ pub fn print_colorized(
.unwrap();
}

/// 带色彩的 print
#[macro_export]
macro_rules! print_colorized {
($fmt: literal, $foreground_color: expr, $background_color: expr $(, $($arg: tt)+)?) => {
$crate::console::print_colorized(format_args!($fmt $(, $($arg)+)?), $foreground_color as u8, $background_color as u8);
};
}

/// 带色彩的 println
#[macro_export]
macro_rules! println_colorized {
($fmt: literal, $foreground_color: expr, $background_color: expr $(, $($arg: tt)+)?) => {
Expand Down
Empty file removed os8/src/fs/README.md
Empty file.
169 changes: 169 additions & 0 deletions os8/src/fs/inode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
use easy_fs::{
EasyFileSystem,
Inode,
};
use crate::drivers::BLOCK_DEVICE;
use crate::sync::UPSafeCell;
use alloc::sync::Arc;
use lazy_static::*;
use bitflags::*;
use alloc::vec::Vec;
use super::File;
use crate::mm::UserBuffer;

/// A wrapper around a filesystem inode
/// to implement File trait atop
pub struct OSInode {
readable: bool,
writable: bool,
inner: UPSafeCell<OSInodeInner>,
}

/// The OS inode inner in 'UPSafeCell'
pub struct OSInodeInner {
offset: usize,
inode: Arc<Inode>,
}

impl OSInode {
/// Construct an OS inode from a inode
pub fn new(
readable: bool,
writable: bool,
inode: Arc<Inode>,
) -> Self {
Self {
readable,
writable,
inner: unsafe { UPSafeCell::new(OSInodeInner {
offset: 0,
inode,
})},
}
}
/// Read all data inside a inode into vector
pub fn read_all(&self) -> Vec<u8> {
let mut inner = self.inner.exclusive_access();
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! {
/// The root of all inodes, or '/' in short
pub static ref ROOT_INODE: Arc<Inode> = {
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
Arc::new(EasyFileSystem::root_inode(&efs))
};
}

/// List all files in the filesystems
pub fn list_apps() {
println!("/**** APPS ****");
for app in ROOT_INODE.ls() {
println!("{}", app);
}
println!("**************/");
}

bitflags! {
/// Flags for opening files
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 {
/// Get the current read write permission on an inode
/// does not check validity for simplicity
/// returns (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)
}
}
}

/// Open a file by path
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
let (readable, writable) = flags.read_write();
if flags.contains(OpenFlags::CREATE) {
if let Some(inode) = ROOT_INODE.find(name) {
// clear size
inode.clear();
Some(Arc::new(OSInode::new(
readable,
writable,
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.exclusive_access();
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.exclusive_access();
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
}
}
45 changes: 45 additions & 0 deletions os8/src/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
mod stdio;
mod inode;
mod pipe;

use crate::mm::UserBuffer;

/// The common abstraction of all IO resources
pub trait File : Send + Sync {
fn readable(&self) -> bool;
fn writable(&self) -> bool;
fn read(&self, buf: UserBuffer) -> usize;
fn write(&self, buf: UserBuffer) -> usize;
}

/// The stat of a inode
#[repr(C)]
#[derive(Debug)]
pub struct Stat {
/// ID of device containing file
pub dev: u64,
/// inode number
pub ino: u64,
/// file type and mode
pub mode: StatMode,
/// number of hard links
pub nlink: u32,
/// unused pad
pad: [u64; 7],
}

bitflags! {
/// The mode of a inode
/// whether a directory or a file
pub struct StatMode: u32 {
const NULL = 0;
/// directory
const DIR = 0o040000;
/// ordinary regular file
const FILE = 0o100000;
}
}

pub use stdio::{Stdin, Stdout};
pub use inode::{OSInode, open_file, OpenFlags, list_apps};
pub use pipe::{Pipe, make_pipe};
Loading

0 comments on commit 1e6c91c

Please sign in to comment.