Обработчик прерываний клавиатуры для собственного ядра (C)
Я пишу крошечную ОС как часть школьного задания, но я застрял, когда дело доходит до ввода с клавиатуры (нажмите клавишу -> отобразить ее на экране). Я использую учебник Bare Bones от osdev.org (кросс-компилятор gcc, загрузчик GRUB, линкер ld) и, поскольку я нахожусь в защищенном режиме, я не могу использовать прерывания BIOS для ввода, поэтому я должен написать свой собственный обработчик прерываний (?) но я не уверен, как это сделать, даже после того, как я прочитал некоторые статьи osdev и обсуждения на форуме. Очень похожая проблема ( http://forum.osdev.org/viewtopic.php?f=1&t=9746) за исключением того, что я не знаю, как "настроить прерывания".
#if !defined(__cplusplus)
#include <stdbool.h> /* C doesn't have booleans by default. */
#endif
#include <stddef.h>
#include <stdint.h>
#define INT_DISABLE 0
#define INT_ENABLE 0x200
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
void outb( unsigned short port, unsigned char val )
{
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port) );
}
static __inline unsigned char inb (unsigned short int port)
{
unsigned char _v;
__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
return _v;
}
void init_pics(int pic1, int pic2)
{
/* send ICW1 */
outb(PIC1, ICW1);
outb(PIC2, ICW1);
/* send ICW2 */
outb(PIC1 + 1, pic1);
outb(PIC2 + 1, pic2);
/* send ICW3 */
outb(PIC1 + 1, 4);
outb(PIC2 + 1, 2);
/* send ICW4 */
outb(PIC1 + 1, ICW4);
outb(PIC2 + 1, ICW4);
/* disable all IRQs */
outb(PIC1 + 1, 0xFF);
}
/*irrelevant code*/
#if defined(__cplusplus)
extern "C" /* Use C linkage for kernel_main. */
#endif
void kernel_main()
{
terminal_initialize();
char c;
init_pics(0x20, 0x28);
c = inb(0x60);
terminal_putchar(c);
}
Это печатает мне белую коробку. Если я пытаюсь прослушать порт 0x64, у меня появляется другой персонаж. Я не ожидаю, что это сработает, потому что у меня нет прерывания. Я думаю, что это должно быть что-то вроде
void _interrupt button_pressed()
{
/*code*/
}
if(button_pressed)
{
c = inb(0x60);
//code to translate the char to ASCII
terminal_putchar(asciiChar);
}
Любая помощь приветствуется. Спасибо
1 ответ
Если есть кто-то заинтересованный, как я решил проблему, вот решение
char c = 0;
init_pics(0x20, 0x28);
do
{
if(inb(0x60)!=c) //PORT FROM WHICH WE READ
{
c = inb(0x60);
if(c>0)
{
terminal_putinput(c); //print on screen
}
}
}
while(c!=1); // 1= ESCAPE
c
переменная содержит код нажатой кнопки. Создав массив перевода, связав с каждым кодом соответствующий код ASCII, я могу напечатать букву / цифру, которая написана на кнопке.
Код кнопок можно найти здесь: http://www.nondot.org/sabre/os/files/HCI/keyboard.txt
ASCII здесь: http://www.ascii-code.com/