finished interrupts for now and a basic scheduler for that, start implementation on paging.
This commit is contained in:
6
makefile
6
makefile
@@ -8,11 +8,12 @@ build: prepare copygrub
|
||||
gcc -c src/kernel/graphics.c -o build/graphics.o -ffreestanding -O2 -Wall -Wextra -m32 # VGA graphics
|
||||
gcc -c src/kernel/tty.c -o build/tty.o -ffreestanding -O2 -Wall -Wextra -m32 # tty
|
||||
gcc -c src/kernel/interrupts.c -o build/interrupts.o -ffreestanding -O2 -Wall -Wextra -m32 # interrupts, C side
|
||||
gcc -c src/kernel/scheduler.c -o build/scheduler.o -ffreestanding -O2 -Wall -Wextra -m32 # scheduler
|
||||
|
||||
gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver
|
||||
|
||||
tar -czf build/initrd build/initrddir/* # build initrd
|
||||
gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link
|
||||
gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/scheduler.o build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link
|
||||
|
||||
cp build/linked build/grub/boot/kernel # copy kernel over to grub template
|
||||
cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template
|
||||
@@ -21,7 +22,8 @@ build: prepare copygrub
|
||||
test: build
|
||||
qemu-system-i386 \
|
||||
-boot d \
|
||||
-cdrom build/live.iso
|
||||
-cdrom build/live.iso \
|
||||
-d int
|
||||
copygrub:
|
||||
cp grubtemplate -r build/grub
|
||||
prepare: clean
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
#define CASCADE_IRQ 2
|
||||
#define IDT_MAX_DESCRIPTORS 32
|
||||
#define IDT_MAX_DESCRIPTORS 256
|
||||
|
||||
typedef struct {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
@@ -34,10 +34,15 @@ typedef struct {
|
||||
uint32_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
typedef struct {
|
||||
uint32_t ds;
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
uint32_t int_no, err_code;
|
||||
uint32_t eip, cs, eflags, useresp, ss;
|
||||
uint32_t ds;
|
||||
|
||||
uint32_t eax, ecx, edx, ebx;
|
||||
uint32_t esp, ebp, esi, edi;
|
||||
|
||||
uint32_t int_no, err_code;
|
||||
|
||||
//uint32_t eip, cs, eflags;
|
||||
uint32_t useresp, ss;
|
||||
} INT_registers_t;
|
||||
typedef struct {
|
||||
uint8_t inuse;
|
||||
@@ -53,7 +58,7 @@ inline void PIC_sendEOI(uint8_t irq) {
|
||||
void PIC_remap(int offset1, int offset2);
|
||||
__attribute__((noreturn))
|
||||
void INT_exhand(INT_registers_t regs);
|
||||
void INT_IRQ(uint8_t IRQ, INT_registers_t regs);
|
||||
void INT_IRQ(INT_registers_t* regs);
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
void idt_init();
|
||||
void IRQ_registerhandler(uint8_t vector, void* callback);
|
||||
|
||||
21
src/headers/keyboard.h
Normal file
21
src/headers/keyboard.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "stddef.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#define KEYBOARD_cmd_setled 0xED
|
||||
#define KEYBOARD_cmd_echo 0xEE
|
||||
#define KEYBOARD_cmd_setscanset 0xF0
|
||||
#define KEYBOARD_cmd_enable 0xF4
|
||||
#define KEYBOARD_cmd_disable 0xF5
|
||||
#define KEYBOARD_cmd_reset 0xFF
|
||||
#define KEYBOARD_resp_ACK 0xFA
|
||||
#define KEYBOARD_resp_resend 0xFE
|
||||
#define KEYBOARD_resp_err 0x00
|
||||
#define KEYBOARD_resp_selftestpass 0xAA
|
||||
#define KEYBOARD_resp_echo 0xEE
|
||||
#define KEYBOARD_resp_testfail1 0xFC
|
||||
#define KEYBOARD_resp_testfail2 0xFD
|
||||
#define KEYBOARD_resp_err2 0xFF
|
||||
#define KEYBOARD_cqsize 128
|
||||
|
||||
extern uint8_t KEYBOARD_cmdqueue[KEYBOARD_cqsize];
|
||||
extern size_t KEYBOARD_cmdqueuesize;
|
||||
0
src/headers/paging.h
Normal file
0
src/headers/paging.h
Normal file
21
src/headers/scheduler.h
Normal file
21
src/headers/scheduler.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "stddef.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#define SCHED_tasksize 128
|
||||
#define SCHED_freq 1000
|
||||
|
||||
typedef struct {
|
||||
uint8_t inUse;
|
||||
uint8_t type;
|
||||
size_t ticks;
|
||||
void* callback;
|
||||
} task_t;
|
||||
|
||||
extern task_t tasks[SCHED_tasksize];
|
||||
|
||||
void tick();
|
||||
size_t schedule_task(size_t tick, void* callback);
|
||||
uint8_t schedule_sleep(size_t tick);
|
||||
size_t schedule_task_fl(double time, void* callback);
|
||||
uint8_t schedule_sleep_fl(double time);
|
||||
task_t* schedule_getTask(size_t index);
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../headers/graphics.h"
|
||||
#include "../headers/tty.h"
|
||||
#include "../headers/interrupts.h"
|
||||
#include "../headers/scheduler.h"
|
||||
|
||||
struct multiboot_info {
|
||||
uint32_t total_size;
|
||||
@@ -55,16 +56,17 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
}
|
||||
kputstr("OK\n");
|
||||
|
||||
kputstr("Setting up interrupts: ");
|
||||
idt_init();
|
||||
kputstr("OK\n");
|
||||
|
||||
kputstr("Setting up IRQs: ");
|
||||
for (uint8_t i=0;i<16;i++) {
|
||||
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
|
||||
IRQ_entries[i].inuse = 0;
|
||||
}
|
||||
kputstr("OK\n");
|
||||
|
||||
kputstr("Setting up interrupts: ");
|
||||
idt_init();
|
||||
kputstr("OK\n");
|
||||
|
||||
kputstr("Initializing PICs: ");
|
||||
PIC_remap(0x20,0x28);
|
||||
kputstr("OK\n");
|
||||
@@ -73,10 +75,8 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
asm volatile("sti");
|
||||
kputstr("OK\n");
|
||||
|
||||
while (1) {}
|
||||
|
||||
kputstr("Initializing Timer: ");
|
||||
uint32_t divisor = 1193180 / 1000;
|
||||
uint32_t divisor = 1193180 / SCHED_freq;
|
||||
uint8_t low = (uint8_t)(divisor & 0xFF);
|
||||
uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF);
|
||||
outb(0x43, 0x36);
|
||||
@@ -84,5 +84,9 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
outb(0x40, high);
|
||||
kputstr("OK\n");
|
||||
|
||||
IRQ_registerhandler(0x00, &tick);
|
||||
|
||||
|
||||
|
||||
while (1) {}
|
||||
}
|
||||
@@ -72,11 +72,14 @@ void INT_exhand(INT_registers_t regs) {
|
||||
uitoa32(regs.int_no, temp);
|
||||
strcon(msg,temp);
|
||||
kpanic(msg);
|
||||
PIC_sendEOI(regs.int_no);
|
||||
}
|
||||
void INT_IRQ(INT_registers_t regs) {
|
||||
void INT_IRQ(INT_registers_t* _regs) {
|
||||
INT_registers_t regs = *_regs;
|
||||
if (IRQ_entries[regs.int_no].inuse) {
|
||||
(void (*)(INT_registers_t))IRQ_entries[regs.int_no].callback(regs);
|
||||
((void (*)(INT_registers_t))IRQ_entries[regs.int_no].callback)(regs);
|
||||
}
|
||||
PIC_sendEOI(regs.int_no);
|
||||
}
|
||||
void idt_init() {
|
||||
idtr.base = (uint32_t)&idt[0];
|
||||
@@ -89,6 +92,6 @@ void idt_init() {
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT
|
||||
}
|
||||
void IRQ_registerhandler(uint8_t vector, void* callback) {
|
||||
IRQ_entries[vector].inuse = 1;
|
||||
IRQ_entries[vector].callback = callback;
|
||||
IRQ_entries[vector].inuse = 1;
|
||||
}
|
||||
77
src/kernel/scheduler.c
Normal file
77
src/kernel/scheduler.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "../headers/scheduler.h"
|
||||
|
||||
task_t tasks[SCHED_tasksize];
|
||||
uint8_t tasksbusy = 0;
|
||||
|
||||
void acquiretasks() {
|
||||
while (tasksbusy) {}
|
||||
tasksbusy = 1;
|
||||
}
|
||||
void freetasks() {
|
||||
tasksbusy = 0;
|
||||
}
|
||||
void tick() {
|
||||
if (tasksbusy) {return;}
|
||||
acquiretasks();
|
||||
for (size_t i=0;i<SCHED_tasksize;i++) {
|
||||
if (tasks[i].inUse) {
|
||||
tasks[i].ticks --;
|
||||
if (tasks[i].ticks == 0) {
|
||||
tasks[i].inUse = 0;
|
||||
if (tasks[i].type == 0) { // callback
|
||||
((void (*)())tasks[i].callback)();
|
||||
} else if (tasks[i].type == 1) { // reset
|
||||
*(uint8_t*)tasks[i].callback = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
freetasks();
|
||||
}
|
||||
size_t schedule_task(size_t tick, void* callback) {
|
||||
acquiretasks();
|
||||
for (size_t i=0;i<SCHED_tasksize;i++) {
|
||||
task_t* task = &tasks[i];
|
||||
if (!task->inUse) {
|
||||
task->inUse = 1;
|
||||
task->ticks = tick;
|
||||
task->callback = callback;
|
||||
task->type = 0;
|
||||
freetasks();
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
freetasks();
|
||||
return 0;
|
||||
}
|
||||
uint8_t schedule_sleep(size_t tick) {
|
||||
volatile uint8_t wait = 1;
|
||||
acquiretasks();
|
||||
for (size_t i=0;i<SCHED_tasksize+1;i++) {
|
||||
if (i == SCHED_tasksize) {
|
||||
freetasks();
|
||||
return 0;
|
||||
}
|
||||
task_t* task = &tasks[i];
|
||||
if (!task->inUse) {
|
||||
task->inUse = 1;
|
||||
task->ticks = tick;
|
||||
task->callback = &wait;
|
||||
task->type = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
freetasks();
|
||||
while (wait) {}
|
||||
return 1;
|
||||
}
|
||||
size_t schedule_task_fl(double time, void* callback) {
|
||||
return schedule_task(time*SCHED_freq, callback);
|
||||
}
|
||||
uint8_t schedule_sleep_fl(double time) {
|
||||
return schedule_sleep(time*SCHED_freq);
|
||||
}
|
||||
task_t* schedule_getTask(size_t index) {
|
||||
if (index == 0) {return 0x00;}
|
||||
return &tasks[index-1];
|
||||
}
|
||||
@@ -34,7 +34,7 @@ void kpanic(char* msg) {
|
||||
|
||||
for (uint16_t x=0;x<VGA_sizex;x++) {
|
||||
for (uint16_t y=0;y<VGA_sizey;y++) {
|
||||
VGA_setpix(x,y,(VGA_pixel){0x00,0xFF,0x00});
|
||||
VGA_setpix(x,y,(VGA_pixel){(uint32_t)msg+x+(y*VGA_sizex)*3,(uint32_t)msg+x+(y*VGA_sizex)*3+1,(uint32_t)msg+x+(y*VGA_sizex)*3+2});
|
||||
}
|
||||
}
|
||||
size_t x=0;
|
||||
|
||||
@@ -3,18 +3,18 @@ extern INT_IRQ
|
||||
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
cli
|
||||
push 0
|
||||
push %1
|
||||
|
||||
pusha
|
||||
mov ax, ds
|
||||
push eax
|
||||
mov ax, 0x08
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
call INT_exhand
|
||||
|
||||
pop eax
|
||||
@@ -24,31 +24,40 @@ isr_stub_%+%1:
|
||||
mov gs, ax
|
||||
popa
|
||||
add esp, 8
|
||||
sti
|
||||
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
cli
|
||||
;call INT_exhand
|
||||
sti
|
||||
sti
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro irq_stub 1
|
||||
irq_stub_%+%1:
|
||||
cli
|
||||
push 0
|
||||
push %1
|
||||
|
||||
pusha
|
||||
xor eax, eax
|
||||
mov ax, ds
|
||||
push eax
|
||||
mov ax, 0x08
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
mov eax, esp
|
||||
push eax
|
||||
|
||||
call INT_IRQ
|
||||
|
||||
add esp, 4
|
||||
pop ebx
|
||||
mov ds, bx
|
||||
mov es, bx
|
||||
@@ -56,6 +65,8 @@ irq_stub_%+%1:
|
||||
mov gs, bx
|
||||
popa
|
||||
add esp, 8
|
||||
sti
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
isr_no_err_stub 0
|
||||
|
||||
Reference in New Issue
Block a user