[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:
2021-09-14 18:48:57 +03:00
parent b6ddeca1c3
commit 913e65b856
326 changed files with 6990 additions and 12229 deletions

19
Kernel/hal/clock/clock.c Normal file
View File

@ -0,0 +1,19 @@
#include <time.h>
#include "clock.h"
#define MILISECONDS_IN_DAY 86400000
volatile TimeSystem _internal_time;
uint32 _internal_frequency_hz;
void TimeHandler(_RegsStack32* UNUSED(r))
{
if (_internal_frequency_hz == 0) return;
_internal_time.Time += 1000/_internal_frequency_hz;
if (_internal_time.Time >= MILISECONDS_IN_DAY)
{
_internal_time.Date++;
_internal_time.Time-=MILISECONDS_IN_DAY;
}
}

9
Kernel/hal/clock/clock.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef __CLOCK__H
#define __CLOCK__H
#include <time.h>
extern void TimeHandler(_RegsStack32 *r);
#endif

View 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
View 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
View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,6 @@
#ifndef _PIC_H
#define _PIC_H
extern void PicRemap(int pic1, int pic2);
#endif

96
Kernel/hal/crash.c Normal file
View File

@ -0,0 +1,96 @@
/*
* crash.c
*
* Created on: Aug 19, 2011
* Author: Tiberiu
*/
#include <debugio.h>
string errorCodes[] =
{
"Division by zero", //0
"Debugger", //1
"Non maskable interrupt", //2
"Breakpoint", //3
"Overflow", //4
"Bounds", //5
"Invalid opcode", //6
"Coprocessor not available", //7
"Double fault", //8
"Coprocessor segment overrun",//9
"Invalid task state segment", //A
"Segment not present", //B
"Stack fault", //C
"General protection fault", //D
"Page fault", //E
"", //F
"Math fault", //10
"Alignment check", //11
"Machine check", //12
"SIMD floating-point exception" //13
};
void CrashMessage(_RegsStack32 *r)
{
ConsoleSetDefaultColor(ColorLightRed);
ConsoleWrite("\n"); uint32 i;
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
ConsoleWrite("There was an unhandled exception: ");
if (r->int_no < 20)
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
ConsoleWrite("Here, this might help find the problem:\n");
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
ConsoleSetDefaultColor(ColorWhite);
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
// Useful info about page fault
if (r->int_no == 0xE)
{
uint32 faulting_address;
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
}
ConsoleSetDefaultColor(ColorLightRed);
ConsoleWrite("\n");
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
}

97
Kernel/hal/crash.c~ Normal file
View File

@ -0,0 +1,97 @@
/*
* crash.c
*
* Created on: Aug 19, 2011
* Author: Tiberiu
*/
#include <debugio.h>
string errorCodes[] =
{
"Division by zero", //0
"Debugger", //1
"Non maskable interrupt", //2
"Breakpoint", //3
"Overflow", //4
"Bounds", //5
"Invalid opcode", //6
"Coprocessor not available", //7
"Double fault", //8
"Coprocessor segment overrun",//9
"Invalid task state segment", //A
"Segment not present", //B
"Stack fault", //C
"General protection fault", //D
"Page fault", //E
"", //F
"Math fault", //10
"Alignment check", //11
"Machine check", //12
"SIMD floating-point exception" //13
};
void CrashMessage(_RegsStack32 *r)
{
ConsoleSetDefaultColor(ColorLightRed);
ConsoleWrite("\n"); uint32 i;
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
ConsoleWrite("There was an unhandled exception: ");
if (r->int_no < 20)
ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
ConsoleWrite("Here, this might help find the problem:\n");
Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
ConsoleSetDefaultColor(ColorWhite);
ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
// Useful info about page fault
if (r->int_no == 0xE)
{
uint32 faulting_address;
asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
ConsoleCursorGoto(a); ConsoleWrite("reason: ");
if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
if (r->err_code & 2) ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
if (r->err_code & 4) ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
if (r->err_code & 8) ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
if (r->err_code & 0x10) ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
}
ConsoleSetDefaultColor(ColorLightRed);
ConsoleWrite("\n");
for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
}

35
Kernel/hal/hal.c Normal file
View File

@ -0,0 +1,35 @@
// HARDWARE ABSTRACTION LAYER
#include "cpu/gdt.h"
#include "cpu/idt.h"
#include "cpu/isrs.h"
#include "cpu/irq.h"
#include "clock/clock.h"
#include "keyboard/keyboard.h"
#include "mouse/mouse.h"
#include <debugio.h>
void HalInitialize()
{
// Initialize cpu
GdtInstall(); Log("%#[HAL] %#Installed GDT\n", ColorYellow, ColorLightGreen);
IdtInstall(); Log("%#[HAL] %#Installed IDT\n", ColorYellow, ColorLightGreen);
IsrsInstall(); Log("%#[HAL] %#Installed ISRs\n", ColorYellow, ColorLightGreen);
IrqInstall(); Log("%#[HAL] %#Installed IRQs\n", ColorYellow, ColorLightGreen);
// Start interrupts
asm volatile ("sti");
Log("%#[HAL] %#Interrupts are started...\n", ColorYellow, ColorLightMagenta);
// Install keyboard
IrqInstallHandler(0, TimeHandler);
IrqInstallHandler(1, KeyboardHandler);
IrqInstallHandler(12, MouseHandler);
KeyboardInstallA(); Log("%#[HAL] %#Installing keyboard... %#[1/2] ", ColorYellow, ColorLightGray, ColorLightGreen);
KeyboardInstallB(); Log("%#[2/2]\n", ColorLightGreen);
// Install mouse driver
MouseInstall(); Log("%#[HAL] %#Installed mouse driver\n", ColorYellow, ColorLightGreen);
}

6
Kernel/hal/hal.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __HAL__H
#define __HAL__H
extern void HalInitialize();
#endif

View File

@ -0,0 +1,327 @@
#include <stdio.h>
#include "keyboard.h"
#define KeybCmdWriteLED 0xed
#define KeybCmdEcho 0xee
#define KeybCmdSetScancodeSet 0xf0
#define KeybCmdGetID 0xf2
#define KeybCmdSetRepeatDelay 0xf3
#define KeybCmdEnable 0xf4
#define KeybCmdSetDefaultDisable 0xf5
#define KeybCmdSetDefault 0xf6
#define KeybCmdResend 0xfe
#define KeybCmdReset 0xff
volatile uint8 KeyState[16];
volatile uint8 KeyboardLastStatus;
volatile uint8 KeyboardLastScancode;
uint8 KeyboardScancodeSet = 2;
// Byte map:
// 0 If set, next code is break
// 1 'Gray' key
// 2 'Weird' key (Pause/Break)
// 3 Scroll
// 4 Num
// 5 Caps
// 6 If set, LEDs changed
uint8 KeyboardModifiers;
const char KeyboardMap[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
0, 0, '\'', 0, '[', '=', 0, 0, 0, 0, '\n', ']', 0, '\\', 0, 0,
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
};
const char KeyboardMapShift[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
0, 0, '\"', 0, '{', '+', 0, 0, 0, 0, '\n', '}', 0, '|', 0, 0,
0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
};
void KeyboardSetKeyStatus (uint8 scancode, uint8 status)
{
int32 index = scancode>>3, pos = scancode & 0x7;
if (status) KeyState[index] |= 1<<pos;
else KeyState[index] &= ~(1<<pos);
}
uint8 KeyboardGetKeyStatus (uint8 scancode)
{
int32 index = scancode>>3, pos = scancode & 0x7;
return KeyState[index] & (1<<pos);
}
void _process_scancode(uint8 scancode)
{
switch (scancode)
{
// Messages from keyboard controller
case 0x00: // Error 0x00
case 0xFC: // Diagnostics failed (MF kb)
case 0xFD: // Diagnostics failed (AT kb)
case 0xFF: KeyboardWaitOutport();
outportb(0x60, KeybCmdEnable);
return; // Error 0xFF, reenable keyboard
case 0xAA: // BAT test successful.
case 0xFA: // ACKnowledge
case 0xFE: // Last command invalid or parity error
case 0xEE: return; // Echo response
// Break
case 0xF0: KeyboardModifiers |= 1; return;
// Special character (gray, etc)
case 0xE0: KeyboardModifiers |= 2; return;
case 0xE1: KeyboardModifiers |= 4; return;
// Remap some characters:
case 0x83: scancode = KeyboardKeyF7; break;
// LEDs
case KeyboardKeyScrollLock:
if ((KeyboardModifiers & 1) == 0) {
KeyboardModifiers ^= 1<<3;
KeyboardModifiers |= 1<<6;
} break;
case KeyboardKeyNumLock:
if ((KeyboardModifiers & 1) == 0) {
KeyboardModifiers ^= 1<<4;
KeyboardModifiers |= 1<<6;
} break;
case KeyboardKeyCapsLock:
if ((KeyboardModifiers & 1) == 0) {
KeyboardModifiers ^= 1<<5;
KeyboardModifiers |= 1<<6;
} break;
}
// Remap most gray characters
if (KeyboardModifiers & 2) switch (scancode)
{
case 0x10: scancode = KeyboardKeyMediaWebSearch; break;
case 0x11: scancode = KeyboardKeyRightAlt; break;
case 0x12: return; // Fake shift, ignore
case 0x14: scancode = KeyboardKeyRightCtrl; break;
case 0x15: scancode = KeyboardKeyMediaPrevious; break;
case 0x18: scancode = KeyboardKeyMediaWebFavorites; break;
case 0x1F: scancode = KeyboardKeyLeftWin; break;
case 0x20: scancode = KeyboardKeyMediaWebRefresh; break;
case 0x21: scancode = KeyboardKeyMediaVolDown; break;
case 0x23: scancode = KeyboardKeyMediaMute; break;
case 0x27: scancode = KeyboardKeyRightWin; break;
case 0x28: scancode = KeyboardKeyMediaWebStop; break;
case 0x2B: scancode = KeyboardKeyMediaCalculator; break;
case 0x2F: scancode = KeyboardKeyMenu; break;
case 0x30: scancode = KeyboardKeyMediaWebForward; break;
case 0x32: scancode = KeyboardKeyMediaVolUp; break;
case 0x34: scancode = KeyboardKeyMediaPause; break;
case 0x37: scancode = KeyboardKeyPower; break;
case 0x38: scancode = KeyboardKeyMediaWebBack; break;
case 0x3A: scancode = KeyboardKeyMediaWebHome; break;
case 0x3B: scancode = KeyboardKeyMediaStop; break;
case 0x3F: scancode = KeyboardKeySleep; break;
case 0x40: scancode = KeyboardKeyMediaComputer; break;
case 0x48: scancode = KeyboardKeyMediaEmail; break;
case 0x4A: scancode = KeyboardKeyNumpadSlash; break;
case 0x4D: scancode = KeyboardKeyMediaNext; break;
case 0x50: scancode = KeyboardKeyMediaSelect; break;
case 0x5A: scancode = KeyboardKeyNumpadEnter; break;
case 0x5E: scancode = KeyboardKeyWake; break;
case 0x69: scancode = KeyboardKeyEnd; break;
case 0x6B: scancode = KeyboardKeyLeft; break;
case 0x6C: scancode = KeyboardKeyHome; break;
case 0x70: scancode = KeyboardKeyInsert; break;
case 0x71: scancode = KeyboardKeyDelete; break;
case 0x72: scancode = KeyboardKeyDown; break;
case 0x74: scancode = KeyboardKeyRight; break;
case 0x75: scancode = KeyboardKeyUp; break;
case 0x7A: scancode = KeyboardKeyPageDown; break;
case 0x7C: scancode = KeyboardKeyPrintScreen; break;
case 0x7D: scancode = KeyboardKeyPageUp; break;
}
// Pause/break
if (KeyboardModifiers & 4)
{
KeyboardSetKeyStatus(KeyboardKeyPause, 1 - (KeyboardModifiers & 1));
if (scancode == 0x77) KeyboardModifiers = 0;
return;
}
KeyboardSetKeyStatus(scancode, 1 - (KeyboardModifiers & 1));
// Give functions something to wait for :P
KeyboardLastScancode = scancode;
KeyboardLastStatus = KeyboardModifiers;
KeyboardModifiers &= ~7;
}
void KeyboardHandler (_RegsStack32* UNUSED(r))
{
// Get scancode from keyboard
uint8 scancode = inportb(0x60);
// Process scancode
_process_scancode(scancode);
// LED update
if (KeyboardModifiers & (1<<6))
{
KeyboardSetLEDs(KeyboardModifiers & (1<<3), KeyboardModifiers & (1<<4), KeyboardModifiers & (1<<5));
KeyboardModifiers &= ~(1<<6);
}
}
void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps)
{
uint8 status = 0;
status |= (scroll > 0);
status |= (num > 0) << 1;
status |= (caps > 0) << 2;
KeyboardWaitOutport();
outportb (0x60, KeybCmdWriteLED);
KeyboardWaitOutport();
outportb (0x60, status);
}
/***************************************
* Set repeat rate/delay *
***************************************
Values for inter-character delay (bits 4-0)
(characters per second; default is 10.9)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
----+----+----+----+----+----+----+----+----
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
Values for delay:
(miliseconds; default is 500)
0 | 1 | 2 | 3
-----+-----+-----+-----
250 | 500 | 750 | 1000
***************************************/
void KeyboardSetRepeatRate(uint8 rate, uint8 delay)
{
if (rate>3 || delay>31) return;
uint8 out = rate<<5 | delay;
KeyboardWaitOutport();
outportb(0x60, KeybCmdSetRepeatDelay);
KeyboardWaitOutport();
outportb(0x60, out);
}
/***************************************
* Set scancode set *
***************************************
1 Set to scancode set 1
2 Set to scancode set 2
3 Set to scancode set 3
***************************************/
void KeyboardSetScancodeSet(uint8 set)
{
if (set>3 || set <= 0) return;
KeyboardWaitOutport();
outportb (0x60, KeybCmdSetScancodeSet);
KeyboardWaitOutport();
outportb (0x60, set);
KeyboardScancodeSet = set;
}
void KeyboardWaitOutport()
{
int fail_safe=200000;
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
}
void KeyboardWaitInport()
{
int fail_safe=200000;
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
}
void KeyboardInstallA()
{
KeyboardWaitOutport();
outportb(0x60, KeybCmdReset); // Reset kb
// Initialize variables
KeyboardLastStatus = 0;
KeyboardModifiers = 0;
int32 i;
for (i = 0; i < 16; i++)
KeyState[i] = 0;
}
void KeyboardInstallB()
{
// Wait for BAT test results
KeyboardWaitInport();
unsigned char temp;
do temp = inportb(0x60);
while (temp!=0xAA && temp!=0xFC);
// Error
if (temp == 0xFC) return;
// Set new repeat rate
KeyboardSetRepeatRate(1, 11);
// Set scancode set 2
KeyboardSetScancodeSet(2); // Set new scancode set
KeyboardWaitOutport();
outportb(0x64, 0x20); // Get "Command unsigned char"
do { temp = inportb(0x60);
} while (temp==0xFA || temp==0xAA);
temp &= ~(1<<6); // Unset bit6: disable conversion
KeyboardWaitOutport();
outportb(0x64, 0x60); // Function to write cmd unsigned char
KeyboardWaitOutport();
outportb(0x60, temp); // Send it
}

View File

@ -0,0 +1,52 @@
#ifndef __KEYBOARD__H
#define __KEYBOARD__H
#include <types.h>
extern const char KeyboardMap[0x80];
extern const char KeyboardMapShift[0x80];
extern volatile uint8 KeyboardLastStatus;
extern volatile uint8 KeyboardLastScancode;
extern void KeyboardSetKeyStatus (uint8 scancode, uint8 status);
extern uint8 KeyboardGetKeyStatus (uint8 scancode);
extern void KeyboardHandler (_RegsStack32 *r);
extern void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps);
/***************************************
* Set repeat rate/delay *
***************************************
Values for inter-character delay (bits 4-0)
(characters per second; default is 10.9)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
----+----+----+----+----+----+----+----+----
0 |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
8 |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
Values for delay:
(miliseconds; default is 500)
0 | 1 | 2 | 3
-----+-----+-----+-----
250 | 500 | 750 | 1000
***************************************/
extern void KeyboardSetRepeatRate(uint8 rate, uint8 delay);
/***************************************
* Set scancode set *
***************************************
1 Set to scancode set 1
2 Set to scancode set 2
3 Set to scancode set 3
***************************************/
extern void KeyboardSetScancodeSet(uint8 set);
extern void KeyboardWaitOutport();
extern void KeyboardWaitInport();
extern void KeyboardInstallA();
extern void KeyboardInstallB();
#endif

116
Kernel/hal/mouse/mouse.c Normal file
View File

@ -0,0 +1,116 @@
#include <stdio.h>
#include <debugio.h>
#include "mouse.h"
#include "../keyboard/keyboard.h"
uint8 MouseCycle = 0;
uint8 MouseCycleExpected = 3;
uint8 Packets[4];
Point MousePosition = {0,0};
Point MouseMinimumPosition = {0,0}, MouseMaximumPosition = {80, 25};
Point Prev = {0,0};
#define SpeedLimit 0x8
// IRQ12
void MouseHandler (_RegsStack32* UNUSED(r))
{
uint8 data = inportb(0x60);
Point delta;
if (MouseCycle == 0 && (data == 0 || data == 0xFA || data == 0xFF || data == 0xAA)) return;
Packets[MouseCycle++] = data;
// Cycle ended
if (MouseCycle >= MouseCycleExpected)
{
MouseCycle = 0;
if (Packets[0] & 0xC0) return; // Discard packet
// Update X position
if (Packets[0] & 0x10) delta.X = (int32) (Packets[1] | 0xFFFFFF00);
else delta.X = (int32) Packets[1];
// Update Y position
if (Packets[0] & 0x20) delta.Y = -1 * (int32) (Packets[2] | 0xFFFFFF00);
else delta.Y = -1 * (int32)Packets[2];
if (delta.X >= SpeedLimit) delta.X = SpeedLimit;
if (delta.X <= -SpeedLimit) delta.X = -SpeedLimit;
if (delta.Y >= SpeedLimit) delta.Y = SpeedLimit;
if (delta.Y <= -SpeedLimit) delta.Y = -SpeedLimit;
MousePosition.X += delta.X;
MousePosition.Y += delta.Y;
// Check limits
if (MousePosition.X < MouseMinimumPosition.X) MousePosition.X = MouseMinimumPosition.X;
if (MousePosition.Y < MouseMinimumPosition.Y) MousePosition.Y = MouseMinimumPosition.Y;
if (MousePosition.X >= MouseMaximumPosition.X) MousePosition.X = MouseMaximumPosition.X - 1;
if (MousePosition.Y >= MouseMaximumPosition.Y) MousePosition.Y = MouseMaximumPosition.Y - 1;
/* TESTING ONLY */
ConsoleSetColor(Prev, 0xFF - ConsoleGetColor(Prev));
ConsoleSetColor(MousePosition, 0xFF - ConsoleGetColor(MousePosition));
Prev = MousePosition;
}
}
void MouseSendCommand(uint8 command)
{
KeyboardWaitOutport();
outportb(0x64, 0xD4);
KeyboardWaitOutport();
outportb(0x60, command);
}
uint8 MouseReadData ()
{
KeyboardWaitInport();
return inportb(0x60);
}
void MouseInstall()
{
KeyboardWaitOutport();
outportb(0x64, 0xA8);
// Enable interrupts
KeyboardWaitOutport();
outportb(0x64, 0x20);
KeyboardWaitInport();
uint8 temp = inportb(0x60) | 2;
temp &= ~0x20;
KeyboardWaitOutport();
outportb(0x64, 0x60);
KeyboardWaitOutport();
outportb(0x60, temp);
// Reset mouse, and enable it
MouseSendCommand(MouseCommandReset);
MouseReadData(); MouseReadData();
MouseSendCommand(MouseCommandSetDefaults);
MouseReadData(); // Read ack
MouseSendCommand(MouseCommandEnableDataReporting);
MouseReadData(); // Read ack
}
void MouseSetLimits (Point min_pos, Point max_pos)
{
MouseMinimumPosition = min_pos;
MouseMaximumPosition = max_pos;
}
MouseState MouseGetState()
{
MouseState ret = { Packets[0] & 0x7, MousePosition};
return ret;
}

36
Kernel/hal/mouse/mouse.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef __MOUSE__H
#define __MOUSE__H
#include <types.h>
typedef struct
{
uint8 Buttons;
Point Position;
} MouseState;
enum MouseCommands
{
MouseCommandReset = 0xFF,
MouseCommandResend = 0xFE,
MouseCommandSetDefaults = 0xF6,
MouseCommandDisableDataReporting = 0xF5,
MouseCommandEnableDataReporting = 0xF4,
MouseCommandSetSampleRate = 0xF3,
MouseCommandGetDeviceID = 0xF2,
MouseCommandSetRemoteMode = 0xF0,
MouseCommandSetWrapMode = 0xEE,
MouseCommandReadData = 0xEB,
MouseCommandSetStreamMode = 0xEA,
MouseCommandStatusRequest = 0xE9,
MouseCommandSetResolution = 0xE8,
MouseCommandSetScaling_2_1 = 0xE7,
MouseCommandSetScaling_1_1 = 0xE6
};
extern void MouseInstall();
extern void MouseHandler (_RegsStack32 *r);
extern void MouseSetLimits (Point min_pos, Point max_pos);
extern MouseState MouseGetState();
#endif

27
Kernel/hal/sysinfo.c Normal file
View File

@ -0,0 +1,27 @@
/*
* sysinfo.c
*
* Provides information about system, and useful utilities
*
* Created on: Aug 17, 2011
* Author: Tiberiu
*/
#include <stdio.h>
#include <multiboot.h>
#include <debugio.h>
#include <memory.h>
#include <../drivers/cmos/cmos.h>
#include "keyboard/keyboard.h"
void SystemReboot()
{
Log("Rebooting system...\n");
KeyboardWaitOutport();
outportb (0x64, 0xFE);
asm("cli");
asm("hlt");
}

40
Kernel/hal/vfs.c Normal file
View File

@ -0,0 +1,40 @@
#include<fileio.h>
#include<storage.h>
#define MAX_FS_COUNT 64
uint32 FsRead(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
{
if (node->Read != NULL) return node->Read(node, offset, size, buffer);
return NULL;
}
uint32 FsWrite(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
{
if (node->Write != NULL) return node->Write(node, offset, size, buffer);
return NULL;
}
void FsOpen(FsNode *node, uint8 read, uint8 write)
{
if (node->Open != NULL) return node->Open(node, read, write);
}
void FsClose(FsNode *node)
{
if (node->Close != NULL) return node->Close();
}
DirectoryEntry *FsReadDir(FsNode *node, uint32 index)
{
if (node->ReadDir != NULL && (node->Flags&7) == FsDirectory)
return node->ReadDir(node, index);
return NULL;
}
FsNode *FsFindDir(FsNode *node, char *name)
{
if (node->FindDir != NULL && (node->Flags&7) == FsDirectory)
return node->FindDir(node, name);
return NULL;
}