]> Zhao Yanbai Git Server - kernel.git/commitdiff
绑定TTY和VT,支持键盘输入回显到VC
authoracevest <zhaoyanbai@126.com>
Wed, 12 Aug 2026 01:19:36 +0000 (09:19 +0800)
committeracevest <zhaoyanbai@126.com>
Wed, 12 Aug 2026 01:19:36 +0000 (09:19 +0800)
12 files changed:
boot/boot.c
drivers/keyboard.c
drivers/vga.c
drivers/vga.h [new file with mode: 0644]
drivers/vt.c
drivers/vt.h
fs/fs.c
include/tty.h
kernel/console.c
kernel/setup.c
kernel/tty.c
lib/vsprintf.c

index 1caf19a6a31b34632b7608913d27c33e1eb251ce..0afe76f122db74663091da58f8b17b817d6c8540 100644 (file)
@@ -108,7 +108,7 @@ void parse_framebuffer(void* addr) {
 void check_kernel(unsigned long addr, unsigned long magic) {
     init_serial();
 
-    // init_ttys();
+    init_ttys();
 
     printk("setup gdt\n");
     setup_gdt();
index 32ca8c311bc6515c547280e26651c5080d205d22..1e0e63c7e93d5c27befd5796e04a7b3cc0ee9217 100644 (file)
@@ -58,9 +58,11 @@ void kbd_bh_handler(void* arg) {
     if (0x80 & kbd_scan_code) {  // break code
         return;
     }
+
     uint8_t inx = kbd_scan_code & 0xFF;
     char ch = kbd_char_tbl[inx];
-    cnsl_kbd_write(ch);
+
+    vt_keyboard_input(ch);
 }
 
 void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
@@ -68,33 +70,13 @@ void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
     add_irq_bh_handler(kbd_bh_handler, NULL);
 }
 
-extern tty_t* const default_tty;
-extern tty_t* const monitor_tty;
-extern tty_t* const debug_tty;
-extern void tty_switch_to_next();
-
 uint64_t kbd_irq_cnt = 0;
 void kbd_debug(uint8_t scan_code) {
     kbd_irq_cnt++;
 
-    if (scan_code == 0x01) {  // Esc
-        // reboot();
-    }
-
-    // printd("[%02x]", scan_code);
-
-    // if (scan_code == 0x3B) {  // F1
-    //     // tty_switch(default_tty);
-    //     vt_switch(0);
-    // } else if (scan_code == 0x3C) {  // F2
-    //     // tty_switch(monitor_tty);
-    //     vt_switch(1);
-    // } else if (scan_code == 0x3D) {  // F3
-    //     // tty_switch(debug_tty);
-    //     vt_switch(2);
-    // }
-
     switch (scan_code) {
+    case 0x01:  // Esc
+        break;
     case 0x3B:  // F1
         vt_switch(0);
         break;
@@ -107,26 +89,4 @@ void kbd_debug(uint8_t scan_code) {
     default:
         break;
     }
-
-    // if (scan_code == 0x43) {  // F9
-    //     void ata_test(uint64_t nr);
-    //     ata_test(0);
-    // }
-    // if (scan_code == 0x44) {  // F10
-    //     void ata_send_read_identify_cmd(int dev);
-    //     ata_send_read_identify_cmd(0);
-    // }
-
-    // if (scan_code == 0x57)  // F11
-    // {
-    //     asm("cli;");
-    //     while (1)
-    //         ;
-    // }
-
-    // if (scan_code == 0x58) {  // F12
-    //     tty_switch_to_next();
-    // }
-
-    // ide_status();
 }
index b2ea42a6df9edd8a66b8718f279520c78648c82d..b8697b6a01b8fa573464ec0470058deca2e06439 100644 (file)
@@ -8,28 +8,11 @@
  */
 
 #include "vt.h"
+#include <vga.h>
 #include <io.h>
 #include <irq.h>
 
-static const paddr_t vga_vram_base_paddr = 0xB8000;
 static uint16_t* vga_vram_base_vaddr = (uint16_t*)pa2va(vga_vram_base_paddr);
-static const size_t vga_cols = 80;
-static const size_t vga_rows = 25;
-static const size_t vga_vram_size = vga_cols * vga_rows;
-static const size_t vga_vram_byte_size = vga_vram_size * sizeof(uint16_t);
-static const size_t TAB_SPACE = 4;
-
-#define VGA_FG_HIGHLIGHT 0b1000
-#define VGA_BG_BLINK 0b1000
-
-#define VGA_BLACK 0b0000
-#define VGA_BLUE 0b0001
-#define VGA_GREEN 0b0010
-#define VGA_CYAN 0b0011
-#define VGA_RED 0b0100
-#define VGA_PURPLE 0b0101
-#define VGA_YELLOW 0b0110
-#define VGA_WHITE 0b0111
 
 uint8_t vga_make_attr(uint8_t fg, uint8_t bg, bool fg_highlight, bool bg_blink) {
     assert((fg & 0x7) == fg);
@@ -104,7 +87,10 @@ void vga_scroll_up(vc_t* vc) {
 
     uint16_t* vram_vaddr = vc->vram_vaddr;
 
-    for (int i = 0; i < ((vc->rows - 1) * vc->cols); i++) {
+    // 如果是VC0则最顶上一行保留用来显示内核版本及编译时间信息
+    const int keep = vc->id == 0 ? vc->cols : 0;
+
+    for (int i = keep; i < ((vc->rows - 1) * vc->cols); i++) {
         vram_vaddr[i] = vram_vaddr[i + vc->cols];
     }
 
@@ -303,11 +289,13 @@ void vga_putc(vc_t* vc, uint8_t c) {
     vga_color_putc(vc, c, vc->default_color);
 }
 
-void vga_write(vc_t* vc, const char* buf, size_t size) {
+int vga_write(vc_t* vc, const char* buf, size_t size) {
     assert(buf != NULL);
     for (size_t i = 0; i < size; i++) {
         vga_putc(vc, buf[i]);
     }
+
+    return size;
 }
 
 void vga_ap_clear() {
diff --git a/drivers/vga.h b/drivers/vga.h
new file mode 100644 (file)
index 0000000..9d27d49
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: vga.h
+ *      Author: Zhao Yanbai
+ *              2026-08-11 19:37:11 Tuesday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+static const paddr_t vga_vram_base_paddr = 0xB8000;
+static const size_t vga_cols = 80;
+static const size_t vga_rows = 25;
+static const size_t vga_vram_size = vga_cols * vga_rows;
+static const size_t vga_vram_byte_size = vga_vram_size * sizeof(uint16_t);
+static const size_t TAB_SPACE = 4;
+
+#define VGA_FG_HIGHLIGHT 0b1000
+#define VGA_BG_BLINK 0b1000
+
+#define VGA_BLACK 0b0000
+#define VGA_BLUE 0b0001
+#define VGA_GREEN 0b0010
+#define VGA_CYAN 0b0011
+#define VGA_RED 0b0100
+#define VGA_PURPLE 0b0101
+#define VGA_YELLOW 0b0110
+#define VGA_WHITE 0b0111
+
+void vga_init_vc(vc_t* vc);
+void vga_switch(vc_t* vc);
+int vga_write(vc_t* vc, const char* buf, size_t size);
+uint8_t vga_make_attr(uint8_t fg, uint8_t bg, bool fg_highlight, bool bg_blink);
+void vga_set_cursor_style(bool block);
\ No newline at end of file
index 652f0bf340b27112d885ff9ebd9ed469af8c628e..3a7b3d12456eb27f42adefdc3a740b2de67ca29a 100644 (file)
@@ -8,12 +8,7 @@
  */
 
 #include "vt.h"
-
-void vga_init_vc(vc_t* vc);
-void vga_switch(vc_t* vc);
-void vga_write(vc_t* vc, const char* buf, size_t size);
-uint8_t vga_make_attr(uint8_t fg, uint8_t bg, bool fg_highlight, bool bg_blink);
-void vga_set_cursor_style(bool block);
+#include <vga.h>
 
 static vc_t vcs[VC_COUNT];
 static vc_t* fg_vc = &vcs[0];
@@ -29,13 +24,16 @@ bool vc_is_view_vc(vc_t* vc) {
     return vc == view_vc;
 }
 
+int vt_write(vc_t* vc, const char* buf, size_t size) {
+    return vga_write(vc, buf, size);
+}
+
 // VT CONSOLE: 仅桥接console用
 int vt_console_write(const char* buf, size_t size) {
     // 找到前台vt调用其write
     assert(fg_vc != NULL);
     assert(fg_vc->id < VC_FOR_TTY_COUNT);
-    vga_write(fg_vc, buf, size);
-    return 0;
+    return vt_write(fg_vc, buf, size);
 }
 
 int vt_console_setup(console_t* console) {
@@ -110,4 +108,46 @@ void init_vt() {
     vt_switch(view_vc_id);
 
     register_console(&vt_console);
-}
\ No newline at end of file
+}
+
+void vt_keyboard_input(uint8_t c) {
+    assert(fg_vc != NULL);
+    assert(fg_vc->id < VC_FOR_TTY_COUNT);
+
+    tty_t* tty = fg_vc->tty;
+    assert(tty != NULL);
+
+    tty_input(tty, c);
+}
+
+void print_kernel_version(const char* version) {
+    vc_t* vc = vt_get_vc(0);
+    uint8_t color = vt_make_attr(VT_WHITE, VT_CYAN, true, false);
+
+    // 清理第一行
+    for (int i = 0; i < vc->cols; i++) {
+        uint16_t c = (color << 8) | ' ';
+        vc->vram_vaddr[i] = c;
+    }
+
+    // 打印版本号
+    for (int i = 0; i < strlen(version); i++) {
+        uint16_t c = (color << 8) | version[i];
+        vc->vram_vaddr[i] = c;
+    }
+}
+
+int vt_tty_write(tty_t* tty, const char* buf, size_t size) {
+    assert(tty != NULL);
+
+    vc_t* vc = tty->private;
+    assert(vc != NULL);
+
+    return vt_write(vc, buf, size);
+
+    return 0;
+}
+
+tty_ops_t vt_tty_ops = {
+    .write = vt_tty_write,
+};
\ No newline at end of file
index 16d1def81a00860652419a6b7fd45725cd5b84b3..d6d255a24c2652b59d5807da885bb9d68702eefc 100644 (file)
@@ -10,6 +10,7 @@
 #pragma once
 
 #include <console.h>
+#include <tty.h>
 
 // 暂不考虑别的类型的VC,直接按VGA来写
 
@@ -45,10 +46,18 @@ struct vc {
     bool show_cursor;
 
     uint16_t* vram_vaddr;
+
+    tty_t* tty;
 };
 
 bool vc_is_fg_vc(vc_t* vc);
 bool vc_is_view_vc(vc_t* vc);
 vc_t* vt_get_vc(int id);
 vc_t* vt_get_ap_vc();
-void vt_switch(int id);
\ No newline at end of file
+void vt_switch(int id);
+
+void vt_keyboard_input(uint8_t c);
+
+void print_kernel_version(const char* version);
+
+extern tty_ops_t vt_tty_ops;
\ No newline at end of file
diff --git a/fs/fs.c b/fs/fs.c
index d14ac936d4fbec37a619ddb35cbd39de80a04444..e4fa3f30f33291cd6ead97b7526c3593474d2099 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
 
 //--------------------------------------------------------------------------
 
-extern chrdev_t cnsl_chrdev;
-
-chrdev_t* chrdev[CHRDEV_SIZE] = {&cnsl_chrdev};
-
 // void ext2_setup_fs();
 unsigned int ext2_search_inpath(const char* path);
 
index 153f4ada7b45c7277e8d9a565749323eb791b7db..ee18ebac912af827804fcd43b631c041ea14b0e6 100644 (file)
@@ -9,47 +9,41 @@
 
 #pragma once
 
-#define TTY_FG_HIGHLIGHT 0b1000
-#define TTY_BG_BLINK 0b1000
+#include <types.h>
 
-#define TTY_BLACK 0b0000
-#define TTY_BLUE 0b0001
-#define TTY_GREEN 0b0010
-#define TTY_CYAN 0b0011
-#define TTY_RED 0b0100
-#define TTY_PURPLE 0b0101
-#define TTY_YELLOW 0b0110
-#define TTY_WHITE 0b0111
+#define TTY_MAX_NAME_LEN 32
+#define TTY_MAX_COUNT 8
+#define TTY_MAX_IN_BUF_SIZE 512
 
-typedef struct tty {
-    char name[32];
+typedef struct tty tty_t;
+typedef struct tty_ops tty_ops_t;
 
-    // 记录字符显示位置
-    unsigned int xpos;
-    unsigned int ypos;
+struct tty_ops {
+    int (*write)(tty_t* tty, const char* buf, size_t size);
+};
 
-    unsigned int fg_color;
-    unsigned int bg_color;
+struct tty {
+    char name[TTY_MAX_NAME_LEN];
 
-    // 最大字符数
-    int max_x;
-    int max_y;
+    uint8_t in_buf[TTY_MAX_IN_BUF_SIZE];
+    int ib_head;
+    int ib_tail;
 
-    // 记录对应的显存起始位置
-    unsigned long base_addr;
-} tty_t;
+    tty_ops_t* ops;
+    void* private;
+};
 
 void init_ttys();
 
-void tty_write(tty_t* tty, const char* buf, size_t size);
-void tty_write_at(tty_t* tty, int xpos, int ypos, const char* buf, size_t size);
-void tty_color_putc(tty_t* tty, char c, unsigned int fg_color, unsigned bg_color);
+// 进程 -> read -> tty_read -> TTY (buf)
+// 键盘: 键盘中断 -> vt_keyboard_input -> tty_input -> TTY (in_buf)
+//                                          └─echo(回显) -> tty_write -> TTY ops->write -> 键盘 TX
+// 串口 RX: 串口中断 -> serial_input -> tty_input -> TTY (in_buf)
+//                                         └─echo(回显) -> tty_write -> TTY ops->write -> 串口 TX
+// 进程 -> write -> tty_write -> TTY ops->write -> [Serial, VT] write -> 硬件
 
-void tty_set_cursor(tty_t* tty);
-void tty_switch(tty_t* tty);
+int tty_write(tty_t* tty, const char* buf, size_t size);
+int tty_read(tty_t* tty, char* buf, size_t size);
 
-void tty_switch_to_next();
-
-void tty_clear(tty_t* tty);
-
-extern tty_t* current_tty;
+// 返回 1 表示成功,0 表示缓冲区满,丢弃
+int tty_input(tty_t* tty, uint8_t c);
index 92b531da162a3b461cf6364ee867b46c8e718d04..b2d6ba7fc99cf0109040f21f87efe9847436fdfd 100644 (file)
@@ -56,7 +56,7 @@ int console_write(const char* buf, size_t size) {
     return 0;
 }
 
-void vga_putc(unsigned int nr, unsigned char c, const unsigned char color);
+#if 0
 
 cnsl_t cnsl;
 
@@ -201,3 +201,4 @@ end:
 }
 
 chrdev_t cnsl_chrdev = {.read = cnsl_read};
+#endif
index 95b94da7d6b2a81f4eb6e4fc4f25afc71fb98314..ae304182cc283deb7ec841e4af762bf5e80c6a32 100644 (file)
@@ -17,7 +17,7 @@
 #include <printk.h>
 #include <string.h>
 #include <system.h>
-#include <tty.h>
+#include <vt.h>
 #include <hpet.h>
 
 extern void init_mm();
@@ -37,43 +37,9 @@ extern void setup_fs();
 extern void setup_ext2();
 
 extern void reboot();
-extern void cnsl_init();
 
 #define VERSION "0.3.1"
-const char* version = "KERNEL v" VERSION " @" BUILDER " [" __DATE__ " " __TIME__
-                      "]"
-                      "\n\n";
-
-void print_kernel_version() {
-    //
-    extern tty_t* const default_tty;
-    tty_t* const tty = default_tty;
-
-    int len = strlen(version);
-
-    for (int i = 0; i < tty->max_x; i++) {
-        char c = i < len ? version[i] : ' ';
-        c = c != '\n' ? c : ' ';
-        c = c != '\t' ? c : ' ';
-
-        //
-        uint32_t fg_color = tty->fg_color;
-        uint32_t bg_color = tty->bg_color;
-
-        fg_color = TTY_WHITE | TTY_FG_HIGHLIGHT;
-        bg_color = TTY_CYAN;
-
-        //
-        char* dst = (char*)tty->base_addr;
-
-        //
-        dst[i * 2 + 0] = c;
-        dst[i * 2 + 1] = ((bg_color) << 4) | (fg_color);
-    }
-
-    //
-    printk(version);
-}
+const char* version = "KERNEL v" VERSION " @" BUILDER " [" __DATE__ " " __TIME__ "]";
 
 void prepare_ap_code(paddr_t paddr) {
     // 注意: 最开始时AP是运行在实模式
@@ -146,9 +112,6 @@ void setup_kernel() {
     setup_sysc();
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
-    cnsl_init();
-    boot_delay(DEFAULT_BOOT_DELAY_TICKS);
-
     setup_fs();
 
     setup_tasks();
@@ -163,12 +126,9 @@ void setup_kernel() {
     detect_cpu();
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
-    print_kernel_version();
+    print_kernel_version(version);
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
-    // extern tty_t* const monitor_tty;
-    // tty_switch(monitor_tty);
-
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
     setup_i8254(100);
index 46895d8e46085ae49867db2518071f180aa57734..780c474b090e94fa3172c21b40e67889cb206314 100644 (file)
 #include <page.h>
 #include <string.h>
 #include <tty.h>
-
-// 从0xB8000处开始有32KB显存可利用
-// 而一屏所需要的显存为 80*25*2 = 4000 约为4K
-// 所以大致可以分出8个tty
-// 每个的起始地址以0x1000对齐
-const uint32_t PHY_VADDR = 0xB8000;
-const uint32_t VADDR = (uint32_t)pa2va(PHY_VADDR);
-#define TTY_VRAM_SIZE (0x1000)
+#include <vt.h>
+#include <errno.h>
 
 #define MAX_NR_TTYS 8
 tty_t ttys[NR_TTYS];
 
-#define MAX_X 80
-#define MAX_Y 25
-#define CHARS_PER_LINE (MAX_X)
-#define BYTES_PER_LINE (CHARS_PER_LINE * 2)
-#define TAB_SPACE 4
-
-tty_t* const default_tty = ttys + 0;
-tty_t* const monitor_tty = ttys + 1;
-tty_t* const debug_tty = ttys + 2;
-
-void tty_clear(tty_t* tty) {
-    char* dst = (char*)tty->base_addr;
-    for (int src = 0; src < (MAX_Y * BYTES_PER_LINE); src += 2) {
-        *dst++ = 0;
-        *dst++ = (tty->bg_color << 4) | tty->fg_color;
-    }
-}
-
-// 因为光标要指向下一个待输出的位置
-// 在这个位置的光标的颜色与该位置已经设置的颜色一样
-// 一般输出一个字符,则光标位置在这个字符之后
-// 而如果输出字符颜色与光标所处位置已经设置的颜色不一致的话
-// 就需要将输出的这个字符的后一个位置的颜色设置成与之一致
-// 这样光标颜色才与输出字符一致
-void __tty_set_next_pos_color(tty_t* tty, char color) {
-    unsigned int xpos = tty->xpos;
-    unsigned int ypos = tty->ypos;
-
-    xpos += 1;  // 指向下一个位置
-
-    ypos += xpos / CHARS_PER_LINE;
-    xpos %= CHARS_PER_LINE;
-
-    if (ypos < MAX_Y) {
-        char* dst = (char*)(tty->base_addr + ypos * BYTES_PER_LINE + 2 * xpos);
-        dst[0] = 0;
-        dst[1] = color;
-    }
-}
-
-void init_tty(tty_t* tty, const char* name, unsigned long base) {
-    assert(0 != tty);
-    assert(NR_TTYS >= 1);
-    assert(NR_TTYS <= MAX_NR_TTYS);
-
-    strlcpy(tty->name, name, sizeof(tty->name));
-
-    tty->fg_color = TTY_FG_HIGHLIGHT | TTY_GREEN;  // 高亮
-    tty->bg_color = TTY_BLACK;                     // 不闪
-
-    tty->max_x = MAX_X;
-    tty->max_y = MAX_Y;
-
-    tty->base_addr = base;
-
-    for (int i = 0; i < TTY_VRAM_SIZE; i += 2) {
-        uint8_t* p = (uint8_t*)base;
-        p[i + 0] = ' ';
-        p[i + 1] = (tty->bg_color << 4) | tty->fg_color;
-    }
-}
-
 void init_ttys() {
-    assert(irq_disabled());
-
-    for (int i = 0; i < NR_TTYS; i++) {
+    for (int i = 0; i < VC_FOR_TTY_COUNT; i++) {
         tty_t* tty = ttys + i;
-        char name[sizeof(tty->name)];
-        sprintf(name, "tty.%u", i);
-        init_tty(tty, name, VADDR + i * TTY_VRAM_SIZE);
+        char name[TTY_MAX_NAME_LEN];
+        sprintf(name, "tty%d", i);
 
-        if (i != TTY_WHITE) {
-            tty->fg_color = TTY_FG_HIGHLIGHT | TTY_WHITE;
-            tty->bg_color = i;
-        } else {
-            tty->fg_color = TTY_FG_HIGHLIGHT | TTY_BLACK;
-            tty->bg_color = TTY_WHITE;
-        }
-    }
+        strcpy(tty->name, name);
 
-    default_tty->fg_color = TTY_FG_HIGHLIGHT | TTY_GREEN;
-    default_tty->bg_color = TTY_BLACK;
+        tty->ib_head = 0;
+        tty->ib_tail = 0;
 
-    monitor_tty->fg_color = TTY_FG_HIGHLIGHT | TTY_WHITE;
-    monitor_tty->bg_color = TTY_BLUE;
+        tty->ops = &vt_tty_ops;
 
-    debug_tty->fg_color = TTY_FG_HIGHLIGHT | TTY_WHITE;
-    debug_tty->bg_color = TTY_BLACK;  // TTY_CYAN;
+        vc_t* vc = vt_get_vc(i);
+        assert(vc != NULL);
 
-    for (int i = 0; i < NR_TTYS; i++) {
-        tty_t* tty = ttys + i;
-        tty_clear(tty);
-    }
-    current_tty = default_tty;
-}
+        tty->private = vc;
+        vc->tty = tty;
 
-void tty_do_scroll_up(tty_t* tty) {
-    // 没越过最后一行不需要上卷
-    if (tty->ypos < MAX_Y - 1) {
-        return;
+        printk("init_ttys: tty %x vcid %d\n", tty, i);
     }
-
-    // 达到最后一行,没到最后一个字符也不用上卷
-    if (tty->ypos == (MAX_Y - 1) && tty->xpos < MAX_X) {
-        return;
-    }
-
-    // 如果是default_tty则保留用来显示内核版本及编译时间信息
-    const int keep = tty != default_tty ? 0 : BYTES_PER_LINE;
-
-    char* dst = (char*)tty->base_addr + keep;
-    for (int src = BYTES_PER_LINE + keep; src < (MAX_Y * BYTES_PER_LINE); src++) {
-        *dst++ = *(char*)(tty->base_addr + src);
-    }
-
-    // 清空最后一行
-    dst = (char*)(tty->base_addr + ((MAX_Y - 1) * BYTES_PER_LINE));
-    for (int i = 0; i < BYTES_PER_LINE; i += 2) {
-        *dst++ = 0;
-        *dst++ = (tty->bg_color << 4) | tty->fg_color;
-    }
-
-    tty->xpos = 0;
-    tty->ypos = MAX_Y - 1;
 }
 
-void tty_color_putc(tty_t* tty, char c, unsigned int fg_color, unsigned bg_color) {
-    bool display = false;
-    bool move_to_next_pos = true;
-    switch (c) {
-    case '\r':
-        tty->xpos = 0;
-    case '\n':
-        tty->xpos = 0;
-        tty->ypos += 1;
-        break;
-    case '\t':
-        tty->xpos += TAB_SPACE;
-        tty->xpos &= ~(TAB_SPACE - 1);
-        break;
-    case '\b':
-        if (tty->xpos == 0) {
-            if (tty->ypos > 0) {
-                tty->xpos = CHARS_PER_LINE - 1;
-                tty->ypos -= 1;
-            } else {
-                tty->ypos = 0;
-            }
-        } else if (tty->xpos > 0) {
-            tty->xpos -= 1;
-        } else {
-            tty->xpos = 0;
-        }
-        c = 0;
-        display = true;
-        move_to_next_pos = false;
-        break;
-    default:
-        display = true;
-        break;
-    }
-
-    tty->ypos += tty->xpos / CHARS_PER_LINE;
-    tty->xpos %= CHARS_PER_LINE;
-
-    // 显示
-    if (display) {
-        unsigned int pos = tty->ypos * BYTES_PER_LINE + tty->xpos * 2;
-        char* va = (char*)(tty->base_addr + pos);
-        va[0] = c;
-        va[1] = (bg_color << 4) | fg_color;
+void tty_putc(tty_t* tty, char c) {
+}
 
-        __tty_set_next_pos_color(tty, va[1]);
+int tty_write(tty_t* tty, const char* buf, size_t size) {
+    assert(tty != NULL);
+    assert(buf != NULL);
 
-        if (move_to_next_pos) {
-            tty->xpos++;
-        }
-    }
+    tty_ops_t* ops = tty->ops;
+    assert(ops != NULL);
 
-    tty_do_scroll_up(tty);
+    return ops->write(tty, buf, size);
 
-    tty_set_cursor(tty);
+    return 0;
 }
 
-void tty_putc(tty_t* tty, char c) {
-    tty_color_putc(tty, c, tty->fg_color, tty->bg_color);
-}
+int tty_read(tty_t* tty, char* buf, size_t size) {
+    assert(tty != NULL);
 
-void tty_write(tty_t* tty, const char* buf, size_t size) {
-    return;
-    assert(0 != tty);
-    if (0 == buf) {
-        return;
+    if (0 == size) {
+        return 0;
     }
 
-    for (size_t i = 0; i < size; i++) {
-        tty_putc(tty, buf[i]);
+    if (NULL == buf) {
+        return -EINVAL;
     }
-}
-
-void tty_write_at(tty_t* tty, int xpos, int ypos, const char* buf, size_t size) {
-    assert(0 != tty);
-    assert(xpos < BYTES_PER_LINE);
-    assert(ypos < MAX_Y);
-    tty->xpos = xpos;
-    tty->ypos = ypos;
-    tty_write(tty, buf, size);
-}
-
-#define VGA_CRTC_ADDR 0x3D4
-#define VGA_CRTC_DATA 0x3D5
-#define VGA_CRTC_START_ADDR_H 0xC
-#define VGA_CRTC_START_ADDR_L 0xD
-#define VGA_CRTC_CURSOR_H 0xE
-#define VGA_CRTC_CURSOR_L 0xF
 
-void tty_set_cursor(tty_t* tty) {
-    if (tty != current_tty) {
-        return;
-    }
-    unsigned int offset = tty->ypos * MAX_X + tty->xpos;
+    // TODO
 
-    unsigned long flags;
-    irq_save(flags);
-    outb(VGA_CRTC_CURSOR_H, VGA_CRTC_ADDR);
-    outb((offset >> 8) & 0xFF, VGA_CRTC_DATA);
-    outb(VGA_CRTC_CURSOR_L, VGA_CRTC_ADDR);
-    outb(offset & 0xFF, VGA_CRTC_DATA);
-    irq_restore(flags);
+    return 0;
 }
 
-void tty_switch(tty_t* tty) {
-    if (0 == tty) {
-        return;
-    }
-
-    unsigned int offset = (tty->base_addr - VADDR) / 2;
+int tty_input(tty_t* tty, uint8_t c) {
+    assert(tty != NULL);
 
-    unsigned long flags;
-    irq_save(flags);
-    outb(VGA_CRTC_START_ADDR_H, VGA_CRTC_ADDR);
-    outb((offset >> 8) & 0xFF, VGA_CRTC_DATA);
-    outb(VGA_CRTC_START_ADDR_L, VGA_CRTC_ADDR);
-    outb((offset) & 0xFF, VGA_CRTC_DATA);
-    irq_restore(flags);
+    int next = (tty->ib_head + 1) % TTY_MAX_IN_BUF_SIZE;
+    if (next == tty->ib_tail) {
+        return 0;
+    }
 
-    current_tty = tty;
+    tty->in_buf[tty->ib_head] = c;
+    tty->ib_head = next;
 
-    tty_set_cursor(current_tty);
-}
+    // 目前先总是回显
+    tty_write(tty, (const char*)&c, 1);
 
-void tty_switch_to_next() {
-    tty_t* tty = ttys + ((current_tty - ttys + 1) % NR_TTYS);
-    tty_switch(tty);
-}
+    // TODO: 唤醒读进程
 
-tty_t* current_tty;
+    return 1;
+}
\ No newline at end of file
index 1129c0ac97b02ca6c655b53146ec5e1f80bc6514..3347e6513bc22c7ac3611bf4a87744b23f26d33b 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));