Change: build process & makefile, tree restructuration
This commit is contained in:
48
src/gdt.c
Normal file
48
src/gdt.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "gdt.h"
|
||||
|
||||
struct gdt_entry
|
||||
{
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
unsigned char base_middle;
|
||||
unsigned char access;
|
||||
unsigned char granularity;
|
||||
unsigned char base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_entry gdt[3];
|
||||
struct gdt_ptr gp;
|
||||
|
||||
extern void gdt_flush();
|
||||
|
||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
|
||||
{
|
||||
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 >> 16) & 0x0F);
|
||||
|
||||
gdt[num].granularity |= (gran & 0xF0);
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
void gdt_install()
|
||||
{
|
||||
gp.limit = (sizeof(struct gdt_entry)*3) - 1;
|
||||
gp.base = (unsigned int)&gdt;
|
||||
|
||||
gdt_set_gate(0, 0, 0, 0, 0);
|
||||
|
||||
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
gdt_flush();
|
||||
}
|
||||
8
src/gdt.h
Normal file
8
src/gdt.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef GDT_H
|
||||
#define GDT_H
|
||||
|
||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
|
||||
void gdt_install();
|
||||
|
||||
#endif
|
||||
42
src/idt.c
Normal file
42
src/idt.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "idt.h"
|
||||
#include "system.h"
|
||||
|
||||
struct idt_entry
|
||||
{
|
||||
unsigned short base_lo;
|
||||
unsigned short sel;
|
||||
unsigned char always0;
|
||||
unsigned char flags;
|
||||
unsigned short base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_ptr
|
||||
{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idt_entry idt[256];
|
||||
struct idt_ptr idtp;
|
||||
|
||||
extern void idt_load();
|
||||
|
||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
|
||||
{
|
||||
idt[num].base_lo = (base & 0xFFFF);
|
||||
idt[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
idt[num].sel = sel;
|
||||
idt[num].always0 = 0;
|
||||
idt[num].flags = flags;
|
||||
}
|
||||
|
||||
void idt_install()
|
||||
{
|
||||
idtp.limit = (sizeof (struct idt_entry)*256) - 1;
|
||||
idtp.base = (unsigned int)&idt;
|
||||
|
||||
memset(&idt, 0, sizeof(struct idt_entry)*256);
|
||||
|
||||
idt_load();
|
||||
}
|
||||
8
src/idt.h
Normal file
8
src/idt.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
|
||||
void idt_install();
|
||||
|
||||
#endif
|
||||
10
src/io.h
Normal file
10
src/io.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef INCLUDE_IO_H
|
||||
#define INCLUDE_IO_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
void outb(unsigned short port, unsigned char data);
|
||||
unsigned char inb(unsigned short port);
|
||||
void x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotientOut, uint32_t* remainderOut);
|
||||
|
||||
#endif
|
||||
44
src/io.s
Normal file
44
src/io.s
Normal file
@@ -0,0 +1,44 @@
|
||||
global outb
|
||||
|
||||
outb:
|
||||
mov al, [esp + 8]
|
||||
mov dx, [esp + 4]
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
global inb
|
||||
|
||||
inb:
|
||||
mov dx, [esp + 4]
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
global x86_div64_32
|
||||
|
||||
x86_div64_32:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
; Arguments:
|
||||
; [ebp + 8] - lower 32 bits of dividend (uint32_t)
|
||||
; [ebp + 12] - upper 32 bits of dividend (uint32_t)
|
||||
; [ebp + 16] - divisor (uint32_t)
|
||||
; [ebp + 20] - pointer to quotient (uint64_t*)
|
||||
; [ebp + 24] - pointer to remainder (uint32_t*)
|
||||
|
||||
mov eax, [ebp + 8]
|
||||
mov edx, [ebp + 12]
|
||||
|
||||
mov ecx, [ebp + 16]
|
||||
|
||||
div ecx
|
||||
mov esi, [ebp + 20]
|
||||
mov [esi], eax
|
||||
|
||||
mov dword [esi + 4], 0
|
||||
|
||||
mov esi, [ebp + 24]
|
||||
mov [esi], edx
|
||||
|
||||
pop ebp
|
||||
ret
|
||||
90
src/irq.c
Normal file
90
src/irq.c
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "system.h"
|
||||
#include "io.h"
|
||||
#include "idt.h"
|
||||
|
||||
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();
|
||||
|
||||
void *irq_routines[16] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void irq_install_handler(int irq, void (*handler)(struct regs *r))
|
||||
{
|
||||
irq_routines[irq] = handler;
|
||||
}
|
||||
|
||||
void irq_uninstall_handler(int irq)
|
||||
{
|
||||
irq_routines[irq] = 0;
|
||||
}
|
||||
|
||||
void irq_remap(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 irq_install()
|
||||
{
|
||||
irq_remap();
|
||||
|
||||
idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
|
||||
idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
|
||||
idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
|
||||
idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
|
||||
idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
|
||||
idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
|
||||
idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
|
||||
idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);
|
||||
idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
|
||||
idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
|
||||
idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
|
||||
idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
|
||||
idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
|
||||
idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
|
||||
idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
|
||||
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
void irq_handler(struct regs *r)
|
||||
{
|
||||
void (*handler)(struct regs *r);
|
||||
|
||||
handler = irq_routines[r->int_no-32];
|
||||
if (handler)
|
||||
{
|
||||
handler(r);
|
||||
}
|
||||
|
||||
if (r->int_no >= 40)
|
||||
{
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
118
src/isr.c
Normal file
118
src/isr.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "system.h"
|
||||
#include "stdio.h"
|
||||
#include "idt.h"
|
||||
|
||||
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();
|
||||
|
||||
void isr_install()
|
||||
{
|
||||
|
||||
idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
|
||||
idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
|
||||
idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
|
||||
idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
|
||||
idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
|
||||
idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
|
||||
idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
|
||||
idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
|
||||
idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
|
||||
idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
|
||||
idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
|
||||
idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
|
||||
idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
|
||||
idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
|
||||
idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
|
||||
idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
|
||||
idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
|
||||
idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
|
||||
idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
|
||||
idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
|
||||
idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
|
||||
idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E);
|
||||
idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E);
|
||||
idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E);
|
||||
idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E);
|
||||
idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E);
|
||||
idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E);
|
||||
idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E);
|
||||
idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E);
|
||||
idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
|
||||
idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
|
||||
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
char *exception_messages[] =
|
||||
{
|
||||
"Division by Zero",
|
||||
"Debug",
|
||||
"Non Maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Into Detected Overflow",
|
||||
"Out of Bounds",
|
||||
"Invalid Opcode",
|
||||
"No Coprocessor",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Bad TSS",
|
||||
"Segment Not Present",
|
||||
"Stack Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"Unknown Interrupt",
|
||||
"Coprocessor Fault",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved"
|
||||
};
|
||||
|
||||
void fault_handler(struct regs *r)
|
||||
{
|
||||
if (r->int_no < 32)
|
||||
{
|
||||
printf("\n\n*** [Kernel panic - %s Exception] ***\nInterrupt error code %u\nedi: %x esi: %u ebp: %u esp: %u\nebx: %u edx: %u ecx: %u eax: %u\neip: %x cs:%x eflags: %x ss: %x\ngs: %x fs: %x es: %x ds: %x\nHalting!\n", exception_messages[r->int_no], r->err_code, r->edi, r->esi, r->ebp, r->esp, r->ebx, r->edx, r->ecx, r->eax, r->eip, r->cs, r->eflags, r->ss, r->gs, r->fs, r->es, r->ds);
|
||||
for (;;);
|
||||
}
|
||||
}
|
||||
|
||||
63
src/kb.c
Normal file
63
src/kb.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "io.h"
|
||||
#include "stdio.h"
|
||||
#include "system.h"
|
||||
|
||||
unsigned char kbdus[128] =
|
||||
{
|
||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
|
||||
'9', '0', '-', '=', '\b', /* Backspace */
|
||||
'\t', /* Tab */
|
||||
'q', 'w', 'e', 'r', /* 19 */
|
||||
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
|
||||
0, /* 29 - Control */
|
||||
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
|
||||
'\'', '`', 0, /* Left shift */
|
||||
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
|
||||
'm', ',', '.', '/', 0, /* Right shift */
|
||||
'*',
|
||||
0, /* Alt */
|
||||
' ', /* Space bar */
|
||||
0, /* Caps lock */
|
||||
0, /* 59 - F1 key ... > */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, /* < ... F10 */
|
||||
0, /* 69 - Num lock*/
|
||||
0, /* Scroll Lock */
|
||||
0, /* Home key */
|
||||
0, /* Up Arrow */
|
||||
0, /* Page Up */
|
||||
'-',
|
||||
0, /* Left Arrow */
|
||||
0,
|
||||
0, /* Right Arrow */
|
||||
'+',
|
||||
0, /* 79 - End key*/
|
||||
0, /* Down Arrow */
|
||||
0, /* Page Down */
|
||||
0, /* Insert Key */
|
||||
0, /* Delete Key */
|
||||
0, 0, 0,
|
||||
0, /* F11 Key */
|
||||
0, /* F12 Key */
|
||||
0, /* All other keys are undefined */
|
||||
};
|
||||
|
||||
void keyboard_handler()
|
||||
{
|
||||
unsigned char scancode;
|
||||
|
||||
scancode = inb(0x60);
|
||||
|
||||
if (scancode & 0x80)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
putc(kbdus[scancode]);
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_install()
|
||||
{
|
||||
irq_install_handler(1, keyboard_handler);
|
||||
}
|
||||
37
src/kmain.c
Normal file
37
src/kmain.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "stdio.h"
|
||||
#include "serial.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "system.h"
|
||||
|
||||
int kmain(int retvalue)
|
||||
{
|
||||
|
||||
init_serial();
|
||||
log("serial connection established", 3);
|
||||
gdt_install();
|
||||
log("initialized GDT entries", 2);
|
||||
idt_install();
|
||||
log("initialized IDT", 2);
|
||||
isr_install();
|
||||
log("initialized ISRs", 2);
|
||||
irq_install();
|
||||
__asm__ __volatile__("sti");
|
||||
log("initialized IRQs", 2),
|
||||
|
||||
log("kernel started", 2);
|
||||
|
||||
clear();
|
||||
|
||||
colorputs("Blank OS version 1 iteration 3 minor 20\n", 10);
|
||||
|
||||
// TODO: Serial printf to dump registers on kernel panic
|
||||
// TODO: Fix scrolling bug (framebuffer driver)
|
||||
// TODO: Fix keyboard driver bug (some keys mapped weirdly) + add suport for SHIFT and backspace (deleting character)
|
||||
// TODO: Grub modules to load programs
|
||||
// TODO: Folder and build process restructuration
|
||||
|
||||
//timer_install();
|
||||
keyboard_install();
|
||||
return retvalue;
|
||||
}
|
||||
440
src/loader.s
Normal file
440
src/loader.s
Normal file
@@ -0,0 +1,440 @@
|
||||
global loader
|
||||
|
||||
section .__mbHeader
|
||||
|
||||
align 0x4
|
||||
section .text:
|
||||
|
||||
MAGIC_NUMBER equ 0x1BADB002 ; multiboot magic
|
||||
FLAGS equ 0x0
|
||||
CHECKSUM equ -MAGIC_NUMBER
|
||||
KERNEL_STACK_SIZE equ 4096
|
||||
|
||||
dd MAGIC_NUMBER
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
extern kmain
|
||||
|
||||
loader:
|
||||
cli
|
||||
; mov eax, 0xCAFEBABE
|
||||
push dword 42
|
||||
call kmain
|
||||
|
||||
.loop:
|
||||
jmp .loop
|
||||
|
||||
global gdt_flush
|
||||
extern gp
|
||||
|
||||
gdt_flush:
|
||||
lgdt [gp]
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
jmp 0x08:flush2
|
||||
|
||||
flush2:
|
||||
ret
|
||||
|
||||
global idt_load
|
||||
extern idtp
|
||||
|
||||
idt_load:
|
||||
lidt [idtp]
|
||||
ret
|
||||
|
||||
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
|
||||
|
||||
; Interrupt service routine exceptions
|
||||
isr0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 0
|
||||
jmp isr_common_stub
|
||||
|
||||
isr1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
jmp isr_common_stub
|
||||
|
||||
isr2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
|
||||
isr3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
|
||||
isr4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
|
||||
isr5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
|
||||
isr6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
|
||||
isr7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
|
||||
isr8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
|
||||
isr9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
|
||||
isr10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
|
||||
isr11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
|
||||
isr12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
|
||||
isr13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
|
||||
isr14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
|
||||
isr15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
|
||||
isr16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
|
||||
isr17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
|
||||
isr18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
|
||||
isr19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
|
||||
isr20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
|
||||
isr21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
|
||||
isr22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
|
||||
isr23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
|
||||
isr24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
|
||||
isr25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
|
||||
isr26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
|
||||
isr27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
|
||||
isr28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
|
||||
isr29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
|
||||
isr30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
|
||||
isr31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern fault_handler
|
||||
|
||||
isr_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, fault_handler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
|
||||
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
|
||||
|
||||
irq0:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 32
|
||||
jmp irq_common_stub
|
||||
|
||||
irq1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
irq2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
irq3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
irq4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
irq5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
irq6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
irq7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
irq8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
|
||||
irq9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
irq10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
irq11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
irq12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
irq13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
irq14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
irq15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern irq_handler
|
||||
|
||||
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, irq_handler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
|
||||
section .bss
|
||||
align 4
|
||||
kernel_stack:
|
||||
resb KERNEL_STACK_SIZE
|
||||
mov esp, kernel_stack + KERNEL_STACK_SIZE
|
||||
65
src/serial.c
Normal file
65
src/serial.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "io.h"
|
||||
#include "serial.h"
|
||||
|
||||
int init_serial()
|
||||
{
|
||||
outb(PORT+1, 0x00);
|
||||
outb(PORT+3, 0x80);
|
||||
outb(PORT+0, 0x03);
|
||||
outb(PORT+1, 0x00);
|
||||
|
||||
outb(PORT+3, 0x03);
|
||||
outb(PORT+2, 0xC7);
|
||||
outb(PORT+4, 0x0B);
|
||||
outb(PORT+4, 0x1E);
|
||||
outb(PORT+0, 0xAE);
|
||||
|
||||
if (inb(PORT+0) != 0xAE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
outb(PORT+4, 0x0F);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_transmit_empty()
|
||||
{
|
||||
return inb(PORT+5) & 0x20;
|
||||
}
|
||||
|
||||
void write_serial(const char a)
|
||||
{
|
||||
while (is_transmit_empty() == 0);
|
||||
outb(PORT, a);
|
||||
}
|
||||
|
||||
void serial_puts(const char* str)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
write_serial(str[0]); // Transmit first byte 2 times
|
||||
while (*str++)
|
||||
{
|
||||
write_serial(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void log(const char* str, const int errlevel)
|
||||
{
|
||||
switch (errlevel)
|
||||
{
|
||||
case 0:
|
||||
serial_puts("[ERROR] ");
|
||||
break;
|
||||
case 1:
|
||||
serial_puts("[WARNING] ");
|
||||
break;
|
||||
case 2:
|
||||
serial_puts("[INFO] ");
|
||||
break;
|
||||
case 3:
|
||||
serial_puts("[DEBUG] ");
|
||||
break;
|
||||
}
|
||||
serial_puts(str);
|
||||
serial_puts("\n");
|
||||
}
|
||||
12
src/serial.h
Normal file
12
src/serial.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef INCLUDE_SERIAL_H
|
||||
#define INCLUDE_SERIAL_H
|
||||
|
||||
#define PORT 0x3f8 //COM1
|
||||
|
||||
int init_serial();
|
||||
int is_transmit_empty();
|
||||
void write_serial(const char a);
|
||||
void serial_puts(const char* str);
|
||||
void log(const char* str, const int errlevel);
|
||||
|
||||
#endif
|
||||
20
src/stdint.h
Normal file
20
src/stdint.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef INCLUDE_STDINT_H
|
||||
#define INCLUDE_STDINT_H
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef signed long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
|
||||
typedef signed long long int int64_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
|
||||
typedef uint8_t bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif
|
||||
337
src/stdio.c
Normal file
337
src/stdio.c
Normal file
@@ -0,0 +1,337 @@
|
||||
#include "io.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "stdint.h"
|
||||
|
||||
char* fb = (char *) 0x000B8000;
|
||||
const unsigned VGA_WIDTH = 80;
|
||||
const unsigned VGA_HEIGHT = 25;
|
||||
const unsigned int COLOR = 0x7;
|
||||
unsigned int VGA_X = 0, VGA_Y = 0;
|
||||
|
||||
void move_cursor(int x, int y)
|
||||
{
|
||||
unsigned short pos = y*VGA_WIDTH+x;
|
||||
|
||||
outb(FB_CMD_PORT, FB_HIGH_BYTE_CMD);
|
||||
outb(FB_DATA_PORT, ((pos >> 8) & 0x00FF));
|
||||
outb(FB_CMD_PORT, FB_LOW_BYTE_CMD);
|
||||
outb(FB_DATA_PORT, pos & 0x00FF);
|
||||
}
|
||||
|
||||
void putchar(int x, int y, char c)
|
||||
{
|
||||
fb[2*(y*VGA_WIDTH+x)] = c;
|
||||
}
|
||||
|
||||
void putcolor(int x, int y, unsigned int color)
|
||||
{
|
||||
fb[2*(y*VGA_WIDTH+x)+1] = color;
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
for (unsigned int y=0; y<VGA_HEIGHT; y++)
|
||||
{
|
||||
for (unsigned int x=0; x<VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y, '\0');
|
||||
putcolor(x, y, COLOR);
|
||||
}
|
||||
}
|
||||
VGA_X = 0;
|
||||
VGA_Y = 0;
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
char getchar(int x, int y)
|
||||
{
|
||||
return fb[2*(y*VGA_WIDTH+x)];
|
||||
}
|
||||
|
||||
unsigned int getcolor(int x, int y)
|
||||
{
|
||||
return fb[2*(y*VGA_WIDTH+x)+1];
|
||||
}
|
||||
|
||||
void scroll(int lines)
|
||||
{
|
||||
for (unsigned int y = lines; y < VGA_HEIGHT; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y-lines, getchar(x, y));
|
||||
putcolor(x, y-lines, getcolor(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int y = VGA_HEIGHT-lines; y<VGA_HEIGHT; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < VGA_WIDTH; x++)
|
||||
{
|
||||
putchar(x, y, '\0');
|
||||
putcolor(x, y, COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void putc(char c)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
VGA_X = 0;
|
||||
VGA_Y++;
|
||||
break;
|
||||
case '\r':
|
||||
VGA_X = 0;
|
||||
break;
|
||||
default:
|
||||
putchar(VGA_X, VGA_Y, c);
|
||||
VGA_X++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (VGA_X >= VGA_WIDTH)
|
||||
{
|
||||
VGA_Y++;
|
||||
VGA_X = 0;
|
||||
}
|
||||
if (VGA_Y >= VGA_HEIGHT) scroll(1);
|
||||
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
void colorputc(char c, unsigned int color)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
VGA_X = 0;
|
||||
VGA_Y++;
|
||||
break;
|
||||
case '\r':
|
||||
VGA_X = 0;
|
||||
break;
|
||||
default:
|
||||
putchar(VGA_X, VGA_Y, c);
|
||||
putcolor(VGA_X, VGA_Y, color);
|
||||
VGA_X++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (VGA_X >= VGA_WIDTH)
|
||||
{
|
||||
VGA_Y++;
|
||||
VGA_X = 0;
|
||||
}
|
||||
if (VGA_Y >= VGA_HEIGHT) scroll(1);
|
||||
move_cursor(VGA_X, VGA_Y);
|
||||
}
|
||||
|
||||
void puts(const char* str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
putc(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void colorputs(const char* str, unsigned int color)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
colorputc(*str, color);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void printf(const char* fmt, ...)
|
||||
{
|
||||
int* argp = (int*) &fmt;
|
||||
int state = PRINTF_STATE_START;
|
||||
int length = PRINTF_LENGTH_START;
|
||||
int radix = 10;
|
||||
bool sign = false;
|
||||
|
||||
argp++;
|
||||
while (*fmt)
|
||||
{
|
||||
switch(state) {
|
||||
case PRINTF_STATE_START:
|
||||
if (*fmt == '%')
|
||||
{
|
||||
state = PRINTF_STATE_LENGTH;
|
||||
}
|
||||
else {
|
||||
putc(*fmt);
|
||||
}
|
||||
break;
|
||||
case PRINTF_STATE_LENGTH:
|
||||
if (*fmt == 'h')
|
||||
{
|
||||
length = PRINTF_LENGTH_SHORT;
|
||||
state = PRINTF_STATE_SHORT;
|
||||
}
|
||||
else if (*fmt == 'l')
|
||||
{
|
||||
length = PRINTF_LENGTH_LONG;
|
||||
state = PRINTF_STATE_LONG;
|
||||
}
|
||||
else {
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
case PRINTF_STATE_SHORT:
|
||||
if (*fmt == 'h')
|
||||
{
|
||||
length = PRINTF_LENGTH_SHORT_SHORT;
|
||||
state = PRINTF_STATE_SPEC;
|
||||
}
|
||||
else {
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
case PRINTF_STATE_LONG:
|
||||
if (*fmt == 'l')
|
||||
{
|
||||
length = PRINTF_LENGTH_LONG_LONG;
|
||||
state = PRINTF_STATE_SPEC;
|
||||
}
|
||||
else {
|
||||
goto PRINTF_STATE_SPEC_;
|
||||
}
|
||||
break;
|
||||
case PRINTF_STATE_SPEC:
|
||||
PRINTF_STATE_SPEC_:
|
||||
switch(*fmt)
|
||||
{
|
||||
case 'c':
|
||||
putc((char)*argp);
|
||||
argp++;
|
||||
break;
|
||||
case 's':
|
||||
puts(*(const char **)argp);
|
||||
argp++;
|
||||
break;
|
||||
case '%':
|
||||
putc('%');
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
radix = 10;
|
||||
sign = true;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
break;
|
||||
case 'u':
|
||||
radix = 10;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
case 'p':
|
||||
radix = 16;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
break;
|
||||
case 'o':
|
||||
radix = 8;
|
||||
sign = false;
|
||||
argp = printf_number(argp, length, sign, radix);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = PRINTF_STATE_START;
|
||||
length = PRINTF_LENGTH_START;
|
||||
radix = 10;
|
||||
sign = false;
|
||||
break;
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
}
|
||||
|
||||
const char charset[] = "0123456789abcdef";
|
||||
|
||||
int* printf_number(int* argp, int length, bool sign, int radix)
|
||||
{
|
||||
char buffer[32];
|
||||
unsigned long long number;
|
||||
int number_sign = 1;
|
||||
int pos = 0;
|
||||
|
||||
switch(length)
|
||||
{
|
||||
case PRINTF_LENGTH_SHORT_SHORT:
|
||||
case PRINTF_LENGTH_SHORT:
|
||||
case PRINTF_LENGTH_START:
|
||||
if (sign)
|
||||
{
|
||||
int n = *argp;
|
||||
if (n < 0)
|
||||
{
|
||||
n = -n;
|
||||
number_sign = -1;
|
||||
}
|
||||
number = (unsigned long long) n;
|
||||
}
|
||||
else {
|
||||
number = *(unsigned int*) argp;
|
||||
}
|
||||
argp++;
|
||||
break;
|
||||
case PRINTF_LENGTH_LONG:
|
||||
if (sign)
|
||||
{
|
||||
long int n = *(long int*)argp;
|
||||
if (n < 0)
|
||||
{
|
||||
n = -n;
|
||||
number_sign = -1;
|
||||
}
|
||||
number = (unsigned long long) n;
|
||||
}
|
||||
else {
|
||||
number = *(unsigned long int*) argp;
|
||||
}
|
||||
argp += 2;
|
||||
break;
|
||||
case PRINTF_LENGTH_LONG_LONG:
|
||||
if (sign)
|
||||
{
|
||||
long long int n = *(long long int*)argp;
|
||||
if (n < 0)
|
||||
{
|
||||
n = -n;
|
||||
number_sign = -1;
|
||||
}
|
||||
number = (unsigned long long) n;
|
||||
}
|
||||
else {
|
||||
number = *(unsigned long long int*) argp;
|
||||
}
|
||||
argp += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
uint32_t rem;
|
||||
x86_div64_32(number, radix, &number, &rem);
|
||||
buffer[pos++] = charset[rem];
|
||||
} while (number > 0);
|
||||
|
||||
if (sign && number_sign < 0)
|
||||
{
|
||||
buffer[pos++] = '-';
|
||||
}
|
||||
|
||||
while (--pos >= 0)
|
||||
{
|
||||
putc(buffer[pos]);
|
||||
}
|
||||
|
||||
return argp;
|
||||
}
|
||||
41
src/stdio.h
Normal file
41
src/stdio.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef INCLUDE_STDIO_H
|
||||
#define INCLUDE_STDIO_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define FB_GREEN 2
|
||||
#define FB_DARK_GREY 8
|
||||
|
||||
#define FB_CMD_PORT 0x3D4
|
||||
#define FB_DATA_PORT 0x3D5
|
||||
#define FB_HIGH_BYTE_CMD 14
|
||||
#define FB_LOW_BYTE_CMD 15
|
||||
|
||||
void move_cursor(int x, int y);
|
||||
void putchar(int x, int y, char c);
|
||||
void puts(const char* str);
|
||||
void colorputs(const char* str, unsigned int color);
|
||||
void clear(void);
|
||||
void putcolor(int x, int y, unsigned int color);
|
||||
char getchar(int x, int y);
|
||||
unsigned int getcolor(int x, int y);
|
||||
void scroll(int lines);
|
||||
void putc(char c);
|
||||
void colorputc(char c, unsigned int color);
|
||||
|
||||
#define PRINTF_STATE_START 0
|
||||
#define PRINTF_STATE_LENGTH 1
|
||||
#define PRINTF_STATE_SHORT 2
|
||||
#define PRINTF_STATE_LONG 3
|
||||
#define PRINTF_STATE_SPEC 4
|
||||
|
||||
#define PRINTF_LENGTH_START 0
|
||||
#define PRINTF_LENGTH_SHORT_SHORT 1
|
||||
#define PRINTF_LENGTH_SHORT 2
|
||||
#define PRINTF_LENGTH_LONG 3
|
||||
#define PRINTF_LENGTH_LONG_LONG 4
|
||||
|
||||
void printf(const char* fmt, ...);
|
||||
int* printf_number(int* argp, int length, bool sign, int radix);
|
||||
|
||||
#endif
|
||||
9
src/string.c
Normal file
9
src/string.c
Normal file
@@ -0,0 +1,9 @@
|
||||
int strlen(char* str)
|
||||
{
|
||||
int len = 0;
|
||||
while (*str++)
|
||||
{
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
6
src/string.h
Normal file
6
src/string.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef INCLUDE_STRING_H
|
||||
#define INCLUDE_STRING_H
|
||||
|
||||
int strlen(char* str);
|
||||
|
||||
#endif
|
||||
8
src/system.c
Normal file
8
src/system.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "system.h"
|
||||
|
||||
void *memset(void *dest, char val, size_t count)
|
||||
{
|
||||
char *temp = (char *)dest;
|
||||
for(; count != 0; count--) *temp++ = val;
|
||||
return dest;
|
||||
}
|
||||
24
src/system.h
Normal file
24
src/system.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
typedef int size_t;
|
||||
|
||||
void *memset(void *dest, char val, size_t count);
|
||||
|
||||
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 isr_install();
|
||||
void irq_install();
|
||||
void irq_install_handler(int irq, void (*handler)(struct regs *r));
|
||||
void irq_uninstall_handler(int irq);
|
||||
void timer_install();
|
||||
void delay(int ticks);
|
||||
void keyboard_install();
|
||||
#endif
|
||||
|
||||
26
src/timer.c
Normal file
26
src/timer.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "system.h"
|
||||
#include "stdio.h"
|
||||
|
||||
int timer_ticks = 0;
|
||||
|
||||
void timer_handler()
|
||||
{
|
||||
timer_ticks++;
|
||||
|
||||
if(timer_ticks % 18 == 0)
|
||||
{
|
||||
puts("One second has passed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void timer_install()
|
||||
{
|
||||
irq_install_handler(0, timer_handler);
|
||||
}
|
||||
|
||||
void delay(int ticks)
|
||||
{
|
||||
unsigned long eticks;
|
||||
eticks = timer_ticks + ticks;
|
||||
while ((unsigned long)timer_ticks < eticks);
|
||||
}
|
||||
Reference in New Issue
Block a user