فهرست منبع

rewrite tty with c++ classes

greatbridf 2 سال پیش
والد
کامیت
5b120d25aa
5فایلهای تغییر یافته به همراه65 افزوده شده و 75 حذف شده
  1. 25 21
      include/kernel/tty.hpp
  2. 1 1
      src/kernel/stdio.cpp
  3. 19 33
      src/kernel/tty.cpp
  4. 1 1
      src/kernel/vfs.cpp
  5. 19 19
      src/kernel_main.cpp

+ 25 - 21
include/kernel/tty.hpp

@@ -1,32 +1,36 @@
 #pragma once
-#include <asm/port_io.h>
+#include <types/allocator.hpp>
+#include <types/buffer.hpp>
+#include <types/cplusplus.hpp>
 #include <types/stdint.h>
 
-#define STRUCT_TTY_NAME_LEN (32)
+class tty : public types::non_copyable {
+public:
+    static constexpr size_t BUFFER_SIZE = 4096;
+    static constexpr size_t NAME_SIZE = 32;
 
-#define SERIAL_TTY_BUFFER_SIZE (4096)
+public:
+    tty();
+    virtual void putchar(char c) = 0;
+    void print(const char* str);
 
-struct tty;
-
-struct tty_operations {
-    void (*put_char)(struct tty* p_tty, char c);
+    char name[NAME_SIZE];
+    types::buffer<types::kernel_ident_allocator> buf;
 };
 
-struct tty {
-    char name[STRUCT_TTY_NAME_LEN];
-    struct tty_operations* ops;
-    union {
-        uint8_t u8[12];
-        uint16_t u16[6];
-        uint32_t u32[3];
-        void* p[12 / sizeof(void*)];
-    } data;
+class vga_tty : public virtual tty {
+public:
+    vga_tty();
+    virtual void putchar(char c) override;
 };
 
-// in kernel_main.c
-extern struct tty* console;
+class serial_tty : public virtual tty {
+public:
+    serial_tty(int id);
+    virtual void putchar(char c) override;
 
-void tty_print(struct tty* p_tty, const char* str);
+public:
+    uint16_t id;
+};
 
-int make_serial_tty(struct tty* p_tty, int id, int buffered);
-int make_vga_tty(struct tty* p_tty);
+inline tty* console;

+ 1 - 1
src/kernel/stdio.cpp

@@ -479,5 +479,5 @@ int strcmp(const char* s1, const char* s2)
 
 void kmsg(const char* msg)
 {
-    tty_print(console, msg);
+    console->print(msg);
 }

+ 19 - 33
src/kernel/tty.cpp

@@ -2,52 +2,38 @@
 #include <kernel/stdio.hpp>
 #include <kernel/tty.hpp>
 #include <kernel/vga.hpp>
+#include <types/stdint.h>
 
-static void serial_tty_put_char(struct tty* p_tty, char c)
+tty::tty()
+    : buf(BUFFER_SIZE)
 {
-    serial_send_data(p_tty->data.u16[0], c);
 }
 
-static void vga_tty_put_char(struct tty* _unused, char c)
+void tty::print(const char* str)
 {
-    static struct vga_char vc = { .c = '\0', .color = VGA_CHAR_COLOR_WHITE };
-    vc.c = c;
-    vga_put_char(&vc);
+    while (*str != '\0')
+        this->putchar(*(str++));
 }
 
-static struct tty_operations serial_tty_ops = {
-    .put_char = serial_tty_put_char,
-};
-
-static struct tty_operations vga_tty_ops = {
-    .put_char = vga_tty_put_char,
-};
+vga_tty::vga_tty()
+{
+    snprintf(this->name, sizeof(this->name), "ttyVGA");
+}
 
-void tty_print(struct tty* p_tty, const char* str)
+serial_tty::serial_tty(int id)
+    : id(id)
 {
-    while (*str != '\0') {
-        p_tty->ops->put_char(p_tty, *str);
-        ++str;
-    }
+    snprintf(this->name, sizeof(this->name), "ttyS%x", (int)id);
 }
 
-int make_serial_tty(struct tty* p_tty, int id, int buffered)
+void serial_tty::putchar(char c)
 {
-    // 0-1: port id
-    // 2  : is_buffered
-    // 3  : unused
-    // 4-7: buffer pointer
-    p_tty->data.u16[0] = id;
-    p_tty->data.p[1] = buffered ? k_malloc(SERIAL_TTY_BUFFER_SIZE) : NULL;
-    p_tty->data.u8[2] = buffered;
-    snprintf(p_tty->name, sizeof(p_tty->name), "ttyS%x", id);
-    p_tty->ops = &serial_tty_ops;
-    return GB_OK;
+    serial_send_data(id, c);
 }
 
-int make_vga_tty(struct tty* p_tty)
+void vga_tty::putchar(char c)
 {
-    snprintf(p_tty->name, sizeof(p_tty->name), "ttyVGA");
-    p_tty->ops = &vga_tty_ops;
-    return GB_OK;
+    static struct vga_char vc = { .c = '\0', .color = VGA_CHAR_COLOR_WHITE };
+    vc.c = c;
+    vga_put_char(&vc);
 }

+ 1 - 1
src/kernel/vfs.cpp

@@ -480,7 +480,7 @@ static size_t console_write(fs::special_node*, const char* buf, size_t, size_t n
 {
     size_t orig_n = n;
     while (n--)
-        console->ops->put_char(console, *(buf++));
+        console->putchar(*(buf++));
 
     return orig_n;
 }

+ 19 - 19
src/kernel_main.cpp

@@ -22,10 +22,9 @@
 
 #define KERNEL_MAIN_BUF_SIZE (128)
 
-struct tty* console = NULL;
 #define printkf(x...)                       \
     snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
-    tty_print(console, buf)
+    console->print(buf)
 
 #define EVE_START(x) printkf(x "... ")
 #define INIT_START(x) EVE_START("initializing " x)
@@ -127,25 +126,23 @@ void init_bss_section(void)
 
 int init_console(const char* name)
 {
-    console = types::_new<types::kernel_ident_allocator, struct tty>();
     if (name[0] == 't' && name[1] == 't' && name[2] == 'y') {
         if (name[3] == 'S' || name[3] == 's') {
             if (name[4] == '0') {
-                make_serial_tty(console, PORT_SERIAL0, 1);
+                console = types::_new<types::kernel_ident_allocator, serial_tty>(PORT_SERIAL0);
                 return GB_OK;
             }
             if (name[4] == '1') {
-                make_serial_tty(console, PORT_SERIAL1, 1);
+                console = types::_new<types::kernel_ident_allocator, serial_tty>(PORT_SERIAL1);
                 return GB_OK;
             }
         }
         if (name[3] == 'V' && name[3] == 'G' && name[3] == 'A') {
-            make_vga_tty(console);
+            console = types::_new<types::kernel_ident_allocator, vga_tty>();
             return GB_OK;
         }
     }
-    ki_free(console);
-    console = NULL;
+    crash();
     return GB_FAILED;
 }
 
@@ -164,11 +161,15 @@ extern "C" void NORETURN kernel_main(void)
 
     load_new_gdt();
 
+    // NOTE:
+    // the initializer of c++ global objects MUST NOT contain
+    // all kinds of memory allocations
+    call_constructors_for_cpp();
+
     char buf[KERNEL_MAIN_BUF_SIZE] = { 0 };
 
-    struct tty early_console;
     assert(init_serial_port(PORT_SERIAL0) == GB_OK);
-    assert(make_serial_tty(&early_console, PORT_SERIAL0, 0) == GB_OK);
+    serial_tty early_console(PORT_SERIAL0);
     console = &early_console;
 
     show_mem_info(buf);
@@ -177,13 +178,6 @@ extern "C" void NORETURN kernel_main(void)
     init_idt();
     INIT_OK();
 
-    // NOTE:
-    // the initializer of c++ global objects MUST NOT contain
-    // all kinds of memory allocations
-    INIT_START("C++ global objects");
-    call_constructors_for_cpp();
-    INIT_OK();
-
     INIT_START("memory allocation");
     init_mem();
     INIT_OK();
@@ -196,7 +190,7 @@ extern "C" void NORETURN kernel_main(void)
     printkf("Testing k_malloc...\n");
     char* k_malloc_buf = (char*)k_malloc(sizeof(char) * 4097);
     snprintf(k_malloc_buf, 4097, "This text is printed on the heap!\n");
-    tty_print(console, k_malloc_buf);
+    kmsg(k_malloc_buf);
     k_free(k_malloc_buf);
 
     assert(init_console("ttyS0") == GB_OK);
@@ -209,7 +203,13 @@ extern "C" void NORETURN kernel_main(void)
 
 void NORETURN __stack_chk_fail(void)
 {
-    tty_print(console, "***** stack smashing detected! *****\n");
+    kmsg("***** stack smashing detected! *****\n");
+    for (;;)
+        assert(0);
+}
+
+extern "C" void NORETURN __cxa_pure_virtual(void)
+{
     for (;;)
         assert(0);
 }