[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
23
Kernel/hal/cpu/gdt-asm.asm
Normal file
@ -0,0 +1,23 @@
|
||||
; GLOBAL DESCRIPTOR TABLE
|
||||
;
|
||||
;
|
||||
|
||||
bits 32
|
||||
; !!! GDT !!!
|
||||
; This will set up our new segment registers. We need to do
|
||||
; something special in order to set CS. We do what is called a
|
||||
; far jump. A jump that includes a segment as well as an offset.
|
||||
|
||||
global GdtFlush ; Allows the C code to link to this
|
||||
extern gp ; Says that 'gp' is in another file
|
||||
GdtFlush:
|
||||
lgdt [gp] ; Load the GDT with our 'gp' which is a special pointer
|
||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!
|
||||
flush2:
|
||||
ret ; Returns back to the C code!
|
74
Kernel/hal/cpu/gdt.c
Normal file
74
Kernel/hal/cpu/gdt.c
Normal file
@ -0,0 +1,74 @@
|
||||
/******************************************************************
|
||||
* gdt.c - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains function prototypes for setting up the GDT *
|
||||
******************************************************************/
|
||||
#define MAX_DESCRIPTORS 5
|
||||
#include "gdt.h"
|
||||
|
||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
|
||||
struct GdtEntry gdt[MAX_DESCRIPTORS];
|
||||
struct GdtPointer gp;
|
||||
|
||||
|
||||
/* Setup a descriptor in the Global Descriptor Table */
|
||||
void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (num >= MAX_DESCRIPTORS) return;
|
||||
|
||||
/* Setup the descriptor base address */
|
||||
gdt[num].base_low = (base & 0xFFFF);
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
|
||||
/* Setup the descriptor limits */
|
||||
gdt[num].limit_low = (limit & 0xFFFF);
|
||||
gdt[num].granularity = ((limit >> 16) & 0x0F);
|
||||
|
||||
/* Finally, set up the granularity and access flags */
|
||||
gdt[num].granularity |= (gran & 0xF0);
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
struct GdtEntry* GdtGetGate(int num)
|
||||
{
|
||||
if (num>MAX_DESCRIPTORS) return 0;
|
||||
return &gdt[num];
|
||||
}
|
||||
|
||||
/* Should be called by main. This will setup the special GDT
|
||||
* pointer, set up the first 3 entries in our GDT, and then
|
||||
* finally call gdt_flush() in our assembler file in order
|
||||
* to tell the processor where the new GDT is and update the
|
||||
* new segment registers */
|
||||
void GdtInstall()
|
||||
{
|
||||
/* Setup the GDT pointer and limit */
|
||||
gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
|
||||
gp.base = (unsigned int)&gdt;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
GdtSetGate(0, 0, 0, 0, 0);
|
||||
|
||||
/* The second entry is our Code Segment. The base address
|
||||
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
||||
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
||||
* Please check the table above in the tutorial in order
|
||||
* to see exactly what each value means */
|
||||
GdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
|
||||
/* The third entry is our Data Segment. It's EXACTLY the
|
||||
* same as our code segment, but the descriptor type in
|
||||
* this entry's access byte says it's a Data Segment */
|
||||
GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
/* User mode Code segment*/
|
||||
GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
/* User mode data segment*/
|
||||
GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
/* Flush out the old GDT and install the new changes! */
|
||||
GdtFlush();
|
||||
}
|
||||
|
38
Kernel/hal/cpu/gdt.h
Normal file
38
Kernel/hal/cpu/gdt.h
Normal file
@ -0,0 +1,38 @@
|
||||
/******************************************************************
|
||||
* gdt.h - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for GDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __GDT_H
|
||||
#define __GDT_H
|
||||
|
||||
/* Defines a GDT entry. We say packed, because it prevents the
|
||||
* compiler from doing things that it thinks is best: Prevent
|
||||
* compiler "optimization" by packing */
|
||||
struct GdtEntry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Special pointer which includes the limit: The max bytes
|
||||
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
|
||||
struct GdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This will be a function in start.asm. We use this to properly
|
||||
* reload the new segment registers */
|
||||
extern void GdtInstall();
|
||||
extern void GdtFlush();
|
||||
extern void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
extern struct GdtEntry* GdtGetGate(int num);
|
||||
|
||||
#endif
|
9
Kernel/hal/cpu/idt-asm.asm
Normal file
9
Kernel/hal/cpu/idt-asm.asm
Normal file
@ -0,0 +1,9 @@
|
||||
bits 32
|
||||
|
||||
; !!! IDT !!!
|
||||
; Loads the IDT defined in '_idtp'
|
||||
global IdtLoad
|
||||
extern idtp
|
||||
IdtLoad:
|
||||
lidt [idtp]
|
||||
ret
|
45
Kernel/hal/cpu/idt.c
Normal file
45
Kernel/hal/cpu/idt.c
Normal file
@ -0,0 +1,45 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include "idt.h"
|
||||
|
||||
extern void IdtLoad();
|
||||
/* Declare an IDT of 256 entries. */
|
||||
struct IdtEntry idt[256];
|
||||
struct IdtPointer idtp;
|
||||
|
||||
/* Use this function to set an entry in the IDT. Alot simpler
|
||||
* than twiddling with the GDT ;) */
|
||||
void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
||||
{
|
||||
/* The interrupt routine's base address */
|
||||
idt[num].base_lo = (base & 0xFFFF);
|
||||
idt[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
/* The segment or 'selector' that this IDT entry will use
|
||||
* is set here, along with any access flags */
|
||||
idt[num].sel = sel;
|
||||
idt[num].always0 = 0;
|
||||
idt[num].flags = flags;
|
||||
}
|
||||
|
||||
struct IdtEntry* IdtGetGate(unsigned char num)
|
||||
{
|
||||
return &idt[num];
|
||||
}
|
||||
|
||||
/* Installs the IDT */
|
||||
void IdtInstall()
|
||||
{
|
||||
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
||||
idtp.limit = (sizeof (struct IdtEntry) * 256) - 1;
|
||||
idtp.base = (unsigned int)&idt;
|
||||
|
||||
/* Clear out the entire IDT, initializing it to zeros */
|
||||
memset (&idt, 0, sizeof(struct IdtEntry) * 256);
|
||||
|
||||
/* Points the processor's internal register to the new IDT */
|
||||
IdtLoad();
|
||||
}
|
31
Kernel/hal/cpu/idt.h
Normal file
31
Kernel/hal/cpu/idt.h
Normal file
@ -0,0 +1,31 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __IDT_H
|
||||
#define __IDT_H
|
||||
|
||||
/* Defines an IDT entry */
|
||||
struct IdtEntry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IdtPointer
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* This exists in 'start.asm', and is used to load our IDT */
|
||||
extern void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
extern struct IdtEntry* IdtGetGate(unsigned char num);
|
||||
extern void IdtInstall();
|
||||
|
||||
#endif
|
159
Kernel/hal/cpu/irq-asm.asm
Normal file
159
Kernel/hal/cpu/irq-asm.asm
Normal file
@ -0,0 +1,159 @@
|
||||
bits 32
|
||||
|
||||
; !!! IRQ !!!
|
||||
global Irq_0
|
||||
global Irq_1
|
||||
global Irq_2
|
||||
global Irq_3
|
||||
global Irq_4
|
||||
global Irq_5
|
||||
global Irq_6
|
||||
global Irq_7
|
||||
global Irq_8
|
||||
global Irq_9
|
||||
global Irq_10
|
||||
global Irq_11
|
||||
global Irq_12
|
||||
global Irq_13
|
||||
global Irq_14
|
||||
global Irq_15
|
||||
|
||||
; 32: IRQ0
|
||||
Irq_0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32; Note that these don't push an error code on the stack:
|
||||
; We need to push a dummy error code
|
||||
jmp irq_common_stub
|
||||
|
||||
; 33: IRQ1
|
||||
Irq_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
; 34: IRQ2
|
||||
Irq_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
; 35: IRQ3
|
||||
Irq_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
; 36: IRQ4
|
||||
Irq_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
; 37: IRQ5
|
||||
Irq_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
; 38: IRQ6
|
||||
Irq_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
; 39: IRQ7
|
||||
Irq_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
; 40: IRQ8
|
||||
Irq_8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
; 41: IRQ9
|
||||
Irq_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
; 42: IRQ10
|
||||
Irq_10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
; 43: IRQ11
|
||||
Irq_11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
; 44: IRQ12
|
||||
Irq_12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
; 45: IRQ13
|
||||
Irq_13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
; 46: IRQ14
|
||||
Irq_14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
; 47: IRQ15
|
||||
Irq_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern IrqHandler
|
||||
|
||||
; This is a stub that we have created for IRQ based ISRs. This calls
|
||||
; 'Irq__handler' in our C code. We need to create this in an 'irq.c'
|
||||
irq_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push eax
|
||||
mov eax, IrqHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
91
Kernel/hal/cpu/irq.c
Normal file
91
Kernel/hal/cpu/irq.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
#include "irq.h"
|
||||
#include "idt.h"
|
||||
|
||||
/* These are own ISRs that point to our special IRQ handler
|
||||
* instead of the regular 'fault_handler' function */
|
||||
extern void Irq_0();
|
||||
extern void Irq_1();
|
||||
extern void Irq_2();
|
||||
extern void Irq_3();
|
||||
extern void Irq_4();
|
||||
extern void Irq_5();
|
||||
extern void Irq_6();
|
||||
extern void Irq_7();
|
||||
extern void Irq_8();
|
||||
extern void Irq_9();
|
||||
extern void Irq_10();
|
||||
extern void Irq_11();
|
||||
extern void Irq_12();
|
||||
extern void Irq_13();
|
||||
extern void Irq_14();
|
||||
extern void Irq_15();
|
||||
|
||||
/* This array is actually an array of function pointers. We use
|
||||
* this to handle custom IRQ handlers for a given IRQ */
|
||||
void *IrqRoutines[16] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* This installs a custom IRQ handler for the given IRQ */
|
||||
void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r))
|
||||
{
|
||||
IrqRoutines[irq] = handler;
|
||||
}
|
||||
|
||||
void IrqUninstallHandler (int irq)
|
||||
{
|
||||
IrqRoutines[irq] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We first remap the interrupt controllers, and then we install
|
||||
* the appropriate ISRs to the correct entries in the IDT. This
|
||||
* is just like installing the exception handlers */
|
||||
void IrqInstall()
|
||||
{
|
||||
PicRemap(32,40);
|
||||
|
||||
IdtSetGate(32, (unsigned)Irq_0, 0x08, 0x8E);
|
||||
IdtSetGate(33, (unsigned)Irq_1, 0x08, 0x8E);
|
||||
IdtSetGate(34, (unsigned)Irq_2, 0x08, 0x8E);
|
||||
IdtSetGate(35, (unsigned)Irq_3, 0x08, 0x8E);
|
||||
IdtSetGate(36, (unsigned)Irq_4, 0x08, 0x8E);
|
||||
IdtSetGate(37, (unsigned)Irq_5, 0x08, 0x8E);
|
||||
IdtSetGate(38, (unsigned)Irq_6, 0x08, 0x8E);
|
||||
IdtSetGate(39, (unsigned)Irq_7, 0x08, 0x8E);
|
||||
IdtSetGate(40, (unsigned)Irq_8, 0x08, 0x8E);
|
||||
IdtSetGate(41, (unsigned)Irq_9, 0x08, 0x8E);
|
||||
IdtSetGate(42, (unsigned)Irq_10, 0x08, 0x8E);
|
||||
IdtSetGate(43, (unsigned)Irq_11, 0x08, 0x8E);
|
||||
IdtSetGate(44, (unsigned)Irq_12, 0x08, 0x8E);
|
||||
IdtSetGate(45, (unsigned)Irq_13, 0x08, 0x8E);
|
||||
IdtSetGate(46, (unsigned)Irq_14, 0x08, 0x8E);
|
||||
IdtSetGate(47, (unsigned)Irq_15, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
// Default IRQ handler, launches other handler if installed.
|
||||
// Also sends end-of-interrupt messages to PIC
|
||||
void IrqHandler (_RegsStack32 *r)
|
||||
{
|
||||
/* This is a blank function pointer */
|
||||
void (*handler)(_RegsStack32 *r);
|
||||
|
||||
/* Find out if we have a custom handler to run for this
|
||||
* IRQ, and then finally, run it */
|
||||
handler = IrqRoutines[r->int_no - 32];
|
||||
if (handler) handler(r);
|
||||
|
||||
/* If the IDT entry that was invoked was greater than 40
|
||||
* (meaning IRQ8 - 15), then we need to send an EOI to
|
||||
* the slave controller */
|
||||
if (r->int_no >=40) outportb(0xA0, 0x20);
|
||||
|
||||
/* In either case, we need to send an EOI to the master
|
||||
* interrupt controller too */
|
||||
outportb(0x20, 0x20);
|
||||
}
|
10
Kernel/hal/cpu/irq.h
Normal file
10
Kernel/hal/cpu/irq.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r));
|
||||
extern void IrqUninstallHandler (int irq);
|
||||
extern void IrqInstall();
|
||||
|
||||
#endif
|
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
217
Kernel/hal/cpu/isrs-asm.asm
Normal file
@ -0,0 +1,217 @@
|
||||
bits 32
|
||||
|
||||
; !!! ISRs !!!
|
||||
global isr_exception_0
|
||||
global isr_exception_1
|
||||
global isr_exception_2
|
||||
global isr_exception_3
|
||||
global isr_exception_4
|
||||
global isr_exception_5
|
||||
global isr_exception_6
|
||||
global isr_exception_7
|
||||
global isr_exception_8
|
||||
global isr_exception_9
|
||||
global isr_exception_10
|
||||
global isr_exception_11
|
||||
global isr_exception_12
|
||||
global isr_exception_13
|
||||
global isr_exception_14
|
||||
global isr_exception_15
|
||||
global isr_exception_16
|
||||
global isr_exception_17
|
||||
global isr_exception_18
|
||||
global isr_exception_19
|
||||
global isr_exception_20
|
||||
global isr_exception_21
|
||||
global isr_exception_22
|
||||
global isr_exception_23
|
||||
global isr_exception_24
|
||||
global isr_exception_25
|
||||
global isr_exception_26
|
||||
global isr_exception_27
|
||||
global isr_exception_28
|
||||
global isr_exception_29
|
||||
global isr_exception_30
|
||||
global isr_exception_31
|
||||
|
||||
isr_exception_0:
|
||||
cli
|
||||
push byte 0; A normal ISR stub that pops a dummy error code to keep a
|
||||
; uniform stack frame
|
||||
push byte 0
|
||||
jmp isr_common_stub
|
||||
isr_exception_1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
jmp isr_common_stub
|
||||
isr_exception_2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
isr_exception_3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
isr_exception_4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
isr_exception_5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
isr_exception_6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
isr_exception_7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
isr_exception_8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
isr_exception_9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
isr_exception_10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
isr_exception_11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
isr_exception_12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
isr_exception_13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
isr_exception_14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
isr_exception_15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
isr_exception_16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
isr_exception_17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
isr_exception_18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
isr_exception_19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
isr_exception_20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
isr_exception_21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
isr_exception_22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
isr_exception_23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
isr_exception_24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
isr_exception_25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
isr_exception_26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
isr_exception_27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
isr_exception_28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
isr_exception_29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
isr_exception_30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
isr_exception_31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern IsrsFaultHandler
|
||||
|
||||
isr_common_stub:
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10 ; Load the Kernel Data Segment descriptor!
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp ; Push us the stack
|
||||
push eax
|
||||
mov eax, IsrsFaultHandler
|
||||
call eax ; A special call, preserves the 'eip' register
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
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!
|
114
Kernel/hal/cpu/isrs.c
Normal file
114
Kernel/hal/cpu/isrs.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include <debugio.h>
|
||||
|
||||
#include "isrs.h"
|
||||
#include "idt.h"
|
||||
|
||||
// Assembly coded
|
||||
extern void isr_exception_0();
|
||||
extern void isr_exception_1();
|
||||
extern void isr_exception_2();
|
||||
extern void isr_exception_3();
|
||||
extern void isr_exception_4();
|
||||
extern void isr_exception_5();
|
||||
extern void isr_exception_6();
|
||||
extern void isr_exception_7();
|
||||
extern void isr_exception_8();
|
||||
extern void isr_exception_9();
|
||||
extern void isr_exception_10();
|
||||
extern void isr_exception_11();
|
||||
extern void isr_exception_12();
|
||||
extern void isr_exception_13();
|
||||
extern void isr_exception_14();
|
||||
extern void isr_exception_15();
|
||||
extern void isr_exception_16();
|
||||
extern void isr_exception_17();
|
||||
extern void isr_exception_18();
|
||||
extern void isr_exception_19();
|
||||
extern void isr_exception_20();
|
||||
extern void isr_exception_21();
|
||||
extern void isr_exception_22();
|
||||
extern void isr_exception_23();
|
||||
extern void isr_exception_24();
|
||||
extern void isr_exception_25();
|
||||
extern void isr_exception_26();
|
||||
extern void isr_exception_27();
|
||||
extern void isr_exception_28();
|
||||
extern void isr_exception_29();
|
||||
extern void isr_exception_30();
|
||||
extern void isr_exception_31();
|
||||
|
||||
|
||||
void* IdtFaultHandlers[32] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
void IsrsInstall()
|
||||
{
|
||||
IdtSetGate(0, (unsigned)isr_exception_0, 0x08, 0x8E);
|
||||
IdtSetGate(1, (unsigned)isr_exception_1, 0x08, 0x8E);
|
||||
IdtSetGate(2, (unsigned)isr_exception_2, 0x08, 0x8E);
|
||||
IdtSetGate(3, (unsigned)isr_exception_3, 0x08, 0x8E);
|
||||
IdtSetGate(4, (unsigned)isr_exception_4, 0x08, 0x8E);
|
||||
IdtSetGate(5, (unsigned)isr_exception_5, 0x08, 0x8E);
|
||||
IdtSetGate(6, (unsigned)isr_exception_6, 0x08, 0x8E);
|
||||
IdtSetGate(7, (unsigned)isr_exception_7, 0x08, 0x8E);
|
||||
IdtSetGate(8, (unsigned)isr_exception_8, 0x08, 0x8E);
|
||||
IdtSetGate(9, (unsigned)isr_exception_9, 0x08, 0x8E);
|
||||
IdtSetGate(10, (unsigned)isr_exception_10, 0x08, 0x8E);
|
||||
IdtSetGate(11, (unsigned)isr_exception_11, 0x08, 0x8E);
|
||||
IdtSetGate(12, (unsigned)isr_exception_12, 0x08, 0x8E);
|
||||
IdtSetGate(13, (unsigned)isr_exception_13, 0x08, 0x8E);
|
||||
IdtSetGate(14, (unsigned)isr_exception_14, 0x08, 0x8E);
|
||||
IdtSetGate(15, (unsigned)isr_exception_15, 0x08, 0x8E);
|
||||
IdtSetGate(16, (unsigned)isr_exception_16, 0x08, 0x8E);
|
||||
IdtSetGate(17, (unsigned)isr_exception_17, 0x08, 0x8E);
|
||||
IdtSetGate(18, (unsigned)isr_exception_18, 0x08, 0x8E);
|
||||
IdtSetGate(19, (unsigned)isr_exception_19, 0x08, 0x8E);
|
||||
IdtSetGate(20, (unsigned)isr_exception_20, 0x08, 0x8E);
|
||||
IdtSetGate(21, (unsigned)isr_exception_21, 0x08, 0x8E);
|
||||
IdtSetGate(22, (unsigned)isr_exception_22, 0x08, 0x8E);
|
||||
IdtSetGate(23, (unsigned)isr_exception_23, 0x08, 0x8E);
|
||||
IdtSetGate(24, (unsigned)isr_exception_24, 0x08, 0x8E);
|
||||
IdtSetGate(25, (unsigned)isr_exception_25, 0x08, 0x8E);
|
||||
IdtSetGate(26, (unsigned)isr_exception_26, 0x08, 0x8E);
|
||||
IdtSetGate(27, (unsigned)isr_exception_27, 0x08, 0x8E);
|
||||
IdtSetGate(28, (unsigned)isr_exception_28, 0x08, 0x8E);
|
||||
IdtSetGate(29, (unsigned)isr_exception_29, 0x08, 0x8E);
|
||||
IdtSetGate(30, (unsigned)isr_exception_30, 0x08, 0x8E);
|
||||
IdtSetGate(31, (unsigned)isr_exception_31, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
|
||||
void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r))
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = function;
|
||||
}
|
||||
|
||||
|
||||
void IsrsUninstallHandler(int interr)
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = 0;
|
||||
}
|
||||
|
||||
|
||||
extern void CrashMessage(_RegsStack32 *r);
|
||||
// Default fault handler; calls other handlers, or displays error message.
|
||||
void IsrsFaultHandler(_RegsStack32 *r)
|
||||
{
|
||||
/* Is this a fault whose number is from 0 to 31? */
|
||||
if (r->int_no < 32)
|
||||
{
|
||||
void (*func)(_RegsStack32 *r);
|
||||
func = IdtFaultHandlers[r->int_no];
|
||||
|
||||
// Halt system if unhandled
|
||||
if (!func) {
|
||||
CrashMessage(r);
|
||||
asm ("cli");
|
||||
asm ("hlt");
|
||||
}
|
||||
|
||||
else (*func)(r);
|
||||
}
|
||||
}
|
10
Kernel/hal/cpu/isrs.h
Normal file
10
Kernel/hal/cpu/isrs.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __ISRS_H_
|
||||
#define __ISRS_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern void IsrsInstall();
|
||||
extern void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r));
|
||||
extern void IsrsUninstallHandler(int interr);
|
||||
|
||||
#endif
|
23
Kernel/hal/cpu/pic.c
Normal file
23
Kernel/hal/cpu/pic.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include "pic.h"
|
||||
|
||||
void PicRemap(int pic1, int pic2)
|
||||
{
|
||||
// Send ICW1
|
||||
outportb(0x20, 0x11);
|
||||
outportb(0xA0, 0x11);
|
||||
|
||||
// send ICW2
|
||||
outportb(0x21, pic1); // remap pics
|
||||
outportb(0xA1, pic2);
|
||||
|
||||
// send ICW3
|
||||
outportb(0x21, 4);
|
||||
outportb(0xA1, 2);
|
||||
|
||||
// Send ICW4
|
||||
outportb(0x21, 0x01);
|
||||
outportb(0xA1, 0x01);
|
||||
|
||||
outportb(0x21, 0x00);
|
||||
}
|
6
Kernel/hal/cpu/pic.h
Normal file
6
Kernel/hal/cpu/pic.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _PIC_H
|
||||
#define _PIC_H
|
||||
|
||||
extern void PicRemap(int pic1, int pic2);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user