From 8e6f9cb31afe48ea4074cea1843ec9e7e8ecf766 Mon Sep 17 00:00:00 2001 From: msh356 Date: Thu, 2 Jul 2026 20:27:00 +0300 Subject: [PATCH] =?UTF-8?q?ROADMAP:=20=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82?= =?UTF-8?q?=201=20=D0=BF=D1=83=D0=BD=D0=BA=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 3 ++- README.md | 2 +- drivers/keyboard.c | 43 +++++++++++++++++++++++++++++++++++++++++++ drivers/keyboard.h | 10 ++++++++++ kernel/idt.c | 3 +++ kernel/kmain.c | 2 ++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 drivers/keyboard.c create mode 100644 drivers/keyboard.h diff --git a/Makefile b/Makefile index 4e3ef4e..52b96c4 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,8 @@ OBJ = boot/boot.o \ kernel/string.o \ drivers/serial.o \ drivers/vga.o \ - drivers/timer.o + drivers/timer.o \ + drivers/keyboard.o # Дефолтное правило (просто сборка бинарника) all: $(TARGET) diff --git a/README.md b/README.md index 205afeb..9bba99d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - [x] Прерывания (GDT/IDT) - [x] UART отладка - [x] Драйвер таймера -- [ ] Драйвер клавиатуры +- [x] Драйвер клавиатуры - [ ] Нормальный драйвер VGA (скролл итд) - [ ] Нормальный драйвер клавиатуры (Caps Lock, Shift, Numpad итд) - [ ] Драйвер PC Speaker diff --git a/drivers/keyboard.c b/drivers/keyboard.c new file mode 100644 index 0000000..6c0ea57 --- /dev/null +++ b/drivers/keyboard.c @@ -0,0 +1,43 @@ +#include "keyboard.h" +#include "serial.h" +#include "vga.h" +#include "../kernel/io.h" // Отсюда заберём inb +#include "../kernel/logger.h" + +// Карта скан-кодов (US Layout, первый сет). 0 — это непечатаемые символы +static const char kbdus[128] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, + ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // Остальное нули +}; + +void keyboard_init(void) { + // Чисто для логов, unmask мы уже сделали в kmain + log_info(LOG_NORMAL, "Keyboard driver ready.\n"); +} + +void keyboard_handler(void) { + // Читаем байт из порта контроллера клавиатуры (8042) + uint8_t scancode = inb(0x60); + + // Если старший бит (0x80) установлен, это отпускание клавиши (Key Release). Игнорируем пока. + if (scancode & 0x80) { + // Здесь можно отслеживать отпускание Shift/Ctrl + } else { + // Клавиша нажата (Key Press). Проверяем, входит ли в нашу карту + if (scancode < 128 && kbdus[scancode] != 0) { + char c = kbdus[scancode]; + + // Выводим символ на экран через VGA драйвер + vga_putchar(c); + + // И дублируем в сериал для надежной отладки + char str[2] = {c, 0}; + kprint_serial(str); + } + } +} diff --git a/drivers/keyboard.h b/drivers/keyboard.h new file mode 100644 index 0000000..424cc53 --- /dev/null +++ b/drivers/keyboard.h @@ -0,0 +1,10 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +// Инициализация (пока просто выведем лог, что всё ок) +void keyboard_init(void); + +// Основной обработчик прерывания, который мы вызовем из idt.c +void keyboard_handler(void); + +#endif diff --git a/kernel/idt.c b/kernel/idt.c index 2eb6aa7..8e3cc7a 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -2,6 +2,7 @@ #include "string.h" #include "../drivers/serial.h" #include "../drivers/timer.h" +#include "../drivers/keyboard.h" // Сам массив IDT на 256 векторов и указатель на него struct idt_entry idt[256]; @@ -76,6 +77,8 @@ void isr_handler(struct registers regs) { void irq_handler(struct registers regs) { if (regs.int_no == 32) { timer_handler(); + } else if (regs.int_no == 33) { + keyboard_handler(); // <-- Вызываем обработчик клавиатуры при векторе 33 } else { char irq_str[4]; itoa(regs.int_no, irq_str, 10); diff --git a/kernel/kmain.c b/kernel/kmain.c index fe6e0c3..00b6725 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -21,6 +21,8 @@ void kernel_main(void) { pic_remap(32, 40); log_info(LOG_NORMAL, "Unmasking IRQ 0... (timer)"); pic_clear_mask(0); + log_info(LOG_NORMAL, "Unmasking IRQ 1... (keyboard)"); + pic_clear_mask(1); log_info(LOG_NORMAL, "Registering timer at 100Hz"); timer_init(100); log_info(LOG_NORMAL, "Enabling IRQ...");