From: acevest Date: Wed, 12 Aug 2026 06:44:17 +0000 (+0800) Subject: 键盘输入对接到前台VC对应的TTY并回显 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=21dd2c9252081c21c0c73da61733fe9bc87a6146;p=kernel.git 键盘输入对接到前台VC对应的TTY并回显 --- diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 1e0e63c..5b68d3a 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -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; diff --git a/include/tty.h b/include/tty.h index ee18eba..d8eb053 100644 --- a/include/tty.h +++ b/include/tty.h @@ -10,6 +10,8 @@ #pragma once #include +#include +#include #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; diff --git a/kernel/tty.c b/kernel/tty.c index 780c474..875d1d5 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -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 diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3347e65..1129c0a 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -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));