Added IRQs and little refactor :3
This commit is contained in:
parent
cac521ded0
commit
ddb45b819b
9
Makefile
9
Makefile
|
@ -22,14 +22,17 @@ KERNEL_OBJS=\
|
||||||
kernel/kernel.o \
|
kernel/kernel.o \
|
||||||
kernel/debugging.o \
|
kernel/debugging.o \
|
||||||
kernel/elf.o \
|
kernel/elf.o \
|
||||||
|
kernel/keyboard.o \
|
||||||
|
|
||||||
LIB_OBJS=\
|
LIB_OBJS=\
|
||||||
$(ARCHDIR)/bootstrap.o \
|
$(ARCHDIR)/bootstrap.o \
|
||||||
$(ARCHDIR)/tty.o \
|
$(ARCHDIR)/tty.o \
|
||||||
$(ARCHDIR)/strlib.o \
|
$(ARCHDIR)/strlib.o \
|
||||||
$(ARCHDIR)/idt.o \
|
$(ARCHDIR)/interrupts/idt.o \
|
||||||
$(ARCHDIR)/interrupt.o \
|
$(ARCHDIR)/interrupts/interrupt.o \
|
||||||
$(ARCHDIR)/gdt.o \
|
$(ARCHDIR)/gdt.o \
|
||||||
|
$(ARCHDIR)/userland.o \
|
||||||
|
$(ARCHDIR)/interrupts/pic.o \
|
||||||
|
|
||||||
OBJS=$(KERNEL_OBJS) $(LIB_OBJS)
|
OBJS=$(KERNEL_OBJS) $(LIB_OBJS)
|
||||||
|
|
||||||
|
@ -50,7 +53,7 @@ clean:
|
||||||
rm -f myos.iso
|
rm -f myos.iso
|
||||||
rm -f isodir/boot/myos.kernel
|
rm -f isodir/boot/myos.kernel
|
||||||
|
|
||||||
$(ARCHDIR)/interrupt.o: CFLAGS += -mgeneral-regs-only
|
$(ARCHDIR)/interrupts/interrupt.o: CFLAGS += -mgeneral-regs-only
|
||||||
# kernel/elf.o: CFLAGS += -masm=intel
|
# kernel/elf.o: CFLAGS += -masm=intel
|
||||||
|
|
||||||
%.o : %.c
|
%.o : %.c
|
||||||
|
|
|
@ -4,7 +4,16 @@
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "io.h"
|
#include "../io.h"
|
||||||
|
|
||||||
|
#define IRQ0 0x20
|
||||||
|
#define IRQ1 (IRQ0 + 1)
|
||||||
|
#define IRQ2 (IRQ0 + 2)
|
||||||
|
#define IRQ3 (IRQ0 + 3)
|
||||||
|
#define IRQ4 (IRQ0 + 4)
|
||||||
|
#define IRQ5 (IRQ0 + 5)
|
||||||
|
#define IRQ6 (IRQ0 + 6)
|
||||||
|
#define IRQ7 (IRQ0 + 7)
|
||||||
|
|
||||||
#define NUM_ENTRIES 0x100
|
#define NUM_ENTRIES 0x100
|
||||||
|
|
||||||
|
@ -104,7 +113,6 @@ struct InterruptDescriptor generate_entry(bool present, void isr(struct interrup
|
||||||
|
|
||||||
void idt_init()
|
void idt_init()
|
||||||
{
|
{
|
||||||
terminal_initialize();
|
|
||||||
struct InterruptDescriptor entry;
|
struct InterruptDescriptor entry;
|
||||||
|
|
||||||
entry = generate_entry(true, exception, 0xF, 0, 0x8);
|
entry = generate_entry(true, exception, 0xF, 0, 0x8);
|
||||||
|
@ -122,18 +130,20 @@ void idt_init()
|
||||||
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
|
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
|
||||||
add_entry(entry, DoubleFault);
|
add_entry(entry, DoubleFault);
|
||||||
|
|
||||||
outb(0x21,0x20); // Tell the PIC to use interrupts 0x20 - 0x27
|
|
||||||
entry = generate_entry(true, irq, 0xE, 0, 0x8);
|
entry = generate_entry(true, irq, 0xE, 0, 0x8);
|
||||||
for (int i = 0x20; i < 0x28; i++)
|
for (int i = IRQ0; i <= IRQ7; i++)
|
||||||
{
|
{
|
||||||
add_entry(entry, i);
|
add_entry(entry, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = generate_entry(true, keyboard_interrupt, 0xE, 0, 0x8);
|
||||||
|
add_entry(entry, IRQ1);
|
||||||
|
|
||||||
struct InterruptDescriptor print_entry;
|
struct InterruptDescriptor print_entry;
|
||||||
print_entry.present = true;
|
print_entry.present = true;
|
||||||
print_entry.offset = (uint32_t)print;
|
print_entry.offset = (uint32_t)print;
|
||||||
print_entry.gate_type = 0xE;
|
print_entry.gate_type = 0xE;
|
||||||
print_entry.ring = 0;
|
print_entry.ring = 3;
|
||||||
print_entry.selector = 0x8;
|
print_entry.selector = 0x8;
|
||||||
|
|
||||||
add_entry(print_entry, 0x80);
|
add_entry(print_entry, 0x80);
|
||||||
|
@ -142,7 +152,7 @@ void idt_init()
|
||||||
input_entry.present = true;
|
input_entry.present = true;
|
||||||
input_entry.offset = (uint32_t)input;
|
input_entry.offset = (uint32_t)input;
|
||||||
input_entry.gate_type = 0xE;
|
input_entry.gate_type = 0xE;
|
||||||
input_entry.ring = 0;
|
input_entry.ring = 3;
|
||||||
input_entry.selector = 0x8;
|
input_entry.selector = 0x8;
|
||||||
|
|
||||||
add_entry(input_entry, 0x81);
|
add_entry(input_entry, 0x81);
|
|
@ -1,7 +1,8 @@
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
#include "io.h"
|
#include <kernel/keyboard.h>
|
||||||
|
#include "../io.h"
|
||||||
|
|
||||||
struct interrupt_frame {
|
struct interrupt_frame {
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
|
@ -45,38 +46,14 @@ __attribute__((interrupt)) void double_fault(struct interrupt_frame* frame)
|
||||||
__attribute__((interrupt)) void exception(struct interrupt_frame* frame)
|
__attribute__((interrupt)) void exception(struct interrupt_frame* frame)
|
||||||
{
|
{
|
||||||
terminal_writestring("Some weird error code stuff\n");
|
terminal_writestring("Some weird error code stuff\n");
|
||||||
/* terminal_writestring("Error code:\n");
|
|
||||||
print_hex_bytes(frame, sizeof(frame));
|
|
||||||
terminal_putchar('\n'); */
|
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void print(struct interrupt_frame* frame)
|
__attribute__((interrupt)) void print(struct interrupt_frame* frame)
|
||||||
{
|
{
|
||||||
/* terminal_initialize();
|
|
||||||
terminal_putchar(test);
|
|
||||||
test++; */
|
|
||||||
|
|
||||||
char* start;
|
char* start;
|
||||||
asm("mov %%edx, %0" : "=r" (start));
|
asm("mov %%edx, %0" : "=r" (start));
|
||||||
terminal_writestring(start);
|
terminal_writestring(start);
|
||||||
|
|
||||||
/* uint8_t* stack;
|
|
||||||
asm("mov %%esp, %0" : "=r" (stack));
|
|
||||||
|
|
||||||
terminal_writestring("\nSTACK:\n");
|
|
||||||
print_hex_bytes(stack - 24, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
print_hex_bytes(stack - 20, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
print_hex_bytes(stack - 16, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
print_hex_bytes(stack - 12, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
print_hex_bytes(stack - 8, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
print_hex_bytes(stack - 4, 4);
|
|
||||||
terminal_putchar('\n'); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
__attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
||||||
|
@ -84,7 +61,7 @@ __attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
||||||
char* buffer;
|
char* buffer;
|
||||||
asm("mov %%edx, %0" : "=r" (buffer));
|
asm("mov %%edx, %0" : "=r" (buffer));
|
||||||
|
|
||||||
size_t index = 0;
|
/* size_t index = 0;
|
||||||
|
|
||||||
char current_character = get_last_key_pressed();
|
char current_character = get_last_key_pressed();
|
||||||
while (current_character != '\n') {
|
while (current_character != '\n') {
|
||||||
|
@ -96,12 +73,18 @@ __attribute__((interrupt)) void input(struct interrupt_frame* frame)
|
||||||
}
|
}
|
||||||
current_character = tmp;
|
current_character = tmp;
|
||||||
}
|
}
|
||||||
buffer[index] = '\0';
|
buffer[index] = '\0'; */
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame)
|
||||||
|
{
|
||||||
|
uint8_t scancode = inb(0x60);
|
||||||
|
handle_keyboard(scancode);
|
||||||
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void irq(struct interrupt_frame* frame)
|
__attribute__((interrupt)) void irq(struct interrupt_frame* frame)
|
||||||
{
|
{
|
||||||
terminal_writestring("Test");
|
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,5 @@ __attribute__((interrupt)) void exception(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void print(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void print(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void input(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void input(struct interrupt_frame* frame);
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void irq(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void irq(struct interrupt_frame* frame);
|
49
arch/i686/interrupts/pic.c
Normal file
49
arch/i686/interrupts/pic.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "../io.h"
|
||||||
|
|
||||||
|
#define PIC1 0x20 /* IO base address for master PIC */
|
||||||
|
#define PIC2 0xA0 /* IO base address for slave PIC */
|
||||||
|
#define PIC1_COMMAND PIC1
|
||||||
|
#define PIC1_DATA (PIC1+1)
|
||||||
|
#define PIC2_COMMAND PIC2
|
||||||
|
#define PIC2_DATA (PIC2+1)
|
||||||
|
|
||||||
|
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
|
||||||
|
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
|
||||||
|
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
|
||||||
|
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
|
||||||
|
#define ICW1_INIT 0x10 /* Initialization - required! */
|
||||||
|
|
||||||
|
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
|
||||||
|
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
|
||||||
|
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
|
||||||
|
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||||
|
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||||
|
|
||||||
|
void init_pic() {
|
||||||
|
uint8_t a1, a2;
|
||||||
|
|
||||||
|
a1 = inb(PIC1_DATA); // save masks
|
||||||
|
a2 = inb(PIC2_DATA);
|
||||||
|
|
||||||
|
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
|
||||||
|
io_wait();
|
||||||
|
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||||
|
io_wait();
|
||||||
|
outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset
|
||||||
|
io_wait();
|
||||||
|
outb(PIC2_DATA, 0xFF); // ICW2: Slave PIC vector offset
|
||||||
|
io_wait();
|
||||||
|
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
||||||
|
io_wait();
|
||||||
|
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
|
||||||
|
io_wait();
|
||||||
|
|
||||||
|
outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
|
||||||
|
io_wait();
|
||||||
|
outb(PIC2_DATA, ICW4_8086);
|
||||||
|
io_wait();
|
||||||
|
|
||||||
|
outb(PIC1_DATA, a1); // restore saved masks.
|
||||||
|
// outb(PIC2_DATA, a2);
|
||||||
|
outb(PIC2_DATA, 0xFF);
|
||||||
|
}
|
|
@ -3,17 +3,19 @@
|
||||||
static inline void outb(uint16_t port, uint8_t val)
|
static inline void outb(uint16_t port, uint8_t val)
|
||||||
{
|
{
|
||||||
__asm__ volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
__asm__ volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||||
/* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint).
|
|
||||||
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
|
|
||||||
* The outb %al, %dx encoding is the only option for all other cases.
|
|
||||||
* %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void inb(uint16_t port, uint8_t val)
|
static inline uint8_t inb(uint16_t port)
|
||||||
{
|
{
|
||||||
__asm__ volatile ( "inb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
uint8_t ret;
|
||||||
/* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint).
|
__asm__ volatile ( "inb %w1, %b0"
|
||||||
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint).
|
: "=a"(ret)
|
||||||
* The outb %al, %dx encoding is the only option for all other cases.
|
: "Nd"(port)
|
||||||
* %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */
|
: "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void io_wait(void)
|
||||||
|
{
|
||||||
|
outb(0x80, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#include "io.h"
|
|
||||||
|
|
||||||
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
|
|
||||||
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
|
|
||||||
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
|
|
||||||
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
|
|
||||||
#define ICW1_INIT 0x10 /* Initialization - required! */
|
|
||||||
|
|
||||||
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
|
|
||||||
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
|
|
||||||
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
|
|
||||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
|
||||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
|
||||||
|
|
||||||
void init_pic() {
|
|
||||||
|
|
||||||
}
|
|
16
arch/i686/userland.s
Normal file
16
arch/i686/userland.s
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.global jump_to_userspace
|
||||||
|
jump_to_userspace:
|
||||||
|
mov $0x20 | 0x3, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
pushl $0x20 | 0x3 /* SS*/
|
||||||
|
pushl $0x00c00100 /* ESP */
|
||||||
|
pushf /* EFLAGS */
|
||||||
|
popl %eax
|
||||||
|
orl $0x200, %eax
|
||||||
|
pushl %eax /* Set interrupts */
|
||||||
|
pushl $0x18 | 0x3 /* CS */
|
||||||
|
pushl $0x00800000 /* EIP */
|
||||||
|
iret
|
3
include/kernel/keyboard.h
Normal file
3
include/kernel/keyboard.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void handle_keyboard(uint8_t scancode);
|
1
include/kernel/pic.h
Normal file
1
include/kernel/pic.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
void init_pic();
|
|
@ -3,133 +3,6 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <strlib.h>
|
#include <strlib.h>
|
||||||
|
|
||||||
static inline uint8_t inb(uint16_t port)
|
|
||||||
{
|
|
||||||
uint8_t ret;
|
|
||||||
__asm__ volatile ( "inb %w1, %b0"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "Nd"(port)
|
|
||||||
: "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_in_shift;
|
|
||||||
|
|
||||||
static unsigned char keyboard_char(unsigned char scancode)
|
|
||||||
{
|
|
||||||
if (0x01 < scancode && scancode < 0x0B) {
|
|
||||||
return scancode - 2 + '1';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scancode == 0x0B) {
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (scancode) {
|
|
||||||
case 0x10:
|
|
||||||
return 'Q';
|
|
||||||
case 0x11:
|
|
||||||
return 'W';
|
|
||||||
case 0x12:
|
|
||||||
return 'E';
|
|
||||||
case 0x13:
|
|
||||||
return 'R';
|
|
||||||
case 0x14:
|
|
||||||
return 'T';
|
|
||||||
case 0x15:
|
|
||||||
return 'Y';
|
|
||||||
case 0x16:
|
|
||||||
return 'U';
|
|
||||||
case 0x17:
|
|
||||||
return 'I';
|
|
||||||
case 0x18:
|
|
||||||
return 'O';
|
|
||||||
case 0x19:
|
|
||||||
return 'P';
|
|
||||||
case 0x1a:
|
|
||||||
return '[';
|
|
||||||
case 0x1b:
|
|
||||||
return ']';
|
|
||||||
case 0x1c:
|
|
||||||
return '\n';
|
|
||||||
case 0x1d:
|
|
||||||
return '\b';
|
|
||||||
case 0x1e:
|
|
||||||
return 'A';
|
|
||||||
case 0x1f:
|
|
||||||
return 'S';
|
|
||||||
case 0x20:
|
|
||||||
return 'D';
|
|
||||||
case 0x21:
|
|
||||||
return 'F';
|
|
||||||
case 0x22:
|
|
||||||
return 'G';
|
|
||||||
case 0x23:
|
|
||||||
return 'H';
|
|
||||||
case 0x24:
|
|
||||||
return 'J';
|
|
||||||
case 0x25:
|
|
||||||
return 'K';
|
|
||||||
case 0x26:
|
|
||||||
return 'L';
|
|
||||||
case 0x27:
|
|
||||||
return ';';
|
|
||||||
case 0x28:
|
|
||||||
return '\'';
|
|
||||||
case 0x29:
|
|
||||||
return '`';
|
|
||||||
case 0x2a:
|
|
||||||
is_in_shift = true;
|
|
||||||
break;
|
|
||||||
case 0x2b:
|
|
||||||
return '\\';
|
|
||||||
case 0x2c:
|
|
||||||
return 'Z';
|
|
||||||
case 0x2d:
|
|
||||||
return 'X';
|
|
||||||
case 0x2e:
|
|
||||||
return 'C';
|
|
||||||
case 0x2f:
|
|
||||||
return 'V';
|
|
||||||
case 0x30:
|
|
||||||
return 'B';
|
|
||||||
case 0x31:
|
|
||||||
return 'N';
|
|
||||||
case 0x32:
|
|
||||||
return 'M';
|
|
||||||
case 0x33:
|
|
||||||
return ',';
|
|
||||||
case 0x34:
|
|
||||||
return '.';
|
|
||||||
case 0x35:
|
|
||||||
return '/';
|
|
||||||
case 0x36:
|
|
||||||
is_in_shift = true;
|
|
||||||
break;
|
|
||||||
case 0x39:
|
|
||||||
return ' ';
|
|
||||||
case 0xaa:
|
|
||||||
is_in_shift = false;
|
|
||||||
break;
|
|
||||||
case 0xb6:
|
|
||||||
is_in_shift = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char get_last_key_pressed()
|
|
||||||
{
|
|
||||||
char scancode = inb(0x60);
|
|
||||||
|
|
||||||
if (is_in_shift) {
|
|
||||||
return keyboard_char(scancode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return to_lower_char(keyboard_char(scancode));
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_hex_digit(uint8_t digit)
|
void print_hex_digit(uint8_t digit)
|
||||||
{
|
{
|
||||||
digit = digit & 0xf;
|
digit = digit & 0xf;
|
||||||
|
|
21
kernel/elf.c
21
kernel/elf.c
|
@ -13,25 +13,12 @@ static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t s
|
||||||
return dstptr;
|
return dstptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void jump_to_userspace();
|
||||||
|
|
||||||
void run_program(uint8_t* program, size_t length)
|
void run_program(uint8_t* program, size_t length)
|
||||||
{
|
{
|
||||||
uint8_t* userland_code = (uint8_t*) 0x0;
|
uint8_t* userland_code = (uint8_t*) 0x00800000;
|
||||||
memcpy(userland_code, program, length);
|
memcpy(userland_code, program, length);
|
||||||
|
|
||||||
print_hex_bytes(userland_code, 1);
|
jump_to_userspace();
|
||||||
terminal_putchar('\n');
|
|
||||||
|
|
||||||
asm ("\
|
|
||||||
mov $0x20 | 0x3, %%ax;\
|
|
||||||
movw %%ax, %%ds;\
|
|
||||||
movw %%ax, %%es;\
|
|
||||||
movw %%ax, %%fs;\
|
|
||||||
movw %%ax, %%gs;\
|
|
||||||
pushl $0x20 | 0x3; /* SS selector */ \
|
|
||||||
pushl $0x00c00100; /* ESP */ \
|
|
||||||
pushf; /* EFLAGS */ \
|
|
||||||
popl %%eax; orl $0x200, %%eax; pushl %%eax; /* Set interrupts in USERPACE */\
|
|
||||||
pushl $0x18 | 0x3; /* CS selector */\
|
|
||||||
pushl $0x0; /* EIP */ \
|
|
||||||
iret;":::"eax");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <kernel/idt.h>
|
#include <kernel/idt.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
#include <kernel/elf.h>
|
#include <kernel/elf.h>
|
||||||
|
#include <kernel/pic.h>
|
||||||
|
|
||||||
/* Check if the compiler thinks you are targeting the wrong operating system. */
|
/* Check if the compiler thinks you are targeting the wrong operating system. */
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
@ -9,34 +10,45 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t program[] = {
|
uint8_t program[] = {
|
||||||
0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0x0 (Just a simple NOP-like instruction)
|
0xba, 0x09, 0x00, 0x80, 0x00, // mov $string, %edx
|
||||||
0xF4 // hlt (halts the CPU, should trap to kernel if interrupts enabled)
|
0xcd, 0x80, // int 0x80
|
||||||
|
0xeb, 0xfe, // jmp .
|
||||||
|
'H',
|
||||||
|
'e',
|
||||||
|
'l',
|
||||||
|
'l',
|
||||||
|
'o',
|
||||||
|
' ',
|
||||||
|
'W',
|
||||||
|
'o',
|
||||||
|
'r',
|
||||||
|
'l',
|
||||||
|
'd',
|
||||||
|
' ',
|
||||||
|
'f',
|
||||||
|
'r',
|
||||||
|
'o',
|
||||||
|
'm',
|
||||||
|
' ',
|
||||||
|
'r',
|
||||||
|
'i',
|
||||||
|
'n',
|
||||||
|
'g',
|
||||||
|
' ',
|
||||||
|
'3',
|
||||||
|
'!',
|
||||||
|
0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
/* Initialize terminal interface */
|
/* Initialize terminal interface */
|
||||||
// terminal_initialize();
|
terminal_initialize();
|
||||||
|
|
||||||
|
init_pic();
|
||||||
idt_init();
|
idt_init();
|
||||||
|
// run_program(program, sizeof(program));
|
||||||
// asm("int $13");
|
|
||||||
// asm("ljmp $0x18, $0x00c00100"); // Example: Far jump to user code segment with selector 0x18
|
|
||||||
|
|
||||||
print_hex_bytes(idt_init, 4);
|
|
||||||
terminal_putchar('\n');
|
|
||||||
|
|
||||||
run_program(program, 15);
|
|
||||||
|
|
||||||
/*
|
|
||||||
char buf[100];
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
asm("mov %0, %%edx" :: "r" (buf));
|
|
||||||
asm("int $0x81");
|
|
||||||
terminal_writestring("newline");
|
|
||||||
terminal_putchar('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
}
|
||||||
}
|
}
|
||||||
|
|
132
kernel/keyboard.c
Normal file
132
kernel/keyboard.c
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <strlib.h>
|
||||||
|
#include <kernel/tty.h>
|
||||||
|
|
||||||
|
static bool is_in_shift;
|
||||||
|
|
||||||
|
char buffer[100];
|
||||||
|
static size_t i;
|
||||||
|
|
||||||
|
static unsigned char keyboard_char(unsigned char scancode)
|
||||||
|
{
|
||||||
|
if (0x01 < scancode && scancode < 0x0B) {
|
||||||
|
return scancode - 2 + '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scancode == 0x0B) {
|
||||||
|
return '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (scancode) {
|
||||||
|
case 0x10:
|
||||||
|
return 'Q';
|
||||||
|
case 0x11:
|
||||||
|
return 'W';
|
||||||
|
case 0x12:
|
||||||
|
return 'E';
|
||||||
|
case 0x13:
|
||||||
|
return 'R';
|
||||||
|
case 0x14:
|
||||||
|
return 'T';
|
||||||
|
case 0x15:
|
||||||
|
return 'Y';
|
||||||
|
case 0x16:
|
||||||
|
return 'U';
|
||||||
|
case 0x17:
|
||||||
|
return 'I';
|
||||||
|
case 0x18:
|
||||||
|
return 'O';
|
||||||
|
case 0x19:
|
||||||
|
return 'P';
|
||||||
|
case 0x1a:
|
||||||
|
return '[';
|
||||||
|
case 0x1b:
|
||||||
|
return ']';
|
||||||
|
case 0x1c:
|
||||||
|
return '\n';
|
||||||
|
case 0x1d:
|
||||||
|
return '\b';
|
||||||
|
case 0x1e:
|
||||||
|
return 'A';
|
||||||
|
case 0x1f:
|
||||||
|
return 'S';
|
||||||
|
case 0x20:
|
||||||
|
return 'D';
|
||||||
|
case 0x21:
|
||||||
|
return 'F';
|
||||||
|
case 0x22:
|
||||||
|
return 'G';
|
||||||
|
case 0x23:
|
||||||
|
return 'H';
|
||||||
|
case 0x24:
|
||||||
|
return 'J';
|
||||||
|
case 0x25:
|
||||||
|
return 'K';
|
||||||
|
case 0x26:
|
||||||
|
return 'L';
|
||||||
|
case 0x27:
|
||||||
|
return ';';
|
||||||
|
case 0x28:
|
||||||
|
return '\'';
|
||||||
|
case 0x29:
|
||||||
|
return '`';
|
||||||
|
case 0x2a:
|
||||||
|
is_in_shift = true;
|
||||||
|
break;
|
||||||
|
case 0x2b:
|
||||||
|
return '\\';
|
||||||
|
case 0x2c:
|
||||||
|
return 'Z';
|
||||||
|
case 0x2d:
|
||||||
|
return 'X';
|
||||||
|
case 0x2e:
|
||||||
|
return 'C';
|
||||||
|
case 0x2f:
|
||||||
|
return 'V';
|
||||||
|
case 0x30:
|
||||||
|
return 'B';
|
||||||
|
case 0x31:
|
||||||
|
return 'N';
|
||||||
|
case 0x32:
|
||||||
|
return 'M';
|
||||||
|
case 0x33:
|
||||||
|
return ',';
|
||||||
|
case 0x34:
|
||||||
|
return '.';
|
||||||
|
case 0x35:
|
||||||
|
return '/';
|
||||||
|
case 0x36:
|
||||||
|
is_in_shift = true;
|
||||||
|
break;
|
||||||
|
case 0x39:
|
||||||
|
return ' ';
|
||||||
|
case 0xaa:
|
||||||
|
is_in_shift = false;
|
||||||
|
break;
|
||||||
|
case 0xb6:
|
||||||
|
is_in_shift = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_keyboard(uint8_t scancode) {
|
||||||
|
char character;
|
||||||
|
|
||||||
|
if (is_in_shift) {
|
||||||
|
character = keyboard_char(scancode);
|
||||||
|
} else {
|
||||||
|
character = to_lower_char(keyboard_char(scancode));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = character;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
terminal_putchar(character);
|
||||||
|
}
|
Loading…
Reference in a new issue