]> Zhao Yanbai Git Server - kernel.git/commitdiff
键盘输入对接到前台VC对应的TTY并回显
authoracevest <zhaoyanbai@126.com>
Wed, 12 Aug 2026 06:44:17 +0000 (14:44 +0800)
committeracevest <zhaoyanbai@126.com>
Wed, 12 Aug 2026 06:44:17 +0000 (14:44 +0800)
drivers/keyboard.c
include/tty.h
kernel/tty.c
lib/vsprintf.c

index 1e0e63c7e93d5c27befd5796e04a7b3cc0ee9217..5b68d3a21fd1e43063946c798196d9a938112667 100644 (file)
@@ -51,7 +51,6 @@ char kbd_char_tbl[] = {
     0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,
 };
 
-// TODO 改造成环形缓冲区
 uint8_t kbd_scan_code;
 void kbd_bh_handler(void* arg) {
     kbd_debug(kbd_scan_code);
@@ -65,15 +64,14 @@ void kbd_bh_handler(void* arg) {
     vt_keyboard_input(ch);
 }
 
+uint64_t kbd_irq_cnt = 0;
 void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
     kbd_scan_code = inb(0x60);
+    kbd_irq_cnt++;
     add_irq_bh_handler(kbd_bh_handler, NULL);
 }
 
-uint64_t kbd_irq_cnt = 0;
 void kbd_debug(uint8_t scan_code) {
-    kbd_irq_cnt++;
-
     switch (scan_code) {
     case 0x01:  // Esc
         break;
index ee18ebac912af827804fcd43b631c041ea14b0e6..d8eb053bac47e45f70d486753ef9103aba90b17c 100644 (file)
@@ -10,6 +10,8 @@
 #pragma once
 
 #include <types.h>
+#include <wait.h>
+#include <semaphore.h>
 
 #define TTY_MAX_NAME_LEN 32
 #define TTY_MAX_COUNT 8
@@ -28,6 +30,8 @@ struct tty {
     uint8_t in_buf[TTY_MAX_IN_BUF_SIZE];
     int ib_head;
     int ib_tail;
+    mutex_t ib_mutex;
+    wait_queue_head_t ib_wait;
 
     tty_ops_t* ops;
     void* private;
index 780c474b090e94fa3172c21b40e67889cb206314..875d1d5c1cc14ed0b7551e2dd2fc33b6f4233e91 100644 (file)
@@ -29,6 +29,8 @@ void init_ttys() {
 
         tty->ib_head = 0;
         tty->ib_tail = 0;
+        mutex_init(&tty->ib_mutex);
+        init_wait_queue_head(&tty->ib_wait);
 
         tty->ops = &vt_tty_ops;
 
@@ -57,6 +59,10 @@ int tty_write(tty_t* tty, const char* buf, size_t size) {
     return 0;
 }
 
+bool _tty_ib_empty(tty_t* tty) {
+    return tty->ib_head == tty->ib_tail;
+}
+
 int tty_read(tty_t* tty, char* buf, size_t size) {
     assert(tty != NULL);
 
@@ -68,26 +74,70 @@ int tty_read(tty_t* tty, char* buf, size_t size) {
         return -EINVAL;
     }
 
-    // TODO
+    size_t n = 0;
 
-    return 0;
+    // 防多进程同时读取输入缓冲区
+    mutex_lock(&tty->ib_mutex);
+    while (true) {
+        unsigned long eflags;
+        irq_save(eflags);
+
+        // 如果输入缓冲区为空,则继续等待
+        if (_tty_ib_empty(tty)) {
+            irq_restore(eflags);
+            mutex_unlock(&tty->ib_mutex);
+            wait_event(&tty->ib_wait, !_tty_ib_empty(tty));
+            mutex_lock(&tty->ib_mutex);
+            continue;
+        }
+
+        irq_restore(eflags);
+
+        // 如果输入缓冲区不为空,则读取输入缓冲区
+        for (n = 0; n < size; n++) {
+            irq_save(eflags);
+
+            if (_tty_ib_empty(tty)) {
+                break;
+            }
+
+            buf[n] = tty->in_buf[tty->ib_tail];
+            tty->ib_tail += 1;
+            tty->ib_tail %= TTY_MAX_IN_BUF_SIZE;
+
+            irq_restore(eflags);
+        }
+
+        break;
+    }
+
+    mutex_unlock(&tty->ib_mutex);
+
+    return n;
 }
 
 int tty_input(tty_t* tty, uint8_t c) {
     assert(tty != NULL);
 
+    unsigned long eflags;
+    irq_save(eflags);
+
     int next = (tty->ib_head + 1) % TTY_MAX_IN_BUF_SIZE;
     if (next == tty->ib_tail) {
+        irq_restore(eflags);
         return 0;
     }
 
     tty->in_buf[tty->ib_head] = c;
     tty->ib_head = next;
 
+    irq_restore(eflags);
+
     // 目前先总是回显
     tty_write(tty, (const char*)&c, 1);
 
-    // TODO: 唤醒读进程
+    // 唤醒读进程
+    wake_up(&tty->ib_wait);
 
     return 1;
 }
\ No newline at end of file
index 3347e6513bc22c7ac3611bf4a87744b23f26d33b..1129c0ac97b02ca6c655b53146ec5e1f80bc6514 100644 (file)
@@ -99,7 +99,7 @@ int vsprintf(char* buf, const char* fmt, va_list args) {
             }
             break;
         case 's':
-             p += write_buf(p, (const char*)va_arg(args, char*), char_fill, char_cnt, align);
+            p += write_buf(p, (const char*)va_arg(args, char*), char_fill, char_cnt, align);
             break;
         case 'u':
             itou(tmp, va_arg(args, uint32_t));