ROADMAP: закрыт 1 пункт
This commit is contained in:
parent
d64856e1b1
commit
8e6f9cb31a
6 changed files with 61 additions and 2 deletions
3
Makefile
3
Makefile
|
|
@ -23,7 +23,8 @@ OBJ = boot/boot.o \
|
||||||
kernel/string.o \
|
kernel/string.o \
|
||||||
drivers/serial.o \
|
drivers/serial.o \
|
||||||
drivers/vga.o \
|
drivers/vga.o \
|
||||||
drivers/timer.o
|
drivers/timer.o \
|
||||||
|
drivers/keyboard.o
|
||||||
|
|
||||||
# Дефолтное правило (просто сборка бинарника)
|
# Дефолтное правило (просто сборка бинарника)
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
- [x] Прерывания (GDT/IDT)
|
- [x] Прерывания (GDT/IDT)
|
||||||
- [x] UART отладка
|
- [x] UART отладка
|
||||||
- [x] Драйвер таймера
|
- [x] Драйвер таймера
|
||||||
- [ ] Драйвер клавиатуры
|
- [x] Драйвер клавиатуры
|
||||||
- [ ] Нормальный драйвер VGA (скролл итд)
|
- [ ] Нормальный драйвер VGA (скролл итд)
|
||||||
- [ ] Нормальный драйвер клавиатуры (Caps Lock, Shift, Numpad итд)
|
- [ ] Нормальный драйвер клавиатуры (Caps Lock, Shift, Numpad итд)
|
||||||
- [ ] Драйвер PC Speaker
|
- [ ] Драйвер PC Speaker
|
||||||
|
|
|
||||||
43
drivers/keyboard.c
Normal file
43
drivers/keyboard.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
drivers/keyboard.h
Normal file
10
drivers/keyboard.h
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef KEYBOARD_H
|
||||||
|
#define KEYBOARD_H
|
||||||
|
|
||||||
|
// Инициализация (пока просто выведем лог, что всё ок)
|
||||||
|
void keyboard_init(void);
|
||||||
|
|
||||||
|
// Основной обработчик прерывания, который мы вызовем из idt.c
|
||||||
|
void keyboard_handler(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "../drivers/serial.h"
|
#include "../drivers/serial.h"
|
||||||
#include "../drivers/timer.h"
|
#include "../drivers/timer.h"
|
||||||
|
#include "../drivers/keyboard.h"
|
||||||
|
|
||||||
// Сам массив IDT на 256 векторов и указатель на него
|
// Сам массив IDT на 256 векторов и указатель на него
|
||||||
struct idt_entry idt[256];
|
struct idt_entry idt[256];
|
||||||
|
|
@ -76,6 +77,8 @@ void isr_handler(struct registers regs) {
|
||||||
void irq_handler(struct registers regs) {
|
void irq_handler(struct registers regs) {
|
||||||
if (regs.int_no == 32) {
|
if (regs.int_no == 32) {
|
||||||
timer_handler();
|
timer_handler();
|
||||||
|
} else if (regs.int_no == 33) {
|
||||||
|
keyboard_handler(); // <-- Вызываем обработчик клавиатуры при векторе 33
|
||||||
} else {
|
} else {
|
||||||
char irq_str[4];
|
char irq_str[4];
|
||||||
itoa(regs.int_no, irq_str, 10);
|
itoa(regs.int_no, irq_str, 10);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ void kernel_main(void) {
|
||||||
pic_remap(32, 40);
|
pic_remap(32, 40);
|
||||||
log_info(LOG_NORMAL, "Unmasking IRQ 0... (timer)");
|
log_info(LOG_NORMAL, "Unmasking IRQ 0... (timer)");
|
||||||
pic_clear_mask(0);
|
pic_clear_mask(0);
|
||||||
|
log_info(LOG_NORMAL, "Unmasking IRQ 1... (keyboard)");
|
||||||
|
pic_clear_mask(1);
|
||||||
log_info(LOG_NORMAL, "Registering timer at 100Hz");
|
log_info(LOG_NORMAL, "Registering timer at 100Hz");
|
||||||
timer_init(100);
|
timer_init(100);
|
||||||
log_info(LOG_NORMAL, "Enabling IRQ...");
|
log_info(LOG_NORMAL, "Enabling IRQ...");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue