summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-06-19 05:22:54 +1000
committerJake Mannens <jake72360@gmail.com>2018-06-19 05:22:54 +1000
commitf6858b7333139441215e83e070e098bf09056762 (patch)
tree65b7ad0680174bc5331a5db8505be4213e6cc736 /kernel
parent627d2d0c0ee5147f53fdba8fc1f9108f8edeb8f3 (diff)
Added foundation code to initialize the PIT and create a 10ms jiffies
counter.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/boot.s34
-rw-r--r--kernel/con.c10
-rw-r--r--kernel/kmain.c22
-rw-r--r--kernel/timer.s34
4 files changed, 90 insertions, 10 deletions
diff --git a/kernel/boot.s b/kernel/boot.s
index be68109..e41c0b2 100644
--- a/kernel/boot.s
+++ b/kernel/boot.s
@@ -1,5 +1,7 @@
global kboot
+global register_isr
extern kmain
+extern timer_init
; Multiboot header
section .mboothdr
@@ -15,6 +17,7 @@ kboot:
cli
call flush_gdt
call flush_idt
+ call timer_init
call kmain
cli
hlt
@@ -80,13 +83,22 @@ idtp:
int_handler:
iret
+irq_handler:
+ iret
+
flush_idt:
push ebp
mov ebp, esp
- mov ecx, 256
+ mov ecx, 0
mov edx, idt
.loop:
mov eax, int_handler
+ cmp ecx, 0x20
+ jl .skip
+ cmp ecx, 0x2f
+ jg .skip
+ mov eax, irq_handler
+.skip:
mov [edx], ax
mov word [edx+2], 0x08
mov byte [edx+4], 0
@@ -94,8 +106,9 @@ flush_idt:
shr eax, 16
mov [edx+6], ax
add edx, 8
- dec ecx
- jz .end
+ inc ecx
+ cmp ecx, 256
+ je .end
jmp .loop
.end:
lidt [idtp]
@@ -104,6 +117,21 @@ flush_idt:
pop ebp
ret
+; void register_isr(uint8_t n, void *handler);
+register_isr:
+ push ebp
+ mov ebp, esp
+ mov edx, [ebp+8]
+ shl edx, 3
+ add edx, idt
+ mov eax, [ebp+12]
+ mov [edx], ax
+ add edx, 6
+ shr eax, 16
+ mov [edx], ax
+ pop ebp
+ ret
+
pic_init:
push ebp
mov ebp, esp
diff --git a/kernel/con.c b/kernel/con.c
index 3b48de1..69c34e1 100644
--- a/kernel/con.c
+++ b/kernel/con.c
@@ -43,8 +43,8 @@ static void scroll_up(void) {
cursorpos(pos);
}
-/* must be called before any console output */
-void con_init(void) {
+/* clear the console and reset the cursor to the starting position */
+void con_clear(void) {
int n = COLS * ROWS;
uint8_t *p = vram;
@@ -57,6 +57,12 @@ void con_init(void) {
cursorpos(0);
}
+/* must be called before any console output */
+void con_init(void) {
+ /* clear the console */
+ con_clear();
+}
+
/* write a zero-terminated string to console */
int puts(char *s) {
uint8_t *p = &vram[pos];
diff --git a/kernel/kmain.c b/kernel/kmain.c
index e31782c..5b10ee1 100644
--- a/kernel/kmain.c
+++ b/kernel/kmain.c
@@ -1,6 +1,16 @@
+#include <asm/io.h>
#include <kernel/con.h>
+#include <stdint.h>
-extern int printf(char *fmt, ...);
+uint32_t ticks = 0;
+
+#define millis() \
+ (ticks * 10)
+
+void sleep(int ms) {
+ uint64_t t = millis() + ms;
+ while(millis() < t);
+}
void kmain(void) {
con_init();
@@ -8,8 +18,10 @@ void kmain(void) {
printf("Kernel booting...\n");
printf("Kernel booted!\n");
- printf("Number: %s %04x\n", "test", 0x18C);
- printf("Number: %s %04X\n", "test", 0x18C);
- printf("Number: %s %#04x\n", "test", 0x18C);
- printf("Number: %s %#04X\n", "test", 0x18C);
+ printf("PIC1 Mask: 0x%02x\n", inb(0x21));
+
+ while(1) {
+ sleep(500);
+ printf("Reliable 500ms tick!\n");
+ }
}
diff --git a/kernel/timer.s b/kernel/timer.s
new file mode 100644
index 0000000..de01ea6
--- /dev/null
+++ b/kernel/timer.s
@@ -0,0 +1,34 @@
+global timer_init
+extern register_isr
+
+; TODO: move this someplace safe (not kmain.c)
+extern ticks
+
+tick_handler:
+ push ax
+ inc dword [ticks]
+ mov al, 0x20
+ out 0x20, al
+ pop ax
+ iret
+
+timer_init:
+ push ebp
+ mov ebp, esp
+ ; register the tick_handler
+ push tick_handler
+ push dword 0x20
+ call register_isr
+ add esp, 8
+ ; initialize the pit
+ mov ax, 0x36
+ out 0x43, al
+ mov ax, 0x2E9C ; 10ms tick interval
+ out 0x40, al
+ mov al, ah
+ out 0x40, al
+ in al, 0x21
+ and al, 0xFE
+ out 0x21, al
+ pop ebp
+ ret