initial razzle
This commit is contained in:
commit
cd3d8871df
29 changed files with 1986 additions and 0 deletions
32
arch/i386/asm.c
Normal file
32
arch/i386/asm.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct regs {
|
||||
unsigned int gs, fs, es, ds;
|
||||
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
unsigned int int_no, err_code;
|
||||
unsigned int eip, cs, eflags, useresp, ss;
|
||||
};
|
||||
|
||||
void __sl_acquire(uint32_t *lock_id) {
|
||||
__asm__("retry_lock: lock bts $0,(%0); pause; jc retry_lock" : "+g"(lock_id));
|
||||
}
|
||||
|
||||
void __sl_release(uint32_t *lock_id) {
|
||||
__asm__("lock btr $0, (%0)" : "+g"(lock_id));
|
||||
}
|
||||
|
||||
static inline void outb(int port, int val) {
|
||||
__asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
}
|
||||
|
||||
static inline unsigned char inb(int port) {
|
||||
unsigned char val;
|
||||
__asm__ volatile("inb %w1, %b0" : "=a"(val) : "Nd"(port) : "memory");
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void interrupt_disable() { __asm__ volatile("cli"); }
|
||||
|
||||
static inline void interrupt_enable() { __asm__ volatile("sti"); }
|
121
arch/i386/gdt.c
Normal file
121
arch/i386/gdt.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/memory.c"
|
||||
#include <stdint.h>
|
||||
|
||||
struct gdt_row_t {
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_middle;
|
||||
uint8_t access;
|
||||
uint8_t granularity_limit_high;
|
||||
uint8_t base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_ptr_t {
|
||||
uint16_t size;
|
||||
uint32_t address;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tss_row_t {
|
||||
uint32_t prev_tss;
|
||||
uint32_t esp_ring0;
|
||||
uint32_t ss_ring0;
|
||||
uint32_t padding[23]; // Extra options RAZZLE doesn't use
|
||||
} __attribute__((packed));
|
||||
|
||||
enum gdt_access_t {
|
||||
GDT_ACCESS_PRESENT = 0b10000000,
|
||||
GDT_ACCESS_DPL_KERNEL = 0b00000000,
|
||||
GDT_ACCESS_DPL_USER = 0b01100000,
|
||||
GDT_ACCESS_CODEDATA = 0b00010000,
|
||||
GDT_ACCESS_EXECUTABLE = 0b00001000,
|
||||
GDT_ACCESS_GROW_DOWN = 0b00000100,
|
||||
GDT_ACCESS_RW = 0b00000010,
|
||||
GDT_ACCESS_ACCESSED = 0b00000001,
|
||||
};
|
||||
|
||||
enum gdt_granularity_t {
|
||||
GDT_GRANULARITY_4K = 0b10001111,
|
||||
GDT_GRANULARITY_MODE_32BIT = 0b01001111,
|
||||
};
|
||||
|
||||
struct tss_row_t tss_entry;
|
||||
|
||||
#define GDT_SIZE (6)
|
||||
struct gdt_row_t gdt[GDT_SIZE];
|
||||
|
||||
void load_gdt(struct gdt_ptr_t *gp) {
|
||||
asm volatile("lgdt (%0)\n\t"
|
||||
"mov $0x10, %%ax\n\t"
|
||||
"mov %%ax, %%ds\n\t"
|
||||
"mov %%ax, %%es\n\t"
|
||||
"mov %%ax, %%fs\n\t"
|
||||
"mov %%ax, %%gs\n\t"
|
||||
"mov %%ax, %%ss\n\t"
|
||||
:
|
||||
: "r"(gp)
|
||||
: "%ax");
|
||||
}
|
||||
|
||||
void set_gdt_row(uint32_t num, uint32_t base, uint32_t limit, uint8_t access,
|
||||
uint8_t granularity) {
|
||||
gdt[num].base_low = base & 0xFFFF;
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
gdt[num].limit_low = limit & 0xFFFF;
|
||||
gdt[num].granularity_limit_high = (limit >> 16) & 0x0F;
|
||||
gdt[num].granularity_limit_high |= granularity & 0xF0;
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
void load_tss(uint16_t gdt_row_num) {
|
||||
gdt_row_num *= 8;
|
||||
__asm__ volatile("mov %0, %%ax; ltr %%ax" : : "r"(gdt_row_num) : "ax");
|
||||
}
|
||||
|
||||
#define KERNEL_CODE_SEL (0x08)
|
||||
#define KERNEL_DATA_SEL (0x10)
|
||||
|
||||
void init_gdt() {
|
||||
struct gdt_ptr_t gp;
|
||||
gp.size = (sizeof(struct gdt_row_t) * GDT_SIZE) - 1;
|
||||
gp.address = (uint32_t)&gdt;
|
||||
|
||||
set_gdt_row(0, 0, 0, 0, 0);
|
||||
|
||||
// Kernelmode code/data degments
|
||||
set_gdt_row(1, 0, 0xFFFFFFFF,
|
||||
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_KERNEL | GDT_ACCESS_CODEDATA |
|
||||
GDT_ACCESS_EXECUTABLE | GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
|
||||
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
|
||||
set_gdt_row(2, 0, 0xFFFFFFFF,
|
||||
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_KERNEL | GDT_ACCESS_CODEDATA |
|
||||
GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
|
||||
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
|
||||
|
||||
// Usermode code/data segments
|
||||
set_gdt_row(3, 0x0000000, 0xFFFFFFFF,
|
||||
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_USER | GDT_ACCESS_CODEDATA |
|
||||
GDT_ACCESS_EXECUTABLE | GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
|
||||
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
|
||||
set_gdt_row(4, 0x0000000, 0xFFFFFFFF,
|
||||
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_USER | GDT_ACCESS_CODEDATA |
|
||||
GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
|
||||
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
|
||||
|
||||
// TSS row
|
||||
set_gdt_row(5, (uint32_t)&tss_entry, sizeof(tss_entry),
|
||||
GDT_ACCESS_PRESENT | GDT_ACCESS_EXECUTABLE | GDT_ACCESS_ACCESSED,
|
||||
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
|
||||
|
||||
// Setup TSS
|
||||
int kstack = 0;
|
||||
memset((char *)&tss_entry, 0, sizeof(tss_entry));
|
||||
tss_entry.ss_ring0 = 0x10;
|
||||
tss_entry.esp_ring0 = (uint32_t)&kstack;
|
||||
|
||||
// Load GDT and TSS
|
||||
load_gdt(&gp);
|
||||
load_tss(5);
|
||||
}
|
52
arch/i386/handlers.h
Normal file
52
arch/i386/handlers.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
extern void irq0();
|
||||
extern void irq1();
|
||||
extern void irq2();
|
||||
extern void irq3();
|
||||
extern void irq4();
|
||||
extern void irq5();
|
||||
extern void irq6();
|
||||
extern void irq7();
|
||||
extern void irq8();
|
||||
extern void irq9();
|
||||
extern void irq10();
|
||||
extern void irq11();
|
||||
extern void irq12();
|
||||
extern void irq13();
|
||||
extern void irq14();
|
||||
extern void irq15();
|
||||
extern void irq128();
|
||||
|
||||
extern void isr0();
|
||||
extern void isr1();
|
||||
extern void isr2();
|
||||
extern void isr3();
|
||||
extern void isr4();
|
||||
extern void isr5();
|
||||
extern void isr6();
|
||||
extern void isr7();
|
||||
extern void isr8();
|
||||
extern void isr9();
|
||||
extern void isr10();
|
||||
extern void isr11();
|
||||
extern void isr12();
|
||||
extern void isr13();
|
||||
extern void isr14();
|
||||
extern void isr15();
|
||||
extern void isr16();
|
||||
extern void isr17();
|
||||
extern void isr18();
|
||||
extern void isr19();
|
||||
extern void isr20();
|
||||
extern void isr21();
|
||||
extern void isr22();
|
||||
extern void isr23();
|
||||
extern void isr24();
|
||||
extern void isr25();
|
||||
extern void isr26();
|
||||
extern void isr27();
|
||||
extern void isr28();
|
||||
extern void isr29();
|
||||
extern void isr30();
|
||||
extern void isr31();
|
86
arch/i386/idt.c
Normal file
86
arch/i386/idt.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/memory.c"
|
||||
#include "./handlers.h"
|
||||
#include "gdt.c"
|
||||
|
||||
struct idt_row_t {
|
||||
uint16_t base_lo;
|
||||
uint16_t sel;
|
||||
uint8_t unset;
|
||||
uint8_t flags;
|
||||
uint16_t base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_ptr_t {
|
||||
uint16_t size;
|
||||
uint32_t address;
|
||||
} __attribute__((packed));
|
||||
|
||||
// TODO: double check this?
|
||||
enum idt_flag_t {
|
||||
IDTFLAG_PRESENT = 0b10000000,
|
||||
IDTFLAG_DPL_KERNEL = 0b00000000,
|
||||
IDTFLAG_DPL_USER = 0b01100000,
|
||||
IDTFLAG_TRAP = 0b00001111,
|
||||
IDTFLAG_INTERRUPT = 0b00001110,
|
||||
};
|
||||
|
||||
#define KERNEL_INTERRUPT_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_KERNEL | IDTFLAG_INTERRUPT)
|
||||
#define USER_TRAP_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_USER | IDTFLAG_INTERRUPT)
|
||||
|
||||
#define IDT_SIZE (256)
|
||||
struct idt_row_t idt[IDT_SIZE];
|
||||
struct idt_ptr_t idtp;
|
||||
|
||||
void load_idt(struct idt_ptr_t *pt) { asm volatile("lidt (%0)" ::"r"(pt)); }
|
||||
|
||||
void set_idt_row(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
|
||||
idt[num].base_hi = (base >> 16) & 0x0000FFFF;
|
||||
idt[num].base_lo = base & 0x0000FFFF;
|
||||
idt[num].sel = sel;
|
||||
idt[num].flags = flags;
|
||||
idt[num].unset = 0;
|
||||
}
|
||||
|
||||
void init_idt() {
|
||||
idtp.size = (sizeof(struct idt_row_t) * IDT_SIZE) - 1;
|
||||
idtp.address = (uint32_t)&idt;
|
||||
|
||||
memset((char *)&idt, 0, sizeof(struct idt_row_t) * IDT_SIZE);
|
||||
|
||||
set_idt_row(0, (uint32_t)isr0, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(1, (uint32_t)isr1, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(2, (uint32_t)isr2, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(3, (uint32_t)isr3, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(4, (uint32_t)isr4, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(5, (uint32_t)isr5, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(6, (uint32_t)isr6, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(7, (uint32_t)isr7, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(8, (uint32_t)isr8, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(9, (uint32_t)isr9, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(10, (uint32_t)isr10, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(11, (uint32_t)isr11, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(12, (uint32_t)isr12, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(13, (uint32_t)isr13, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(14, (uint32_t)isr14, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(15, (uint32_t)isr15, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(16, (uint32_t)isr16, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(17, (uint32_t)isr17, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(18, (uint32_t)isr18, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(19, (uint32_t)isr19, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(20, (uint32_t)isr20, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(21, (uint32_t)isr21, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(22, (uint32_t)isr22, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(23, (uint32_t)isr23, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(24, (uint32_t)isr24, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(25, (uint32_t)isr25, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(26, (uint32_t)isr26, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(27, (uint32_t)isr27, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(28, (uint32_t)isr28, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(29, (uint32_t)isr29, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(30, (uint32_t)isr30, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(31, (uint32_t)isr31, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
|
||||
load_idt(&idtp);
|
||||
}
|
11
arch/i386/init.c
Normal file
11
arch/i386/init.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "./gdt.c"
|
||||
#include "./idt.c"
|
||||
#include "./irq.c"
|
||||
|
||||
void arch_init() {
|
||||
init_gdt();
|
||||
init_idt();
|
||||
init_irq();
|
||||
}
|
81
arch/i386/irq.c
Normal file
81
arch/i386/irq.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/ps2.c"
|
||||
#include "../../kernel/syscall.c"
|
||||
#include "./asm.c"
|
||||
#include "./idt.c"
|
||||
#include "handlers.h"
|
||||
|
||||
enum irq_code_t {
|
||||
IRQCODE_PIT = 32,
|
||||
IRQCODE_PS2 = 33,
|
||||
IRQCODE_SYSCALL = 128,
|
||||
};
|
||||
|
||||
void kb_handler() {
|
||||
uint8_t char_code = inb(0x60);
|
||||
handle_keypress(char_code);
|
||||
}
|
||||
|
||||
void remap_irq(void) {
|
||||
outb(0x20, 0x11);
|
||||
outb(0xA0, 0x11);
|
||||
outb(0x21, 0x20);
|
||||
outb(0xA1, 0x28);
|
||||
outb(0x21, 0x04);
|
||||
outb(0xA1, 0x02);
|
||||
outb(0x21, 0x01);
|
||||
outb(0xA1, 0x01);
|
||||
outb(0x21, 0x0);
|
||||
outb(0xA1, 0x0);
|
||||
}
|
||||
|
||||
void init_irq() {
|
||||
remap_irq();
|
||||
|
||||
set_idt_row(32, (uint32_t)irq0, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(33, (uint32_t)irq1, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(34, (uint32_t)irq2, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(35, (uint32_t)irq3, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(36, (uint32_t)irq4, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(37, (uint32_t)irq5, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(38, (uint32_t)irq6, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(39, (uint32_t)irq7, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(40, (uint32_t)irq8, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(41, (uint32_t)irq9, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(42, (uint32_t)irq10, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(43, (uint32_t)irq11, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(44, (uint32_t)irq12, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(45, (uint32_t)irq13, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(46, (uint32_t)irq14, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
set_idt_row(47, (uint32_t)irq15, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
|
||||
|
||||
set_idt_row(128, (uint32_t)irq128, KERNEL_CODE_SEL, USER_TRAP_FLAG);
|
||||
}
|
||||
|
||||
void irq_handler(struct regs *r) {
|
||||
switch (r->int_no) {
|
||||
case IRQCODE_SYSCALL: {
|
||||
syscall(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case IRQCODE_PIT: {
|
||||
schedule(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case IRQCODE_PS2: {
|
||||
kb_handler();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// Send EOI to follower controller
|
||||
if (r->int_no >= 40 && r->int_no < 48) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
|
||||
// Send EOI to leader controller
|
||||
outb(0x20, 0x20);
|
||||
}
|
143
arch/i386/irq.s
Normal file
143
arch/i386/irq.s
Normal file
|
@ -0,0 +1,143 @@
|
|||
.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 irq128
|
||||
|
||||
irq0:
|
||||
cli
|
||||
push $0
|
||||
push $32
|
||||
jmp irq_handle
|
||||
|
||||
irq1:
|
||||
cli
|
||||
push $1
|
||||
push $33
|
||||
jmp irq_handle
|
||||
|
||||
irq2:
|
||||
cli
|
||||
push $2
|
||||
push $34
|
||||
jmp irq_handle
|
||||
|
||||
irq3:
|
||||
cli
|
||||
push $3
|
||||
push $35
|
||||
jmp irq_handle
|
||||
|
||||
irq4:
|
||||
cli
|
||||
push $4
|
||||
push $36
|
||||
jmp irq_handle
|
||||
|
||||
irq5:
|
||||
cli
|
||||
push $5
|
||||
push $37
|
||||
jmp irq_handle
|
||||
|
||||
irq6:
|
||||
cli
|
||||
push $6
|
||||
push $38
|
||||
jmp irq_handle
|
||||
|
||||
irq7:
|
||||
cli
|
||||
push $7
|
||||
push $39
|
||||
jmp irq_handle
|
||||
|
||||
irq8:
|
||||
cli
|
||||
push $8
|
||||
push $40
|
||||
jmp irq_handle
|
||||
|
||||
irq9:
|
||||
cli
|
||||
push $9
|
||||
push $41
|
||||
jmp irq_handle
|
||||
|
||||
irq10:
|
||||
cli
|
||||
push $10
|
||||
push $42
|
||||
jmp irq_handle
|
||||
|
||||
irq11:
|
||||
cli
|
||||
push $11
|
||||
push $43
|
||||
jmp irq_handle
|
||||
|
||||
irq12:
|
||||
cli
|
||||
push $12
|
||||
push $44
|
||||
jmp irq_handle
|
||||
|
||||
irq13:
|
||||
cli
|
||||
push $13
|
||||
push $45
|
||||
jmp irq_handle
|
||||
|
||||
irq14:
|
||||
cli
|
||||
push $14
|
||||
push $46
|
||||
jmp irq_handle
|
||||
|
||||
irq15:
|
||||
cli
|
||||
push $15
|
||||
push $47
|
||||
jmp irq_handle
|
||||
|
||||
irq128:
|
||||
cli
|
||||
push $0x80
|
||||
push $0x80
|
||||
jmp irq_handle
|
||||
|
||||
irq_handle:
|
||||
pusha
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
movl %esp, %eax
|
||||
push %eax
|
||||
movl $irq_handler, %eax
|
||||
call *%eax
|
||||
pop %eax
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
pop %ds
|
||||
popal
|
||||
addl $8, %esp
|
||||
iret
|
243
arch/i386/isr.s
Normal file
243
arch/i386/isr.s
Normal file
|
@ -0,0 +1,243 @@
|
|||
.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
|
||||
|
||||
isr0:
|
||||
cli
|
||||
push $0
|
||||
push $0
|
||||
jmp isr_handle
|
||||
|
||||
isr1:
|
||||
cli
|
||||
push $0
|
||||
push $1
|
||||
jmp isr_handle
|
||||
|
||||
isr2:
|
||||
cli
|
||||
push $0
|
||||
push $2
|
||||
jmp isr_handle
|
||||
|
||||
isr3:
|
||||
cli
|
||||
push $0
|
||||
push $3
|
||||
jmp isr_handle
|
||||
|
||||
isr4:
|
||||
cli
|
||||
push $0
|
||||
push $4
|
||||
jmp isr_handle
|
||||
|
||||
isr5:
|
||||
cli
|
||||
push $0
|
||||
push $5
|
||||
jmp isr_handle
|
||||
|
||||
isr6:
|
||||
cli
|
||||
push $0
|
||||
push $6
|
||||
jmp isr_handle
|
||||
|
||||
isr7:
|
||||
cli
|
||||
push $0
|
||||
push $7
|
||||
jmp isr_handle
|
||||
|
||||
isr8:
|
||||
cli
|
||||
push $0
|
||||
push $8
|
||||
jmp isr_handle
|
||||
|
||||
isr9:
|
||||
cli
|
||||
push $0
|
||||
push $9
|
||||
jmp isr_handle
|
||||
|
||||
isr10:
|
||||
cli
|
||||
push $10
|
||||
jmp isr_handle
|
||||
|
||||
isr11:
|
||||
cli
|
||||
push $11
|
||||
jmp isr_handle
|
||||
|
||||
isr12:
|
||||
cli
|
||||
push $12
|
||||
jmp isr_handle
|
||||
|
||||
isr13:
|
||||
cli
|
||||
push $13
|
||||
jmp isr_handle
|
||||
|
||||
isr14:
|
||||
cli
|
||||
push $14
|
||||
jmp isr_handle
|
||||
|
||||
isr15:
|
||||
cli
|
||||
push $0
|
||||
push $15
|
||||
jmp isr_handle
|
||||
|
||||
isr16:
|
||||
cli
|
||||
push $0
|
||||
push $16
|
||||
jmp isr_handle
|
||||
|
||||
isr17:
|
||||
cli
|
||||
push $0
|
||||
push $17
|
||||
jmp isr_handle
|
||||
|
||||
isr18:
|
||||
cli
|
||||
push $0
|
||||
push $18
|
||||
jmp isr_handle
|
||||
|
||||
isr19:
|
||||
cli
|
||||
push $0
|
||||
push $19
|
||||
jmp isr_handle
|
||||
|
||||
isr20:
|
||||
cli
|
||||
push $0
|
||||
push $20
|
||||
jmp isr_handle
|
||||
|
||||
isr21:
|
||||
cli
|
||||
push $0
|
||||
push $21
|
||||
jmp isr_handle
|
||||
|
||||
isr22:
|
||||
cli
|
||||
push $0
|
||||
push $22
|
||||
jmp isr_handle
|
||||
|
||||
isr23:
|
||||
cli
|
||||
push $0
|
||||
push $23
|
||||
jmp isr_handle
|
||||
|
||||
isr24:
|
||||
cli
|
||||
push $0
|
||||
push $24
|
||||
jmp isr_handle
|
||||
|
||||
isr25:
|
||||
cli
|
||||
push $0
|
||||
push $25
|
||||
jmp isr_handle
|
||||
|
||||
isr26:
|
||||
cli
|
||||
push $0
|
||||
push $26
|
||||
jmp isr_handle
|
||||
|
||||
isr27:
|
||||
cli
|
||||
push $0
|
||||
push $27
|
||||
jmp isr_handle
|
||||
|
||||
isr28:
|
||||
cli
|
||||
push $0
|
||||
push $28
|
||||
jmp isr_handle
|
||||
|
||||
isr29:
|
||||
cli
|
||||
push $0
|
||||
push $29
|
||||
jmp isr_handle
|
||||
|
||||
isr30:
|
||||
cli
|
||||
push $0
|
||||
push $30
|
||||
jmp isr_handle
|
||||
|
||||
isr31:
|
||||
cli
|
||||
push $0
|
||||
push $31
|
||||
jmp isr_handle
|
||||
|
||||
isr_handle:
|
||||
pushal
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
movl %esp, %eax
|
||||
push %eax
|
||||
movl $fault_handler, %eax
|
||||
call *%eax
|
||||
pop %eax
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
pop %ds
|
||||
popal
|
||||
addl $8, %esp
|
||||
iret
|
26
arch/i386/loader.s
Normal file
26
arch/i386/loader.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
.set ALIGN, 1<<0
|
||||
.set MEMINFO, 1<<1
|
||||
.set FLAGS, ALIGN | MEMINFO
|
||||
.set MAGIC, 0x1BADB002
|
||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
||||
|
||||
.section .multiboot
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
stack_bottom:
|
||||
.skip 16384
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
.global _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
mov $stack_top, %esp
|
||||
call kernel_main
|
||||
|
||||
.size _start, . - _start
|
66
arch/i386/scheduler.c
Normal file
66
arch/i386/scheduler.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "asm.c"
|
||||
|
||||
enum eflags_t {
|
||||
EFLAG_CARRY = 0x0001,
|
||||
EFLAG_RES = 0x0002,
|
||||
EFLAG_PARITY = 0x0004,
|
||||
EFLAG_INTERRUPT = 0x0200
|
||||
};
|
||||
|
||||
void initialize_registers(struct regs *new_regs, char *entrypoint,
|
||||
uint32_t address_base, uint32_t address_space_size) {
|
||||
new_regs->eip = (unsigned int)entrypoint;
|
||||
|
||||
new_regs->edi = 0;
|
||||
new_regs->esi = 0;
|
||||
new_regs->ebx = 0;
|
||||
new_regs->edx = 0;
|
||||
new_regs->ecx = 0;
|
||||
new_regs->eax = 0;
|
||||
|
||||
new_regs->eflags = EFLAG_INTERRUPT;
|
||||
new_regs->useresp = (unsigned int)address_base + address_space_size - 1;
|
||||
new_regs->ebp = new_regs->useresp;
|
||||
|
||||
new_regs->ds = 35;
|
||||
new_regs->es = 35;
|
||||
new_regs->fs = 35;
|
||||
new_regs->gs = 35;
|
||||
new_regs->ss = 27;
|
||||
}
|
||||
|
||||
void store_registers(struct regs *machine_regs, struct regs *current_regs) {
|
||||
current_regs->edi = machine_regs->edi;
|
||||
current_regs->esi = machine_regs->esi;
|
||||
current_regs->ebx = machine_regs->ebx;
|
||||
current_regs->edx = machine_regs->edx;
|
||||
current_regs->ecx = machine_regs->ecx;
|
||||
current_regs->eax = machine_regs->eax;
|
||||
current_regs->eip = machine_regs->eip;
|
||||
current_regs->eflags = machine_regs->eflags;
|
||||
current_regs->useresp = machine_regs->useresp;
|
||||
current_regs->ebp = machine_regs->ebp;
|
||||
}
|
||||
|
||||
void switch_context(struct regs *machine_regs, struct regs *new_regs) {
|
||||
machine_regs->edi = new_regs->edi;
|
||||
machine_regs->esi = new_regs->esi;
|
||||
machine_regs->ebx = new_regs->ebx;
|
||||
machine_regs->edx = new_regs->edx;
|
||||
machine_regs->ecx = new_regs->ecx;
|
||||
machine_regs->eax = new_regs->eax;
|
||||
machine_regs->eip = new_regs->eip;
|
||||
machine_regs->eflags = new_regs->eflags;
|
||||
machine_regs->esp = machine_regs->esp;
|
||||
machine_regs->useresp = new_regs->useresp;
|
||||
machine_regs->ebp = new_regs->ebp;
|
||||
|
||||
machine_regs->ds = 35;
|
||||
machine_regs->es = 35;
|
||||
machine_regs->fs = 35;
|
||||
machine_regs->gs = 35;
|
||||
machine_regs->ss = 35;
|
||||
machine_regs->cs = 27;
|
||||
}
|
8
arch/i386/syscall.c
Normal file
8
arch/i386/syscall.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#define INVOKE_SYSCALL(syscall_num) \
|
||||
__asm__ volatile("movl %0, %%eax;" \
|
||||
"int $0x80;" \
|
||||
: \
|
||||
: "r"(syscall_num) \
|
||||
: "%eax")
|
Loading…
Add table
Add a link
Reference in a new issue