Interrupts

This commit is contained in:
notsomeidiot123 2024-11-04 17:38:17 -05:00
parent 9cda603a34
commit 6400fafa81
9 changed files with 485 additions and 9 deletions

View File

@ -65,6 +65,17 @@ If all else fails, the bootloader will attempt to enable the a20 line by using t
While any GDT loaded for the Kernel will work, once the Kernel wants to load user processes, it will fail to locate user segments in the GDT if the one loaded is not the one expected. Because of this, the Kernel will need to load it's own if the one it wants is not loaded by this bootloader. To allow for detection, the key "0xaa55" is written at the end of the GDT, marking the last segment invalid, but allowing for the detection of the correct GDT being pre-loaded. This detection will only occurr during boot time, and unexpected writes will cause the Kernel to crash.
#### GDT Layout:
|INDEX|ENTRY TYPE|
|-----|----------|
|0x00 |Null Entry|
|0x08 |Kernel Code (16)|
|0x10 |Kernel Code (32)|
|0x18 |Kernel Data (32)|
|0x20 |User Code (32) |
|0x28 |User Data (32) |
|0x30 |TSS |
### Error Codes
|Error Code|Description|

View File

@ -20,6 +20,7 @@ bootloader:
kernel:
nasm src/kernel/entry.s -o bin/kernel/entry.o -f elf32
sh c_build_helper.sh
nasm src/kernel/arch_i386/idt.s -o bin/kernel/idt.o -felf32
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
ld -T linker.ld bin/kernel/*.o -melf_i386
# %.o: $(SRCS)

365
src/kernel/arch_i386/idt.s Normal file
View File

@ -0,0 +1,365 @@
global _isr0
global _isr1
global _isr2;
global _isr3;
global _isr4;
global _isr5;
global _isr6
global _isr7
global _isr8
global _isr9
global _isr10
global _isr11
global _isr12
global _isr13
global _isr14
global _isr15
global _isr16
global _isr17
global _isr18
global _isr19
global _isr20
global _isr21
global _isr22
global _isr23
global _isr24
global _isr25
global _isr26
global _isr27
global _isr28
global _isr29
global _isr30
global _isr31
global load_idt
load_idt:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
lidt [eax]
pop ebp
ret
_isr0:
cli
push dword 0
push dword 0
jmp _isr_common_stub
_isr1:
cli
push dword 0
push dword 1
jmp _isr_common_stub
_isr2:
cli
push dword 0
push dword 2
jmp _isr_common_stub
_isr3:
cli
push dword 0
push dword 3
jmp _isr_common_stub
_isr4:
cli
push dword 0
push dword 4
jmp _isr_common_stub
_isr5:
cli
push dword 0
push dword 5
jmp _isr_common_stub
_isr6:
cli
push dword 0
push dword 6
jmp _isr_common_stub
_isr7:
cli
push dword 0
push dword 7
jmp _isr_common_stub
_isr8:
cli
push dword 0
push dword 8
jmp _isr_common_stub
_isr9:
cli
push dword 0
push dword 9
jmp _isr_common_stub
_isr10:
cli
push dword 10
jmp _isr_common_stub
_isr11:
cli
push dword 11
jmp _isr_common_stub
_isr12:
cli
push dword 12
jmp _isr_common_stub
_isr13:
cli
push dword 13
jmp _isr_common_stub
_isr14:
cli
push dword 14
jmp _isr_common_stub
_isr15:
cli
push dword 0
push dword 15
jmp _isr_common_stub
_isr16:
cli
push dword 0
push dword 16
jmp _isr_common_stub
_isr17:
cli
push dword 17
jmp _isr_common_stub
_isr18:
cli
push dword 0
push dword 18
jmp _isr_common_stub
_isr19:
cli
push dword 0
push dword 19
jmp _isr_common_stub
_isr20:
cli
push dword 0
push dword 20
jmp _isr_common_stub
_isr21:
cli
push dword 21
jmp _isr_common_stub
_isr22:
cli
push dword 0
push dword 22
jmp _isr_common_stub
_isr23:
cli
push dword 0
push dword 23
jmp _isr_common_stub
_isr24:
cli
push dword 0
push dword 24
jmp _isr_common_stub
_isr25:
cli
push dword 0
push dword 25
jmp _isr_common_stub
_isr26:
cli
push dword 0
push dword 26
jmp _isr_common_stub
_isr27:
cli
push dword 0
push dword 27
jmp _isr_common_stub
_isr28:
cli
push dword 0
push dword 28
jmp _isr_common_stub
_isr29:
cli
push dword 29
jmp _isr_common_stub
_isr30:
cli
push dword 30
jmp _isr_common_stub
_isr31:
cli
push dword 0
push dword 31
jmp _isr_common_stub
extern _isr_handler
global _isr_common_stub
_isr_common_stub:
push eax
push ebx
push ecx
push edx
push ebp
push esi
push edi
push ds
push es
push fs
push gs
push esp;push argument
call _isr_handler
pop esp
pop gs
pop fs
pop es
pop ds
pop edi
pop esi
pop ebp
pop edx
pop ecx
pop ebx
pop eax
add esp, 8
iret
extern _irq_handler
global _irq_common_stub
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
global _syscall
_irq0:
cli
push 0
push 32
jmp _irq_common_stub
_irq1:
cli
push 0
push 33
jmp _irq_common_stub
_irq2:
cli
push 0
push 34
jmp _irq_common_stub
_irq3:
cli
push 0
push 35
jmp _irq_common_stub
_irq4:
cli
push 0
push 36
jmp _irq_common_stub
_irq5:
cli
push 0
push 37
jmp _irq_common_stub
_irq6:
cli
push 0
push 38
jmp _irq_common_stub
_irq7:
cli
push 0
push 39
jmp _irq_common_stub
_irq8:
cli
push 0
push 40
jmp _irq_common_stub
_irq9:
cli
push 0
push 41
jmp _irq_common_stub
_irq10:
cli
push 0
push 42
jmp _irq_common_stub
_irq11:
cli
push 0
push 43
jmp _irq_common_stub
_irq12:
cli
push 0
push 44
jmp _irq_common_stub
_irq13:
cli
push 0
push 45
jmp _irq_common_stub
_irq14:
cli
push 0
push 46
jmp _irq_common_stub
_irq15:
cli
push 0
push 47
jmp _irq_common_stub
_syscall:
cli
push 0
push 0x80
_irq_common_stub:
push eax
push ebx
push ecx
push edx
push ebp
push esi
push edi
push ds
push es
push fs
push gs
push esp;push argument
call _irq_handler
pop esp
pop gs
pop fs
pop es
pop ds
pop edi
pop esi
pop ebp
pop edx
pop ecx
pop ebx
pop eax
add esp, 8
iret

View File

@ -1,5 +1,51 @@
#include "../shared/interrupts.h"
#include "../drivers/serial.h"
#include <stdint.h>
extern void _isr0();
extern void _isr1();
extern void _irq0();
extern void _irq1();
extern void _syscall();
idt_t idt_desc;
uint64_t idt_table[256];
inline void set_idt_entry(uint32_t index, void *ptr, uint8_t flags, uint16_t segment){
uint32_t offset = (uint32_t) ptr;
idt_table[index] = ((uint64_t)(offset >> 16) << 48) | ((uint64_t)(flags | 0x80) << 40) | (segment << 16) | (offset & 0xffff);
}
cpu_registers_t *(*interrupt_handlers[16])(cpu_registers_t *regs) = {0};
void _irq_handler(cpu_registers_t *regs){
if(regs->int_no == 0x80){
syscall(regs);
}
else if(interrupt_handlers[regs->int_no - 32])
{
regs = interrupt_handlers[regs->int_no - 32](regs);
}
}
void _isr_handler(cpu_registers_t *regs){
printf("Error!!\n");
for(;;);
}
cpu_registers_t *syscall(cpu_registers_t *regs){
}
void init_idt(){
for(uint32_t i = 0; i < 32; i++){
set_idt_entry(i, (_isr0 + (_isr1 - _isr0) * i), IDT_GATE_TRAP, 0x10);
}
for(uint32_t i = 0; i < 16; i++){
set_idt_entry(i + 32, (_irq0 + (_irq1 - _irq0) * i), IDT_GATE_INT, 0x10);
}
}
idt_desc.pointer = (uint32_t)idt_table;
idt_desc.size = sizeof(idt_table);
asm volatile("lidt (%0)" : : "m"(idt_desc));
}

View File

@ -29,7 +29,7 @@ void pm_reserve(uint32_t address){
int pm_init(kernel_info_t *kernel_info){
mmap_entry_t *mmap = (mmap_entry_t*)(kernel_info->mmap_ptr);
printf("mmap count: %d\n| start | length |type|\n|--------|--------|----|\n", kernel_info->mmap_entry_count);
// printf("mmap count: %d\n| start | length |type|\n|--------|--------|----|\n", kernel_info->mmap_entry_count);
for(uint32_t i = 0; i < mmap_count; i++){
pm_map[i] = 0xff;
}
@ -51,19 +51,19 @@ int pm_init(kernel_info_t *kernel_info){
// printf("%d, %x, %d\n", j >> 3, pm_map[(mmap[i].entry_base >> 12 ) + (j >> 3)], mmap[i].type);
// }
}
printf("|%x|", mmap[i].entry_base);
printf("%x", mmap[i].entry_length);
printf("|%d |\n", mmap[i].type);
// printf("|%x|", mmap[i].entry_base);
// printf("%x", mmap[i].entry_length);
// printf("|%d |\n", mmap[i].type);
}
for(uint32_t i = 0; i < 512; i++){
pm_reserve(i * 4096);
}
printf("%x", pm_map);
// printf("%x", pm_map);
void *kernel_addr = (void *)_start;
while(get_paddr(kernel_addr)){
printf("%x\n", kernel_addr);
// printf("%x\n", kernel_addr);
pm_reserve(get_paddr(kernel_addr));
kernel_addr += 0x1000;
}
@ -75,6 +75,7 @@ void map(void *vaddr, void *paddr, uint32_t flags){
uint32_t *pd = (uint32_t*)0xfffff000;
if(!pd[pd_index]){
pd[pd_index] = pm_alloc() | 1;
asm volatile("invlpg (%0)" : : "b"(0xffc00000 + (pd_index * 0x400)) : "memory");
}
uint32_t *pt = (uint32_t *)(0xffc00000 + (pd_index * 0x400));
pt[pt_index] = (uint32_t)paddr | flags;

5
src/kernel/drivers/pic.c Normal file
View File

@ -0,0 +1,5 @@
#include "pic.h"
void init_pic(uint8_t idt_index){
}

18
src/kernel/drivers/pic.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
#define PIC_EOI 0x20
#define PIC_ICW1_ICW4 0x01
#define PIC_ICW1_SINGLE 0x02
#define PIC_ICW1_INT4 0x04
#define PIC_ICW1_LEVEL 0x08
#define PIC_ICW1_INIT 0x10
#define PIC_ICW4_8086 0x01
#define P

View File

@ -1,11 +1,12 @@
#include "shared/memory.h"
#include "shared/string.h"
#include "shared/kstdlib.h"
#include "shared/interrupts.h"
#include "drivers/serial.h"
extern void kmain(kernel_info_t *kernel_info){
init_serial();
pm_init(kernel_info);
init_idt();
return;
}

View File

@ -1 +1,29 @@
void init_idt();
#pragma once
#include <stdint.h>
void init_idt();
typedef struct cpu_registers{
uint32_t gs, fs, es, ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no; uint32_t pfa;
uint32_t eip, cs, eflags, useresp, ss;
}__attribute__((packed))cpu_registers_t;
typedef struct idt{
uint16_t size;
uint32_t pointer;
}__attribute__((packed))idt_t;
#define IDT_GATE_TASK 0x5
#define IDT_GATE_INT16 0x6
#define IDT_GATE_TRAP16 0x7
#define IDT_GATE_INT 0xe
#define IDT_GATE_TRAP 0xf
#define IDT_DPL_KERNEL 0 << 5
#define IDT_DPL_USER 3 << 5
inline void enable_interrupts(){
asm volatile("sti");
}
inline void disable_interrupts(){
asm volatile("cli");
}