Add wnohang, make PS/2 driver write input to display scheme, which then passes it to the shell

This commit is contained in:
Jeremy Soller 2016-09-22 10:10:27 -06:00
parent 046236c10f
commit 76b0c7eeea
9 changed files with 151 additions and 96 deletions

View file

@ -24,12 +24,12 @@ all: $(KBUILD)/harddrive.bin
clean:
cargo clean
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/pcid/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
rm -rf initfs/bin
rm -rf build

View file

@ -42,7 +42,7 @@ impl Mapper {
/// Map a page to the next free frame
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)
}

View file

@ -7,7 +7,10 @@ use keymap;
pub fn keyboard() {
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 {
let mut irqs = [0; 8];
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");
}
file.write(&irqs).expect("ps2d: failed to write irq:1");
let (scancode, pressed) = if data >= 0x80 {
(data - 0x80, false)
} else {
(data, true)
};
if pressed {
print!("{}", keymap::get_char(scancode));
if scancode == 0x2A {
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 {
thread::yield_now();
}

View file

@ -1,67 +1,71 @@
static ENGLISH: [[char; 3]; 58] = [
['\0', '\0', '\0'],
['\x1B', '\x1B', '\x1B'],
['1', '!', '1'],
['2', '@', '2'],
['3', '#', '3'],
['4', '$', '4'],
['5', '%', '5'],
['6', '^', '6'],
['7', '&', '7'],
['8', '*', '8'],
['9', '(', '9'],
['0', ')', '0'],
['-', '_', '-'],
['=', '+', '='],
['\0', '\0', '\0'],
['\t', '\t', '\t'],
['q', 'Q', 'q'],
['w', 'W', 'w'],
['e', 'E', 'e'],
['r', 'R', 'r'],
['t', 'T', 't'],
['y', 'Y', 'y'],
['u', 'U', 'u'],
['i', 'I', 'i'],
['o', 'O', 'o'],
['p', 'P', 'p'],
['[', '{', '['],
[']', '}', ']'],
['\n', '\n', '\n'],
['\0', '\0', '\0'],
['a', 'A', 'a'],
['s', 'S', 's'],
['d', 'D', 'd'],
['f', 'F', 'f'],
['g', 'G', 'g'],
['h', 'H', 'h'],
['j', 'J', 'j'],
['k', 'K', 'k'],
['l', 'L', 'l'],
[';', ':', ';'],
['\'', '"', '\''],
['`', '~', '`'],
['\0', '\0', '\0'],
['\\', '|', '\\'],
['z', 'Z', 'z'],
['x', 'X', 'x'],
['c', 'C', 'c'],
['v', 'V', 'v'],
['b', 'B', 'b'],
['n', 'N', 'n'],
['m', 'M', 'm'],
[',', '<', ','],
['.', '>', '.'],
['/', '?', '/'],
['\0', '\0', '\0'],
['\0', '\0', '\0'],
['\0', '\0', '\0'],
[' ', ' ', ' ']
static ENGLISH: [[char; 2]; 58] = [
['\0', '\0'],
['\x1B', '\x1B'],
['1', '!'],
['2', '@'],
['3', '#'],
['4', '$'],
['5', '%'],
['6', '^'],
['7', '&'],
['8', '*'],
['9', '('],
['0', ')'],
['-', '_'],
['=', '+'],
['\x7F', '\x7F'],
['\t', '\t'],
['q', 'Q'],
['w', 'W'],
['e', 'E'],
['r', 'R'],
['t', 'T'],
['y', 'Y'],
['u', 'U'],
['i', 'I'],
['o', 'O'],
['p', 'P'],
['[', '{'],
[']', '}'],
['\n', '\n'],
['\0', '\0'],
['a', 'A'],
['s', 'S'],
['d', 'D'],
['f', 'F'],
['g', 'G'],
['h', 'H'],
['j', 'J'],
['k', 'K'],
['l', 'L'],
[';', ':'],
['\'', '"'],
['`', '~'],
['\0', '\0'],
['\\', '|'],
['z', 'Z'],
['x', 'X'],
['c', 'C'],
['v', 'V'],
['b', 'B'],
['n', 'N'],
['m', 'M'],
[',', '<'],
['.', '>'],
['/', '?'],
['\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) {
c[0]
if shift {
c[1]
} else {
c[0]
}
} else {
'\0'
}

View file

@ -8,6 +8,7 @@ extern crate ransid;
extern crate syscall;
use std::cell::RefCell;
use std::collections::VecDeque;
use std::fs::File;
use std::io::{Read, Write};
use std::{slice, thread};
@ -24,32 +25,55 @@ pub mod primitive;
struct DisplayScheme {
console: RefCell<Console>,
display: RefCell<Display>
display: RefCell<Display>,
input: RefCell<VecDeque<u8>>
}
impl Scheme for DisplayScheme {
fn open(&self, _path: &[u8], _flags: usize) -> Result<usize> {
Ok(0)
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
if path == b"input" {
Ok(1)
} else {
Ok(0)
}
}
fn dup(&self, _id: usize) -> Result<usize> {
Ok(0)
fn dup(&self, id: usize) -> Result<usize> {
Ok(id)
}
fn fsync(&self, _id: usize) -> Result<usize> {
Ok(0)
}
fn write(&self, _id: usize, buf: &[u8]) -> Result<usize> {
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)
fn read(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
let mut i = 0;
let mut input = self.input.borrow_mut();
while i < buf.len() && ! input.is_empty() {
buf[i] = input.pop_front().unwrap();
i += 1;
}
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> {
@ -89,15 +113,27 @@ fn main() {
display: RefCell::new(Display::new(width, height,
unsafe { slice::from_raw_parts_mut(onscreen 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 {
let mut packet = Packet::default();
socket.read(&mut packet).expect("vesad: failed to read display scheme");
//println!("vesad: {:?}", packet);
scheme.handle(&mut packet);
socket.write(&packet).expect("vesad: failed to write display scheme");
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.input.borrow().is_empty() {
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");
}
}
}
});
}

View file

@ -18,7 +18,7 @@ use elf::{self, program_header};
use scheme;
use syscall;
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};
pub fn brk(address: usize) -> Result<usize> {
@ -594,7 +594,7 @@ pub fn sched_yield() -> Result<usize> {
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
loop {
{
@ -616,6 +616,8 @@ pub fn waitpid(pid: usize, status_ptr: usize, _options: usize) -> Result<usize>
if exited {
let mut contexts = context::contexts_mut();
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
} else if flags & WNOHANG == WNOHANG {
return Ok(0);
}
}

2
libstd

@ -1 +1 @@
Subproject commit ae80aff4d39b2d3a83f7d32bc95739e4e1169184
Subproject commit a5a6e9fe349d80918d6fc233d23530c4bf3b4f96

View file

@ -11,13 +11,13 @@ pub fn main() {
let sh = args.next().expect("login: no sh provided");
let sh_args: Vec<String> = args.collect();
syscall::close(2);
syscall::close(1);
syscall::close(0);
let _ = syscall::close(2);
let _ = syscall::close(1);
let _ = syscall::close(0);
syscall::open(&tty, syscall::flag::O_RDWR);
syscall::open(&tty, syscall::flag::O_RDWR);
syscall::open(&tty, syscall::flag::O_RDWR);
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
let _ = syscall::open(&tty, syscall::flag::O_RDWR);
thread::spawn(move || {
loop {

View file

@ -41,3 +41,5 @@ pub const O_FSYNC: usize = 0x80;
pub const O_CREAT: usize = 0x200;
pub const O_TRUNC: usize = 0x400;
pub const O_EXCL: usize = 0x800;
pub const WNOHANG: usize = 1;