Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added keyboard support #10

Merged
merged 3 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ LIBS:=$(LIBS) -nostdlib -lk -lgcc

ARCHDIR=arch/$(HOSTARCH)
MMUDIR=mmu
DEVICEDIR=arch/devices

include $(ARCHDIR)/make.config
include ${MMUDIR}/make.config
include ${DEVICEDIR}/make.config

CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS)
Expand All @@ -32,7 +34,8 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)
KERNEL_OBJS=\
$(KERNEL_ARCH_OBJS) \
kernel/kernel.o \
${MMU_OBJS}
${MMU_OBJS} \
${KERNEL_DEVICE_OBJS}

OBJS=\
$(ARCHDIR)/crti.o \
Expand All @@ -41,6 +44,7 @@ $(KERNEL_OBJS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \
${MMU_OBJS} \
${KERNEL_DEVICE_OBJS} \

LINK_LIST=\
$(LDFLAGS) \
Expand Down
127 changes: 127 additions & 0 deletions kernel/arch/devices/keyboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include<arch/devices/keyboard.h>
#include<kernel/tty.h>
#include<stdio.h>

unsigned char kbdus[256] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
'9', '0', '-', '=', '\b', /* Backspace */
'\t', /* Tab */
'q', 'w', 'e', 'r', /* 19 */
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
0, /* 29 - Control */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
'\'', '`', 0, /* Left shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
'm', ',', '.', '/', 0, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0,
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
'\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, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0

};

void pause(){
int i = 0;
while(i < 100000000){
i++;
}
while(inb(0x60) & 0x80){

};
}

int shift = 0;
int caps = 0;
int ctrl = 0;
void keyboard_handler(struct regs *r){
unsigned char scancode;
scancode = inb(0x60);

if (scancode & 0x80)
{
if(scancode == 0xAA || scancode == 0xB6)
shift = 0;
if(scancode == 0xE0 || scancode == 0x14)
ctrl = 1;
}
else
{

if(scancode == 0x2a || scancode == 0x36){shift = 1;return;}
if(scancode == 0x3a){ caps = ~caps; return;}
if(scancode == 0x14 || scancode == 0xE0) { ctrl = 1; return;}
if(scancode == 0x1c){terminal_new_line();return;}
/* if(scancode == 0x0e){
if(shell_can_backspace()){
printchar(kbdus[scancode]);
}
shell_backspace();
return;
}*/
if(shift || caps){
printf("%c",kbdus[scancode+90]);
}else{
if(ctrl & scancode == 0x21)
{
printf("Exiting with code 0\n");
asm("hlt");
}
printf("%c",kbdus[scancode]);
}
}
}
8 changes: 8 additions & 0 deletions kernel/arch/devices/make.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
KERNEL_ARCH_CFLAGS=
KERNEL_ARCH_CPPFLAGS=
KERNEL_ARCH_LDFLAGS=
KERNEL_ARCH_LIBS=

KERNEL_DEVICE_OBJS=\
$(DEVICEDIR)/keyboard.o \

Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@


global gdt_flush
extern kgdtr
gdt_flush:
lgdt [kgdtr] ; Load the GDT with our '_gp' which is a special pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!
flush2:
ret ; Returns back to the C code!


global idt_load
extern kidtr
idt_load:
Expand Down Expand Up @@ -175,3 +191,72 @@ isr_common_stub:
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!

global irq0
global irq1
global irq2
global irq3
global irq4
global irq5
global irq6
global irq7
global irq8
global irq9
global irq10
global irq11
global irq12
global irq13
global irq14
global irq15

%macro make_irq 1
irq%1:
cli
push byte 0
push byte %1+32
jmp irq_common_stub
%endmacro

make_irq 0
make_irq 1
make_irq 2
make_irq 3
make_irq 4
make_irq 5
make_irq 6
make_irq 7
make_irq 8
make_irq 9
make_irq 10
make_irq 11
make_irq 12
make_irq 13
make_irq 14
make_irq 15

extern irq_handler

; This is a stub that we have created for IRQ based ISRs. This calls
; '_irq_handler' in our C code. We need to create this in an 'irq.c'
irq_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
6 changes: 0 additions & 6 deletions kernel/arch/i386/boot.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ stack_top:
_start:
movl $stack_top, %esp
call _init
call gdt_init
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
call kernel_main
1: hlt
jmp 1b
Expand Down
101 changes: 101 additions & 0 deletions kernel/arch/i386/interrupts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include<arch/i386/interrupts.h>
#include<stdio.h>

extern void _asm_int_0();
extern void _asm_int_1();
extern void isr0();

extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();

void *irq_routines[16] ={
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};

void fault_handler(struct regs *r)
{
printf("ERROR everywhere\n");
if (r->int_no < 32)
{
printf("ERROR here\n");
asm("hlt");
} else {
printf("ERROR there\n");
asm("hlt");
}
}

void setup_isr(void) {
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, 0);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,1);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,2);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,3);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,4);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,5);
create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE,6);
}

void irq_install_handler(int irq, void (*handler)(struct regs *r)){
irq_routines[irq] = handler;
}
void irq_uninstall_handler(int irq){
irq_routines[irq] = 0;
}

void irq_install(){
create_idt_descriptor(0x08, (unsigned)irq0, INTGATE,32);
create_idt_descriptor(0x08, (unsigned)irq1, INTGATE,33);
create_idt_descriptor(0x08, (unsigned)irq2, INTGATE,34);
create_idt_descriptor(0x08, (unsigned)irq3, INTGATE,35);
create_idt_descriptor(0x08, (unsigned)irq4, INTGATE,36);
create_idt_descriptor(0x08, (unsigned)irq5, INTGATE,37);
create_idt_descriptor(0x08, (unsigned)irq6, INTGATE,38);
create_idt_descriptor(0x08, (unsigned)irq7, INTGATE,39);
create_idt_descriptor(0x08, (unsigned)irq8, INTGATE,40);
create_idt_descriptor(0x08, (unsigned)irq9, INTGATE,41);
create_idt_descriptor(0x08, (unsigned)irq10, INTGATE,42);
create_idt_descriptor(0x08, (unsigned)irq11, INTGATE,43);
create_idt_descriptor(0x08, (unsigned)irq12, INTGATE,44);
create_idt_descriptor(0x08, (unsigned)irq13, INTGATE,45);
create_idt_descriptor(0x08, (unsigned)irq14, INTGATE,46);
create_idt_descriptor(0x08, (unsigned)irq15, INTGATE,47);
}

void irq_handler(struct regs *r){
void (*handler)(struct regs *r);

handler = irq_routines[r->int_no - 32];
if (handler)
{
handler(r);
}

// * If the IDT entry that was invoked was greater than 40
// * (meaning IRQ8 - 15), then we need to send an EOI to
// * the slave controller
if (r->int_no >= 40)
{
outb(0xA0, 0x20);
}

// * In either case, we need to send an EOI to the master
// * interrupt controller too
outb(0x20, 0x20);
}


4 changes: 3 additions & 1 deletion kernel/arch/i386/make.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ KERNEL_ARCH_LIBS=
KERNEL_ARCH_OBJS=\
$(ARCHDIR)/boot.o \
$(ARCHDIR)/tty.o \
${ARCHDIR}/x86_int.o \
${ARCHDIR}/interrupts.o \
${ARCHDIR}/x86.o \
${ARCHDIR}/asm/interrupts.o \

Loading