Add wnohang, make PS/2 driver write input to display scheme, which then passes it to the shell
This commit is contained in:
parent
046236c10f
commit
76b0c7eeea
6
Makefile
6
Makefile
|
@ -24,12 +24,12 @@ all: $(KBUILD)/harddrive.bin
|
||||||
clean:
|
clean:
|
||||||
cargo clean
|
cargo clean
|
||||||
cargo clean --manifest-path libstd/Cargo.toml
|
cargo clean --manifest-path libstd/Cargo.toml
|
||||||
cargo clean --manifest-path init/Cargo.toml
|
|
||||||
cargo clean --manifest-path ion/Cargo.toml
|
|
||||||
cargo clean --manifest-path login/Cargo.toml
|
|
||||||
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/pcid/Cargo.toml
|
cargo clean --manifest-path drivers/pcid/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/vesad/Cargo.toml
|
cargo clean --manifest-path drivers/vesad/Cargo.toml
|
||||||
|
cargo clean --manifest-path programs/init/Cargo.toml
|
||||||
|
cargo clean --manifest-path programs/ion/Cargo.toml
|
||||||
|
cargo clean --manifest-path programs/login/Cargo.toml
|
||||||
cargo clean --manifest-path schemes/example/Cargo.toml
|
cargo clean --manifest-path schemes/example/Cargo.toml
|
||||||
rm -rf initfs/bin
|
rm -rf initfs/bin
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl Mapper {
|
||||||
|
|
||||||
/// Map a page to the next free frame
|
/// Map a page to the next free frame
|
||||||
pub fn map(&mut self, page: Page, flags: EntryFlags) {
|
pub fn map(&mut self, page: Page, flags: EntryFlags) {
|
||||||
let frame = allocate_frame().expect("out of memory");
|
let frame = allocate_frame().expect("out of frames");
|
||||||
self.map_to(page, frame, flags)
|
self.map_to(page, frame, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@ use keymap;
|
||||||
|
|
||||||
pub fn keyboard() {
|
pub fn keyboard() {
|
||||||
let mut file = File::open("irq:1").expect("ps2d: failed to open irq:1");
|
let mut file = File::open("irq:1").expect("ps2d: failed to open irq:1");
|
||||||
|
let mut input = File::open("display:input").expect("ps2d: failed to open display:input");
|
||||||
|
|
||||||
|
let mut lshift = false;
|
||||||
|
let mut rshift = false;
|
||||||
loop {
|
loop {
|
||||||
let mut irqs = [0; 8];
|
let mut irqs = [0; 8];
|
||||||
if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::<usize>() {
|
if file.read(&mut irqs).expect("ps2d: failed to read irq:1") >= mem::size_of::<usize>() {
|
||||||
|
@ -16,17 +19,25 @@ pub fn keyboard() {
|
||||||
asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile");
|
asm!("in al, dx" : "={al}"(data) : "{dx}"(0x60) : : "intel", "volatile");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.write(&irqs).expect("ps2d: failed to write irq:1");
|
||||||
|
|
||||||
let (scancode, pressed) = if data >= 0x80 {
|
let (scancode, pressed) = if data >= 0x80 {
|
||||||
(data - 0x80, false)
|
(data - 0x80, false)
|
||||||
} else {
|
} else {
|
||||||
(data, true)
|
(data, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
if pressed {
|
if scancode == 0x2A {
|
||||||
print!("{}", keymap::get_char(scancode));
|
lshift = pressed;
|
||||||
|
} else if scancode == 0x36 {
|
||||||
|
rshift = pressed;
|
||||||
|
} else if pressed {
|
||||||
|
let c = keymap::get_char(scancode, lshift || rshift);
|
||||||
|
if c != '\0' {
|
||||||
|
print!("{}", c);
|
||||||
|
input.write(&[c as u8]).expect("ps2d: failed to write input");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write(&irqs).expect("ps2d: failed to write irq:1");
|
|
||||||
} else {
|
} else {
|
||||||
thread::yield_now();
|
thread::yield_now();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +1,71 @@
|
||||||
static ENGLISH: [[char; 3]; 58] = [
|
static ENGLISH: [[char; 2]; 58] = [
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
['\x1B', '\x1B', '\x1B'],
|
['\x1B', '\x1B'],
|
||||||
['1', '!', '1'],
|
['1', '!'],
|
||||||
['2', '@', '2'],
|
['2', '@'],
|
||||||
['3', '#', '3'],
|
['3', '#'],
|
||||||
['4', '$', '4'],
|
['4', '$'],
|
||||||
['5', '%', '5'],
|
['5', '%'],
|
||||||
['6', '^', '6'],
|
['6', '^'],
|
||||||
['7', '&', '7'],
|
['7', '&'],
|
||||||
['8', '*', '8'],
|
['8', '*'],
|
||||||
['9', '(', '9'],
|
['9', '('],
|
||||||
['0', ')', '0'],
|
['0', ')'],
|
||||||
['-', '_', '-'],
|
['-', '_'],
|
||||||
['=', '+', '='],
|
['=', '+'],
|
||||||
['\0', '\0', '\0'],
|
['\x7F', '\x7F'],
|
||||||
['\t', '\t', '\t'],
|
['\t', '\t'],
|
||||||
['q', 'Q', 'q'],
|
['q', 'Q'],
|
||||||
['w', 'W', 'w'],
|
['w', 'W'],
|
||||||
['e', 'E', 'e'],
|
['e', 'E'],
|
||||||
['r', 'R', 'r'],
|
['r', 'R'],
|
||||||
['t', 'T', 't'],
|
['t', 'T'],
|
||||||
['y', 'Y', 'y'],
|
['y', 'Y'],
|
||||||
['u', 'U', 'u'],
|
['u', 'U'],
|
||||||
['i', 'I', 'i'],
|
['i', 'I'],
|
||||||
['o', 'O', 'o'],
|
['o', 'O'],
|
||||||
['p', 'P', 'p'],
|
['p', 'P'],
|
||||||
['[', '{', '['],
|
['[', '{'],
|
||||||
[']', '}', ']'],
|
[']', '}'],
|
||||||
['\n', '\n', '\n'],
|
['\n', '\n'],
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
['a', 'A', 'a'],
|
['a', 'A'],
|
||||||
['s', 'S', 's'],
|
['s', 'S'],
|
||||||
['d', 'D', 'd'],
|
['d', 'D'],
|
||||||
['f', 'F', 'f'],
|
['f', 'F'],
|
||||||
['g', 'G', 'g'],
|
['g', 'G'],
|
||||||
['h', 'H', 'h'],
|
['h', 'H'],
|
||||||
['j', 'J', 'j'],
|
['j', 'J'],
|
||||||
['k', 'K', 'k'],
|
['k', 'K'],
|
||||||
['l', 'L', 'l'],
|
['l', 'L'],
|
||||||
[';', ':', ';'],
|
[';', ':'],
|
||||||
['\'', '"', '\''],
|
['\'', '"'],
|
||||||
['`', '~', '`'],
|
['`', '~'],
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
['\\', '|', '\\'],
|
['\\', '|'],
|
||||||
['z', 'Z', 'z'],
|
['z', 'Z'],
|
||||||
['x', 'X', 'x'],
|
['x', 'X'],
|
||||||
['c', 'C', 'c'],
|
['c', 'C'],
|
||||||
['v', 'V', 'v'],
|
['v', 'V'],
|
||||||
['b', 'B', 'b'],
|
['b', 'B'],
|
||||||
['n', 'N', 'n'],
|
['n', 'N'],
|
||||||
['m', 'M', 'm'],
|
['m', 'M'],
|
||||||
[',', '<', ','],
|
[',', '<'],
|
||||||
['.', '>', '.'],
|
['.', '>'],
|
||||||
['/', '?', '/'],
|
['/', '?'],
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
['\0', '\0', '\0'],
|
['\0', '\0'],
|
||||||
[' ', ' ', ' ']
|
[' ', ' ']
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn get_char(scancode: u8) -> char {
|
pub fn get_char(scancode: u8, shift: bool) -> char {
|
||||||
if let Some(c) = ENGLISH.get(scancode as usize) {
|
if let Some(c) = ENGLISH.get(scancode as usize) {
|
||||||
c[0]
|
if shift {
|
||||||
|
c[1]
|
||||||
|
} else {
|
||||||
|
c[0]
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
'\0'
|
'\0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern crate ransid;
|
||||||
extern crate syscall;
|
extern crate syscall;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::{slice, thread};
|
use std::{slice, thread};
|
||||||
|
@ -24,32 +25,55 @@ pub mod primitive;
|
||||||
|
|
||||||
struct DisplayScheme {
|
struct DisplayScheme {
|
||||||
console: RefCell<Console>,
|
console: RefCell<Console>,
|
||||||
display: RefCell<Display>
|
display: RefCell<Display>,
|
||||||
|
input: RefCell<VecDeque<u8>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scheme for DisplayScheme {
|
impl Scheme for DisplayScheme {
|
||||||
fn open(&self, _path: &[u8], _flags: usize) -> Result<usize> {
|
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
|
||||||
Ok(0)
|
if path == b"input" {
|
||||||
|
Ok(1)
|
||||||
|
} else {
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dup(&self, _id: usize) -> Result<usize> {
|
fn dup(&self, id: usize) -> Result<usize> {
|
||||||
Ok(0)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, _id: usize, buf: &[u8]) -> Result<usize> {
|
fn read(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
let mut display = self.display.borrow_mut();
|
let mut i = 0;
|
||||||
self.console.borrow_mut().write(buf, |event| {
|
let mut input = self.input.borrow_mut();
|
||||||
match event {
|
while i < buf.len() && ! input.is_empty() {
|
||||||
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data),
|
buf[i] = input.pop_front().unwrap();
|
||||||
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data),
|
i += 1;
|
||||||
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data)
|
}
|
||||||
|
Ok(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||||
|
if id == 1 {
|
||||||
|
let mut input = self.input.borrow_mut();
|
||||||
|
for &b in buf.iter() {
|
||||||
|
input.push_back(b);
|
||||||
}
|
}
|
||||||
});
|
Ok(buf.len())
|
||||||
Ok(buf.len())
|
} else {
|
||||||
|
let mut display = self.display.borrow_mut();
|
||||||
|
self.console.borrow_mut().write(buf, |event| {
|
||||||
|
match event {
|
||||||
|
Event::Char { x, y, c, color, .. } => display.char(x * 8, y * 16, c, color.data),
|
||||||
|
Event::Rect { x, y, w, h, color } => display.rect(x * 8, y * 16, w * 8, h * 16, color.data),
|
||||||
|
Event::Scroll { rows, color } => display.scroll(rows * 16, color.data)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self, _id: usize) -> Result<usize> {
|
fn close(&self, _id: usize) -> Result<usize> {
|
||||||
|
@ -89,15 +113,27 @@ fn main() {
|
||||||
display: RefCell::new(Display::new(width, height,
|
display: RefCell::new(Display::new(width, height,
|
||||||
unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) },
|
unsafe { slice::from_raw_parts_mut(onscreen as *mut u32, size) },
|
||||||
unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }
|
unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) }
|
||||||
))
|
)),
|
||||||
|
input: RefCell::new(VecDeque::new())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut blocked = VecDeque::new();
|
||||||
loop {
|
loop {
|
||||||
let mut packet = Packet::default();
|
let mut packet = Packet::default();
|
||||||
socket.read(&mut packet).expect("vesad: failed to read display scheme");
|
socket.read(&mut packet).expect("vesad: failed to read display scheme");
|
||||||
//println!("vesad: {:?}", packet);
|
//println!("vesad: {:?}", packet);
|
||||||
scheme.handle(&mut packet);
|
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.input.borrow().is_empty() {
|
||||||
socket.write(&packet).expect("vesad: failed to write display scheme");
|
blocked.push_back(packet);
|
||||||
|
} else {
|
||||||
|
scheme.handle(&mut packet);
|
||||||
|
socket.write(&packet).expect("vesad: failed to write display scheme");
|
||||||
|
}
|
||||||
|
while ! scheme.input.borrow().is_empty() {
|
||||||
|
if let Some(mut packet) = blocked.pop_front() {
|
||||||
|
scheme.handle(&mut packet);
|
||||||
|
socket.write(&packet).expect("vesad: failed to write display scheme");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use elf::{self, program_header};
|
||||||
use scheme;
|
use scheme;
|
||||||
use syscall;
|
use syscall;
|
||||||
use syscall::error::*;
|
use syscall::error::*;
|
||||||
use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE};
|
use syscall::flag::{CLONE_VM, CLONE_FS, CLONE_FILES, MAP_WRITE, MAP_WRITE_COMBINE, WNOHANG};
|
||||||
use syscall::validate::{validate_slice, validate_slice_mut};
|
use syscall::validate::{validate_slice, validate_slice_mut};
|
||||||
|
|
||||||
pub fn brk(address: usize) -> Result<usize> {
|
pub fn brk(address: usize) -> Result<usize> {
|
||||||
|
@ -594,7 +594,7 @@ pub fn sched_yield() -> Result<usize> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize> {
|
pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
||||||
//TODO: Implement status_ptr and options
|
//TODO: Implement status_ptr and options
|
||||||
loop {
|
loop {
|
||||||
{
|
{
|
||||||
|
@ -616,6 +616,8 @@ pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize>
|
||||||
if exited {
|
if exited {
|
||||||
let mut contexts = context::contexts_mut();
|
let mut contexts = context::contexts_mut();
|
||||||
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
|
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
|
||||||
|
} else if flags & WNOHANG == WNOHANG {
|
||||||
|
return Ok(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
libstd
2
libstd
|
@ -1 +1 @@
|
||||||
Subproject commit ae80aff4d39b2d3a83f7d32bc95739e4e1169184
|
Subproject commit a5a6e9fe349d80918d6fc233d23530c4bf3b4f96
|
|
@ -11,13 +11,13 @@ pub fn main() {
|
||||||
let sh = args.next().expect("login: no sh provided");
|
let sh = args.next().expect("login: no sh provided");
|
||||||
let sh_args: Vec<String> = args.collect();
|
let sh_args: Vec<String> = args.collect();
|
||||||
|
|
||||||
syscall::close(2);
|
let _ = syscall::close(2);
|
||||||
syscall::close(1);
|
let _ = syscall::close(1);
|
||||||
syscall::close(0);
|
let _ = syscall::close(0);
|
||||||
|
|
||||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||||
syscall::open(&tty, syscall::flag::O_RDWR);
|
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -41,3 +41,5 @@ pub const O_FSYNC: usize = 0x80;
|
||||||
pub const O_CREAT: usize = 0x200;
|
pub const O_CREAT: usize = 0x200;
|
||||||
pub const O_TRUNC: usize = 0x400;
|
pub const O_TRUNC: usize = 0x400;
|
||||||
pub const O_EXCL: usize = 0x800;
|
pub const O_EXCL: usize = 0x800;
|
||||||
|
|
||||||
|
pub const WNOHANG: usize = 1;
|
||||||
|
|
Loading…
Reference in a new issue