Compare commits

...

9 Commits

Author SHA1 Message Date
Alex Kotov b2ef7c4073
Add links to README.md 2022-12-10 14:27:04 +04:00
Alex Kotov e46588a13e
Remove unnecessary "cli" and "sti" 2022-12-10 13:38:46 +04:00
Alex Kotov 08e17da327
Rewrite interrupts 2022-12-09 21:55:21 +04:00
Alex Kotov a2163e6493
Use new debug output formatter 2022-12-09 07:28:48 +04:00
Alex Kotov 921d7a2ae7
Use new IDT code 2022-12-09 01:04:40 +04:00
Alex Kotov 9e55308d5f
Fix hardware interrupts 2022-12-08 07:17:23 +04:00
Alex Kotov d625623625
Load TSS 2022-12-08 06:53:14 +04:00
Alex Kotov dd270c997b
Use new constants 2022-12-08 01:54:28 +04:00
Alex Kotov c65fc174ac
Use new bitfields 2022-12-07 23:29:46 +04:00
17 changed files with 281 additions and 504 deletions

View File

@ -3,5 +3,15 @@ Tailix kernel
My OS kernel attempt =)
Links
-----
### Paging
* https://stackoverflow.com/a/6224824
* https://littleosbook.github.io/#paging-and-the-kernel
### Interrupts
* https://www.kernel.org/doc/Documentation/x86/kernel-stacks
* https://lwn.net/Articles/484932/

View File

@ -21,8 +21,8 @@ CFLAGS = \
-I$(DRIVERS_PREFIX)/include
CPPFLAGS = \
-DKERNAUX_ENABLE_ASSERT \
-DKERNAUX_ENABLE_GUARD
-DKERNAUX_DEBUG \
-DKERNAUX_BITFIELDS
# Architecture-dependent
OBJS = start.s.o
@ -33,15 +33,8 @@ OBJS += paging.c.o
# Architecture-independent
OBJS += info.c.o
# Built-in drivers
OBJS += timer.c.o
OBJS += protected.c.o
OBJS += interrupts/main.asm.cpp.o
OBJS += interrupts/exception.c.o
OBJS += interrupts/hwint.c.o
OBJS += interrupts/syscall.c.o
OBJS += interrupts.c.o interrupts.asm.cpp.o
all: $(KERNEL)

View File

@ -3,8 +3,6 @@
#define MEM_UPPER_BASE ((unsigned long)(1 * 1024 * 1024)) // 1 MB
#define IDT_SIZE 256 // maximal size
#define GDT_NULL_INDEX 0
#define GDT_KERNEL_CS_INDEX 1
#define GDT_KERNEL_DS_INDEX 2

98
src/interrupts.asm Normal file
View File

@ -0,0 +1,98 @@
#include "config.h"
[EXTERN interrupts_handler]
%macro NOERRCODE 1
[GLOBAL interrupts_cb_%1]
interrupts_cb_%1:
push dword 0
push dword %1
jmp common_part
%endmacro
%macro ERRCODE 1
[GLOBAL interrupts_cb_%1]
interrupts_cb_%1:
push dword %1
jmp common_part
%endmacro
common_part:
pushad
mov ax, ds ; Lower 16-bits of eax = ds.
push dword eax ; save the data segment descriptor
mov ax, GDT_KERNEL_DS_SELECTOR
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call interrupts_handler
pop dword eax ; reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popad
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
; Protected mode exteptions
NOERRCODE 0x00 ; #DE - Divide Error Exception
NOERRCODE 0x01 ; #DB - Debug Exception
NOERRCODE 0x02 ; NMI - Non-maskable interrupt
NOERRCODE 0x03 ; #BP - Breakpoint Exception
NOERRCODE 0x04 ; #OF - Overflow Exception
NOERRCODE 0x05 ; #BR - BOUND Range Exceeded Exception
NOERRCODE 0x06 ; #UD - Invalid Opcode Exception
NOERRCODE 0x07 ; #NM - Device Not Available Exception
ERRCODE 0x08 ; #DF - Double Fault Exception
NOERRCODE 0x09 ; Reserved - Coprocessor Segment Overrun
ERRCODE 0x0a ; #TS - Invalid TSS Exception
ERRCODE 0x0b ; #NP - Segment Not Present
ERRCODE 0x0c ; #SS - Stack Fault Exception
ERRCODE 0x0d ; #GP - General Protection Exception
ERRCODE 0x0e ; #PF - Page-Fault Exception
NOERRCODE 0x0f ; Reserved
NOERRCODE 0x10 ; #MF - x87 FPU Floating-Point Error
ERRCODE 0x11 ; #AC - Alignment Check Exception
NOERRCODE 0x12 ; #MC - Machine-Check Exception
NOERRCODE 0x13 ; #XF - SIMD Floating-Point Exception
NOERRCODE 0x14 ; Reserved
NOERRCODE 0x15 ; Reserved
NOERRCODE 0x16 ; Reserved
NOERRCODE 0x17 ; Reserved
NOERRCODE 0x18 ; Reserved
NOERRCODE 0x19 ; Reserved
NOERRCODE 0x1a ; Reserved
NOERRCODE 0x1b ; Reserved
NOERRCODE 0x1c ; Reserved
NOERRCODE 0x1d ; Reserved
NOERRCODE 0x1e ; Reserved
NOERRCODE 0x1f ; Reserved
; Hardware IRQs
NOERRCODE 0x20 ; Programmable Interval Timer
NOERRCODE 0x21 ; Keyboard
NOERRCODE 0x22 ; Slave PIC
NOERRCODE 0x23 ; COM 2/4
NOERRCODE 0x24 ; COM 1/3
NOERRCODE 0x25 ; LPT 2
NOERRCODE 0x26 ; Floppy Drive Controller
NOERRCODE 0x27 ; LPT 1
NOERRCODE 0x28 ; Real Time Clock
NOERRCODE 0x29 ; Master PIC
NOERRCODE 0x2a ; Reserved
NOERRCODE 0x2b ; Reserved
NOERRCODE 0x2c ; Reserved
NOERRCODE 0x2d ; Coprocessor exception
NOERRCODE 0x2e ; Hard Drive Controller
NOERRCODE 0x2f ; Reserved

95
src/interrupts.c Normal file
View File

@ -0,0 +1,95 @@
#include <kernaux/arch/i386.h>
#include <kernaux/asm/i386.h>
#include <stdint.h>
#include <string.h>
#define IDT_SIZE 256
static struct KernAux_Arch_I386_DTR idt_pointer;
static struct KernAux_Arch_I386_IDTE idt[IDT_SIZE];
void interrupts_init()
{
memset(&idt_pointer, 0, sizeof(idt_pointer));
memset(&idt, 0, sizeof(idt));
}
void interrupts_load()
{
idt_pointer.size = sizeof(struct KernAux_Arch_I386_IDTE) * IDT_SIZE - 1;
idt_pointer.offset = (uint32_t)&idt;
kernaux_asm_i386_flush_idt((uint32_t)&idt_pointer);
}
void interrupts_handler() {}
#define init_intr(num, dpl) do { \
void interrupts_cb_##num(); \
KernAux_Arch_I386_IDTE_init_intr( \
&idt[num], \
(uint32_t)interrupts_cb_##num, \
kernel_cs_selector, \
dpl \
); \
} while (0)
void interrupts_setup(const uint16_t kernel_cs_selector)
{
memset(idt, 0, sizeof(idt));
// Protected mode exteptions
init_intr(0x00, 0);
init_intr(0x01, 0);
init_intr(0x02, 0);
init_intr(0x03, 0);
init_intr(0x04, 0);
init_intr(0x05, 0);
init_intr(0x06, 0);
init_intr(0x07, 0);
init_intr(0x08, 0);
init_intr(0x09, 0);
init_intr(0x0a, 0);
init_intr(0x0b, 0);
init_intr(0x0c, 0);
init_intr(0x0d, 0);
init_intr(0x0e, 0);
init_intr(0x0f, 0);
init_intr(0x10, 0);
init_intr(0x11, 0);
init_intr(0x12, 0);
init_intr(0x13, 0);
init_intr(0x14, 0);
init_intr(0x15, 0);
init_intr(0x16, 0);
init_intr(0x17, 0);
init_intr(0x18, 0);
init_intr(0x19, 0);
init_intr(0x1a, 0);
init_intr(0x1b, 0);
init_intr(0x1c, 0);
init_intr(0x1d, 0);
init_intr(0x1e, 0);
init_intr(0x1f, 0);
// Hardware IRQs
init_intr(0x20, 0);
init_intr(0x21, 0);
init_intr(0x22, 0);
init_intr(0x23, 0);
init_intr(0x24, 0);
init_intr(0x25, 0);
init_intr(0x26, 0);
init_intr(0x27, 0);
init_intr(0x28, 0);
init_intr(0x29, 0);
init_intr(0x2a, 0);
init_intr(0x2b, 0);
init_intr(0x2c, 0);
init_intr(0x2d, 0);
init_intr(0x2e, 0);
init_intr(0x2f, 0);
}

10
src/interrupts.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef KERNEL_INCLUDED_INTERRUPTS
#define KERNEL_INCLUDED_INTERRUPTS
#include <stdint.h>
void interrupts_init();
void interrupts_load();
void interrupts_setup(uint16_t kernel_cs_selector);
#endif

View File

@ -1,16 +0,0 @@
#ifndef KERNEL_INCLUDED_INTERRUPTS_CONFIG
#define KERNEL_INCLUDED_INTERRUPTS_CONFIG 1
#define INT_EXCEPTION_COUNT 32
#define INT_HWINT_COUNT 16
#define INT_TOTAL_COUNT (INT_EXCEPTION_COUNT + INT_HWINT_COUNT)
#define INT_EXCEPTION_FIRST 0
#define INT_EXCEPTION_LAST (INT_EXCEPTION_FIRST + INT_EXCEPTION_COUNT - 1)
#define INT_HWINT_FIRST (INT_EXCEPTION_LAST + 1)
#define INT_HWINT_LAST (INT_HWINT_FIRST + INT_HWINT_COUNT - 1)
#define INT_SYSCALL 0x80
#endif

View File

@ -1,51 +0,0 @@
#include "main.h"
#include "../panic.h"
#include <drivers/console.h>
static const char *const messages[] = {
"0 #DE - Divide Error Exception",
"1 #DB - Debug Exception",
"2 NMI - Non-maskable interrupt",
"3 #BP - Breakpoint Exception",
"4 #OF - Overflow Exception",
"5 #BR - BOUND Range Exceeded Exception",
"6 #UD - Invalid Opcode Exception",
"7 #NM - Device Not Available Exception",
"8 #DF - Double Fault Exception",
"9 Reserved - Coprocessor Segment Overrun",
"10 #TS - Invalid TSS Exception",
"11 #NP - Segment Not Present",
"12 #SS - Stack Fault Exception",
"13 #GP - General Protection Exception",
"14 #PF - Page-Fault Exception",
"15 Reserved",
"16 #MF - x87 FPU Floating-Point Error",
"17 #AC - Alignment Check Exception",
"18 #MC - Machine-Check Exception",
"19 #XF - SIMD Floating-Point Exception",
"20 Reserved",
"21 Reserved",
"22 Reserved",
"23 Reserved",
"24 Reserved",
"25 Reserved",
"26 Reserved",
"27 Reserved",
"28 Reserved",
"29 Reserved",
"30 Reserved",
"31 Reserved"
};
void exception_handler(struct IsrRegisters regs)
{
if (regs.int_no > INT_EXCEPTION_LAST) return;
drivers_console_printf(
"[FAIL] exception: Unhandled protected-mode exception: %s\n",
messages[regs.int_no]
);
panic("Can not continue.");
}

View File

@ -1,43 +0,0 @@
#include "main.h"
#include <drivers/console.h>
#include <drivers/intel_8259_pic.h>
static hwint_handler_t handlers[INT_HWINT_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void hwint_handler(struct IsrRegisters regs)
{
if (regs.int_no >= INT_HWINT_COUNT) return;
const unsigned char hwint_no = regs.int_no - INT_HWINT_FIRST;
const hwint_handler_t handler = handlers[hwint_no];
if (!handler) {
drivers_console_printf("[WARN] hwint: Unhandled hardware interrupt: %u\n", hwint_no);
return;
}
handler();
drivers_intel_8259_pic_eoi(regs.int_no);
}
void hwint_register_handler(unsigned int int_no, hwint_handler_t handler)
{
if (int_no >= INT_HWINT_COUNT) {
return;
}
handlers[int_no] = handler;
drivers_intel_8259_pic_enable(int_no);
}
void hwint_unregister_handler(unsigned int int_no)
{
if (int_no >= INT_HWINT_COUNT) {
return;
}
drivers_intel_8259_pic_disable(int_no);
handlers[int_no] = 0;
}

View File

@ -1,111 +0,0 @@
#include "../config.h"
#include "config.h"
%macro INTERRUPT_NOERRCODE 2
[GLOBAL interrupt_%2]
interrupt_%2:
cli
push dword 0
push dword %2
jmp %1_wrapper
%endmacro
%macro INTERRUPT_ERRCODE 2
[GLOBAL interrupt_%2]
interrupt_%2:
cli
push dword %2
jmp %1_wrapper
%endmacro
%macro INTERRUPT_COMMON 1
[EXTERN %1_handler]
%1_wrapper:
pushad
mov ax, ds ; Lower 16-bits of eax = ds.
push dword eax ; save the data segment descriptor
mov ax, GDT_KERNEL_DS_SELECTOR
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call %1_handler
pop dword eax ; reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popad
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
%endmacro
INTERRUPT_COMMON exception
INTERRUPT_COMMON hwint
INTERRUPT_COMMON syscall
; Protected mode exteptions
INTERRUPT_NOERRCODE exception, 0 ; #DE - Divide Error Exception
INTERRUPT_NOERRCODE exception, 1 ; #DB - Debug Exception
INTERRUPT_NOERRCODE exception, 2 ; NMI - Non-maskable interrupt
INTERRUPT_NOERRCODE exception, 3 ; #BP - Breakpoint Exception
INTERRUPT_NOERRCODE exception, 4 ; #OF - Overflow Exception
INTERRUPT_NOERRCODE exception, 5 ; #BR - BOUND Range Exceeded Exception
INTERRUPT_NOERRCODE exception, 6 ; #UD - Invalid Opcode Exception
INTERRUPT_NOERRCODE exception, 7 ; #NM - Device Not Available Exception
INTERRUPT_ERRCODE exception, 8 ; #DF - Double Fault Exception
INTERRUPT_NOERRCODE exception, 9 ; Reserved - Coprocessor Segment Overrun
INTERRUPT_ERRCODE exception, 10 ; #TS - Invalid TSS Exception
INTERRUPT_ERRCODE exception, 11 ; #NP - Segment Not Present
INTERRUPT_ERRCODE exception, 12 ; #SS - Stack Fault Exception
INTERRUPT_ERRCODE exception, 13 ; #GP - General Protection Exception
INTERRUPT_ERRCODE exception, 14 ; #PF - Page-Fault Exception
INTERRUPT_NOERRCODE exception, 15 ; Reserved
INTERRUPT_NOERRCODE exception, 16 ; #MF - x87 FPU Floating-Point Error
INTERRUPT_ERRCODE exception, 17 ; #AC - Alignment Check Exception
INTERRUPT_NOERRCODE exception, 18 ; #MC - Machine-Check Exception
INTERRUPT_NOERRCODE exception, 19 ; #XF - SIMD Floating-Point Exception
INTERRUPT_NOERRCODE exception, 20 ; Reserved
INTERRUPT_NOERRCODE exception, 21 ; Reserved
INTERRUPT_NOERRCODE exception, 22 ; Reserved
INTERRUPT_NOERRCODE exception, 23 ; Reserved
INTERRUPT_NOERRCODE exception, 24 ; Reserved
INTERRUPT_NOERRCODE exception, 25 ; Reserved
INTERRUPT_NOERRCODE exception, 26 ; Reserved
INTERRUPT_NOERRCODE exception, 27 ; Reserved
INTERRUPT_NOERRCODE exception, 28 ; Reserved
INTERRUPT_NOERRCODE exception, 29 ; Reserved
INTERRUPT_NOERRCODE exception, 30 ; Reserved
INTERRUPT_NOERRCODE exception, 31 ; Reserved
; Hardware IRQs
INTERRUPT_NOERRCODE hwint, 32 ; Programmable Interval Timer
INTERRUPT_NOERRCODE hwint, 33 ; Keyboard
INTERRUPT_NOERRCODE hwint, 34 ; Slave PIC
INTERRUPT_NOERRCODE hwint, 35 ; COM 2/4
INTERRUPT_NOERRCODE hwint, 36 ; COM 1/3
INTERRUPT_NOERRCODE hwint, 37 ; LPT 2
INTERRUPT_NOERRCODE hwint, 38 ; Floppy Drive Controller
INTERRUPT_NOERRCODE hwint, 39 ; LPT 1
INTERRUPT_NOERRCODE hwint, 40 ; Real Time Clock
INTERRUPT_NOERRCODE hwint, 41 ; Master PIC
INTERRUPT_NOERRCODE hwint, 42 ; Reserved
INTERRUPT_NOERRCODE hwint, 43 ; Reserved
INTERRUPT_NOERRCODE hwint, 44 ; Reserved
INTERRUPT_NOERRCODE hwint, 45 ; Coprocessor exception
INTERRUPT_NOERRCODE hwint, 46 ; Hard Drive Controller
INTERRUPT_NOERRCODE hwint, 47 ; Reserved
; Syscalls
INTERRUPT_NOERRCODE syscall, INT_SYSCALL

View File

@ -1,89 +0,0 @@
#ifndef KERNEL_INCLUDED_INTERRUPTS_MAIN
#define KERNEL_INCLUDED_INTERRUPTS_MAIN 1
#include "config.h"
struct IsrRegisters {
unsigned int ds; // Data segment selector
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
unsigned int int_no, err_code; // Interrupt number and error code (if applicable)
unsigned int ip, cs, flags, sp, ss; // Pushed by the processor automatically.
};
// Protected mode exteptions
void interrupt_0();
void interrupt_1();
void interrupt_2();
void interrupt_3();
void interrupt_4();
void interrupt_5();
void interrupt_6();
void interrupt_7();
void interrupt_8();
void interrupt_9();
void interrupt_10();
void interrupt_11();
void interrupt_12();
void interrupt_13();
void interrupt_14();
void interrupt_15();
void interrupt_16();
void interrupt_17();
void interrupt_18();
void interrupt_19();
void interrupt_20();
void interrupt_21();
void interrupt_22();
void interrupt_23();
void interrupt_24();
void interrupt_25();
void interrupt_26();
void interrupt_27();
void interrupt_28();
void interrupt_29();
void interrupt_30();
void interrupt_31();
// Hardware IRQs
void interrupt_32();
void interrupt_33();
void interrupt_34();
void interrupt_35();
void interrupt_36();
void interrupt_37();
void interrupt_38();
void interrupt_39();
void interrupt_40();
void interrupt_41();
void interrupt_42();
void interrupt_43();
void interrupt_44();
void interrupt_45();
void interrupt_46();
void interrupt_47();
// Syscalls
void interrupt_0x80();
/*********
* hwint *
*********/
typedef void(*hwint_handler_t)();
void hwint_register_handler(unsigned int int_no, hwint_handler_t handler);
void hwint_unregister_handler(unsigned int int_no);
/***********
* syscall *
***********/
enum Kernel_Syscall_Number {
KERNEL_SYSCALL_EXIT = 0,
};
#endif

View File

@ -1,23 +0,0 @@
#include "main.h"
#include <drivers/console.h>
static void syscall_do_exit(struct IsrRegisters regs);
void syscall_handler(const struct IsrRegisters regs)
{
const unsigned int id = regs.eax << 16 >> 16;
drivers_console_printf("[INFO] syscall: number %u\n", id);
switch (id) {
case KERNEL_SYSCALL_EXIT: syscall_do_exit(regs); break;
}
}
void syscall_do_exit(const struct IsrRegisters regs)
{
const unsigned int exit_code = regs.ebx << 16 >> 16;
drivers_console_printf("[WARN] syscall: process try to exit with error code %u, haha\n", exit_code);
}

View File

@ -1,14 +1,20 @@
#define KERNAUX_ACCESS_PROTECTED
#include "paging.h"
#include "info.h"
#include "panic.h"
#include "protected.h"
#include "interrupts.h"
#include <drivers/console.h>
#include <kernaux/generic/display.h>
#include <kernaux/macro.h>
#include <kernaux/multiboot2.h>
#include <kernaux/pfa.h>
#include <stdarg.h>
#include <stdint.h>
// Defined in linker script
@ -23,6 +29,14 @@ static struct Kernel_Info kinfo;
static struct KernAux_PFA pfa;
static struct Paging paging;
void my_putc(void *display KERNAUX_UNUSED, char c);
void my_vprintf(void *display KERNAUX_UNUSED, const char *format, va_list va);
static const struct KernAux_Display display = {
.putc = my_putc,
.vprintf = my_vprintf,
};
void main(
const unsigned long multiboot2_info_magic,
const struct KernAux_Multiboot2_Info *const multiboot2_info
@ -33,7 +47,7 @@ void main(
panic("Multiboot 2 info magic number is invalid.");
}
KernAux_Multiboot2_Info_print(multiboot2_info, drivers_console_printf);
KernAux_Multiboot2_Info_print(multiboot2_info, &display);
if (!KernAux_Multiboot2_Info_is_valid(multiboot2_info)) {
panic("Multiboot 2 info is invalid.");
@ -65,7 +79,19 @@ void main(
paging_load(&paging);
paging_enable();
interrupts_init();
protected_initialize(&kinfo);
drivers_console_puts("[INFO] main: Finished.");
}
void my_putc(void *display KERNAUX_UNUSED, char c)
{
drivers_console_putc(c);
}
void my_vprintf(void *display KERNAUX_UNUSED, const char *format, va_list va)
{
drivers_console_vprintf(format, va);
}

View File

@ -18,26 +18,26 @@ void paging_enable()
uint32_t cr0 = kernaux_asm_i386_read_cr0();
uint32_t cr4 = kernaux_asm_i386_read_cr4();
assert(cr0 & KERNAUX_ARCH_I386_CR0_PE, "The boot loader should have put us in protected mode.");
assert(cr0 & KERNAUX_ARCH_X86_CR0_PE, "The boot loader should have put us in protected mode.");
// First clear PG and PGE flag, as PGE must be enabled after PG.
kernaux_asm_i386_write_cr0(cr0 & ~KERNAUX_ARCH_I386_CR0_PG);
kernaux_asm_i386_write_cr4(cr4 & ~(KERNAUX_ARCH_I386_CR4_PGE | KERNAUX_ARCH_I386_CR4_PSE));
kernaux_asm_i386_write_cr0(cr0 & ~KERNAUX_ARCH_X86_CR0_PG);
kernaux_asm_i386_write_cr4(cr4 & ~(KERNAUX_ARCH_X86_CR4_PGE | KERNAUX_ARCH_X86_CR4_PSE));
cr0 = kernaux_asm_i386_read_cr0();
cr4 = kernaux_asm_i386_read_cr4();
// Our page table contains 4MB entries.
// cr4 |= KERNAUX_ARCH_I386_CR4_PSE;
// cr4 |= KERNAUX_ARCH_X86_CR4_PSE;
kernaux_asm_i386_write_cr4(cr4);
// First enable paging, then enable global page flag.
cr0 |= KERNAUX_ARCH_I386_CR0_PG;
cr0 |= KERNAUX_ARCH_X86_CR0_PG;
kernaux_asm_i386_write_cr0(cr0);
cr0 |= KERNAUX_ARCH_I386_CR0_WP;
cr0 |= KERNAUX_ARCH_X86_CR0_WP;
kernaux_asm_i386_write_cr0(cr0);
kernaux_asm_i386_write_cr4(cr4);
@ -89,33 +89,33 @@ void mapping(
struct KernAux_Arch_I386_PageDir *const page_dir = &paging->page_dir;
struct KernAux_Arch_I386_PageTable *const page_table = &paging->page_tables[pde_index];
struct KernAux_Arch_I386_PDE *const pde = &page_dir->pdes[pde_index];
struct KernAux_Arch_I386_PTE *const pte = &page_table->ptes[pte_index];
union KernAux_Arch_I386_PDE *const pde = &page_dir->pdes[pde_index];
union KernAux_Arch_I386_PTE *const pte = &page_table->ptes[pte_index];
if (!pde->present) {
pde->addr = KERNAUX_ARCH_I386_ADDR_TO_PDE_ADDR(page_table);
if (!pde->bitfields.present) {
pde->bitfields.addr = KERNAUX_ARCH_I386_ADDR_TO_PDE_ADDR(page_table);
pde->available1 = 0;
pde->page_size = 0;
pde->available0 = 0;
pde->accessed = 0;
pde->cache_disabled = 0;
pde->write_through = 0;
pde->user = 0;
pde->writable = 1;
pde->present = 1;
pde->bitfields.available1 = 0;
pde->bitfields.page_size = 0;
pde->bitfields.available0 = 0;
pde->bitfields.accessed = 0;
pde->bitfields.cache_disabled = 0;
pde->bitfields.write_through = 0;
pde->bitfields.user = 0;
pde->bitfields.writable = 1;
pde->bitfields.present = 1;
}
pte->addr = KERNAUX_ARCH_I386_ADDR_TO_PTE_ADDR(phys);
pte->bitfields.addr = KERNAUX_ARCH_I386_ADDR_TO_PTE_ADDR(phys);
pte->available = 1;
pte->global = 1;
pte->attr_table = 0;
pte->dirty = 0;
pte->accessed = 0;
pte->cache_disabled = 0;
pte->write_through = 0;
pte->user = 0;
pte->writable = 1;
pte->present = 1;
pte->bitfields.available = 1;
pte->bitfields.global = 1;
pte->bitfields.attr_table = 0;
pte->bitfields.dirty = 0;
pte->bitfields.accessed = 0;
pte->bitfields.cache_disabled = 0;
pte->bitfields.write_through = 0;
pte->bitfields.user = 0;
pte->bitfields.writable = 1;
pte->bitfields.present = 1;
}

View File

@ -2,7 +2,7 @@
#include "config.h"
#include "info.h"
#include "interrupts/main.h"
#include "interrupts.h"
#include <drivers/console.h>
#include <drivers/intel_8259_pic.h>
@ -13,17 +13,11 @@
#include <string.h>
static struct KernAux_Arch_I386_DTR gdt_pointer;
static struct KernAux_Arch_I386_DTR idt_pointer;
static struct KernAux_Arch_I386_DTE gdt_entries[GDT_SIZE];
static struct KernAux_Arch_I386_IDTE idt_entries[IDT_SIZE];
static struct KernAux_Arch_I386_DTE gdt_entries[GDT_SIZE];
static struct KernAux_Arch_I386_TSS tss;
static void gdt_set_gates();
static void idt_set_gates();
static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
void protected_initialize(const struct Kernel_Info *const kinfo)
{
@ -34,7 +28,7 @@ void protected_initialize(const struct Kernel_Info *const kinfo)
gdt_set_gates();
drivers_console_puts("[INFO] protected: Setup IDT.");
idt_set_gates();
interrupts_setup(GDT_KERNEL_CS_SELECTOR);
drivers_console_puts("[INFO] protected: Setup TSS.");
memset(&tss, 0, sizeof(tss));
@ -51,12 +45,10 @@ void protected_initialize(const struct Kernel_Info *const kinfo)
);
drivers_console_puts("[INFO] protected: Load IDT.");
idt_pointer.size = sizeof(struct KernAux_Arch_I386_IDTE) * IDT_SIZE - 1;
idt_pointer.offset = (uint32_t)&idt_entries;
kernaux_asm_i386_flush_idt((uint32_t)&idt_pointer);
interrupts_load();
// drivers_console_puts("[INFO] protected: Load TSS.");
// kernaux_asm_i386_flush_tss(GDT_TSS_SELECTOR);
drivers_console_puts("[INFO] protected: Load TSS.");
kernaux_asm_i386_flush_tss(GDT_TSS_SELECTOR);
drivers_console_puts("[INFO] protected: Enable interrupts.");
asm volatile ("sti");
@ -158,86 +150,8 @@ void gdt_set_gates()
.read_write = 0,
.conforming_expand_down = 0,
.code = 1,
.always_1 = 1, // was 0
.DPL = 3,
.always_1 = 0,
.DPL = 0,
.present = 1,
};
}
void idt_set_gates()
{
memset(idt_entries, 0, sizeof(idt_entries));
const uint16_t flags_base = 0x8e;
const uint16_t flags_priv_user = 0x60;
// exception
idt_set_gate(0, (uint32_t)interrupt_0, 0x08, flags_base);
idt_set_gate(1, (uint32_t)interrupt_1, 0x08, flags_base);
idt_set_gate(2, (uint32_t)interrupt_2, 0x08, flags_base);
idt_set_gate(3, (uint32_t)interrupt_3, 0x08, flags_base);
idt_set_gate(4, (uint32_t)interrupt_4, 0x08, flags_base);
idt_set_gate(5, (uint32_t)interrupt_5, 0x08, flags_base);
idt_set_gate(6, (uint32_t)interrupt_6, 0x08, flags_base);
idt_set_gate(7, (uint32_t)interrupt_7, 0x08, flags_base);
idt_set_gate(8, (uint32_t)interrupt_8, 0x08, flags_base);
idt_set_gate(9, (uint32_t)interrupt_9, 0x08, flags_base);
idt_set_gate(10, (uint32_t)interrupt_10, 0x08, flags_base);
idt_set_gate(11, (uint32_t)interrupt_11, 0x08, flags_base);
idt_set_gate(12, (uint32_t)interrupt_12, 0x08, flags_base);
idt_set_gate(13, (uint32_t)interrupt_13, 0x08, flags_base);
idt_set_gate(14, (uint32_t)interrupt_14, 0x08, flags_base);
idt_set_gate(15, (uint32_t)interrupt_15, 0x08, flags_base);
idt_set_gate(16, (uint32_t)interrupt_16, 0x08, flags_base);
idt_set_gate(17, (uint32_t)interrupt_17, 0x08, flags_base);
idt_set_gate(18, (uint32_t)interrupt_18, 0x08, flags_base);
idt_set_gate(19, (uint32_t)interrupt_19, 0x08, flags_base);
idt_set_gate(20, (uint32_t)interrupt_20, 0x08, flags_base);
idt_set_gate(21, (uint32_t)interrupt_21, 0x08, flags_base);
idt_set_gate(22, (uint32_t)interrupt_22, 0x08, flags_base);
idt_set_gate(23, (uint32_t)interrupt_23, 0x08, flags_base);
idt_set_gate(24, (uint32_t)interrupt_24, 0x08, flags_base);
idt_set_gate(25, (uint32_t)interrupt_25, 0x08, flags_base);
idt_set_gate(26, (uint32_t)interrupt_26, 0x08, flags_base);
idt_set_gate(27, (uint32_t)interrupt_27, 0x08, flags_base);
idt_set_gate(28, (uint32_t)interrupt_28, 0x08, flags_base);
idt_set_gate(29, (uint32_t)interrupt_29, 0x08, flags_base);
idt_set_gate(30, (uint32_t)interrupt_30, 0x08, flags_base);
idt_set_gate(31, (uint32_t)interrupt_31, 0x08, flags_base);
// hwint: master PIC
idt_set_gate(32, (uint32_t)interrupt_32, 0x08, flags_base);
idt_set_gate(33, (uint32_t)interrupt_33, 0x08, flags_base);
idt_set_gate(34, (uint32_t)interrupt_34, 0x08, flags_base);
idt_set_gate(35, (uint32_t)interrupt_35, 0x08, flags_base);
idt_set_gate(36, (uint32_t)interrupt_36, 0x08, flags_base);
idt_set_gate(37, (uint32_t)interrupt_37, 0x08, flags_base);
idt_set_gate(38, (uint32_t)interrupt_38, 0x08, flags_base);
idt_set_gate(39, (uint32_t)interrupt_39, 0x08, flags_base);
// hwint: slave PIC
idt_set_gate(40, (uint32_t)interrupt_40, 0x08, flags_base);
idt_set_gate(41, (uint32_t)interrupt_41, 0x08, flags_base);
idt_set_gate(42, (uint32_t)interrupt_42, 0x08, flags_base);
idt_set_gate(43, (uint32_t)interrupt_43, 0x08, flags_base);
idt_set_gate(44, (uint32_t)interrupt_44, 0x08, flags_base);
idt_set_gate(45, (uint32_t)interrupt_45, 0x08, flags_base);
idt_set_gate(46, (uint32_t)interrupt_46, 0x08, flags_base);
idt_set_gate(47, (uint32_t)interrupt_47, 0x08, flags_base);
// syscall
idt_set_gate(
INT_SYSCALL,
(uint32_t)interrupt_0x80,
0x08,
flags_base | flags_priv_user
);
}
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
KernAux_Arch_I386_IDTE_set_offset(&idt_entries[num], base);
idt_entries[num].selector = sel;
idt_entries[num]._zero0 = 0;
idt_entries[num].flags = flags;
}

View File

@ -1,21 +0,0 @@
#include "timer.h"
#include <drivers/console.h>
#include <drivers/intel_8253_pit.h>
#include <kernaux/asm/i386.h>
void timer_initialize(unsigned int frequency)
{
drivers_console_puts("[INFO] timer: Initialize timer.");
drivers_intel_8253_pit_initialize(frequency);
}
void timer_register_handler(timer_handler_t handler)
{
hwint_register_handler(0, handler);
}
void timer_unregister_handler()
{
hwint_unregister_handler(0);
}

View File

@ -1,13 +0,0 @@
#ifndef KERNEL_INCLUDED_TIMER
#define KERNEL_INCLUDED_TIMER 1
#include "interrupts/main.h"
typedef hwint_handler_t timer_handler_t;
void timer_initialize(unsigned int frequency);
void timer_register_handler(timer_handler_t handler);
void timer_unregister_handler();
#endif