diff options
-rw-r--r-- | doc/LINKS.TODO | 3 | ||||
-rw-r--r-- | src/Makefile | 9 | ||||
-rw-r--r-- | src/interrupts.c | 53 | ||||
-rw-r--r-- | src/interrupts.h | 17 | ||||
-rw-r--r-- | src/kernel.c | 7 | ||||
-rw-r--r-- | src/keyboard.c | 18 | ||||
-rw-r--r-- | src/keyboard.h | 19 |
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( ÷_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 |