summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/LINKS.TODO3
-rw-r--r--src/Makefile9
-rw-r--r--src/interrupts.c53
-rw-r--r--src/interrupts.h17
-rw-r--r--src/kernel.c7
-rw-r--r--src/keyboard.c18
-rw-r--r--src/keyboard.h19
7 files changed, 84 insertions, 42 deletions
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index df6471d..53cc093 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -41,3 +41,6 @@ PIC:
http://www.brokenthorn.com/Resources/OSDevPic.html
http://wiki.osdev.org/8259_PIC
+keyboard:
+http://wiki.osdev.org/"8042"_PS/2_Controller
+
diff --git a/src/Makefile b/src/Makefile
index 9c6a931..14aa939 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -28,11 +28,11 @@ kernel.bin: kernel.elf
kernel.sym: kernel.elf
$(OBJCOPY) --only-keep-debug kernel.elf kernel.sym
-kernel.elf: kernel.o console.o vga.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o string.o stdlib.o stdio.o setjmp.o
+kernel.elf: kernel.o console.o vga.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o keyboard.o string.o stdlib.o stdio.o setjmp.o
$(LD) -o kernel.elf -N -n -Ttext 0x8400 --oformat elf32-i386 \
kernel.o console.o vga.o serial.o port.o port_asm.o \
- interrupts.o interrupts_asm.o string.o stdlib.o stdio.o \
- setjmp.o
+ interrupts.o interrupts_asm.o keyboard.o \
+ string.o stdlib.o stdio.o setjmp.o
magic.bin: magic.asm
$(NASM) magic.asm -DMAGIC='"$(MAGIC)"' -f bin -o magic.bin
@@ -61,6 +61,9 @@ interrupts.o: interrupts.c interrupts.h
interrupts_asm.o: interrupts.asm
$(NASM) interrupts.asm $(NASMFLAGS) -o interrupts_asm.o
+keyboard.o: keyboard.c keyboard.h
+ $(CC) $(CFLAGS) -c -o keyboard.o keyboard.c
+
string.o: string.c string.h
$(CC) $(CFLAGS) -c -o string.o string.c
diff --git a/src/interrupts.c b/src/interrupts.c
index 0c3c72a..81fcfb1 100644
--- a/src/interrupts.c
+++ b/src/interrupts.c
@@ -5,6 +5,8 @@
#include "kernel.h"
+#include "keyboard.h"
+
// TODO: for now the code segment is the first entry in the boot GDT
#define GDT_CODE_SEGMENT_SELECTOR 8
@@ -17,9 +19,6 @@
// types of IDT entries
#define IDT_TYPE_INTERRUPT_GATE 0xE
-// offset for hardware interrupts
-#define IRQ_BASE 0x20
-
// PIC constants
#define ICW1_ICW4 0x01 // support a 4th initialization word (ICW4)
@@ -83,34 +82,30 @@ void interrupts_init( interrupt_t *interrupt )
interrupt_handler_init_void( &empty_interrupt_handler );
for( int i = 0; i < NOF_INTERRUPTS; i++ ) {
- interrupts_register_interrupt( interrupt, i, GDT_CODE_SEGMENT_SELECTOR,
- &interrupts_ignore_request, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- empty_interrupt_handler );
+ interrupts_register_interrupt_gate( interrupt, i, GDT_CODE_SEGMENT_SELECTOR,
+ &interrupts_ignore_request, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
+ interrupts_register_interrupt_handler( empty_interrupt_handler );
}
// divide-by-zero exception 0x00
interrupt_handler_t divide_by_zero_interrupt_handler;
interrupt_handler_init( &divide_by_zero_interrupt_handler, 0x00, interrupt, interrupts_exception_division_by_zero );
- interrupts_register_interrupt( interrupt, 0x00, GDT_CODE_SEGMENT_SELECTOR,
- &interrupts_handle_exception_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- divide_by_zero_interrupt_handler );
+ interrupts_register_interrupt_gate( interrupt, 0x00, GDT_CODE_SEGMENT_SELECTOR,
+ &interrupts_handle_exception_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
+ interrupts_register_interrupt_handler( divide_by_zero_interrupt_handler );
// IRQ 0 - PIT - programmable interrupt timer
interrupt_handler_t pit_interrupt_handler;
interrupt_handler_init( &pit_interrupt_handler, IRQ_BASE + 0x00, interrupt, interrupts_interrupt_PIT );
- interrupts_register_interrupt( interrupt, IRQ_BASE + 0x00, GDT_CODE_SEGMENT_SELECTOR,
- &interrupts_handle_irq_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- pit_interrupt_handler );
+ interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x00, GDT_CODE_SEGMENT_SELECTOR,
+ &interrupts_handle_irq_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
+ interrupts_register_interrupt_handler( pit_interrupt_handler );
// IRQ 1 - keyboard
- interrupt_handler_t keyboard_interrupt_handler;
- interrupt_handler_init( &keyboard_interrupt_handler, IRQ_BASE + 0x01, interrupt, interrupts_interrupt_keyboard );
-
- interrupts_register_interrupt( interrupt, IRQ_BASE + 0x01, GDT_CODE_SEGMENT_SELECTOR,
- &interrupts_handle_irq_0x01, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- keyboard_interrupt_handler );
+ interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x01, GDT_CODE_SEGMENT_SELECTOR,
+ &interrupts_handle_irq_0x01, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
port8_init( &interrupt->PIC_master_control, 0x20 );
port8_init( &interrupt->PIC_master_data, 0x21 );
@@ -151,10 +146,9 @@ void interrupts_init( interrupt_t *interrupt )
active_interrupt = interrupt;
}
-void interrupts_register_interrupt( interrupt_t *interrupts,
+void interrupts_register_interrupt_gate( interrupt_t *interrupts,
uint8_t interrupt_no, uint16_t gdt_code_segment_selector,
- void (*helper_handler)( ), uint8_t privilege_level, uint8_t descriptor_type,
- interrupt_handler_t handler )
+ void (*helper_handler)( ), uint8_t privilege_level, uint8_t descriptor_type )
{
interrupt_gate_descriptor_t *descr = &interrupts->descriptor_table[interrupt_no];
@@ -163,8 +157,11 @@ void interrupts_register_interrupt( interrupt_t *interrupts,
descr->gdt_code_segment_selector = gdt_code_segment_selector;
descr->access = IDT_PRESENT_BIT | (( privilege_level & 0x3 ) << 5 ) | descriptor_type;
descr->reserved = 0;
-
- interrupts->interrupt_handler[interrupt_no] = handler;
+}
+
+void interrupts_register_interrupt_handler( interrupt_handler_t handler )
+{
+ handler.interrupt->interrupt_handler[handler.interrupt_no] = handler;
}
uint32_t interrupts_exception_division_by_zero( interrupt_t *interrupt, uint32_t esp )
@@ -184,16 +181,6 @@ uint32_t interrupts_interrupt_PIT( interrupt_t *interrupt, uint32_t esp )
return esp;
}
-uint32_t interrupts_interrupt_keyboard( interrupt_t *interrupt, uint32_t esp )
-{
- puts( "KBD KBD KBD KBD KBD KBD KBD" );
-
-int y = 0;
-int x = 12 / y;
-printf( "Hex number is 0x%X and string is '%s'\n", x, "abaos" );
- return esp;
-}
-
uint32_t interrupts_handle_static_interrupt( uint8_t interrupt_no, uint32_t esp )
{
if( active_interrupt == NULL ) {
diff --git a/src/interrupts.h b/src/interrupts.h
index 82f95f4..7903057 100644
--- a/src/interrupts.h
+++ b/src/interrupts.h
@@ -5,6 +5,12 @@
#include "port.h"
+// total number of supported interrupts
+#define NOF_INTERRUPTS 256
+
+// offset for hardware interrupts
+#define IRQ_BASE 0x20
+
// TCC 0.9.26 bug?, __attribute__( ( packed ) ) on structs not working,
// also not working on members.. resorting to pragmas
#if defined( __TINYC__ )
@@ -26,8 +32,6 @@ typedef struct interrupt_gate_descriptor_t {
#pragma pack()
#endif
-#define NOF_INTERRUPTS 256
-
#if defined( __TINYC__ )
#pragma pack(1)
#endif
@@ -49,6 +53,7 @@ typedef struct interrupt_handler_t {
uint8_t interrupt_no;
struct interrupt_t *interrupt;
interrupt_handler_func_t handle;
+ void *driver;
} interrupt_handler_t;
void interrupt_handler_init_void( interrupt_handler_t *handler );
@@ -71,10 +76,11 @@ typedef struct interrupt_t {
void interrupts_enable( void );
void interrupts_disable( void );
void interrupts_init( interrupt_t *interrupt );
-void interrupts_register_interrupt( interrupt_t *interrupt,
+void interrupts_register_interrupt_gate( interrupt_t *interrupt,
uint8_t interrupt_no, uint16_t gdt_code_segment_selector,
- void (*helper_handler)( ), uint8_t privilege_level, uint8_t descriptor_type,
- interrupt_handler_t handler );
+ void (*helper_handler)( ), uint8_t privilege_level, uint8_t descriptor_type );
+void interrupts_register_interrupt_handler( interrupt_handler_t handler );
+
void interrupts_load_idt( interrupt_descriptor_table_pointer_t *idt_pointer );
uint32_t interrupts_handle_interrupt( interrupt_t *interrupt, uint8_t interrupt_no, uint32_t esp );
@@ -84,7 +90,6 @@ uint32_t interrupts_handle_static_interrupt( uint8_t interrupt_no, uint32_t esp
uint32_t interrupts_exception_division_by_zero( interrupt_t *interrupt, uint32_t esp );
uint32_t interrupts_interrupt_PIT( interrupt_t *interrupt, uint32_t esp );
-uint32_t interrupts_interrupt_keyboard( interrupt_t *interrupt, uint32_t esp );
void interrupts_ignore_request( );
void interrupts_handle_exception_0x00( );
diff --git a/src/kernel.c b/src/kernel.c
index eba75ba..cd15484 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -7,6 +7,7 @@
#include "stdlib.h"
#include "stdio.h"
#include "interrupts.h"
+#include "keyboard.h"
#include "setjmp.h"
static jmp_buf panic_jmp_buf;
@@ -34,6 +35,12 @@ void entry( void )
puts( "Initializing interrupts" );
interrupt_t interrupt;
interrupts_init( &interrupt );
+
+ keyboard_t keyboard;
+ keyboard_init( &keyboard );
+ interrupt_handler_t keyboard_interrupt_handler;
+ interrupt_handler_init( &keyboard_interrupt_handler, IRQ_BASE + 0x01, &interrupt, keyboard_handle_interrupt );
+ interrupts_register_interrupt_handler( keyboard_interrupt_handler );
// exit point in case of kernel panic, do this as soon as
// possible
diff --git a/src/keyboard.c b/src/keyboard.c
new file mode 100644
index 0000000..672d85c
--- /dev/null
+++ b/src/keyboard.c
@@ -0,0 +1,18 @@
+#include "keyboard.h"
+
+#include "stdio.h"
+
+void keyboard_init( keyboard_t *keyboard )
+{
+ memset( keyboard, 0, sizeof( keyboard_t ) );
+}
+
+uint32_t keyboard_handle_interrupt( interrupt_t *interrupt, uint32_t esp )
+{
+ puts( "KBD KBD KBD KBD KBD KBD KBD" );
+
+int y = 0;
+int x = 12 / y;
+printf( "Hex number is 0x%X and string is '%s'\n", x, "abaos" );
+ return esp;
+}
diff --git a/src/keyboard.h b/src/keyboard.h
new file mode 100644
index 0000000..b0d87f5
--- /dev/null
+++ b/src/keyboard.h
@@ -0,0 +1,19 @@
+#ifndef KEYBOARD_H
+#define KEYBOARD_H
+
+#include "string.h"
+
+#include "interrupts.h"
+#include "port.h"
+
+typedef struct {
+ interrupt_t *interrupts;
+ port8_t command_port;
+ port8_t data_port;
+} keyboard_t;
+
+void keyboard_init( keyboard_t *keyboard );
+
+uint32_t keyboard_handle_interrupt( interrupt_t *interrupt, uint32_t esp );
+
+#endif // KEYBOARD_H