mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 09:06:32 +00:00
@ -146,11 +146,11 @@ void ps2_keyboard_handler(ul irq_num, ul buf_vaddr, struct pt_regs *regs)
|
|||||||
unsigned char x = io_in8(PORT_PS2_KEYBOARD_DATA);
|
unsigned char x = io_in8(PORT_PS2_KEYBOARD_DATA);
|
||||||
ps2_keyboard_parse_keycode((uint8_t)x);
|
ps2_keyboard_parse_keycode((uint8_t)x);
|
||||||
uint8_t count = kfifo_in((struct kfifo_t *)buf_vaddr, &x, sizeof(unsigned char));
|
uint8_t count = kfifo_in((struct kfifo_t *)buf_vaddr, &x, sizeof(unsigned char));
|
||||||
if (count == 0)
|
// if (count == 0)
|
||||||
{
|
// {
|
||||||
kwarn("ps2 keyboard buffer full.");
|
// kwarn("ps2 keyboard buffer full.");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
wait_queue_wakeup(&ps2_keyboard_wait_queue, PROC_UNINTERRUPTIBLE);
|
wait_queue_wakeup(&ps2_keyboard_wait_queue, PROC_UNINTERRUPTIBLE);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use core::sync::atomic::AtomicI32;
|
|||||||
use alloc::sync::{Arc, Weak};
|
use alloc::sync::{Arc, Weak};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
driver::tty::tty_device::TTY_DEVICES,
|
||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{devfs_register, DevFS, DeviceINode},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
|
vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
|
||||||
@ -17,7 +18,14 @@ use crate::{
|
|||||||
pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
|
pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new());
|
static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = {
|
||||||
|
let tty0 = TTY_DEVICES
|
||||||
|
.read()
|
||||||
|
.get("tty0")
|
||||||
|
.expect("Initializing PS2_KEYBOARD_FSM: Cannot found TTY0!")
|
||||||
|
.clone();
|
||||||
|
SpinLock::new(TypeOneFSM::new(tty0))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -5,7 +5,7 @@ use thingbuf::mpsc::{
|
|||||||
errors::{TryRecvError, TrySendError},
|
errors::{TryRecvError, TrySendError},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::libs::rwlock::RwLock;
|
use crate::{libs::rwlock::RwLock, kdebug};
|
||||||
|
|
||||||
pub mod tty_device;
|
pub mod tty_device;
|
||||||
|
|
||||||
@ -59,6 +59,7 @@ struct TtyCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum TtyError {
|
pub enum TtyError {
|
||||||
/// 缓冲区满,返回成功传送的字节数
|
/// 缓冲区满,返回成功传送的字节数
|
||||||
BufferFull(usize),
|
BufferFull(usize),
|
||||||
@ -281,6 +282,7 @@ impl TtyCore {
|
|||||||
|
|
||||||
/// @brief 关闭输入回显
|
/// @brief 关闭输入回显
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn disable_echo(&self) {
|
pub fn disable_echo(&self) {
|
||||||
self.state.write().set(TtyCoreState::ECHO_ON, false);
|
self.state.write().set(TtyCoreState::ECHO_ON, false);
|
||||||
}
|
}
|
||||||
@ -291,6 +293,7 @@ impl TtyCore {
|
|||||||
///
|
///
|
||||||
/// @return false 未开启输入回显
|
/// @return false 未开启输入回显
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn echo_enabled(&self) -> bool {
|
pub fn echo_enabled(&self) -> bool {
|
||||||
return self.state.read().contains(TtyCoreState::ECHO_ON);
|
return self.state.read().contains(TtyCoreState::ECHO_ON);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,62 @@
|
|||||||
use alloc::sync::{Arc, Weak};
|
use alloc::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
string::{String, ToString},
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
filesystem::{
|
filesystem::{
|
||||||
devfs::{DeviceINode, DevFS},
|
devfs::{devfs_register, DevFS, DeviceINode},
|
||||||
vfs::{file::FileMode, FilePrivateData, IndexNode},
|
vfs::{file::FileMode, FilePrivateData, FileType, IndexNode, Metadata, ROOT_INODE},
|
||||||
},
|
},
|
||||||
kerror, libs::rwlock::RwLock, syscall::SystemError,
|
include::bindings::bindings::{printk_color, textui_putchar, BLACK, WHITE},
|
||||||
|
kdebug, kerror,
|
||||||
|
libs::rwlock::RwLock,
|
||||||
|
print,
|
||||||
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{TtyCore, TtyError, TtyFileFlag, TtyFilePrivateData};
|
use super::{TtyCore, TtyError, TtyFileFlag, TtyFilePrivateData};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// 所有TTY设备的B树。用于根据名字,找到Arc<TtyDevice>
|
||||||
|
/// TODO: 待设备驱动模型完善,具有类似功能的机制后,删掉这里
|
||||||
|
pub static ref TTY_DEVICES: RwLock<BTreeMap<String, Arc<TtyDevice>>> = RwLock::new(BTreeMap::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief TTY设备
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TtyDevice {
|
pub struct TtyDevice {
|
||||||
|
/// TTY核心
|
||||||
core: TtyCore,
|
core: TtyCore,
|
||||||
fs: RwLock<Weak<DevFS>>
|
/// TTY所属的文件系统
|
||||||
|
fs: RwLock<Weak<DevFS>>,
|
||||||
|
/// TTY设备私有信息
|
||||||
|
private_data: RwLock<TtyDevicePrivateData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TtyDevicePrivateData {
|
||||||
|
/// TTY设备名(如tty1)
|
||||||
|
name: String,
|
||||||
|
/// TTY设备文件的元数据
|
||||||
|
metadata: Metadata,
|
||||||
|
// TODO: 增加指向输出端口连接的设备的指针
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TtyDevice {
|
impl TtyDevice {
|
||||||
pub fn new() -> Arc<TtyDevice> {
|
pub fn new(name: &str) -> Arc<TtyDevice> {
|
||||||
return Arc::new(TtyDevice {
|
let result = Arc::new(TtyDevice {
|
||||||
core: TtyCore::new(),
|
core: TtyCore::new(),
|
||||||
fs: RwLock::new(Weak::default()),
|
fs: RwLock::new(Weak::default()),
|
||||||
|
private_data: TtyDevicePrivateData::new(name),
|
||||||
});
|
});
|
||||||
|
// 默认开启输入回显
|
||||||
|
result.core.enable_echo();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 判断文件私有信息是否为TTY的私有信息
|
/// @brief 判断文件私有信息是否为TTY文件的私有信息
|
||||||
#[inline]
|
#[inline]
|
||||||
fn verify_file_private_data<'a>(
|
fn verify_file_private_data<'a>(
|
||||||
&self,
|
&self,
|
||||||
@ -36,6 +67,39 @@ impl TtyDevice {
|
|||||||
}
|
}
|
||||||
return Err(SystemError::EIO);
|
return Err(SystemError::EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief 获取TTY设备名
|
||||||
|
#[inline]
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
return self.private_data.read().name.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 检查TTY文件的读写参数是否合法
|
||||||
|
#[inline]
|
||||||
|
pub fn check_rw_param(&self, len: usize, buf: &[u8]) -> Result<(), SystemError> {
|
||||||
|
if len > buf.len() {
|
||||||
|
return Err(SystemError::EINVAL);
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 向TTY的输入端口导入数据
|
||||||
|
pub fn input(&self, buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
|
let r: Result<usize, TtyError> = self.core.input(buf, false);
|
||||||
|
if r.is_ok() {
|
||||||
|
return Ok(r.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = r.unwrap_err();
|
||||||
|
match r {
|
||||||
|
TtyError::BufferFull(x) => return Ok(x),
|
||||||
|
TtyError::Closed => return Err(SystemError::ENODEV),
|
||||||
|
e => {
|
||||||
|
kerror!("tty error occurred while writing data to its input port, msg={e:?}");
|
||||||
|
return Err(SystemError::EBUSY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceINode for TtyDevice {
|
impl DeviceINode for TtyDevice {
|
||||||
@ -45,15 +109,40 @@ impl DeviceINode for TtyDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IndexNode for TtyDevice {
|
impl IndexNode for TtyDevice {
|
||||||
|
/// @brief 打开TTY设备
|
||||||
|
///
|
||||||
|
/// @param data 文件私有信息
|
||||||
|
/// @param mode 打开模式
|
||||||
|
///
|
||||||
|
/// TTY设备通过mode来确定这个文件到底是stdin/stdout/stderr
|
||||||
|
/// - mode的值为O_RDONLY时,表示这个文件是stdin
|
||||||
|
/// - mode的值为O_WRONLY时,表示这个文件是stdout
|
||||||
|
/// - mode的值为O_WRONLY | O_SYNC时,表示这个文件是stderr
|
||||||
fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
|
fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
|
||||||
let p = TtyFilePrivateData::default();
|
let mut p = TtyFilePrivateData::default();
|
||||||
|
|
||||||
|
// 检查打开模式
|
||||||
|
let accmode = mode.accmode();
|
||||||
|
if accmode == FileMode::O_RDONLY.accmode() {
|
||||||
|
p.flags.insert(TtyFileFlag::STDIN);
|
||||||
|
} else if accmode == FileMode::O_WRONLY.accmode() {
|
||||||
|
if mode.contains(FileMode::O_SYNC) {
|
||||||
|
p.flags.insert(TtyFileFlag::STDERR);
|
||||||
|
} else {
|
||||||
|
p.flags.insert(TtyFileFlag::STDOUT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(SystemError::EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存文件私有信息
|
||||||
*data = FilePrivateData::Tty(p);
|
*data = FilePrivateData::Tty(p);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_at(
|
fn read_at(
|
||||||
&self,
|
&self,
|
||||||
offset: usize,
|
_offset: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
data: &mut crate::filesystem::vfs::FilePrivateData,
|
data: &mut crate::filesystem::vfs::FilePrivateData,
|
||||||
@ -65,9 +154,10 @@ impl IndexNode for TtyDevice {
|
|||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
self.check_rw_param(len, buf)?;
|
||||||
|
|
||||||
// 读取stdin队列
|
// 读取stdin队列
|
||||||
let r: Result<usize, TtyError> = self.core.read_stdin(buf, true);
|
let r: Result<usize, TtyError> = self.core.read_stdin(&mut buf[0..len], true);
|
||||||
if r.is_ok() {
|
if r.is_ok() {
|
||||||
return Ok(r.unwrap());
|
return Ok(r.unwrap());
|
||||||
}
|
}
|
||||||
@ -76,6 +166,7 @@ impl IndexNode for TtyDevice {
|
|||||||
TtyError::EOF(n) => {
|
TtyError::EOF(n) => {
|
||||||
return Ok(n);
|
return Ok(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
x => {
|
x => {
|
||||||
kerror!("Error occurred when reading tty, msg={x:?}");
|
kerror!("Error occurred when reading tty, msg={x:?}");
|
||||||
return Err(SystemError::ECONNABORTED);
|
return Err(SystemError::ECONNABORTED);
|
||||||
@ -85,7 +176,7 @@ impl IndexNode for TtyDevice {
|
|||||||
|
|
||||||
fn write_at(
|
fn write_at(
|
||||||
&self,
|
&self,
|
||||||
offset: usize,
|
_offset: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
data: &mut crate::filesystem::vfs::FilePrivateData,
|
data: &mut crate::filesystem::vfs::FilePrivateData,
|
||||||
@ -98,16 +189,19 @@ impl IndexNode for TtyDevice {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.check_rw_param(len, buf)?;
|
||||||
|
|
||||||
// 根据当前文件是stdout还是stderr,选择不同的发送方式
|
// 根据当前文件是stdout还是stderr,选择不同的发送方式
|
||||||
let r: Result<usize, TtyError> = if data.flags.contains(TtyFileFlag::STDOUT) {
|
let r: Result<usize, TtyError> = if data.flags.contains(TtyFileFlag::STDOUT) {
|
||||||
self.core.stdout(buf, true)
|
self.core.stdout(&buf[0..len], true)
|
||||||
} else if data.flags.contains(TtyFileFlag::STDERR) {
|
} else if data.flags.contains(TtyFileFlag::STDERR) {
|
||||||
self.core.stderr(buf, true)
|
self.core.stderr(&buf[0..len], true)
|
||||||
} else {
|
} else {
|
||||||
return Err(SystemError::EPERM);
|
return Err(SystemError::EPERM);
|
||||||
};
|
};
|
||||||
|
|
||||||
if r.is_ok() {
|
if r.is_ok() {
|
||||||
|
self.sync().expect("Failed to sync tty device!");
|
||||||
return Ok(r.unwrap());
|
return Ok(r.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,4 +225,94 @@ impl IndexNode for TtyDevice {
|
|||||||
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
|
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
|
||||||
return Err(SystemError::ENOTSUP);
|
return Err(SystemError::ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> Result<Metadata, SystemError> {
|
||||||
|
return Ok(self.private_data.read().metadata.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync(&self) -> Result<(), SystemError> {
|
||||||
|
// TODO: 引入IO重定向后,需要将输出重定向到对应的设备。
|
||||||
|
// 目前只是简单的输出到屏幕(为了实现的简便)
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut buf = [0u8; 512];
|
||||||
|
let r: Result<usize, TtyError> = self.core.read_output(&mut buf[0..511], false);
|
||||||
|
let len;
|
||||||
|
match r {
|
||||||
|
Ok(x) => {
|
||||||
|
len = x;
|
||||||
|
}
|
||||||
|
Err(TtyError::EOF(x)) | Err(TtyError::BufferEmpty(x)) => {
|
||||||
|
len = x;
|
||||||
|
}
|
||||||
|
_ => return Err(SystemError::EIO),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 输出到屏幕
|
||||||
|
print!("{}", unsafe {
|
||||||
|
core::str::from_utf8_unchecked(&buf[0..len])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TtyDevicePrivateData {
|
||||||
|
pub fn new(name: &str) -> RwLock<Self> {
|
||||||
|
let mut metadata = Metadata::new(FileType::CharDevice, 0o755);
|
||||||
|
metadata.size = TtyCore::STDIN_BUF_SIZE as i64;
|
||||||
|
return RwLock::new(TtyDevicePrivateData {
|
||||||
|
name: name.to_string(),
|
||||||
|
metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 导出到C的tty初始化函数
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rs_tty_init() -> i32 {
|
||||||
|
let r = tty_init();
|
||||||
|
if r.is_ok() {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return r.unwrap_err().to_posix_errno();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 初始化TTY设备
|
||||||
|
pub fn tty_init() -> Result<(), SystemError> {
|
||||||
|
let tty: Arc<TtyDevice> = TtyDevice::new("tty0");
|
||||||
|
let devfs_root_inode = ROOT_INODE().lookup("/dev");
|
||||||
|
if devfs_root_inode.is_err() {
|
||||||
|
return Err(devfs_root_inode.unwrap_err());
|
||||||
|
}
|
||||||
|
// 当前关闭键盘输入回显
|
||||||
|
// TODO: 完善Termios之后, 改为默认开启键盘输入回显.
|
||||||
|
tty.core.disable_echo();
|
||||||
|
let guard = TTY_DEVICES.upgradeable_read();
|
||||||
|
|
||||||
|
// 如果已经存在了这个设备
|
||||||
|
if guard.contains_key("tty0") {
|
||||||
|
return Err(SystemError::EEXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut guard = guard.upgrade();
|
||||||
|
|
||||||
|
guard.insert("tty0".to_string(), tty.clone());
|
||||||
|
|
||||||
|
drop(guard);
|
||||||
|
|
||||||
|
let r = devfs_register(&tty.name(), tty);
|
||||||
|
if r.is_err() {
|
||||||
|
return Err(devfs_root_inode.unwrap_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,8 @@ use super::vfs::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
kerror,
|
kerror,
|
||||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
time::TimeSpec, syscall::SystemError,
|
syscall::SystemError,
|
||||||
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
use alloc::{
|
use alloc::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
@ -94,9 +95,14 @@ impl DevFS {
|
|||||||
///
|
///
|
||||||
/// @param name 设备名称
|
/// @param name 设备名称
|
||||||
/// @param device 设备节点的结构体
|
/// @param device 设备节点的结构体
|
||||||
pub fn register_device<T: DeviceINode>(&self, name: &str, device: Arc<T>) -> Result<(), SystemError> {
|
pub fn register_device<T: DeviceINode>(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
device: Arc<T>,
|
||||||
|
) -> Result<(), SystemError> {
|
||||||
let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone();
|
let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone();
|
||||||
match device.metadata().unwrap().file_type {
|
let metadata = device.metadata()?;
|
||||||
|
match metadata.file_type {
|
||||||
// 字节设备挂载在 /dev/char
|
// 字节设备挂载在 /dev/char
|
||||||
FileType::CharDevice => {
|
FileType::CharDevice => {
|
||||||
if let Err(_) = dev_root_inode.find("char") {
|
if let Err(_) = dev_root_inode.find("char") {
|
||||||
@ -108,8 +114,13 @@ impl DevFS {
|
|||||||
.as_any_ref()
|
.as_any_ref()
|
||||||
.downcast_ref::<LockedDevFSInode>()
|
.downcast_ref::<LockedDevFSInode>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// 在 /dev/char 下创建设备节点
|
||||||
dev_char_inode.add_dev(name, device.clone())?;
|
dev_char_inode.add_dev(name, device.clone())?;
|
||||||
|
|
||||||
|
// 特殊处理 tty 设备,挂载在 /dev 下
|
||||||
|
if name.starts_with("tty") && name.len() > 3 {
|
||||||
|
dev_root_inode.add_dev(name, device.clone())?;
|
||||||
|
}
|
||||||
device.set_fs(dev_char_inode.0.lock().fs.clone());
|
device.set_fs(dev_char_inode.0.lock().fs.clone());
|
||||||
}
|
}
|
||||||
FileType::BlockDevice => {
|
FileType::BlockDevice => {
|
||||||
@ -135,7 +146,11 @@ impl DevFS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 卸载设备
|
/// @brief 卸载设备
|
||||||
pub fn unregister_device<T: DeviceINode>(&self, name: &str, device: Arc<T>) -> Result<(), SystemError> {
|
pub fn unregister_device<T: DeviceINode>(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
device: Arc<T>,
|
||||||
|
) -> Result<(), SystemError> {
|
||||||
let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone();
|
let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone();
|
||||||
match device.metadata().unwrap().file_type {
|
match device.metadata().unwrap().file_type {
|
||||||
// 字节设备挂载在 /dev/char
|
// 字节设备挂载在 /dev/char
|
||||||
@ -325,7 +340,11 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(&self, _data: &mut super::vfs::FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
|
fn open(
|
||||||
|
&self,
|
||||||
|
_data: &mut super::vfs::FilePrivateData,
|
||||||
|
_mode: &FileMode,
|
||||||
|
) -> Result<(), SystemError> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,6 +478,7 @@ impl IndexNode for LockedDevFSInode {
|
|||||||
_buf: &mut [u8],
|
_buf: &mut [u8],
|
||||||
_data: &mut super::vfs::file::FilePrivateData,
|
_data: &mut super::vfs::file::FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
|
kerror!("DevFS: read_at is not supported!");
|
||||||
Err(SystemError::ENOTSUP)
|
Err(SystemError::ENOTSUP)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,4 +531,3 @@ pub fn devfs_register<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(),
|
|||||||
pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> {
|
pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> {
|
||||||
return devfs_exact_ref!().unregister_device(name, device);
|
return devfs_exact_ref!().unregister_device(name, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ bitflags! {
|
|||||||
const O_APPEND = 0o00002000;
|
const O_APPEND = 0o00002000;
|
||||||
/// 非阻塞式IO模式
|
/// 非阻塞式IO模式
|
||||||
const O_NONBLOCK = 0o00004000;
|
const O_NONBLOCK = 0o00004000;
|
||||||
/// used to be O_SYNC, see below
|
/// 每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新
|
||||||
const O_DSYNC = 0o00010000;
|
const O_DSYNC = 0o00010000;
|
||||||
/// fcntl, for BSD compatibility
|
/// fcntl, for BSD compatibility
|
||||||
const FASYNC = 0o00020000;
|
const FASYNC = 0o00020000;
|
||||||
@ -76,9 +76,18 @@ bitflags! {
|
|||||||
const O_NOATIME = 0o01000000;
|
const O_NOATIME = 0o01000000;
|
||||||
/// set close_on_exec
|
/// set close_on_exec
|
||||||
const O_CLOEXEC = 0o02000000;
|
const O_CLOEXEC = 0o02000000;
|
||||||
|
/// 每次write都等到物理I/O完成,包括write引起的文件属性的更新
|
||||||
|
const O_SYNC = 0o04000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FileMode {
|
||||||
|
/// @brief 获取文件的访问模式的值
|
||||||
|
#[inline]
|
||||||
|
pub fn accmode(&self) -> u32 {
|
||||||
|
return self.bits() & FileMode::O_ACCMODE.bits();
|
||||||
|
}
|
||||||
|
}
|
||||||
/// @brief 抽象文件结构体
|
/// @brief 抽象文件结构体
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
@ -128,7 +137,6 @@ impl File {
|
|||||||
if buf.len() < len {
|
if buf.len() < len {
|
||||||
return Err(SystemError::ENOBUFS);
|
return Err(SystemError::ENOBUFS);
|
||||||
}
|
}
|
||||||
|
|
||||||
let len = self
|
let len = self
|
||||||
.inode
|
.inode
|
||||||
.read_at(self.offset, len, buf, &mut self.private_data)?;
|
.read_at(self.offset, len, buf, &mut self.private_data)?;
|
||||||
@ -151,7 +159,7 @@ impl File {
|
|||||||
}
|
}
|
||||||
let len = self
|
let len = self
|
||||||
.inode
|
.inode
|
||||||
.write_at(self.offset, len, buf, &mut FilePrivateData::Unused)?;
|
.write_at(self.offset, len, buf, &mut self.private_data)?;
|
||||||
self.offset += len;
|
self.offset += len;
|
||||||
return Ok(len);
|
return Ok(len);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
syscall::SystemError,
|
syscall::SystemError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::file::FileMode;
|
use self::{core::generate_inode_id, file::FileMode};
|
||||||
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
||||||
|
|
||||||
/// vfs容许的最大的路径名称长度
|
/// vfs容许的最大的路径名称长度
|
||||||
@ -332,6 +332,11 @@ pub trait IndexNode: Any + Sync + Send + Debug {
|
|||||||
fn truncate(&self, _len: usize) -> Result<(), SystemError> {
|
fn truncate(&self, _len: usize) -> Result<(), SystemError> {
|
||||||
return Err(SystemError::ENOTSUP);
|
return Err(SystemError::ENOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief 将当前inode的内容同步到具体设备上
|
||||||
|
fn sync(&self) -> Result<(), SystemError> {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn IndexNode {
|
impl dyn IndexNode {
|
||||||
@ -516,3 +521,24 @@ pub struct Dirent {
|
|||||||
d_type: u8, // entry的类型
|
d_type: u8, // entry的类型
|
||||||
d_name: u8, // 文件entry的名字(是一个零长数组), 本字段仅用于占位
|
d_name: u8, // 文件entry的名字(是一个零长数组), 本字段仅用于占位
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Metadata {
|
||||||
|
pub fn new(file_type: FileType, mode: u32) -> Self {
|
||||||
|
Metadata {
|
||||||
|
dev_id: 0,
|
||||||
|
inode_id: generate_inode_id(),
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: TimeSpec::default(),
|
||||||
|
mtime: TimeSpec::default(),
|
||||||
|
ctime: TimeSpec::default(),
|
||||||
|
file_type,
|
||||||
|
mode,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
raw_dev: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -164,11 +164,11 @@ impl IndexNode for MountFSInode {
|
|||||||
offset: usize,
|
offset: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
_data: &mut FilePrivateData,
|
data: &mut FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
return self
|
return self
|
||||||
.inner_inode
|
.inner_inode
|
||||||
.write_at(offset, len, buf, &mut FilePrivateData::Unused);
|
.write_at(offset, len, buf, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -26,22 +26,21 @@
|
|||||||
#include <common/printk.h>
|
#include <common/printk.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
#include <common/stdio.h>
|
#include <common/stdio.h>
|
||||||
|
#include <common/string.h>
|
||||||
#include <common/time.h>
|
#include <common/time.h>
|
||||||
#include <common/unistd.h>
|
#include <common/unistd.h>
|
||||||
#include <common/string.h>
|
|
||||||
#include <driver/disk/ahci/ahci.h>
|
#include <driver/disk/ahci/ahci.h>
|
||||||
#include <driver/disk/ahci/ahci_rust.h>
|
#include <driver/disk/ahci/ahci_rust.h>
|
||||||
#include <driver/pci/pci.h>
|
#include <driver/pci/pci.h>
|
||||||
|
#include <driver/virtio/virtio.h>
|
||||||
#include <include/DragonOS/refcount.h>
|
#include <include/DragonOS/refcount.h>
|
||||||
#include <include/DragonOS/signal.h>
|
#include <include/DragonOS/signal.h>
|
||||||
|
#include <libs/libUI/textui.h>
|
||||||
|
#include <mm/mm-types.h>
|
||||||
#include <mm/mm.h>
|
#include <mm/mm.h>
|
||||||
#include <mm/mmio.h>
|
#include <mm/mmio.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <process/process.h>
|
#include <process/process.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
#include <time/sleep.h>
|
|
||||||
#include <mm/mm-types.h>
|
|
||||||
#include <driver/pci/pci.h>
|
|
||||||
#include <driver/virtio/virtio.h>
|
|
||||||
#include <smp/smp.h>
|
#include <smp/smp.h>
|
||||||
|
#include <time/sleep.h>
|
||||||
|
@ -39,7 +39,6 @@ extern crate alloc;
|
|||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
extern crate num;
|
extern crate num;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate num_derive;
|
extern crate num_derive;
|
||||||
@ -99,6 +98,5 @@ pub fn panic(info: &PanicInfo) -> ! {
|
|||||||
pub extern "C" fn __rust_demo_func() -> i32 {
|
pub extern "C" fn __rust_demo_func() -> i32 {
|
||||||
printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
|
printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::kdebug;
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
|
use crate::driver::tty::tty_device::TtyDevice;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const NUM_SCAN_CODES: u8 = 0x80;
|
pub const NUM_SCAN_CODES: u8 = 0x80;
|
||||||
@ -26,21 +28,25 @@ pub enum KeyFlag {
|
|||||||
pub struct TypeOneFSM {
|
pub struct TypeOneFSM {
|
||||||
status: ScanCodeStatus,
|
status: ScanCodeStatus,
|
||||||
current_state: TypeOneFSMState,
|
current_state: TypeOneFSMState,
|
||||||
|
tty: Arc<TtyDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeOneFSM {
|
impl TypeOneFSM {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Self {
|
pub fn new(tty: Arc<TtyDevice>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
status: ScanCodeStatus::new(),
|
status: ScanCodeStatus::new(),
|
||||||
current_state: TypeOneFSMState::Start,
|
current_state: TypeOneFSMState::Start,
|
||||||
|
tty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 解析扫描码
|
/// @brief 解析扫描码
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
|
pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
|
||||||
self.current_state = self.current_state.parse(scancode, &mut self.status);
|
self.current_state = self
|
||||||
|
.current_state
|
||||||
|
.parse(scancode, &mut self.status, &self.tty);
|
||||||
self.current_state
|
self.current_state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,30 +69,42 @@ pub enum TypeOneFSMState {
|
|||||||
|
|
||||||
impl TypeOneFSMState {
|
impl TypeOneFSMState {
|
||||||
/// @brief 状态机总控程序
|
/// @brief 状态机总控程序
|
||||||
fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
fn parse(
|
||||||
|
&self,
|
||||||
|
scancode: u8,
|
||||||
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
|
) -> TypeOneFSMState {
|
||||||
// kdebug!("the code is {:#x}\n", scancode);
|
// kdebug!("the code is {:#x}\n", scancode);
|
||||||
match self {
|
match self {
|
||||||
TypeOneFSMState::Start => {
|
TypeOneFSMState::Start => {
|
||||||
return self.handle_start(scancode, scancode_status);
|
return self.handle_start(scancode, scancode_status, tty);
|
||||||
}
|
}
|
||||||
TypeOneFSMState::PauseBreak(n) => {
|
TypeOneFSMState::PauseBreak(n) => {
|
||||||
return self.handle_pause_break(*n, scancode_status);
|
return self.handle_pause_break(*n, scancode_status, tty);
|
||||||
}
|
}
|
||||||
TypeOneFSMState::Func0 => {
|
TypeOneFSMState::Func0 => {
|
||||||
return self.handle_func0(scancode, scancode_status);
|
return self.handle_func0(scancode, scancode_status, tty);
|
||||||
}
|
}
|
||||||
TypeOneFSMState::Type3 => {
|
TypeOneFSMState::Type3 => {
|
||||||
return self.handle_type3(scancode, scancode_status);
|
return self.handle_type3(scancode, scancode_status, tty);
|
||||||
|
}
|
||||||
|
TypeOneFSMState::PrtscPress(n) => {
|
||||||
|
return self.handle_prtsc_press(*n, scancode_status, tty)
|
||||||
}
|
}
|
||||||
TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status),
|
|
||||||
TypeOneFSMState::PrtscRelease(n) => {
|
TypeOneFSMState::PrtscRelease(n) => {
|
||||||
return self.handle_prtsc_release(*n, scancode_status)
|
return self.handle_prtsc_release(*n, scancode_status, tty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 处理起始状态
|
/// @brief 处理起始状态
|
||||||
fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
fn handle_start(
|
||||||
|
&self,
|
||||||
|
scancode: u8,
|
||||||
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
|
) -> TypeOneFSMState {
|
||||||
//kdebug!("in handle_start the code is {:#x}\n",scancode);
|
//kdebug!("in handle_start the code is {:#x}\n",scancode);
|
||||||
match scancode {
|
match scancode {
|
||||||
0xe1 => {
|
0xe1 => {
|
||||||
@ -97,7 +115,7 @@ impl TypeOneFSMState {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
//kdebug!("in _d the code is {:#x}\n",scancode);
|
//kdebug!("in _d the code is {:#x}\n",scancode);
|
||||||
return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status);
|
return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status, tty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,16 +125,17 @@ impl TypeOneFSMState {
|
|||||||
&self,
|
&self,
|
||||||
scancode: u8,
|
scancode: u8,
|
||||||
scancode_status: &mut ScanCodeStatus,
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
) -> TypeOneFSMState {
|
) -> TypeOneFSMState {
|
||||||
static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
|
static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
|
||||||
let i = match self {
|
let i = match self {
|
||||||
TypeOneFSMState::PauseBreak(i) => *i,
|
TypeOneFSMState::PauseBreak(i) => *i,
|
||||||
_ => {
|
_ => {
|
||||||
return self.handle_type3(scancode, scancode_status);
|
return self.handle_type3(scancode, scancode_status, tty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
|
if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
|
||||||
return self.handle_type3(scancode, scancode_status);
|
return self.handle_type3(scancode, scancode_status, tty);
|
||||||
} else {
|
} else {
|
||||||
if i == 5 {
|
if i == 5 {
|
||||||
// 所有Pause Break扫描码都被清除
|
// 所有Pause Break扫描码都被清除
|
||||||
@ -127,7 +146,12 @@ impl TypeOneFSMState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
fn handle_func0(
|
||||||
|
&self,
|
||||||
|
scancode: u8,
|
||||||
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
|
) -> TypeOneFSMState {
|
||||||
//0xE0
|
//0xE0
|
||||||
match scancode {
|
match scancode {
|
||||||
0x2a => {
|
0x2a => {
|
||||||
@ -190,7 +214,7 @@ impl TypeOneFSMState {
|
|||||||
}
|
}
|
||||||
0x53 => {
|
0x53 => {
|
||||||
scancode_status.del = true;
|
scancode_status.del = true;
|
||||||
Self::emit(127);
|
Self::emit(tty, 127);
|
||||||
}
|
}
|
||||||
0xd3 => {
|
0xd3 => {
|
||||||
scancode_status.del = false;
|
scancode_status.del = false;
|
||||||
@ -209,32 +233,32 @@ impl TypeOneFSMState {
|
|||||||
}
|
}
|
||||||
0x48 => {
|
0x48 => {
|
||||||
scancode_status.arrow_u = true;
|
scancode_status.arrow_u = true;
|
||||||
Self::emit(224);
|
Self::emit(tty, 224);
|
||||||
Self::emit(72);
|
Self::emit(tty, 72);
|
||||||
}
|
}
|
||||||
0xc8 => {
|
0xc8 => {
|
||||||
scancode_status.arrow_u = false;
|
scancode_status.arrow_u = false;
|
||||||
}
|
}
|
||||||
0x4b => {
|
0x4b => {
|
||||||
scancode_status.arrow_l = true;
|
scancode_status.arrow_l = true;
|
||||||
Self::emit(224);
|
Self::emit(tty, 224);
|
||||||
Self::emit(75);
|
Self::emit(tty, 75);
|
||||||
}
|
}
|
||||||
0xcb => {
|
0xcb => {
|
||||||
scancode_status.arrow_l = false;
|
scancode_status.arrow_l = false;
|
||||||
}
|
}
|
||||||
0x50 => {
|
0x50 => {
|
||||||
scancode_status.arrow_d = true;
|
scancode_status.arrow_d = true;
|
||||||
Self::emit(224);
|
Self::emit(tty, 224);
|
||||||
Self::emit(80);
|
Self::emit(tty, 80);
|
||||||
}
|
}
|
||||||
0xd0 => {
|
0xd0 => {
|
||||||
scancode_status.arrow_d = false;
|
scancode_status.arrow_d = false;
|
||||||
}
|
}
|
||||||
0x4d => {
|
0x4d => {
|
||||||
scancode_status.arrow_r = true;
|
scancode_status.arrow_r = true;
|
||||||
Self::emit(224);
|
Self::emit(tty, 224);
|
||||||
Self::emit(77);
|
Self::emit(tty, 77);
|
||||||
}
|
}
|
||||||
0xcd => {
|
0xcd => {
|
||||||
scancode_status.arrow_r = false;
|
scancode_status.arrow_r = false;
|
||||||
@ -245,14 +269,14 @@ impl TypeOneFSMState {
|
|||||||
scancode_status.kp_forward_slash = true;
|
scancode_status.kp_forward_slash = true;
|
||||||
|
|
||||||
let ch = '/' as u8;
|
let ch = '/' as u8;
|
||||||
Self::emit(ch);
|
Self::emit(tty, ch);
|
||||||
}
|
}
|
||||||
0xb5 => {
|
0xb5 => {
|
||||||
scancode_status.kp_forward_slash = false;
|
scancode_status.kp_forward_slash = false;
|
||||||
}
|
}
|
||||||
0x1c => {
|
0x1c => {
|
||||||
scancode_status.kp_enter = true;
|
scancode_status.kp_enter = true;
|
||||||
Self::emit('\n' as u8);
|
Self::emit(tty, '\n' as u8);
|
||||||
}
|
}
|
||||||
0x9c => {
|
0x9c => {
|
||||||
scancode_status.kp_enter = false;
|
scancode_status.kp_enter = false;
|
||||||
@ -264,7 +288,12 @@ impl TypeOneFSMState {
|
|||||||
return TypeOneFSMState::Start;
|
return TypeOneFSMState::Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
fn handle_type3(
|
||||||
|
&self,
|
||||||
|
scancode: u8,
|
||||||
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
|
) -> TypeOneFSMState {
|
||||||
// 判断按键是被按下还是抬起
|
// 判断按键是被按下还是抬起
|
||||||
let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
|
let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
|
||||||
false
|
false
|
||||||
@ -311,13 +340,15 @@ impl TypeOneFSMState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if key != KeyFlag::NoneFlag {
|
if key != KeyFlag::NoneFlag {
|
||||||
Self::emit(ch);
|
Self::emit(tty, ch);
|
||||||
}
|
}
|
||||||
return TypeOneFSMState::Start;
|
return TypeOneFSMState::Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit(_ch: u8) {
|
#[inline(always)]
|
||||||
// todo: 发送到tty
|
fn emit(tty: &Arc<TtyDevice>, ch: u8) {
|
||||||
|
// 发送到tty
|
||||||
|
tty.input(&[ch]).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 处理Prtsc按下事件
|
/// @brief 处理Prtsc按下事件
|
||||||
@ -325,6 +356,7 @@ impl TypeOneFSMState {
|
|||||||
&self,
|
&self,
|
||||||
scancode: u8,
|
scancode: u8,
|
||||||
scancode_status: &mut ScanCodeStatus,
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
) -> TypeOneFSMState {
|
) -> TypeOneFSMState {
|
||||||
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
|
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
|
||||||
let i = match self {
|
let i = match self {
|
||||||
@ -336,7 +368,7 @@ impl TypeOneFSMState {
|
|||||||
return TypeOneFSMState::Start;
|
return TypeOneFSMState::Start;
|
||||||
}
|
}
|
||||||
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
||||||
return self.handle_type3(scancode, scancode_status);
|
return self.handle_type3(scancode, scancode_status, tty);
|
||||||
} else {
|
} else {
|
||||||
if i == 3 {
|
if i == 3 {
|
||||||
// 成功解析出PrtscPress
|
// 成功解析出PrtscPress
|
||||||
@ -352,6 +384,7 @@ impl TypeOneFSMState {
|
|||||||
&self,
|
&self,
|
||||||
scancode: u8,
|
scancode: u8,
|
||||||
scancode_status: &mut ScanCodeStatus,
|
scancode_status: &mut ScanCodeStatus,
|
||||||
|
tty: &Arc<TtyDevice>,
|
||||||
) -> TypeOneFSMState {
|
) -> TypeOneFSMState {
|
||||||
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
|
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
|
||||||
let i = match self {
|
let i = match self {
|
||||||
@ -363,7 +396,7 @@ impl TypeOneFSMState {
|
|||||||
return TypeOneFSMState::Start;
|
return TypeOneFSMState::Start;
|
||||||
}
|
}
|
||||||
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
||||||
return self.handle_type3(scancode, scancode_status);
|
return self.handle_type3(scancode, scancode_status, tty);
|
||||||
} else {
|
} else {
|
||||||
if i == 3 {
|
if i == 3 {
|
||||||
// 成功解析出PrtscRelease
|
// 成功解析出PrtscRelease
|
||||||
@ -446,7 +479,7 @@ const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
|
|||||||
/*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8,
|
/*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8,
|
||||||
/*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8,
|
/*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8,
|
||||||
/*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
|
/*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
|
||||||
/*0x0e*/ 0x0e as u8, 0x0e as u8, // BACKSPACE
|
/*0x0e \b */ 8 as u8, 8 as u8, // BACKSPACE
|
||||||
/*0x0f*/ '\t' as u8, '\t' as u8, // TAB
|
/*0x0f*/ '\t' as u8, '\t' as u8, // TAB
|
||||||
/*0x10*/ 'q' as u8, 'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8,
|
/*0x10*/ 'q' as u8, 'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8,
|
||||||
/*0x12*/ 'e' as u8, 'E' as u8, /*0x13*/ 'r' as u8, 'R' as u8,
|
/*0x12*/ 'e' as u8, 'E' as u8, /*0x13*/ 'r' as u8, 'R' as u8,
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
#include <driver/interrupt/apic/apic_timer.h>
|
#include <driver/interrupt/apic/apic_timer.h>
|
||||||
|
|
||||||
|
extern int rs_tty_init();
|
||||||
|
|
||||||
ul bsp_idt_size, bsp_gdt_size;
|
ul bsp_idt_size, bsp_gdt_size;
|
||||||
|
|
||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
@ -135,6 +137,7 @@ void system_initialize()
|
|||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
vfs_init();
|
vfs_init();
|
||||||
|
rs_tty_init();
|
||||||
|
|
||||||
cpu_init();
|
cpu_init();
|
||||||
ps2_keyboard_init();
|
ps2_keyboard_init();
|
||||||
|
@ -48,6 +48,7 @@ extern void process_exit_signal(struct process_control_block *pcb);
|
|||||||
extern void initial_proc_init_signal(struct process_control_block *pcb);
|
extern void initial_proc_init_signal(struct process_control_block *pcb);
|
||||||
extern void rs_process_exit_fpstate(struct process_control_block *pcb);
|
extern void rs_process_exit_fpstate(struct process_control_block *pcb);
|
||||||
extern int process_init_files();
|
extern int process_init_files();
|
||||||
|
extern int rs_init_stdio();
|
||||||
|
|
||||||
// 设置初始进程的PCB
|
// 设置初始进程的PCB
|
||||||
#define INITIAL_PROC(proc) \
|
#define INITIAL_PROC(proc) \
|
||||||
@ -452,10 +453,6 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
|||||||
current_pcb->mm->brk_end = brk_start_addr;
|
current_pcb->mm->brk_end = brk_start_addr;
|
||||||
current_pcb->mm->stack_start = stack_start_addr;
|
current_pcb->mm->stack_start = stack_start_addr;
|
||||||
|
|
||||||
// 关闭之前的文件描述符
|
|
||||||
process_exit_files(current_pcb);
|
|
||||||
process_init_files();
|
|
||||||
|
|
||||||
// 清除进程的vfork标志位
|
// 清除进程的vfork标志位
|
||||||
current_pcb->flags &= ~PF_VFORK;
|
current_pcb->flags &= ~PF_VFORK;
|
||||||
|
|
||||||
@ -540,9 +537,10 @@ struct process_control_block *process_init_rt_pcb(struct process_control_block *
|
|||||||
ul initial_kernel_thread(ul arg)
|
ul initial_kernel_thread(ul arg)
|
||||||
{
|
{
|
||||||
kinfo("initial proc running...\targ:%#018lx, vruntime=%d", arg, current_pcb->virtual_runtime);
|
kinfo("initial proc running...\targ:%#018lx, vruntime=%d", arg, current_pcb->virtual_runtime);
|
||||||
|
int val = 0;
|
||||||
|
val = scm_enable_double_buffer();
|
||||||
|
|
||||||
scm_enable_double_buffer();
|
rs_init_stdio();
|
||||||
|
|
||||||
// block_io_scheduler_init();
|
// block_io_scheduler_init();
|
||||||
ahci_init();
|
ahci_init();
|
||||||
mount_root_fs();
|
mount_root_fs();
|
||||||
|
@ -7,7 +7,7 @@ use alloc::boxed::Box;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{asm::current::current_pcb, fpu::FpState},
|
arch::{asm::current::current_pcb, fpu::FpState},
|
||||||
filesystem::vfs::file::{File, FileDescriptorVec},
|
filesystem::vfs::{file::{File, FileDescriptorVec, FileMode}, ROOT_INODE},
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{
|
||||||
process_control_block, CLONE_FS, PROC_INTERRUPTIBLE,
|
process_control_block, CLONE_FS, PROC_INTERRUPTIBLE,
|
||||||
PROC_RUNNING, PROC_STOPPED, PROC_UNINTERRUPTIBLE,
|
PROC_RUNNING, PROC_STOPPED, PROC_UNINTERRUPTIBLE,
|
||||||
@ -350,4 +350,37 @@ pub extern "C" fn rs_process_exit_fpstate(pcb: &'static mut process_control_bloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rs_init_stdio() -> i32 {
|
||||||
|
let r = init_stdio();
|
||||||
|
if r.is_ok() {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return r.unwrap_err().to_posix_errno();
|
||||||
|
}
|
||||||
|
}
|
||||||
// =========== 以上为导出到C的函数,在将来,进程管理模块被完全重构之后,需要删掉他们 END ============
|
// =========== 以上为导出到C的函数,在将来,进程管理模块被完全重构之后,需要删掉他们 END ============
|
||||||
|
|
||||||
|
/// @brief 初始化pid=1的进程的stdio
|
||||||
|
pub fn init_stdio() -> Result<(), SystemError> {
|
||||||
|
if current_pcb().pid != 1 {
|
||||||
|
return Err(SystemError::EPERM);
|
||||||
|
}
|
||||||
|
let tty_inode = ROOT_INODE()
|
||||||
|
.lookup("/dev/tty0")
|
||||||
|
.expect("Init stdio: can't find tty0");
|
||||||
|
let stdin =
|
||||||
|
File::new(tty_inode.clone(), FileMode::O_RDONLY).expect("Init stdio: can't create stdin");
|
||||||
|
let stdout =
|
||||||
|
File::new(tty_inode.clone(), FileMode::O_WRONLY).expect("Init stdio: can't create stdout");
|
||||||
|
let stderr = File::new(tty_inode.clone(), FileMode::O_WRONLY | FileMode::O_SYNC)
|
||||||
|
.expect("Init stdio: can't create stderr");
|
||||||
|
|
||||||
|
/*
|
||||||
|
按照规定,进程的文件描述符数组的前三个位置,分别是stdin, stdout, stderr
|
||||||
|
*/
|
||||||
|
assert_eq!(current_pcb().alloc_fd(stdin).unwrap(), 0);
|
||||||
|
assert_eq!(current_pcb().alloc_fd(stdout).unwrap(), 1);
|
||||||
|
assert_eq!(current_pcb().alloc_fd(stderr).unwrap(), 2);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
@ -6,3 +6,12 @@ pub struct TimeSpec {
|
|||||||
pub tv_sec: i64,
|
pub tv_sec: i64,
|
||||||
pub tv_nsec: i64,
|
pub tv_nsec: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TimeSpec {
|
||||||
|
pub fn new(sec: i64, nsec: i64) -> TimeSpec {
|
||||||
|
return TimeSpec {
|
||||||
|
tv_sec: sec,
|
||||||
|
tv_nsec: nsec,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -309,6 +309,11 @@ int shell_cmd_cat(int argc, char **argv)
|
|||||||
|
|
||||||
// 打开文件
|
// 打开文件
|
||||||
int fd = open(file_path, 0);
|
int fd = open(file_path, 0);
|
||||||
|
if (fd <= 0)
|
||||||
|
{
|
||||||
|
printf("ERROR: Cannot open file: %s, fd=%d\n", file_path, fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// 获取文件总大小
|
// 获取文件总大小
|
||||||
int file_size = lseek(fd, 0, SEEK_END);
|
int file_size = lseek(fd, 0, SEEK_END);
|
||||||
// 将文件指针切换回文件起始位置
|
// 将文件指针切换回文件起始位置
|
||||||
@ -320,6 +325,11 @@ int shell_cmd_cat(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
memset(buf, 0, 512);
|
memset(buf, 0, 512);
|
||||||
int l = read(fd, buf, 511);
|
int l = read(fd, buf, 511);
|
||||||
|
if (l < 0)
|
||||||
|
{
|
||||||
|
printf("ERROR: Cannot read file: %s\n", file_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
buf[l] = '\0';
|
buf[l] = '\0';
|
||||||
|
|
||||||
file_size -= l;
|
file_size -= l;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include <libKeyboard/keyboard.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <libKeyboard/keyboard.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -90,14 +90,14 @@ void main_loop(int kb_fd)
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// 打开键盘文件
|
// 打开键盘文件
|
||||||
char kb_file_path[] = "/dev/char/ps2_keyboard";
|
// char kb_file_path[] = "/dev/char/ps2_keyboard";
|
||||||
|
|
||||||
int kb_fd = open(kb_file_path, 0);
|
// int kb_fd = open(kb_file_path, 0);
|
||||||
print_ascii_logo();
|
print_ascii_logo();
|
||||||
// printf("before mkdir\n");
|
// printf("before mkdir\n");
|
||||||
// mkdir("/aaac", 0);
|
// mkdir("/aaac", 0);
|
||||||
// printf("after mkdir\n");
|
// printf("after mkdir\n");
|
||||||
main_loop(kb_fd);
|
main_loop(0);
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -155,9 +155,18 @@ int shell_readline(int fd, char *buf)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
key = keyboard_analyze_keycode(fd);
|
// key = keyboard_analyze_keycode(fd);
|
||||||
|
key = getchar();
|
||||||
|
// printf("key = %d\n", key);
|
||||||
|
if (key == 224)
|
||||||
|
{
|
||||||
|
key = getchar();
|
||||||
|
// printf("key = %d\n", key);
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case 72:
|
||||||
// 向上方向键
|
// 向上方向键
|
||||||
if (count_history != 0 && key == 0xc8)
|
if (count_history != 0)
|
||||||
{
|
{
|
||||||
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
||||||
printf("%c", '\b');
|
printf("%c", '\b');
|
||||||
@ -167,17 +176,27 @@ int shell_readline(int fd, char *buf)
|
|||||||
change_command(buf, 1);
|
change_command(buf, 1);
|
||||||
count = strlen(buf);
|
count = strlen(buf);
|
||||||
}
|
}
|
||||||
|
key = 0xc8;
|
||||||
|
break;
|
||||||
|
case 80:
|
||||||
// 向下方向键
|
// 向下方向键
|
||||||
if (count_history != 0 && key == 0x50)
|
if (count_history != 0)
|
||||||
{
|
{
|
||||||
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
||||||
printf("%c", '\b');
|
printf("%c", '\b');
|
||||||
clear_command(count, buf);
|
clear_command(count, buf);
|
||||||
count = 0;
|
count = 0;
|
||||||
//向现在
|
// 向历史
|
||||||
change_command(buf, -1);
|
change_command(buf, -1);
|
||||||
count = strlen(buf);
|
count = strlen(buf);
|
||||||
}
|
}
|
||||||
|
key = 0x50;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (key == '\n')
|
if (key == '\n')
|
||||||
{
|
{
|
||||||
if (count > 0 && current_command_index >= count_history)
|
if (count > 0 && current_command_index >= count_history)
|
||||||
|
@ -57,7 +57,7 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode);
|
|||||||
int fclose(FILE *stream);
|
int fclose(FILE *stream);
|
||||||
int puts(const char *s);
|
int puts(const char *s);
|
||||||
int putchar(int c);
|
int putchar(int c);
|
||||||
|
int getchar(void);
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
|
|
||||||
|
#include <libsystem/syscall.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libsystem/syscall.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static char *write_num(char *str, uint64_t num, int base, int field_width, int precision, int flags);
|
static char *write_num(char *str, uint64_t num, int base, int field_width, int precision, int flags);
|
||||||
static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags);
|
static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags);
|
||||||
@ -46,7 +47,8 @@ int printf(const char *fmt, ...)
|
|||||||
|
|
||||||
count = vsprintf(buf, fmt, args);
|
count = vsprintf(buf, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
put_string(buf, COLOR_WHITE, COLOR_BLACK);
|
// put_string(buf, COLOR_WHITE, COLOR_BLACK);
|
||||||
|
write(1, buf, count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,13 @@ int fprintf(FILE *restrict stream, const char *restrict format, ...)
|
|||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getchar(void)
|
||||||
|
{
|
||||||
|
unsigned int c;
|
||||||
|
read(0, &c, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
int puts(const char *s)
|
int puts(const char *s)
|
||||||
{
|
{
|
||||||
return put_string(s, COLOR_WHITE, COLOR_BLACK);
|
return put_string(s, COLOR_WHITE, COLOR_BLACK);
|
||||||
@ -47,17 +54,17 @@ int ferror(FILE *stream)
|
|||||||
|
|
||||||
int fclose(FILE *stream)
|
int fclose(FILE *stream)
|
||||||
{
|
{
|
||||||
|
int retval = close(stream->fd);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
if (stream->fd >= 3)
|
if (stream->fd >= 3)
|
||||||
{
|
|
||||||
int retcval = close(stream->fd);
|
|
||||||
free(stream);
|
free(stream);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 请注意,这个函数的实现,没有遵照posix,行为也与Linux的不一致,请在将来用Rust重构时改变它,以使得它的行为与Linux的一致。
|
// FIXME:
|
||||||
|
// 请注意,这个函数的实现,没有遵照posix,行为也与Linux的不一致,请在将来用Rust重构时改变它,以使得它的行为与Linux的一致。
|
||||||
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||||
{
|
{
|
||||||
FILE *stream = malloc(sizeof(FILE));
|
FILE *stream = malloc(sizeof(FILE));
|
||||||
|
Reference in New Issue
Block a user