Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix bugs of SYS_execve that uses SYS_mmap not correctly, and add exam…
Browse files Browse the repository at this point in the history
…ple app for ELF loader.
thesayol committed May 7, 2024
1 parent 9f8e68d commit e35b067
Showing 72 changed files with 881 additions and 3,619 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@ members = [
"crates/axfs_vfs",
"crates/axio",
"crates/capability",
"crates/crate_interface",
"crates/driver_9p",
"crates/driver_block",
"crates/driver_common",
@@ -22,11 +21,8 @@ members = [
"crates/driver_virtio",
"crates/dtb",
"crates/flatten_objects",
"crates/handler_table",
"crates/kernel_guard",
"crates/lazy_init",
"crates/linked_list",
"crates/memory_addr",
"crates/page_table",
"crates/page_table_entry",
"crates/percpu",
@@ -37,7 +33,7 @@ members = [
"crates/spinlock",
"crates/timer_list",
"crates/tuple_for_each",
"crates/line_discipline",
"crates/tty",

"modules/axalloc",
"modules/axlog",
@@ -72,7 +68,3 @@ lto = true
[profile.reldebug]
inherits = "release"
debug = true


[patch.crates-io]
crate_interface = { path = "crates/crate_interface" }
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ RuxOS was inspired by [Unikraft](https://github.com/unikraft/unikraft) and [Arce
* [x] SMP scheduling with single run queue
* [x] File system
* [x] Compatible with Linux apps
* [x] Dynamically loading apps
* [ ] Interrupt driven device I/O
* [ ] Async I/O

@@ -63,6 +64,9 @@ The currently supported applications (Rust), as well as their dependent modules
| [iperf](apps/c/iperf/) | alloc, paging, net, fs, blkfs, select, fp_simd | A network performance test tool |
| [redis](apps/c/redis/) | alloc, paging, fp_simd, irq, multitask, fs, blkfs, net, pipe, epoll, poll, virtio-9p, rtc | A Redis server on Ruxos |
| [sqlite3](apps/c/sqlite3/) | alloc, paging, fs, fp_simd, blkfs | A simple test for Sqlite3 API |
| [cpp](apps/c/cpp/) | alloc, paging, irq, multitask, fs, random-hw | C++ benchmark |
| [dl](apps/c/dl/) | paging, alloc, irq, musl, multitask, fs, pipe, poll, rtc, signal, virtio-9p | An example for dynamically loading apps |


## Build & Run

4 changes: 2 additions & 2 deletions api/ruxfeat/Cargo.toml
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ irq = ["ruxhal/irq", "ruxruntime/irq", "ruxtask?/irq"]
rtc = ["ruxhal/rtc", "ruxruntime/rtc"]

# Memory
alloc = ["axalloc", "ruxruntime/alloc", "ruxfs/alloc"]
alloc = ["axalloc", "ruxruntime/alloc", "ruxfs/alloc", "ruxhal/alloc"]
alloc-tlsf = ["axalloc/tlsf"]
alloc-slab = ["axalloc/slab"]
alloc-buddy = ["axalloc/buddy"]
@@ -71,7 +71,7 @@ log-level-info = ["axlog/log-level-info"]
log-level-debug = ["axlog/log-level-debug"]
log-level-trace = ["axlog/log-level-trace"]

tty=["ruxhal/tty", "ruxruntime/tty"]
tty=["ruxhal/tty", "ruxruntime/tty", "alloc", "irq"]

[dependencies]
ruxruntime = { path = "../../modules/ruxruntime" }
8 changes: 5 additions & 3 deletions api/ruxos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ authors = [
"Shiping Yuan <robert_yuan@pku.edu.com>",
]
description = "POSIX-compatible APIs for Ruxos modules"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
repository = "https://github.com/syswonder/ruxos/tree/main/api/ruxos_posix_api"

[features]
@@ -52,18 +52,20 @@ axnet = { path = "../../modules/axnet", optional = true }
# Other crates
axio = { path = "../../crates/axio" }
axerrno = { path = "../../crates/axerrno" }
memory_addr = { path = "../../crates/memory_addr" }
memory_addr = "0.1.0"
static_assertions = "1.1.0"
spin = { version = "0.9" }
spinlock = { path = "../../crates/spinlock" }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
flatten_objects = { path = "../../crates/flatten_objects" }
page_table = { path = "../../crates/page_table" }
crate_interface = { path = "../../crates/crate_interface" }
crate_interface = "0.1.1"

cfg-if = "1.0"
elf = { version = "0.7", default-features = false }
bitflags = "2.2"

lazy_init = { path = "../../crates/lazy_init" }

[build-dependencies]
bindgen = { version = "0.66" }
15 changes: 14 additions & 1 deletion api/ruxos_posix_api/src/imp/execve/mod.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,11 @@ pub fn sys_execve(pathname: *const c_char, argv: usize, envp: usize) -> ! {

// non 8B info
stack.push(&[0u8; 32], 16);
<<<<<<< HEAD
let rand = rand();
=======
let rand = unsafe { [sys_random(), sys_random()] };
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
let p_rand = stack.push(&rand, 16);

// auxv
@@ -88,7 +92,6 @@ pub fn sys_execve(pathname: *const c_char, argv: usize, envp: usize) -> ! {
// handle envs and args
let mut env_vec = vec![];
let mut arg_vec = vec![];
let mut argc = 0;

let mut envp = envp as *const usize;
unsafe {
@@ -104,7 +107,10 @@ pub fn sys_execve(pathname: *const c_char, argv: usize, envp: usize) -> ! {
while *argv != 0 {
arg_vec.push(*argv);
argv = argv.add(1);
<<<<<<< HEAD
argc += 1;
=======
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
}
arg_vec.push(0);
}
@@ -113,7 +119,11 @@ pub fn sys_execve(pathname: *const c_char, argv: usize, envp: usize) -> ! {
stack.push(&auxv, 16);
stack.push(&env_vec, 8);
stack.push(&arg_vec, 8);
<<<<<<< HEAD
let sp = stack.push(&[argc], 8);
=======
let sp = stack.push(&[arg_vec.len() - 1], 8); // argc
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)

// try run
debug!(
@@ -148,11 +158,14 @@ fn set_sp_and_jmp(sp: usize, entry: usize) -> ! {
unreachable!("sys_execve: unknown arch, sp 0x{sp:x}, entry 0x{entry:x}");
}

<<<<<<< HEAD
/// for AT_RANDOM
fn rand() -> [i64; 2] {
unsafe { [sys_random(), sys_random()] }
}

=======
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
fn platform() -> usize {
#[cfg(target_arch = "aarch64")]
const PLATFORM_STRING: &[u8] = b"aarch64\0";
20 changes: 20 additions & 0 deletions api/ruxos_posix_api/src/imp/execve/stack.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use alloc::{vec, vec::Vec};

<<<<<<< HEAD
use ruxconfig::TASK_STACK_SIZE;

const STACK_SIZE: usize = TASK_STACK_SIZE;
=======
const STACK_SIZE: usize = ruxconfig::TASK_STACK_SIZE;
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)

#[derive(Debug)]
pub struct Stack {
@@ -20,6 +24,7 @@ impl Stack {
top: STACK_SIZE,
}
}
<<<<<<< HEAD

/// panic if overflow
fn panic_if_of(&self) {
@@ -44,6 +49,21 @@ impl Stack {
self.top = self.align(align);

self.panic_if_of();
=======

/// addr of top of stack
pub fn sp(&self) -> usize {
self.data.as_ptr() as usize + self.top
}

/// push data to stack and return the addr of sp
pub fn push<T>(&mut self, data: &[T], align: usize) -> usize {
// move sp to right place
self.top -= core::mem::size_of_val(data);
self.top = memory_addr::align_down(self.top, align);

assert!(self.top <= self.data.len(), "sys_execve: stack overflow.");
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)

// write data into stack
let sp = self.sp() as *mut T;
2 changes: 1 addition & 1 deletion api/ruxos_posix_api/src/imp/ioctl.rs
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ pub fn sys_ioctl(fd: c_int, request: usize, data: usize) -> c_int {
TIOCGPGRP => {
warn!("stdout TIOCGPGRP, pretend to be have a tty process group.");
unsafe {
*(data as *mut u32) = sys_getpgid(0)as _;
*(data as *mut u32) = sys_getpgid(0) as _;
}
Ok(0)
}
74 changes: 32 additions & 42 deletions api/ruxos_posix_api/src/imp/stdio.rs
Original file line number Diff line number Diff line change
@@ -19,60 +19,50 @@ use {
core::sync::atomic::{AtomicBool, Ordering},
};

fn console_read_bytes() -> Option<u8> {
let ret = ruxhal::console::getchar().map(|c| if c == b'\r' { b'\n' } else { c });
if let Some(c) = ret {
let _ = console_write_bytes(&[c]);
}
ret
}

fn console_write_bytes(buf: &[u8]) -> AxResult<usize> {
ruxhal::console::write_bytes(buf);
Ok(buf.len())
}
// fn console_read_bytes() -> Option<u8> {
// let ret = ruxhal::console::getchar().map(|c| if c == b'\r' { b'\n' } else { c });
// if let Some(c) = ret {
// let _ = console_write_bytes(&[c]);
// }
// ret
// }

// fn console_write_bytes(buf: &[u8]) -> AxResult<usize> {
// ruxhal::console::write_bytes(buf);
// Ok(buf.len())
// }

struct StdinRaw;
struct StdoutRaw;

#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
static STDIO_TTY_NAME: lazy_init::LazyInit<alloc::string::String> = lazy_init::LazyInit::new();
#[cfg(not(feature = "alloc"))]
static STDIO_TTY_NAME: &str = "dummy";

fn get_stdio_tty_name() -> &'static str {
#[cfg(feature = "alloc")]
{
if !STDIO_TTY_NAME.is_init() {
let name = ruxhal::get_all_device_names().first().unwrap().clone();
STDIO_TTY_NAME.init_by(name);
}
}
&STDIO_TTY_NAME
}

impl Read for StdinRaw {
// Non-blocking read, returns number of bytes read.
fn read(&mut self, buf: &mut [u8]) -> AxResult<usize> {
let names = ruxhal::get_all_device_names();

// read the first tty device
if let Some(name) = names.get(0) {
return Ok(ruxhal::tty_read(buf, name));
};

Ok(0)

// let mut read_len = 0;
// while read_len < buf.len() {
// if let Some(c) = console_read_bytes() {
// buf[read_len] = c;
// read_len += 1;
// } else {
// break;
// }
// }
// Ok(read_len)
Ok(ruxhal::tty_read(buf, get_stdio_tty_name()))
}
}

impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> AxResult<usize> {
let mut a = alloc::vec![];
for u in buf {
a.push(*u as char);
}
let names = ruxhal::get_all_device_names();
let mut len = 0;
if let Some(name) = names.get(0) {
len = ruxhal::tty_write(buf, name);
}
Ok(len)
// console_write_bytes(buf)
Ok(ruxhal::tty_write(buf, get_stdio_tty_name()))
}

fn flush(&mut self) -> AxResult {
1 change: 0 additions & 1 deletion api/ruxos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@
#![cfg_attr(all(not(test), not(doc)), no_std)]
#![feature(ip_in_core)]
#![feature(result_option_inspect)]
#![feature(doc_cfg)]
#![feature(doc_auto_cfg)]
#![allow(clippy::missing_safety_doc)]
26 changes: 26 additions & 0 deletions apps/c/dl/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
# ELF loader

<<<<<<< HEAD
> 细节请看 RuxOS 手册.
## 如何运行

1. 使用 Musl 编译 `rootfs/` 下的文件.
=======
> Read the RuxOS Book for detail.
## Quick Start

1. Compile the C files with Musl in `rootfs/`.
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
```sh
cd rootfs/
musl-gcc libadd.c -shared -o lib/libadd.so
musl-gcc hello.c -Llib -ladd -o bin/hello
```

<<<<<<< HEAD
2. 将 Musl 动态链接器放入 `rootfs/lib` 下.

3. 运行
@@ -27,5 +36,22 @@ ruxgo -b && ruxgo -r

```sh
# 在 RuxOS 目录下.
=======
2. Copy the Musl dyanmic linker to `rootfs/lib`.

3. Run

Run with `ruxgo`:

```sh
# in apps/c/dl
ruxgo -b && ruxgo -r
```

Run with `make`

```sh
# in the RuxOS main directory.
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
make run ARCH=aarch64 A=apps/c/dl V9P=y MUSL=y LOG=debug
```
7 changes: 6 additions & 1 deletion apps/c/dl/axbuild.mk
Original file line number Diff line number Diff line change
@@ -2,4 +2,9 @@ app-objs=main.o

ARGS = /bin/hello
ENVS =
V9P_PATH=${APP}/rootfs
<<<<<<< HEAD
V9P_PATH=${APP}/rootfs
=======
V9P_PATH=${APP}/rootfs
# make run ARCH=aarch64 A=apps/c/dl V9P=y MUSL=y LOG=debug
>>>>>>> 5d0b4af (fix bugs of SYS_execve that uses SYS_mmap not correctly, and add example app for ELF loader.)
2 changes: 1 addition & 1 deletion apps/c/dl/features.txt
Original file line number Diff line number Diff line change
@@ -8,4 +8,4 @@ pipe
poll
rtc
signal
virtio-9p
virtio-9p
2 changes: 1 addition & 1 deletion apps/fs/shell/Cargo.toml
Original file line number Diff line number Diff line change
@@ -13,5 +13,5 @@ default = []
[dependencies]
axfs_vfs = { path = "../../../crates/axfs_vfs", optional = true }
axfs_ramfs = { path = "../../../crates/axfs_ramfs", optional = true }
crate_interface = { path = "../../../crates/crate_interface", optional = true }
crate_interface = { version = "0.1.1", optional = true }
axstd = { path = "../../../ulib/axstd", features = ["alloc", "fs","blkfs"], optional = true }
1 change: 0 additions & 1 deletion crates/allocator/src/lib.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@
//! - [`IdAllocator`]: Used to allocate unique IDs.
#![no_std]
#![feature(result_option_inspect)]
#![cfg_attr(feature = "allocator_api", feature(allocator_api))]

#[cfg(feature = "bitmap")]
20 changes: 0 additions & 20 deletions crates/crate_interface/Cargo.toml

This file was deleted.

38 changes: 0 additions & 38 deletions crates/crate_interface/README.md

This file was deleted.

196 changes: 0 additions & 196 deletions crates/crate_interface/src/lib.rs

This file was deleted.

43 changes: 0 additions & 43 deletions crates/crate_interface/tests/test_crate_interface.rs

This file was deleted.

2 changes: 1 addition & 1 deletion crates/driver_9p/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Zheng Wu <hello_weekday@163.com>"]
description = "Common traits and types for 9p drivers"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/crates/driver_9p"

2 changes: 1 addition & 1 deletion crates/driver_display/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Shiping Yuan <robert_yuan@pku.edu.com>"]
description = "Common traits and types for graphics device drivers"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/crates/driver_display"

2 changes: 1 addition & 1 deletion crates/dtb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Leping Wang <xuehao14@126.com>"]
description = "Device tree basic operations"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/crates/dtb"

1 change: 0 additions & 1 deletion crates/flatten_objects/src/lib.rs
Original file line number Diff line number Diff line change
@@ -39,7 +39,6 @@
//! ```
#![no_std]
#![feature(const_maybe_uninit_zeroed)]
#![feature(maybe_uninit_uninit_array)]
#![feature(const_maybe_uninit_uninit_array)]

14 changes: 0 additions & 14 deletions crates/handler_table/Cargo.toml

This file was deleted.

23 changes: 0 additions & 23 deletions crates/handler_table/README.md

This file was deleted.

58 changes: 0 additions & 58 deletions crates/handler_table/src/lib.rs

This file was deleted.

20 changes: 0 additions & 20 deletions crates/kernel_guard/Cargo.toml

This file was deleted.

56 changes: 0 additions & 56 deletions crates/kernel_guard/README.md

This file was deleted.

23 changes: 0 additions & 23 deletions crates/kernel_guard/src/arch/aarch64.rs

This file was deleted.

23 changes: 0 additions & 23 deletions crates/kernel_guard/src/arch/mod.rs

This file was deleted.

27 changes: 0 additions & 27 deletions crates/kernel_guard/src/arch/riscv.rs

This file was deleted.

29 changes: 0 additions & 29 deletions crates/kernel_guard/src/arch/x86.rs

This file was deleted.

248 changes: 0 additions & 248 deletions crates/kernel_guard/src/lib.rs

This file was deleted.

315 changes: 0 additions & 315 deletions crates/line_discipline/src/buffer.rs

This file was deleted.

692 changes: 0 additions & 692 deletions crates/line_discipline/src/driver.rs

This file was deleted.

253 changes: 0 additions & 253 deletions crates/line_discipline/src/ldisc.rs

This file was deleted.

60 changes: 0 additions & 60 deletions crates/line_discipline/src/lib.rs

This file was deleted.

416 changes: 0 additions & 416 deletions crates/line_discipline/src/tty.rs

This file was deleted.

504 changes: 0 additions & 504 deletions crates/line_discipline/src/utils.rs

This file was deleted.

14 changes: 0 additions & 14 deletions crates/memory_addr/Cargo.toml

This file was deleted.

20 changes: 0 additions & 20 deletions crates/memory_addr/README.md

This file was deleted.

393 changes: 0 additions & 393 deletions crates/memory_addr/src/lib.rs

This file was deleted.

2 changes: 1 addition & 1 deletion crates/page_table/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,5 +11,5 @@ documentation = "https://rcore-os.github.io/arceos/page_table/index.html"

[dependencies]
log = "0.4"
memory_addr = { path = "../memory_addr" }
memory_addr = "0.1.0"
page_table_entry = { path = "../page_table_entry" }
1 change: 0 additions & 1 deletion crates/page_table/src/lib.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
#![no_std]
#![feature(const_trait_impl)]
#![feature(result_option_inspect)]
#![feature(doc_auto_cfg)]

#[macro_use]
2 changes: 1 addition & 1 deletion crates/page_table_entry/Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ documentation = "https://rcore-os.github.io/arceos/page_table_entry/index.html"
[dependencies]
log = "0.4"
bitflags = "2.2"
memory_addr = { path = "../memory_addr" }
memory_addr = "0.1.0"
aarch64-cpu = "9.3" # TODO: put it in [target.'cfg(target_arch = "aarch64")'.dependencies]

[target.'cfg(target_arch = "x86_64")'.dependencies]
2 changes: 1 addition & 1 deletion crates/percpu/Cargo.toml
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ default = []

[dependencies]
cfg-if = "1.0"
kernel_guard = { path = "../kernel_guard", optional = true }
kernel_guard = { version = "0.1.0", optional = true }
percpu_macros = { path = "../percpu_macros" }

[target.'cfg(target_arch = "x86_64")'.dependencies]
2 changes: 1 addition & 1 deletion crates/spinlock/Cargo.toml
Original file line number Diff line number Diff line change
@@ -16,4 +16,4 @@ default = []

[dependencies]
cfg-if = "1.0"
kernel_guard = { path = "../kernel_guard" }
kernel_guard = "0.1.0"
3 changes: 1 addition & 2 deletions crates/line_discipline/Cargo.toml → crates/tty/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
[package]
name = "line_discipline"
name = "tty"
version = "0.0.1"
edition = "2021"

[dependencies]
spin = { version = "0.9", default-features = false, features = [] }
spinlock = { path = "../spinlock" }
lazy_init = { path = "../lazy_init" }
log = "0.4"
140 changes: 140 additions & 0 deletions crates/tty/src/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//! functions for tty buffer.
//! Drivers should fill the buffer by functions below.
//! then the data will be passed to line discipline for processing.
/// tty buffer size.
const TTY_BUF_SIZE: usize = 4096;

/// ring buffer.
#[derive(Debug)]
struct RingBuffer {
/// data.
buf: [u8; TTY_BUF_SIZE],

/// the first element or empty slot if buffer is empty.
head: usize,

/// the first empty slot.
tail: usize,

/// number of elements.
len: usize,
}

/// tty buffer.
/// TODO: use flip buffer.
#[derive(Debug)]
pub struct TtyBuffer {
/// use ring buffer to save chars.
buffer: spinlock::SpinNoIrq<RingBuffer>,
}

impl TtyBuffer {
pub fn new() -> Self {
Self {
buffer: spinlock::SpinNoIrq::new(RingBuffer {
buf: [0u8; TTY_BUF_SIZE],
head: 0,
tail: 0,
len: 0,
}),
}
}

/// get `index`th element without changing buffer.
pub fn see(&self, index: usize) -> u8 {
let buf = self.buffer.lock();
if index < buf.len {
buf.buf[(index + buf.head) % TTY_BUF_SIZE]
} else {
0
}
}

/// push a char to tail.
pub fn push(&self, ch: u8) {
let mut buf = self.buffer.lock();
if buf.len != TTY_BUF_SIZE {
buf.len += 1;
let idx = buf.tail;
buf.buf[idx] = ch;
buf.tail = (buf.tail + 1) % TTY_BUF_SIZE;
}
}

/// delete and return the heading char.
pub fn pop(&self) -> u8 {
self.delete(0)
}

/// insert `ch` to `index`th position.
pub fn insert(&self, ch: u8, index: usize) {
let mut buf = self.buffer.lock();
// if not full and index is right
if buf.len != TTY_BUF_SIZE && index <= buf.len {
// shift buffer[index..move_len+index] one slot right.
let move_len = buf.len - index;
let mut i = buf.tail;
for _ in 0..move_len {
i -= 1;
buf.buf[(i + 1) % TTY_BUF_SIZE] = buf.buf[i % TTY_BUF_SIZE];
}
// insert
let idx = (buf.head + index) % TTY_BUF_SIZE;
buf.buf[idx] = ch;
buf.len += 1;
buf.tail = (buf.tail + 1) % TTY_BUF_SIZE;
}
}

/// delete and return the `index`th element.
pub fn delete(&self, index: usize) -> u8 {
let mut buf = self.buffer.lock();
// if not empty and index is right
if buf.len != 0 && index < buf.len {
let move_len = buf.len - index;
let mut i = index + buf.head;

// save retval
let ret = buf.buf[i % TTY_BUF_SIZE];

// copy move_len elements from buffer[index+head] to buffer[index+head-1];
for _ in 0..move_len {
buf.buf[i % TTY_BUF_SIZE] = buf.buf[(i + 1) % TTY_BUF_SIZE];
i += 1;
}

// len -= 1
buf.len -= 1;
buf.tail -= 1;
ret
} else {
0
}
}

/// get current length of buffer.
pub fn len(&self) -> usize {
self.buffer.lock().len
}
}

/// a buffer for echo of line discipline.
/// additionally saving the cursor position.
#[derive(Debug)]
pub struct EchoBuffer {
/// chars buffer.
pub buffer: TtyBuffer,

/// current column of cursor.
pub col: usize,
}

impl EchoBuffer {
pub fn new() -> Self {
Self {
buffer: TtyBuffer::new(),
col: 0,
}
}
}
20 changes: 20 additions & 0 deletions crates/tty/src/constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pub const LF: u8 = b'\n';
pub const CR: u8 = b'\r';

pub const DEL: u8 = b'\x7f';
pub const BS: u8 = b'\x08';

pub const SPACE: u8 = b' ';

/// escape
pub const ESC: u8 = 27;
/// [
pub const LEFT_BRACKET: u8 = 91;

/// an arrow char is `ARROW_PREFIX` + `UP/DOWN/RIGHT/LEFT`
pub const ARROW_PREFIX: [u8; 2] = [ESC, LEFT_BRACKET];

// const UP: u8 = 65;
// const DOWN: u8 = 66;
pub const RIGHT: u8 = 67;
pub const LEFT: u8 = 68;
159 changes: 159 additions & 0 deletions crates/tty/src/driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//! the first thing a driver should do is registering itself by `register_driver()`,
//! which will allocate an index for this driver.
//!
//! then, driver should register every device it has by `register_device()`,
//! which will allocate an index for this device.
use crate::tty::TtyStruct;
use alloc::string::String;
use alloc::sync::Arc;
use alloc::{vec, vec::Vec};
use lazy_init::LazyInit;
use spinlock::SpinNoIrq;

/// all tty drivers.
/// only be written when registering a driver.
pub(super) static ALL_DRIVERS: LazyInit<SpinNoIrq<Vec<Arc<TtyDriver>>>> = LazyInit::new();

/// the operations a tty driver must implement.
/// passed by driver when registering itself.
#[derive(Debug)]
pub struct TtyDriverOps {
/// push a char to device.
pub putchar: fn(u8),
}

/// tty driver.
#[derive(Debug)]
pub struct TtyDriver {
/// driver operations.
pub ops: TtyDriverOps,

/// driver's devices.
/// TODO: maybe use rwlock for dynamicly adding devices is better.
ttys: SpinNoIrq<Vec<Arc<TtyStruct>>>,

/// index of driver.
index: usize,

/// name of driver.
name: String,
}

impl TtyDriver {
pub fn new(ops: TtyDriverOps, name: &str) -> Self {
Self {
ops,
ttys: SpinNoIrq::new(vec![]),
index: 0,
name: String::from(name),
}
}

/// add a device, return its index, -1 means failure.
fn add_one_device(&self, tty: Arc<TtyStruct>) -> isize {
let index = self.ttys.lock().len();

// set index of device
tty.set_index(index);

// set name of device
let mut name = self.name.clone();
name.push(core::char::from_digit(index as _, 16).unwrap());
tty.set_name(&name);

// save this device
self.ttys.lock().push(tty);

// return device's index
index as _
}

pub fn name(&self) -> String {
self.name.clone()
}

pub fn index(&self) -> usize {
self.index
}

/// get all devices' name
pub fn get_all_device_names(&self) -> Vec<String> {
let mut ret = vec![];
for dev in self.ttys.lock().iter() {
let name = dev.name();
ret.push(name);
}
ret
}

/// get device
pub fn get_device_by_name(&self, name: &str) -> Option<Arc<TtyStruct>> {
for tty in self.ttys.lock().iter() {
if tty.name() == name {
return Some(tty.clone());
}
}
None
}

/// get device
pub fn get_device_by_index(&self, index: usize) -> Option<Arc<TtyStruct>> {
let lock = self.ttys.lock();
if let Some(dev) = lock.get(index) {
return Some(dev.clone());
}
None
}
}

pub fn init() {
ALL_DRIVERS.init_by(SpinNoIrq::new(vec![]));
}

/// get driver by index.
pub fn get_driver_by_index(index: usize) -> Option<Arc<TtyDriver>> {
let lock = ALL_DRIVERS.lock();
for driver in lock.iter() {
if driver.index == index {
return Some(driver.clone());
}
}
None
}

/// called by driver to register itself.
/// return driver's index.
pub fn register_driver(ops: TtyDriverOps, name: &str) -> usize {
// create a tty driver structure
let mut driver = TtyDriver::new(ops, name);

// lock
let mut lock = ALL_DRIVERS.lock();

// grant an index to the driver
let index = lock.len();
driver.index = index;

// push
lock.push(Arc::new(driver));

// return index
index
}

/// called by driver to register device.
/// return device's index, or -1 on failure.
pub fn register_device(driver_index: usize) -> isize {
let mut index = -1;
// if driver is found
if let Some(driver) = get_driver_by_index(driver_index) {
// create a tty structure
let tty = Arc::new(TtyStruct::new(driver.clone()));

// save this structure
index = driver.add_one_device(tty.clone());
crate::tty::add_one_device(tty.clone());
}
index
}
212 changes: 212 additions & 0 deletions crates/tty/src/ldisc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
//! TTY line discipline process all incoming and outgoing chars from/to a tty device.
//! the currently implemented line discipline is N_TTY.
//! line disciplines are registered when a device is registered.
use alloc::sync::Arc;
use spinlock::SpinNoIrq;

use crate::{
buffer::{EchoBuffer, TtyBuffer},
tty::TtyStruct,
};

/// tty line discipline.
#[derive(Debug)]
pub struct TtyLdisc {
/// chars that can be read by kernel.
read_buf: TtyBuffer,

/// chars being echoed on the screen.
echo_buf: SpinNoIrq<EchoBuffer>,

/// chars from driver, and not yet been processed.
rec_buf: TtyBuffer,
}

/// implement N_TTY.
impl TtyLdisc {
pub fn new() -> Self {
Self {
read_buf: TtyBuffer::new(),
echo_buf: SpinNoIrq::new(EchoBuffer::new()),
rec_buf: TtyBuffer::new(),
}
}

/// kernel reads data.
pub fn read(&self, buf: &mut [u8]) -> usize {
let read_buf = &self.read_buf;

// len of this reading
let len = buf.len().min(read_buf.len());

// return if nothing can be read
if len == 0 {
return 0;
}

// copy data from read_buf to `buf`
for ch in buf.iter_mut().take(len) {
*ch = read_buf.pop();
}

len
}

/// driver sends data from device for processing and echoing.
/// running in irq.
pub fn receive_buf(&self, tty: Arc<TtyStruct>, buf: &[u8]) {
use crate::constant::*;

let rec_buf = &self.rec_buf;

// save data to receive buffer
for ch in buf {
rec_buf.push(*ch);
}

// process chars in receive buffer
while rec_buf.len() > 0 {
let ch = rec_buf.see(0);

// if char may be arrow char
if ch == ARROW_PREFIX[0] {
// no enough len, just break, waitting for next time
if rec_buf.len() < 3 {
break;
}

// enough len, but not a arrow char, just ignore
if rec_buf.see(1) != ARROW_PREFIX[1] {
rec_buf.pop();
rec_buf.pop();
break;
}

// it is an arrow char, get it
rec_buf.pop();
rec_buf.pop();
let ch = rec_buf.pop();

// deal with arrow char
match ch {
LEFT => {
let mut lock = self.echo_buf.lock();
// if can go left
if lock.col > 0 {
self.write(tty.clone(), &[ARROW_PREFIX[0], ARROW_PREFIX[1], ch]);
lock.col -= 1;
}
}
RIGHT => {
let mut lock = self.echo_buf.lock();
// if can go right
if lock.col < lock.buffer.len() {
self.write(tty.clone(), &[ARROW_PREFIX[0], ARROW_PREFIX[1], ch]);
lock.col += 1;
}
}
_ => {
// it is UP/DOWN, just ignore
}
}
// not a arrow char, handle it as a normal char
} else {
let ch = rec_buf.pop();
match ch {
CR | LF => {
// always '\n'
let ch = LF;

// echo
self.write(tty.clone(), &[ch]);

// push this char to echo buffer
let mut lock = self.echo_buf.lock();
lock.buffer.push(ch);

// copy echo buffer to read buffer
// FIXME: currently will push all data to read_buf
let len = lock.buffer.len();
for _ in 0..len {
self.read_buf.push(lock.buffer.pop());
}

// echo buffer's column is set to 0
lock.col = 0;
}
BS | DEL => {
let mut lock = self.echo_buf.lock();
let col = lock.col;
let len = lock.buffer.len();
// if can delete
if col > 0 {
// perform a backspace
self.write(tty.clone(), &[BS, SPACE, BS]);

// if cursor is not on the rightmost
if col != len {
for i in col..len {
let ch = lock.buffer.see(i);
self.write(tty.clone(), &[ch]);
}
self.write(tty.clone(), &[SPACE]);
for _ in 0..(len - col + 1) {
self.write(
tty.clone(),
&[ARROW_PREFIX[0], ARROW_PREFIX[1], LEFT],
);
}
}

// modify echo buffer
lock.buffer.delete(col - 1);
lock.col -= 1;
}
}
_ => {
// process normal chars.
let mut echo_buf = self.echo_buf.lock();
let col = echo_buf.col;
let len = echo_buf.buffer.len();

// echo
self.write(tty.clone(), &[ch]);

// if cursor is not on the rightmost
if col != len {
for i in col..len {
self.write(tty.clone(), &[echo_buf.buffer.see(i)]);
}
for _ in 0..(len - col) {
self.write(tty.clone(), &[ARROW_PREFIX[0], ARROW_PREFIX[1], LEFT]);
}
}

// modify echo buffer
echo_buf.buffer.insert(ch, col);
echo_buf.col += 1;
}
}
}
}
}

/// kernel writes data to device.
pub fn write(&self, tty: Arc<TtyStruct>, buf: &[u8]) -> usize {
let mut len = 0;
let driver = tty.driver();
for ch in buf {
len += 1;
// call driver's method
(driver.ops.putchar)(*ch);
}
len
}
}

impl Default for TtyLdisc {
fn default() -> Self {
Self::new()
}
}
63 changes: 63 additions & 0 deletions crates/tty/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//! Init
//!
//! firstly, a driver registers itself to get its index.
//! next, the driver registers all devices it found to get their indices.
//!
//! Read
//!
//! when a device receives data, it will cause a irq.
//! then the driver sends the data to tty layer using their indices.
//! finally, kernel will get the data using the device's name.
//!
//! Write
//!
//! kernel writes data to a device using its name.
#![no_std]

extern crate alloc;

mod buffer;
mod constant;
mod driver;
mod ldisc;
mod tty;

use driver::get_driver_by_index;

pub use driver::{register_device, register_driver, TtyDriverOps};
pub use tty::{get_all_device_names, get_device_by_name};

/// called by driver when irq, to send data from hardware.
pub fn tty_receive_buf(driver_index: usize, device_index: usize, buf: &[u8]) {
// check the validation of index
if let Some(driver) = get_driver_by_index(driver_index) {
if let Some(tty) = driver.get_device_by_index(device_index) {
tty.ldisc().receive_buf(tty.clone(), buf);
}
}
}

/// called by kernel to read a tty device.
pub fn tty_read(buf: &mut [u8], dev_name: &str) -> usize {
if let Some(tty) = get_device_by_name(dev_name) {
tty.ldisc().read(buf)
} else {
0
}
}

/// called by kernel to write a tty device.
pub fn tty_write(buf: &[u8], dev_name: &str) -> usize {
if let Some(tty) = get_device_by_name(dev_name) {
tty.ldisc().write(tty.clone(), buf)
} else {
0
}
}

/// init
pub fn init() {
driver::init();
tty::init();
}
95 changes: 95 additions & 0 deletions crates/tty/src/tty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use core::sync::atomic::AtomicUsize;

use alloc::{string::String, sync::Arc, vec, vec::Vec};
use lazy_init::LazyInit;
use spinlock::SpinNoIrq;

use crate::{driver::TtyDriver, ldisc::TtyLdisc};

/// all registered devices.
pub(super) static ALL_DEVICES: LazyInit<SpinNoIrq<Vec<Arc<TtyStruct>>>> = LazyInit::new();

/// tty device.
#[derive(Debug)]
pub struct TtyStruct {
/// driver of device.
driver: Arc<TtyDriver>,

/// device's line discipline.
ldisc: Arc<TtyLdisc>,

/// index of device.
index: AtomicUsize,

/// name of device.
name: SpinNoIrq<String>,
}

impl TtyStruct {
pub fn new(driver: Arc<TtyDriver>) -> Self {
Self {
driver: driver.clone(),
ldisc: Arc::new(TtyLdisc::new()),
index: AtomicUsize::new(0),
name: SpinNoIrq::new(String::new()),
}
}

/// get tty line discipline.
pub fn ldisc(&self) -> Arc<TtyLdisc> {
self.ldisc.clone()
}

/// set device index.
pub fn set_index(&self, index: usize) {
self.index
.store(index, core::sync::atomic::Ordering::Relaxed);
}

/// set name of device
pub fn set_name(&self, name: &str) {
let mut lock = self.name.lock();
lock.clone_from(&String::from(name));
}

/// Convert a tty structure into a name, reflecting the kernel naming policy.
pub fn name(&self) -> String {
self.name.lock().clone()
}

/// get device's driver.
pub fn driver(&self) -> Arc<TtyDriver> {
self.driver.clone()
}
}

/// called by kernel to get a device.
pub fn get_device_by_name(name: &str) -> Option<Arc<TtyStruct>> {
let lock = ALL_DEVICES.lock();
for tty in lock.iter() {
if tty.name() == name {
return Some(tty.clone());
}
}
None
}

/// called by kernel to get all devices' names.
/// usually used in init to get the view of tty.
pub fn get_all_device_names() -> Vec<String> {
let mut ret = vec![];
let alldev = ALL_DEVICES.lock();
for dev in alldev.iter() {
ret.push(dev.name());
}
ret
}

/// save a device when registered.
pub fn add_one_device(tty: Arc<TtyStruct>) {
ALL_DEVICES.lock().push(tty);
}

pub fn init() {
ALL_DEVICES.init_by(SpinNoIrq::new(vec![]));
}
4 changes: 0 additions & 4 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
* [axfs_vfs](../crates/axfs_vfs): Virtual filesystem interfaces used by Ruxos.
* [axio](../crates/axio): `std::io`-like I/O traits for `no_std` environment.
* [capability](../crates/capability): Provide basic capability-based security.
* [crate_interface](../crates/crate_interface): Provides a way to define an interface (trait) in a crate, but can implement or use it in any crate. [![Crates.io](https://img.shields.io/crates/v/crate_interface)](https://crates.io/crates/crate_interface)
* [driver_9p](../crates/driver_9p/): Basic 9pfs operation traits for 9p protocol drivers.
* [driver_block](../crates/driver_block): Common traits and types for block storage drivers.
* [driver_common](../crates/driver_common): Device driver interfaces used by Ruxos.
@@ -37,11 +36,8 @@
* [driver_pci](../crates/driver_pci): Structures and functions for PCI bus operations.
* [driver_virtio](../crates/driver_virtio): Wrappers of some devices in the `virtio-drivers` crate, that implement traits in the `driver_common` series crates.
* [flatten_objects](../crates/flatten_objects): A container that stores numbered objects. Each object can be assigned with a unique ID.
* [handler_table](../crates/handler_table): A lock-free table of event handlers. [![Crates.io](https://img.shields.io/crates/v/handler_table)](https://crates.io/crates/handler_table)
* [kernel_guard](../crates/kernel_guard): RAII wrappers to create a critical section with local IRQs or preemption disabled. [![Crates.io](https://img.shields.io/crates/v/kernel_guard)](https://crates.io/crates/kernel_guard)
* [lazy_init](../crates/lazy_init): A wrapper for lazy initialized values without concurrency safety but more efficient.
* [linked_list](../crates/linked_list): Linked lists that supports arbitrary removal in constant time.
* [memory_addr](../crates/memory_addr): Wrappers and helper functions for physical and virtual addresses. [![Crates.io](https://img.shields.io/crates/v/memory_addr)](https://crates.io/crates/memory_addr)
* [page_table](../crates/page_table): Generic page table structures for various hardware architectures.
* [page_table_entry](../crates/page_table_entry): Page table entry definition for various hardware architectures.
* [percpu](../crates/percpu): Define and access per-CPU data structures.
2 changes: 1 addition & 1 deletion modules/axalloc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -19,6 +19,6 @@ buddy = ["allocator/buddy"]
log = "0.4"
cfg-if = "1.0"
spinlock = { path = "../../crates/spinlock" }
memory_addr = { path = "../../crates/memory_addr" }
memory_addr = "0.1.0"
allocator = { path = "../../crates/allocator", features = ["bitmap"] }
axerrno = { path = "../../crates/axerrno" }
2 changes: 1 addition & 1 deletion modules/axlog/Cargo.toml
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ default = []
cfg-if = "1.0"
log = "0.4"
spinlock = { path = "../../crates/spinlock" }
crate_interface = { path = "../../crates/crate_interface" }
crate_interface = { version = "0.1.1" }
chrono = { version = "0.4", optional = true }

[dev-dependencies]
2 changes: 1 addition & 1 deletion modules/rux9p/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Zheng Wu <hello_weekday@163.com>"]
description = "RuxOS Plan-9 filesystem module"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/modules/rux9p"

2 changes: 1 addition & 1 deletion modules/ruxdisplay/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Shiping Yuan <robert_yuan@pku.edu.com>"]
description = "Ruxos graphics module"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/modules/ruxdisplay"

4 changes: 2 additions & 2 deletions modules/ruxfs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -38,9 +38,9 @@ axfs_devfs = { path = "../../crates/axfs_devfs", optional = true }
axfs_ramfs = { path = "../../crates/axfs_ramfs", optional = true }
ruxdriver = { path = "../ruxdriver", features = ["block"] }
axsync = { path = "../axsync" }
crate_interface = { path = "../../crates/crate_interface", optional = true }
crate_interface = { version = "0.1.1", optional = true }
axalloc = { path = "../axalloc", optional = true }
memory_addr = { path = "../../crates/memory_addr" }
memory_addr = "0.1.0"

[dependencies.fatfs]
git = "https://github.com/rafalh/rust-fatfs"
3 changes: 0 additions & 3 deletions modules/ruxfs/src/mounts.rs
Original file line number Diff line number Diff line change
@@ -18,16 +18,13 @@ use crate::fs;
pub(crate) fn devfs() -> Arc<fs::devfs::DeviceFileSystem> {
let null = fs::devfs::NullDev;
let zero = fs::devfs::ZeroDev;
let bar = fs::devfs::ZeroDev;
let random = fs::devfs::RandomDev;
let urandom = fs::devfs::RandomDev;
let devfs = fs::devfs::DeviceFileSystem::new();
let foo_dir = devfs.mkdir("foo");
devfs.add("null", Arc::new(null));
devfs.add("zero", Arc::new(zero));
devfs.add("random", Arc::new(random));
devfs.add("urandom", Arc::new(urandom));
foo_dir.add("bar", Arc::new(bar));
Arc::new(devfs)
}

6 changes: 5 additions & 1 deletion modules/ruxfs/src/root.rs
Original file line number Diff line number Diff line change
@@ -162,7 +162,11 @@ impl VfsNodeOps for RootDirectory {
}

pub(crate) fn init_rootfs(mount_points: Vec<MountPoint>) {
let main_fs = mount_points.get(0).expect("No filesystem found").fs.clone();
let main_fs = mount_points
.first()
.expect("No filesystem found")
.fs
.clone();
let mut root_dir = RootDirectory::new(main_fs);

for mp in mount_points.iter().skip(1) {
9 changes: 0 additions & 9 deletions modules/ruxfs/tests/test_common/mod.rs
Original file line number Diff line number Diff line change
@@ -217,14 +217,6 @@ fn test_devfs_ramfs() -> Result<()> {
assert!(!md.is_file());
assert!(md.is_dir());

// stat /dev/foo/bar
let fname = ".//.///././/./dev///.///./foo//././bar";
let file = File::open(fname)?;
let md = file.metadata()?;
println!("metadata of {:?}: {:?}", fname, md);
assert_eq!(md.file_type(), FileType::CharDevice);
assert!(!md.is_dir());

// error cases
assert_err!(fs::metadata("/dev/null/"), NotADirectory);
assert_err!(fs::create_dir("dev"), AlreadyExists);
@@ -242,7 +234,6 @@ fn test_devfs_ramfs() -> Result<()> {
assert_eq!(fs::write(".///dev//..//233//.///test.txt", "test"), Ok(()));
assert_err!(fs::remove_file("./dev//../..//233//.///test.txt"), NotFound);
assert_eq!(fs::remove_file("./dev//..//233//../233/./test.txt"), Ok(()));
assert_eq!(fs::remove_dir("dev//foo/../foo/../.././/233"), Ok(()));
assert_err!(fs::remove_dir("very/../dev//"), PermissionDenied);

// tests in /tmp
6 changes: 3 additions & 3 deletions modules/ruxfutex/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Zhi Zhou <saltyfish2233@gmail.com>"]
description = "Ruxos futex implementation"
license = "GPL-3.0-or-later OR Apache-2.0"
license = "Mulan PSL v2"
homepage = "https://github.com/syswonder/ruxos"
repository = "https://github.com/syswonder/ruxos/tree/main/modules/ruxfutex"

@@ -15,7 +15,7 @@ default = []
irq = ["ruxtask/irq"]

[dependencies]
# Ruxos modules
# RuxOS modules
axerrno = { path = "../../crates/axerrno" }

ruxconfig = { path = "../ruxconfig" }
@@ -30,4 +30,4 @@ ahash = { version = "0.8.7", default-features = false, features = [
] }

[dev-dependencies]
memory_addr = { path = "../../crates/memory_addr" }
memory_addr = "0.1.0"
11 changes: 5 additions & 6 deletions modules/ruxhal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ rtc = []
tls = ["alloc"]
default = []
musl = []
tty = ["line_discipline", "irq"]

[dependencies]
log = "0.4"
@@ -32,17 +31,17 @@ embedded-hal = "0.2.7"
axlog = { path = "../axlog" }
ruxconfig = { path = "../ruxconfig" }
axalloc = { path = "../axalloc", optional = true }
kernel_guard = { path = "../../crates/kernel_guard" }
kernel_guard = "0.1.0"
spinlock = { path = "../../crates/spinlock" }
ratio = { path = "../../crates/ratio" }
lazy_init = { path = "../../crates/lazy_init" }
page_table = { path = "../../crates/page_table", optional = true }
page_table_entry = { path = "../../crates/page_table_entry" }
percpu = { path = "../../crates/percpu" }
memory_addr = { path = "../../crates/memory_addr" }
handler_table = { path = "../../crates/handler_table" }
crate_interface = { path = "../../crates/crate_interface" }
line_discipline = { path = "../../crates/line_discipline", optional = true }
memory_addr = "0.1.0"
handler_table = "0.1.0"
crate_interface = "0.1.1"
tty = { path = "../../crates/tty", optional = true }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86 = "0.52"
12 changes: 8 additions & 4 deletions modules/ruxhal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@
#![no_std]
#![feature(asm_const)]
#![feature(naked_functions)]
#![feature(const_maybe_uninit_zeroed)]
#![feature(const_option)]
#![feature(doc_auto_cfg)]

@@ -96,6 +95,8 @@ pub use self::platform::platform_init_secondary;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub static mut COMLINE_BUF: [u8; 256] = [0; 256];

#[allow(unused)]
/// read a tty device specified by its name.
pub fn tty_read(buf: &mut [u8], dev_name: &str) -> usize {
#[cfg(not(feature = "tty"))]
{
@@ -113,29 +114,32 @@ pub fn tty_read(buf: &mut [u8], dev_name: &str) -> usize {

#[cfg(feature = "tty")]
{
line_discipline::tty_read(buf, dev_name)
tty::tty_read(buf, dev_name)
}
}

#[cfg(feature = "alloc")]
extern crate alloc;

/// get all tty devices' names.
#[cfg(feature = "alloc")]
pub fn get_all_device_names() -> alloc::vec::Vec<alloc::string::String> {
#[cfg(feature = "tty")]
{
line_discipline::get_all_device_names()
tty::get_all_device_names()
}
#[cfg(not(feature = "tty"))]
{
alloc::vec![alloc::string::String::from("notty")]
}
}

#[allow(unused)]
/// write a tty device specified by its name.
pub fn tty_write(buf: &[u8], dev_name: &str) -> usize {
#[cfg(feature = "tty")]
{
line_discipline::tty_write(buf, dev_name)
tty::tty_write(buf, dev_name)
}
#[cfg(not(feature = "tty"))]
{
Loading

0 comments on commit e35b067

Please sign in to comment.