Browse Source

第一套键盘扫描码的状态机 (#216)

第一套键盘扫描码的状态机
---------

Co-authored-by: guanjinquan <[email protected]>
Co-authored-by: longjin <[email protected]>
Gou Ngai 1 year ago
parent
commit
5fb12ce447

+ 4 - 1
kernel/src/driver/keyboard/ps2_keyboard.c

@@ -14,6 +14,7 @@ static struct kfifo_t kb_buf;
 // 缓冲区等待队列
 static wait_queue_node_t ps2_keyboard_wait_queue;
 extern void ps2_keyboard_register(struct vfs_file_operations_t *);
+extern void ps2_keyboard_parse_keycode(uint8_t input); 
 
 // 缓冲区读写锁
 static spinlock_t ps2_kb_buf_rw_lock;
@@ -143,7 +144,7 @@ struct vfs_file_operations_t ps2_keyboard_fops =
 void ps2_keyboard_handler(ul irq_num, ul buf_vaddr, struct pt_regs *regs)
 {
     unsigned char x = io_in8(PORT_PS2_KEYBOARD_DATA);
-
+    ps2_keyboard_parse_keycode((uint8_t)x);
     uint8_t count = kfifo_in((struct kfifo_t *)buf_vaddr, &x, sizeof(unsigned char));
     if (count == 0)
     {
@@ -152,6 +153,7 @@ void ps2_keyboard_handler(ul irq_num, ul buf_vaddr, struct pt_regs *regs)
     }
 
     wait_queue_wakeup(&ps2_keyboard_wait_queue, PROC_UNINTERRUPTIBLE);
+    
 }
 /**
  * @brief 初始化键盘驱动程序的函数
@@ -216,4 +218,5 @@ void ps2_keyboard_exit()
 {
     irq_unregister(PS2_KEYBOARD_INTR_VECTOR);
     kfifo_free_alloc(&kb_buf);
+
 }

+ 1 - 18
kernel/src/driver/keyboard/ps2_keyboard.h

@@ -2,14 +2,13 @@
 
 #include <common/glib.h>
 
-#define PS2_KEYBOARD_INTR_VECTOR 0x21   // 键盘的中断向量号
+#define PS2_KEYBOARD_INTR_VECTOR 0x21 // 键盘的中断向量号
 
 // 定义键盘循环队列缓冲区大小为100bytes
 #define ps2_keyboard_buffer_size 8
 
 #define KEYBOARD_CMD_RESET_BUFFER 1
 
-
 #define PORT_PS2_KEYBOARD_DATA 0x60
 #define PORT_PS2_KEYBOARD_STATUS 0x64
 #define PORT_PS2_KEYBOARD_CONTROL 0x64
@@ -30,11 +29,8 @@
 #define wait_ps2_keyboard_read() while (io_in8(PORT_PS2_KEYBOARD_STATUS) & PS2_KEYBOARD_FLAG_OUTBUF_FULL)
 // #define wait_ps2_keyboard_read() (1)
 
-
 extern struct vfs_file_operations_t ps2_keyboard_fops;
 
-
-
 /**
  * @brief 初始化键盘驱动程序的函数
  *
@@ -46,16 +42,3 @@ void ps2_keyboard_init();
  *
  */
 void ps2_keyboard_exit();
-
-/**
- * @brief 解析键盘扫描码
- * 
- */
-void ps2_keyboard_analyze_keycode();
-
-/**
- * @brief 从缓冲队列中获取键盘扫描码
- * @return 键盘扫描码
- * 若缓冲队列为空则返回-1
- */
-int ps2_keyboard_get_scancode();

+ 18 - 3
kernel/src/driver/keyboard/ps2_keyboard.rs

@@ -8,13 +8,18 @@ use crate::{
         vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
     },
     include::bindings::bindings::{vfs_file_operations_t, vfs_file_t, vfs_index_node_t},
-    libs::rwlock::RwLock,
-    time::TimeSpec, syscall::SystemError,
+    libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
+    syscall::SystemError,
+    time::TimeSpec,
 };
 
 #[derive(Debug)]
 pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
 
+lazy_static! {
+    static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new());
+}
+
 #[derive(Debug)]
 pub struct PS2KeyBoardInode {
     /// uuid 暂时不知道有什么用(x
@@ -122,7 +127,10 @@ impl IndexNode for LockedPS2KeyBoardInode {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut crate::filesystem::vfs::FilePrivateData) -> Result<(), SystemError> {
+    fn close(
+        &self,
+        _data: &mut crate::filesystem::vfs::FilePrivateData,
+    ) -> Result<(), SystemError> {
         let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
         if prev_ref_count == 1 {
             // 最后一次关闭,需要释放
@@ -167,3 +175,10 @@ impl IndexNode for LockedPS2KeyBoardInode {
         return Err(SystemError::ENOTSUP);
     }
 }
+
+#[allow(dead_code)]
+#[no_mangle]
+/// for test
+pub extern "C" fn ps2_keyboard_parse_keycode(input: u8) {
+    PS2_KEYBOARD_FSM.lock().parse(input);
+}

+ 1 - 0
kernel/src/filesystem/devfs/mod.rs

@@ -511,3 +511,4 @@ 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> {
     return devfs_exact_ref!().unregister_device(name, device);
 }
+

+ 2 - 1
kernel/src/lib.rs

@@ -51,7 +51,7 @@ use mm::allocator::KernelAllocator;
 // <3>
 use crate::{
     arch::asm::current::current_pcb,
-    include::bindings::bindings::{process_do_exit, BLACK, GREEN},
+    include::bindings::bindings::{process_do_exit, BLACK, GREEN}, filesystem::vfs::ROOT_INODE,
 };
 
 // 声明全局的slab分配器
@@ -99,5 +99,6 @@ pub fn panic(info: &PanicInfo) -> ! {
 pub extern "C" fn __rust_demo_func() -> i32 {
     printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
 
+
     return 0;
 }

+ 511 - 0
kernel/src/libs/keyboard_parser.rs

@@ -0,0 +1,511 @@
+use crate::kdebug;
+
+#[allow(dead_code)]
+pub const NUM_SCAN_CODES: u8 = 0x80;
+#[allow(dead_code)]
+pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2;
+
+#[allow(dead_code)]
+pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下
+
+/// 标志状态
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq)]
+#[allow(dead_code)]
+pub enum KeyFlag {
+    NoneFlag = 0 as u8,
+    PauseBreak = 1 as u8,
+    PrintScreenPress = 2 as u8,
+    PrintScreenRelease = 4 as u8,
+    OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
+}
+
+/// @brief A FSM to parse type one keyboard scan code
+#[derive(Debug)]
+#[allow(dead_code)]
+pub struct TypeOneFSM {
+    status: ScanCodeStatus,
+    current_state: TypeOneFSMState,
+}
+
+impl TypeOneFSM {
+    #[allow(dead_code)]
+    pub fn new() -> Self {
+        Self {
+            status: ScanCodeStatus::new(),
+            current_state: TypeOneFSMState::Start,
+        }
+    }
+
+    /// @brief 解析扫描码
+    #[allow(dead_code)]
+    pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
+        self.current_state = self.current_state.parse(scancode, &mut self.status);
+        self.current_state
+    }
+}
+
+/// @brief 第一类扫描码状态机的状态
+#[derive(Debug, Copy, Clone)]
+pub enum TypeOneFSMState {
+    /// 起始状态
+    Start,
+    /// PauseBreak 第n个扫描码
+    PauseBreak(u8),
+    /// 多扫描码功能键起始状态
+    Func0,
+    /// 第三类扫描码或字符
+    Type3,
+
+    PrtscPress(u8),
+    PrtscRelease(u8),
+}
+
+impl TypeOneFSMState {
+    /// @brief 状态机总控程序
+    fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
+        // kdebug!("the code is {:#x}\n", scancode);
+        match self {
+            TypeOneFSMState::Start => {
+                return self.handle_start(scancode, scancode_status);
+            }
+            TypeOneFSMState::PauseBreak(n) => {
+                return self.handle_pause_break(*n, scancode_status);
+            }
+            TypeOneFSMState::Func0 => {
+                return self.handle_func0(scancode, scancode_status);
+            }
+            TypeOneFSMState::Type3 => {
+                return self.handle_type3(scancode, scancode_status);
+            }
+            TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status),
+            TypeOneFSMState::PrtscRelease(n) => {
+                return self.handle_prtsc_release(*n, scancode_status)
+            }
+        }
+    }
+
+    /// @brief 处理起始状态
+    fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
+        //kdebug!("in handle_start the code is {:#x}\n",scancode);
+        match scancode {
+            0xe1 => {
+                return TypeOneFSMState::PauseBreak(1);
+            }
+            0xe0 => {
+                return TypeOneFSMState::Func0;
+            }
+            _ => {
+                //kdebug!("in _d the code is {:#x}\n",scancode);
+                return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status);
+            }
+        }
+    }
+
+    /// @brief 处理PauseBreak状态
+    fn handle_pause_break(
+        &self,
+        scancode: u8,
+        scancode_status: &mut ScanCodeStatus,
+    ) -> TypeOneFSMState {
+        static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
+        let i = match self {
+            TypeOneFSMState::PauseBreak(i) => *i,
+            _ => {
+                return self.handle_type3(scancode, scancode_status);
+            }
+        };
+        if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
+            return self.handle_type3(scancode, scancode_status);
+        } else {
+            if i == 5 {
+                // 所有Pause Break扫描码都被清除
+                return TypeOneFSMState::Start;
+            } else {
+                return TypeOneFSMState::PauseBreak(i + 1);
+            }
+        }
+    }
+
+    fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
+        //0xE0
+        match scancode {
+            0x2a => {
+                return TypeOneFSMState::PrtscPress(2);
+            }
+            0xb7 => {
+                return TypeOneFSMState::PrtscRelease(2);
+            }
+            0x1d => {
+                // 按下右边的ctrl
+                scancode_status.ctrl_r = true;
+            }
+            0x9d => {
+                // 松开右边的ctrl
+                scancode_status.ctrl_r = false;
+            }
+            0x38 => {
+                // 按下右边的alt
+                scancode_status.alt_r = true;
+            }
+            0xb8 => {
+                // 松开右边的alt
+                scancode_status.alt_r = false;
+            }
+            0x5b => {
+                scancode_status.gui_l = true;
+            }
+            0xdb => {
+                scancode_status.gui_l = false;
+            }
+            0x5c => {
+                scancode_status.gui_r = true;
+            }
+            0xdc => {
+                scancode_status.gui_r = false;
+            }
+            0x5d => {
+                scancode_status.apps = true;
+            }
+            0xdd => {
+                scancode_status.apps = false;
+            }
+            0x52 => {
+                scancode_status.insert = true;
+            }
+            0xd2 => {
+                scancode_status.insert = false;
+            }
+            0x47 => {
+                scancode_status.home = true;
+            }
+            0xc7 => {
+                scancode_status.home = false;
+            }
+            0x49 => {
+                scancode_status.pgup = true;
+            }
+            0xc9 => {
+                scancode_status.pgup = false;
+            }
+            0x53 => {
+                scancode_status.del = true;
+                Self::emit(127);
+            }
+            0xd3 => {
+                scancode_status.del = false;
+            }
+            0x4f => {
+                scancode_status.end = true;
+            }
+            0xcf => {
+                scancode_status.end = false;
+            }
+            0x51 => {
+                scancode_status.pgdn = true;
+            }
+            0xd1 => {
+                scancode_status.pgdn = false;
+            }
+            0x48 => {
+                scancode_status.arrow_u = true;
+                Self::emit(224);
+                Self::emit(72);
+            }
+            0xc8 => {
+                scancode_status.arrow_u = false;
+            }
+            0x4b => {
+                scancode_status.arrow_l = true;
+                Self::emit(224);
+                Self::emit(75);
+            }
+            0xcb => {
+                scancode_status.arrow_l = false;
+            }
+            0x50 => {
+                scancode_status.arrow_d = true;
+                Self::emit(224);
+                Self::emit(80);
+            }
+            0xd0 => {
+                scancode_status.arrow_d = false;
+            }
+            0x4d => {
+                scancode_status.arrow_r = true;
+                Self::emit(224);
+                Self::emit(77);
+            }
+            0xcd => {
+                scancode_status.arrow_r = false;
+            }
+
+            0x35 => {
+                // 数字小键盘的 / 符号
+                scancode_status.kp_forward_slash = true;
+
+                let ch = '/' as u8;
+                Self::emit(ch);
+            }
+            0xb5 => {
+                scancode_status.kp_forward_slash = false;
+            }
+            0x1c => {
+                scancode_status.kp_enter = true;
+                Self::emit('\n' as u8);
+            }
+            0x9c => {
+                scancode_status.kp_enter = false;
+            }
+            _ => {
+                return TypeOneFSMState::Start;
+            }
+        }
+        return TypeOneFSMState::Start;
+    }
+
+    fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
+        // 判断按键是被按下还是抬起
+        let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
+            false
+        } else {
+            true
+        };
+
+        // 计算扫描码位于码表的第几行
+        let mut col: usize = 0;
+        let index = scancode & 0x7f;
+
+        // shift被按下
+        if scancode_status.shift_l || scancode_status.shift_r {
+            col = 1;
+        }
+
+        let ch = TYPE1_KEY_CODE_MAPTABLE[col + 2 * index as usize];
+        //kdebug!("in type3 ch is {:#x}\n",ch);
+        let mut key = KeyFlag::OtherKey; // 可视字符
+
+        match index {
+            0x2a => {
+                scancode_status.shift_l = flag_make;
+                key = KeyFlag::NoneFlag;
+            }
+            0x36 => {
+                scancode_status.shift_r = flag_make;
+                key = KeyFlag::NoneFlag;
+            }
+            0x1d => {
+                scancode_status.ctrl_l = flag_make;
+                key = KeyFlag::NoneFlag;
+            }
+            0x38 => {
+                scancode_status.ctrl_r = flag_make;
+                key = KeyFlag::NoneFlag;
+            }
+            _ => {
+                if flag_make == false {
+                    //kdebug!("in type3 ch is {:#x}\n",ch);
+                    key = KeyFlag::NoneFlag;
+                }
+            }
+        }
+
+        if key != KeyFlag::NoneFlag {
+            Self::emit(ch);
+        }
+        return TypeOneFSMState::Start;
+    }
+
+    fn emit(_ch: u8) {
+        // todo: 发送到tty
+    }
+
+    /// @brief 处理Prtsc按下事件
+    fn handle_prtsc_press(
+        &self,
+        scancode: u8,
+        scancode_status: &mut ScanCodeStatus,
+    ) -> TypeOneFSMState {
+        static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
+        let i = match self {
+            TypeOneFSMState::PrtscPress(i) => *i,
+            _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
+        };
+        if i > 3 {
+            // 解析错误,返回起始状态
+            return TypeOneFSMState::Start;
+        }
+        if scancode != PRTSC_SCAN_CODE[i as usize] {
+            return self.handle_type3(scancode, scancode_status);
+        } else {
+            if i == 3 {
+                // 成功解析出PrtscPress
+                return TypeOneFSMState::Start;
+            } else {
+                // 继续解析
+                return TypeOneFSMState::PrtscPress(i + 1);
+            }
+        }
+    }
+
+    fn handle_prtsc_release(
+        &self,
+        scancode: u8,
+        scancode_status: &mut ScanCodeStatus,
+    ) -> TypeOneFSMState {
+        static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
+        let i = match self {
+            TypeOneFSMState::PrtscRelease(i) => *i,
+            _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
+        };
+        if i > 3 {
+            // 解析错误,返回起始状态
+            return TypeOneFSMState::Start;
+        }
+        if scancode != PRTSC_SCAN_CODE[i as usize] {
+            return self.handle_type3(scancode, scancode_status);
+        } else {
+            if i == 3 {
+                // 成功解析出PrtscRelease
+                return TypeOneFSMState::Start;
+            } else {
+                // 继续解析
+                return TypeOneFSMState::PrtscRelease(i + 1);
+            }
+        }
+    }
+}
+
+/// 按键状态
+#[derive(Debug)]
+pub struct ScanCodeStatus {
+    // Shift 按键
+    shift_l: bool,
+    shift_r: bool,
+    // Ctrl 按键
+    ctrl_l: bool,
+    ctrl_r: bool,
+    // Alt 按键
+    alt_l: bool,
+    alt_r: bool,
+    //
+    gui_l: bool,
+    gui_r: bool,
+    //
+    apps: bool,
+    insert: bool,
+    // page up/down
+    pgup: bool,
+    pgdn: bool,
+    del: bool,
+    home: bool,
+    end: bool,
+    arrow_u: bool,
+    arrow_l: bool,
+    arrow_d: bool,
+    arrow_r: bool,
+    // 斜杠
+    kp_forward_slash: bool,
+    // 回车
+    kp_enter: bool,
+}
+
+impl ScanCodeStatus {
+    fn new() -> Self {
+        ScanCodeStatus {
+            shift_l: false,
+            shift_r: false,
+            ctrl_l: false,
+            ctrl_r: false,
+            alt_l: false,
+            alt_r: false,
+            gui_l: false,
+            gui_r: false,
+            apps: false,
+            insert: false,
+            pgup: false,
+            pgdn: false,
+            del: false,
+            home: false,
+            end: false,
+            arrow_u: false,
+            arrow_l: false,
+            arrow_d: false,
+            arrow_r: false,
+            kp_forward_slash: false,
+            kp_enter: false,
+        }
+    }
+}
+
+const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
+    /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
+    /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8,
+    /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8,
+    /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' 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,
+    /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
+    /*0x0e*/ 0x0e as u8, 0x0e as u8, // BACKSPACE
+    /*0x0f*/ '\t' as u8, '\t' as u8, // TAB
+    /*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,
+    /*0x14*/ 't' as u8, 'T' as u8, /*0x15*/ 'y' as u8, 'Y' as u8,
+    /*0x16*/ 'u' as u8, 'U' as u8, /*0x17*/ 'i' as u8, 'I' as u8,
+    /*0x18*/ 'o' as u8, 'O' as u8, /*0x19*/ 'p' as u8, 'P' as u8,
+    /*0x1a*/ '[' as u8, '{' as u8, /*0x1b*/ ']' as u8, '}' as u8,
+    /*0x1c*/ '\n' as u8, '\n' as u8, // ENTER
+    /*0x1d*/ 0x1d, 0x1d, // CTRL Left
+    /*0x1e*/ 'a' as u8, 'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8,
+    /*0x20*/ 'd' as u8, 'D' as u8, /*0x21*/ 'f' as u8, 'F' as u8,
+    /*0x22*/ 'g' as u8, 'G' as u8, /*0x23*/ 'h' as u8, 'H' as u8,
+    /*0x24*/ 'j' as u8, 'J' as u8, /*0x25*/ 'k' as u8, 'K' as u8,
+    /*0x26*/ 'l' as u8, 'L' as u8, /*0x27*/ ';' as u8, ':' as u8,
+    /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8, /*0x2a*/ 0x2a,
+    0x2a, // SHIFT Left
+    /*0x2b*/ '\\' as u8, '|' as u8, /*0x2c*/ 'z' as u8, 'Z' as u8,
+    /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8,
+    /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8,
+    /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8,
+    /*0x33*/ ',' as u8, '<' as u8, /*0x34*/ '.' as u8, '>' as u8,
+    /*0x35*/ '/' as u8, '?' as u8, /*0x36*/ 0x36, 0x36, // SHIFT Right
+    /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left
+    /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK
+    /*0x3b*/ 0, 0, // F1
+    /*0x3c*/ 0, 0, // F2
+    /*0x3d*/ 0, 0, // F3
+    /*0x3e*/ 0, 0, // F4
+    /*0x3f*/ 0, 0, // F5
+    /*0x40*/ 0, 0, // F6
+    /*0x41*/ 0, 0, // F7
+    /*0x42*/ 0, 0, // F8
+    /*0x43*/ 0, 0, // F9
+    /*0x44*/ 0, 0, // F10
+    /*0x45*/ 0, 0, // NUM LOCK
+    /*0x46*/ 0, 0, // SCROLL LOCK
+    /*0x47*/ '7' as u8, 0, /*PAD HONE*/
+    /*0x48*/ '8' as u8, 0, /*PAD UP*/
+    /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/
+    /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/
+    /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/
+    /*0x4c*/ '5' as u8, 0, /*PAD MID*/
+    /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/
+    /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/
+    /*0x4f*/ '1' as u8, 0, /*PAD END*/
+    /*0x50*/ '2' as u8, 0, /*PAD DOWN*/
+    /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/
+    /*0x52*/ '0' as u8, 0, /*PAD INS*/
+    /*0x53*/ '.' as u8, 0, /*PAD DOT*/
+    /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
+    /*0x58*/ 0, 0, // F12
+    /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
+    /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
+    /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
+    /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
+    /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
+    /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
+    /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
+    /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
+    /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
+    /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
+];

+ 1 - 1
kernel/src/libs/mod.rs

@@ -13,4 +13,4 @@ pub mod vec_cursor;
 #[macro_use]
 pub mod volatile;
 pub mod wait_queue;
-
+pub mod keyboard_parser;

+ 0 - 1
tools/run-qemu.sh

@@ -35,7 +35,6 @@ QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot or
 
 QEMU_ARGUMENT+="-s -S -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
 
-
 if [ $flag_can_run -eq 1 ]; then
     case "$1" in
         --bios) 

+ 1 - 1
user/libs/libKeyboard/keyboard.c

@@ -528,6 +528,6 @@ int keyboard_analyze_keycode(int fd)
 int keyboard_get_scancode(int fd)
 {
     unsigned int ret = 0;
-    read(fd, &ret, 1);
+    read(fd, &ret, 1); 
     return ret;
 }