From 6b37f0f956fb863e32d07953ef8e3a05b72ac58b Mon Sep 17 00:00:00 2001 From: Jianfeng Jiang Date: Fri, 6 Jan 2023 11:14:34 +0800 Subject: [PATCH] implement canonical line discipline --- src/apps/busybox/README.md | 3 +- src/apps/busybox/busybox | 2 +- src/framework/jinux-frame/src/config.rs | 2 +- src/framework/jinux-frame/src/device/mod.rs | 6 +- .../src/device/{console.rs => serial.rs} | 32 +- src/framework/jinux-frame/src/driver/mod.rs | 2 +- src/framework/jinux-frame/src/driver/rtc.rs | 45 +-- src/framework/jinux-frame/src/lib.rs | 4 +- src/framework/jinux-frame/src/log.rs | 2 +- src/framework/jinux-frame/src/time.rs | 41 ++- src/framework/jinux-frame/src/trap/mod.rs | 2 +- src/jinux-boot/src/main.rs | 1 - .../libs/jinux-std/src/driver/console.rs | 54 ---- src/services/libs/jinux-std/src/driver/mod.rs | 4 +- src/services/libs/jinux-std/src/driver/tty.rs | 80 +++++ src/services/libs/jinux-std/src/fs/file.rs | 4 +- src/services/libs/jinux-std/src/fs/stat.rs | 10 + src/services/libs/jinux-std/src/fs/stdio.rs | 35 +-- .../libs/jinux-std/src/process/mod.rs | 6 +- .../jinux-std/src/process/process_group.rs | 16 +- .../libs/jinux-std/src/syscall/mod.rs | 9 +- .../libs/jinux-std/src/syscall/openat.rs | 21 +- .../libs/jinux-std/src/syscall/setpgid.rs | 5 + .../libs/jinux-std/src/syscall/stat.rs | 16 + .../libs/jinux-std/src/syscall/write.rs | 1 + .../libs/jinux-std/src/tty/line_discipline.rs | 276 ++++++++++++++++-- src/services/libs/jinux-std/src/tty/mod.rs | 28 +- src/services/libs/jinux-std/src/tty/termio.rs | 119 +++++++- .../jinux-std/src/vm/page_fault_handler.rs | 3 +- src/tests/console_input.rs | 2 +- src/tests/rtc.rs | 2 +- 31 files changed, 641 insertions(+), 192 deletions(-) rename src/framework/jinux-frame/src/device/{console.rs => serial.rs} (71%) delete mode 100644 src/services/libs/jinux-std/src/driver/console.rs create mode 100644 src/services/libs/jinux-std/src/driver/tty.rs create mode 100644 src/services/libs/jinux-std/src/syscall/stat.rs diff --git a/src/apps/busybox/README.md b/src/apps/busybox/README.md index 1e127258..687043ad 100644 --- a/src/apps/busybox/README.md +++ b/src/apps/busybox/README.md @@ -3,4 +3,5 @@ We don't include the source code of busybox here since the source code is really After download the source code of busybox 1.35.0 and unzip, then cd to the directory of busybox 1. `make defconfig`. We set all config as default. -2. change the line in .config: `#CONFIG_STATIC is not set` => `CONFIG_STATIC=y`. We need a static-linked busybox binary since we does not support dynamic linking now. \ No newline at end of file +2. Set static link option in .config: `CONFIG_STATIC=y`. We need a static-linked busybox binary since we does not support dynamic linking now. +3. Set standalone shell option in .config: `CONFIG_FEATURE_SH_STANDALONE=y`. The standalone ash will try to call busybox applets instead of search binaries in host system. e.g., when running ls, standalone ash will invoke `busybox ash`. \ No newline at end of file diff --git a/src/apps/busybox/busybox b/src/apps/busybox/busybox index fff51115..9e5aabe0 100755 --- a/src/apps/busybox/busybox +++ b/src/apps/busybox/busybox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be0c152c1e47d3109f808cda876c3a90a1ef959007741e126086552e1063eede +oid sha256:6db28e1ed8bdac06ac595b2126cefc10ecf16156bf4c1005950f561aedc0531a size 2701792 diff --git a/src/framework/jinux-frame/src/config.rs b/src/framework/jinux-frame/src/config.rs index 04fa5c18..ba3b4dcb 100644 --- a/src/framework/jinux-frame/src/config.rs +++ b/src/framework/jinux-frame/src/config.rs @@ -15,6 +15,6 @@ pub const PAGE_SIZE_BITS: usize = 0xc; pub const KVA_START: usize = (usize::MAX) << PAGE_SIZE_BITS; -pub const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Close; +pub const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Error; /// This value represent the base timer frequency in Hz pub const TIMER_FREQ: u64 = 100; diff --git a/src/framework/jinux-frame/src/device/mod.rs b/src/framework/jinux-frame/src/device/mod.rs index 0861faa7..605a501f 100644 --- a/src/framework/jinux-frame/src/device/mod.rs +++ b/src/framework/jinux-frame/src/device/mod.rs @@ -1,19 +1,19 @@ //! Device-related APIs. pub mod framebuffer; -pub mod console; mod io_port; pub mod pci; +pub mod serial; pub use self::io_port::IoPort; /// first step to init device, call before the memory allocator init pub(crate) fn first_init(framebuffer: &'static mut bootloader::boot_info::FrameBuffer) { framebuffer::init(framebuffer); - console::init(); + serial::init(); } /// second step to init device, call after the memory allocator init pub(crate) fn second_init() { - console::register_console_input_callback(|trap| {}); + serial::register_serial_input_irq_handler(|trap| {}); } diff --git a/src/framework/jinux-frame/src/device/console.rs b/src/framework/jinux-frame/src/device/serial.rs similarity index 71% rename from src/framework/jinux-frame/src/device/console.rs rename to src/framework/jinux-frame/src/device/serial.rs index 33bba592..47e9a2cd 100644 --- a/src/framework/jinux-frame/src/device/console.rs +++ b/src/framework/jinux-frame/src/device/serial.rs @@ -1,6 +1,8 @@ +use alloc::{sync::Arc, vec::Vec}; use lazy_static::lazy_static; +use spin::Mutex; -use crate::{cell::Cell, driver::pic, x86_64_util::*, IrqAllocateHandle, TrapFrame}; +use crate::{cell::Cell, debug, driver::pic, x86_64_util::*, IrqAllocateHandle, TrapFrame}; use core::fmt::{self, Write}; bitflags::bitflags! { @@ -18,8 +20,13 @@ const SERIAL_LINE_CTRL: u16 = SERIAL_DATA + 3; const SERIAL_MODEM_CTRL: u16 = SERIAL_DATA + 4; const SERIAL_LINE_STS: u16 = SERIAL_DATA + 5; lazy_static! { - static ref CONSOLE_IRQ_CALLBACK: Cell = - Cell::new(pic::allocate_irq(4).unwrap()); + static ref CONSOLE_IRQ_CALLBACK: Cell = { + let irq = Cell::new(pic::allocate_irq(4).unwrap()); + irq.get().on_active(handle_serial_input); + irq + }; + pub static ref SERIAL_INPUT_CALLBACKS: Mutex>> = + Mutex::new(Vec::new()); } /// Initializes the serial port. @@ -43,13 +50,26 @@ pub(crate) fn init() { out8(SERIAL_INT_EN, 0x01); } -pub fn register_console_input_callback(callback: F) +pub(crate) fn register_serial_input_irq_handler(callback: F) where F: Fn(&TrapFrame) + Sync + Send + 'static, { CONSOLE_IRQ_CALLBACK.get().on_active(callback); } +fn handle_serial_input(trap_frame: &TrapFrame) { + // debug!("keyboard interrupt was met"); + if SERIAL_INPUT_CALLBACKS.is_locked() { + return; + } + let lock = SERIAL_INPUT_CALLBACKS.lock(); + let received_char = receive_char().unwrap(); + debug!("receive char = {:?}", received_char); + for callback in lock.iter() { + callback(received_char); + } +} + fn line_sts() -> LineSts { LineSts::from_bits_truncate(in8(SERIAL_LINE_STS)) } @@ -99,13 +119,13 @@ pub fn print(args: fmt::Arguments) { #[macro_export] macro_rules! console_print { ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::device::console::print(format_args!($fmt $(, $($arg)+)?)) + $crate::device::serial::print(format_args!($fmt $(, $($arg)+)?)) } } #[macro_export] macro_rules! console_println { ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::device::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + $crate::device::serial::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) } } diff --git a/src/framework/jinux-frame/src/driver/mod.rs b/src/framework/jinux-frame/src/driver/mod.rs index 8c8fcb9a..aecf74e0 100644 --- a/src/framework/jinux-frame/src/driver/mod.rs +++ b/src/framework/jinux-frame/src/driver/mod.rs @@ -6,8 +6,8 @@ pub mod acpi; pub mod apic; pub mod ioapic; pub mod pic; -pub mod timer; pub mod rtc; +pub mod timer; pub use apic::ack; pub use timer::TimerCallback; diff --git a/src/framework/jinux-frame/src/driver/rtc.rs b/src/framework/jinux-frame/src/driver/rtc.rs index 9e545f7d..427941f1 100644 --- a/src/framework/jinux-frame/src/driver/rtc.rs +++ b/src/framework/jinux-frame/src/driver/rtc.rs @@ -1,52 +1,58 @@ use core::sync::atomic::AtomicU8; use core::sync::atomic::Ordering::Relaxed; -use acpi::{sdt::Signature, fadt::Fadt}; +use acpi::{fadt::Fadt, sdt::Signature}; use lazy_static::lazy_static; use spin::Mutex; -use crate::{x86_64_util::{out8, in8}, time::Time}; +use crate::{ + time::Time, + x86_64_util::{in8, out8}, +}; use super::acpi::ACPI_TABLES; -const CMOS_ADDRESS : u16 = 0x70; -const CMOS_DATA : u16 = 0x71; -pub(crate) static CENTURY_REGISTER : AtomicU8 = AtomicU8::new(0); +const CMOS_ADDRESS: u16 = 0x70; +const CMOS_DATA: u16 = 0x71; +pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0); -lazy_static!{ - static ref READ_TIME : Mutex