Compare commits

..

2 Commits

5 changed files with 789 additions and 1 deletions

View File

@@ -38,7 +38,7 @@ TARGET = BOOTX64.EFI
TARGET_SO = bootx64.so TARGET_SO = bootx64.so
OBJ = $(BUILD_DIR)/main.o OBJ = $(BUILD_DIR)/main.o
KERNEL_TARGET = kernel.elf KERNEL_TARGET = kernel.elf
KERNEL_OBJS = $(BUILD_DIR)/kernel.o $(BUILD_DIR)/string_utils.o $(BUILD_DIR)/commands.o KERNEL_OBJS = $(BUILD_DIR)/kernel.o $(BUILD_DIR)/string_utils.o $(BUILD_DIR)/commands.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/isr.o
KERNEL_LD = kernel.ld KERNEL_LD = kernel.ld
# QEMU settings # QEMU settings
@@ -111,6 +111,16 @@ $(BUILD_DIR)/commands.o: $(SRC_DIR)/commands.c
$(CC) -ffreestanding -fno-stack-protector -fno-pic -fshort-wchar \ $(CC) -ffreestanding -fno-stack-protector -fno-pic -fshort-wchar \
-mno-red-zone -Wall -Wextra $(EFI_INCLUDES) -c $< -o $@ -mno-red-zone -Wall -Wextra $(EFI_INCLUDES) -c $< -o $@
$(BUILD_DIR)/idt.o: $(SRC_DIR)/idt.c
@echo "Compiling idt.c..."
$(CC) -ffreestanding -fno-stack-protector -fno-pic -fshort-wchar \
-mno-red-zone -Wall -Wextra $(EFI_INCLUDES) -c $< -o $@
$(BUILD_DIR)/isr.o: $(SRC_DIR)/isr.S
@echo "Compiling isr.S..."
$(CC) -ffreestanding -fno-stack-protector -fno-pic -fshort-wchar \
-mno-red-zone -Wall -Wextra $(EFI_INCLUDES) -c $< -o $@
# Link kernel ELF # Link kernel ELF
$(BUILD_DIR)/$(KERNEL_TARGET): $(KERNEL_OBJS) $(KERNEL_LD) $(BUILD_DIR)/$(KERNEL_TARGET): $(KERNEL_OBJS) $(KERNEL_LD)
@echo "Linking kernel ELF..." @echo "Linking kernel ELF..."

166
idt.c Normal file
View File

@@ -0,0 +1,166 @@
#include "idt.h"
#define IDT_SIZE 256
#define IDT_TYPE_INTERRUPT 0x8E
typedef struct {
UINT16 offset_low;
UINT16 selector;
UINT8 ist;
UINT8 type_attr;
UINT16 offset_mid;
UINT32 offset_high;
UINT32 zero;
} __attribute__((packed)) IdtEntry;
typedef struct {
UINT16 limit;
UINT64 base;
} __attribute__((packed)) IdtPtr;
static IdtEntry idt[IDT_SIZE];
static BootInfo *gBoot = NULL;
extern void (*isr_stub_table[])(void);
static void idt_set_gate(UINTN index, void (*handler)(void))
{
UINT64 addr = (UINT64)(UINTN)handler;
UINT16 selector = 0;
__asm__ __volatile__("mov %%cs, %0" : "=r"(selector));
idt[index].offset_low = (UINT16)(addr & 0xFFFF);
idt[index].selector = selector;
idt[index].ist = 0;
idt[index].type_attr = IDT_TYPE_INTERRUPT;
idt[index].offset_mid = (UINT16)((addr >> 16) & 0xFFFF);
idt[index].offset_high = (UINT32)((addr >> 32) & 0xFFFFFFFF);
idt[index].zero = 0;
}
static void lidt(const IdtPtr *idtr)
{
__asm__ __volatile__("lidt (%0)" :: "r"(idtr));
}
static const CHAR16 *exception_name(UINTN vector)
{
switch (vector) {
case 0: return L"Divide Error";
case 1: return L"Debug";
case 2: return L"Non-Maskable Interrupt";
case 3: return L"Breakpoint";
case 4: return L"Overflow";
case 5: return L"Bound Range Exceeded";
case 6: return L"Invalid Opcode";
case 7: return L"Device Not Available";
case 8: return L"Double Fault";
case 9: return L"Coprocessor Segment Overrun";
case 10: return L"Invalid TSS";
case 11: return L"Segment Not Present";
case 12: return L"Stack-Segment Fault";
case 13: return L"General Protection Fault";
case 14: return L"Page Fault";
case 15: return L"Reserved";
case 16: return L"x87 Floating-Point";
case 17: return L"Alignment Check";
case 18: return L"Machine Check";
case 19: return L"SIMD Floating-Point";
case 20: return L"Virtualization";
case 21: return L"Control Protection";
case 22: return L"Reserved";
case 23: return L"Reserved";
case 24: return L"Reserved";
case 25: return L"Reserved";
case 26: return L"Reserved";
case 27: return L"Reserved";
case 28: return L"Hypervisor Injection";
case 29: return L"VMM Communication";
case 30: return L"Security";
case 31: return L"Reserved";
default: return L"Unknown";
}
}
static inline void outb(UINT16 port, UINT8 value)
{
__asm__ __volatile__("outb %0, %1" :: "a"(value), "Nd"(port));
}
static void pic_eoi(UINTN vector)
{
if (vector >= 40) {
outb(0xA0, 0x20); /* EOI to slave PIC */
}
outb(0x20, 0x20); /* EOI to master PIC */
}
static void halt_forever(void)
{
for (;;) {
__asm__ __volatile__("cli; hlt");
}
}
void isr_handler(ISRFrame *frame)
{
UINT64 cr2 = 0;
/* Hardware IRQs (vectors 32-47): send EOI and return */
if (frame->vector >= 32 && frame->vector <= 47) {
pic_eoi(frame->vector);
return;
}
/* CPU exceptions (vectors 0-31): print diagnostics and halt */
if (gBoot != NULL && gBoot->print != NULL) {
gBoot->print(L"\n\rEXCEPTION: %d (%s)\n\r", frame->vector,
exception_name(frame->vector));
gBoot->print(L" Error Code: 0x%lx\n\r", frame->error_code);
gBoot->print(L" RIP: 0x%lx CS: 0x%lx RFLAGS: 0x%lx\n\r",
frame->rip, frame->cs, frame->rflags);
}
if (frame->vector == 14) {
__asm__ __volatile__("mov %%cr2, %0" : "=r"(cr2));
if (gBoot != NULL && gBoot->print != NULL) {
gBoot->print(L" CR2: 0x%lx\n\r", cr2);
}
}
halt_forever();
}
void idt_init(BootInfo *Boot)
{
IdtPtr old_idtr;
IdtPtr idtr;
IdtEntry *old_idt = NULL;
UINTN i = 0;
gBoot = Boot;
/* Read the firmware's existing IDT so we can preserve its entries */
__asm__ __volatile__("sidt %0" : "=m"(old_idtr));
old_idt = (IdtEntry *)(UINTN)old_idtr.base;
/* Copy the entire existing IDT first (preserves firmware IRQ handlers) */
for (i = 0; i < IDT_SIZE; i++) {
if (old_idt != NULL && (i * sizeof(IdtEntry)) < (UINTN)(old_idtr.limit + 1)) {
idt[i] = old_idt[i];
} else {
idt_set_gate(i, isr_stub_table[i]);
}
}
/* Override only CPU exception vectors (0-31) with our handlers */
for (i = 0; i < 32; i++) {
idt_set_gate(i, isr_stub_table[i]);
}
idtr.limit = (UINT16)(sizeof(idt) - 1);
idtr.base = (UINT64)(UINTN)idt;
lidt(&idtr);
}

32
idt.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef IDT_H
#define IDT_H
#include <efi.h>
#include "boot_info.h"
typedef struct {
UINT64 r15;
UINT64 r14;
UINT64 r13;
UINT64 r12;
UINT64 r11;
UINT64 r10;
UINT64 r9;
UINT64 r8;
UINT64 rbp;
UINT64 rdi;
UINT64 rsi;
UINT64 rdx;
UINT64 rcx;
UINT64 rbx;
UINT64 rax;
UINT64 vector;
UINT64 error_code;
UINT64 rip;
UINT64 cs;
UINT64 rflags;
} ISRFrame;
void idt_init(BootInfo *Boot);
#endif

577
isr.S Normal file
View File

@@ -0,0 +1,577 @@
.text
.global isr_handler
.global isr_stub_table
.macro ISR_NOERR num
.global isr\num
isr\num:
pushq $0
pushq $\num
jmp isr_common
.endm
.macro ISR_ERR num
.global isr\num
isr\num:
pushq $\num
jmp isr_common
.endm
isr_common:
cld
pushq %rax
pushq %rbx
pushq %rcx
pushq %rdx
pushq %rsi
pushq %rdi
pushq %rbp
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq %rsp, %rdi
call isr_handler
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbp
popq %rdi
popq %rsi
popq %rdx
popq %rcx
popq %rbx
popq %rax
addq $16, %rsp
iretq
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_ERR 30
ISR_NOERR 31
ISR_NOERR 32
ISR_NOERR 33
ISR_NOERR 34
ISR_NOERR 35
ISR_NOERR 36
ISR_NOERR 37
ISR_NOERR 38
ISR_NOERR 39
ISR_NOERR 40
ISR_NOERR 41
ISR_NOERR 42
ISR_NOERR 43
ISR_NOERR 44
ISR_NOERR 45
ISR_NOERR 46
ISR_NOERR 47
ISR_NOERR 48
ISR_NOERR 49
ISR_NOERR 50
ISR_NOERR 51
ISR_NOERR 52
ISR_NOERR 53
ISR_NOERR 54
ISR_NOERR 55
ISR_NOERR 56
ISR_NOERR 57
ISR_NOERR 58
ISR_NOERR 59
ISR_NOERR 60
ISR_NOERR 61
ISR_NOERR 62
ISR_NOERR 63
ISR_NOERR 64
ISR_NOERR 65
ISR_NOERR 66
ISR_NOERR 67
ISR_NOERR 68
ISR_NOERR 69
ISR_NOERR 70
ISR_NOERR 71
ISR_NOERR 72
ISR_NOERR 73
ISR_NOERR 74
ISR_NOERR 75
ISR_NOERR 76
ISR_NOERR 77
ISR_NOERR 78
ISR_NOERR 79
ISR_NOERR 80
ISR_NOERR 81
ISR_NOERR 82
ISR_NOERR 83
ISR_NOERR 84
ISR_NOERR 85
ISR_NOERR 86
ISR_NOERR 87
ISR_NOERR 88
ISR_NOERR 89
ISR_NOERR 90
ISR_NOERR 91
ISR_NOERR 92
ISR_NOERR 93
ISR_NOERR 94
ISR_NOERR 95
ISR_NOERR 96
ISR_NOERR 97
ISR_NOERR 98
ISR_NOERR 99
ISR_NOERR 100
ISR_NOERR 101
ISR_NOERR 102
ISR_NOERR 103
ISR_NOERR 104
ISR_NOERR 105
ISR_NOERR 106
ISR_NOERR 107
ISR_NOERR 108
ISR_NOERR 109
ISR_NOERR 110
ISR_NOERR 111
ISR_NOERR 112
ISR_NOERR 113
ISR_NOERR 114
ISR_NOERR 115
ISR_NOERR 116
ISR_NOERR 117
ISR_NOERR 118
ISR_NOERR 119
ISR_NOERR 120
ISR_NOERR 121
ISR_NOERR 122
ISR_NOERR 123
ISR_NOERR 124
ISR_NOERR 125
ISR_NOERR 126
ISR_NOERR 127
ISR_NOERR 128
ISR_NOERR 129
ISR_NOERR 130
ISR_NOERR 131
ISR_NOERR 132
ISR_NOERR 133
ISR_NOERR 134
ISR_NOERR 135
ISR_NOERR 136
ISR_NOERR 137
ISR_NOERR 138
ISR_NOERR 139
ISR_NOERR 140
ISR_NOERR 141
ISR_NOERR 142
ISR_NOERR 143
ISR_NOERR 144
ISR_NOERR 145
ISR_NOERR 146
ISR_NOERR 147
ISR_NOERR 148
ISR_NOERR 149
ISR_NOERR 150
ISR_NOERR 151
ISR_NOERR 152
ISR_NOERR 153
ISR_NOERR 154
ISR_NOERR 155
ISR_NOERR 156
ISR_NOERR 157
ISR_NOERR 158
ISR_NOERR 159
ISR_NOERR 160
ISR_NOERR 161
ISR_NOERR 162
ISR_NOERR 163
ISR_NOERR 164
ISR_NOERR 165
ISR_NOERR 166
ISR_NOERR 167
ISR_NOERR 168
ISR_NOERR 169
ISR_NOERR 170
ISR_NOERR 171
ISR_NOERR 172
ISR_NOERR 173
ISR_NOERR 174
ISR_NOERR 175
ISR_NOERR 176
ISR_NOERR 177
ISR_NOERR 178
ISR_NOERR 179
ISR_NOERR 180
ISR_NOERR 181
ISR_NOERR 182
ISR_NOERR 183
ISR_NOERR 184
ISR_NOERR 185
ISR_NOERR 186
ISR_NOERR 187
ISR_NOERR 188
ISR_NOERR 189
ISR_NOERR 190
ISR_NOERR 191
ISR_NOERR 192
ISR_NOERR 193
ISR_NOERR 194
ISR_NOERR 195
ISR_NOERR 196
ISR_NOERR 197
ISR_NOERR 198
ISR_NOERR 199
ISR_NOERR 200
ISR_NOERR 201
ISR_NOERR 202
ISR_NOERR 203
ISR_NOERR 204
ISR_NOERR 205
ISR_NOERR 206
ISR_NOERR 207
ISR_NOERR 208
ISR_NOERR 209
ISR_NOERR 210
ISR_NOERR 211
ISR_NOERR 212
ISR_NOERR 213
ISR_NOERR 214
ISR_NOERR 215
ISR_NOERR 216
ISR_NOERR 217
ISR_NOERR 218
ISR_NOERR 219
ISR_NOERR 220
ISR_NOERR 221
ISR_NOERR 222
ISR_NOERR 223
ISR_NOERR 224
ISR_NOERR 225
ISR_NOERR 226
ISR_NOERR 227
ISR_NOERR 228
ISR_NOERR 229
ISR_NOERR 230
ISR_NOERR 231
ISR_NOERR 232
ISR_NOERR 233
ISR_NOERR 234
ISR_NOERR 235
ISR_NOERR 236
ISR_NOERR 237
ISR_NOERR 238
ISR_NOERR 239
ISR_NOERR 240
ISR_NOERR 241
ISR_NOERR 242
ISR_NOERR 243
ISR_NOERR 244
ISR_NOERR 245
ISR_NOERR 246
ISR_NOERR 247
ISR_NOERR 248
ISR_NOERR 249
ISR_NOERR 250
ISR_NOERR 251
ISR_NOERR 252
ISR_NOERR 253
ISR_NOERR 254
ISR_NOERR 255
isr_stub_table:
.quad isr0
.quad isr1
.quad isr2
.quad isr3
.quad isr4
.quad isr5
.quad isr6
.quad isr7
.quad isr8
.quad isr9
.quad isr10
.quad isr11
.quad isr12
.quad isr13
.quad isr14
.quad isr15
.quad isr16
.quad isr17
.quad isr18
.quad isr19
.quad isr20
.quad isr21
.quad isr22
.quad isr23
.quad isr24
.quad isr25
.quad isr26
.quad isr27
.quad isr28
.quad isr29
.quad isr30
.quad isr31
.quad isr32
.quad isr33
.quad isr34
.quad isr35
.quad isr36
.quad isr37
.quad isr38
.quad isr39
.quad isr40
.quad isr41
.quad isr42
.quad isr43
.quad isr44
.quad isr45
.quad isr46
.quad isr47
.quad isr48
.quad isr49
.quad isr50
.quad isr51
.quad isr52
.quad isr53
.quad isr54
.quad isr55
.quad isr56
.quad isr57
.quad isr58
.quad isr59
.quad isr60
.quad isr61
.quad isr62
.quad isr63
.quad isr64
.quad isr65
.quad isr66
.quad isr67
.quad isr68
.quad isr69
.quad isr70
.quad isr71
.quad isr72
.quad isr73
.quad isr74
.quad isr75
.quad isr76
.quad isr77
.quad isr78
.quad isr79
.quad isr80
.quad isr81
.quad isr82
.quad isr83
.quad isr84
.quad isr85
.quad isr86
.quad isr87
.quad isr88
.quad isr89
.quad isr90
.quad isr91
.quad isr92
.quad isr93
.quad isr94
.quad isr95
.quad isr96
.quad isr97
.quad isr98
.quad isr99
.quad isr100
.quad isr101
.quad isr102
.quad isr103
.quad isr104
.quad isr105
.quad isr106
.quad isr107
.quad isr108
.quad isr109
.quad isr110
.quad isr111
.quad isr112
.quad isr113
.quad isr114
.quad isr115
.quad isr116
.quad isr117
.quad isr118
.quad isr119
.quad isr120
.quad isr121
.quad isr122
.quad isr123
.quad isr124
.quad isr125
.quad isr126
.quad isr127
.quad isr128
.quad isr129
.quad isr130
.quad isr131
.quad isr132
.quad isr133
.quad isr134
.quad isr135
.quad isr136
.quad isr137
.quad isr138
.quad isr139
.quad isr140
.quad isr141
.quad isr142
.quad isr143
.quad isr144
.quad isr145
.quad isr146
.quad isr147
.quad isr148
.quad isr149
.quad isr150
.quad isr151
.quad isr152
.quad isr153
.quad isr154
.quad isr155
.quad isr156
.quad isr157
.quad isr158
.quad isr159
.quad isr160
.quad isr161
.quad isr162
.quad isr163
.quad isr164
.quad isr165
.quad isr166
.quad isr167
.quad isr168
.quad isr169
.quad isr170
.quad isr171
.quad isr172
.quad isr173
.quad isr174
.quad isr175
.quad isr176
.quad isr177
.quad isr178
.quad isr179
.quad isr180
.quad isr181
.quad isr182
.quad isr183
.quad isr184
.quad isr185
.quad isr186
.quad isr187
.quad isr188
.quad isr189
.quad isr190
.quad isr191
.quad isr192
.quad isr193
.quad isr194
.quad isr195
.quad isr196
.quad isr197
.quad isr198
.quad isr199
.quad isr200
.quad isr201
.quad isr202
.quad isr203
.quad isr204
.quad isr205
.quad isr206
.quad isr207
.quad isr208
.quad isr209
.quad isr210
.quad isr211
.quad isr212
.quad isr213
.quad isr214
.quad isr215
.quad isr216
.quad isr217
.quad isr218
.quad isr219
.quad isr220
.quad isr221
.quad isr222
.quad isr223
.quad isr224
.quad isr225
.quad isr226
.quad isr227
.quad isr228
.quad isr229
.quad isr230
.quad isr231
.quad isr232
.quad isr233
.quad isr234
.quad isr235
.quad isr236
.quad isr237
.quad isr238
.quad isr239
.quad isr240
.quad isr241
.quad isr242
.quad isr243
.quad isr244
.quad isr245
.quad isr246
.quad isr247
.quad isr248
.quad isr249
.quad isr250
.quad isr251
.quad isr252
.quad isr253
.quad isr254
.quad isr255
.section .note.GNU-stack,"",@progbits

View File

@@ -2,6 +2,7 @@
#include "boot_info.h" #include "boot_info.h"
#include "commands.h" #include "commands.h"
#include "idt.h"
#define SAFE_PRINT(Boot, ...) \ #define SAFE_PRINT(Boot, ...) \
do { \ do { \
@@ -34,6 +35,8 @@ void kmain(BootInfo *Boot)
} }
} }
idt_init(Boot);
SAFE_PRINT(Boot, L"================================================\n\r"); SAFE_PRINT(Boot, L"================================================\n\r");
SAFE_PRINT(Boot, L" Welcome to Simple UEFI Operating System!\n\r"); SAFE_PRINT(Boot, L" Welcome to Simple UEFI Operating System!\n\r");
SAFE_PRINT(Boot, L"================================================\n\r"); SAFE_PRINT(Boot, L"================================================\n\r");