summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile33
-rw-r--r--kernel/boot.obin0 -> 3184 bytes
-rw-r--r--kernel/boot.s127
-rw-r--r--kernel/con.c96
-rw-r--r--kernel/con.obin0 -> 6496 bytes
-rwxr-xr-xkernel/kernelbin0 -> 14092 bytes
-rw-r--r--kernel/kmain.c10
-rw-r--r--kernel/kmain.obin0 -> 3288 bytes
-rw-r--r--kernel/link.ld11
-rw-r--r--kernel/vsprintf.c18
-rw-r--r--kernel/vsprintf.obin0 -> 3464 bytes
11 files changed, 295 insertions, 0 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
new file mode 100644
index 0000000..0f3ac41
--- /dev/null
+++ b/kernel/Makefile
@@ -0,0 +1,33 @@
+TARGET = kernel
+
+SRCS = $(wildcard *.c)
+ASMS = $(wildcard *.s)
+OBJS = $(SRCS:.c=.o) $(ASMS:.s=.o)
+
+CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -gstabs+
+LDFLAGS = -m elf_i386 -Tlink.ld
+ASMFLAGS = -f elf32
+
+CC = gcc $(CFLAGS)
+LD = ld $(LDFLAGS)
+ASM = nasm $(ASMFLAGS)
+
+all: build
+
+build: $(TARGET)
+
+.s.o:
+ $(ASM) -o $*.o $^
+
+.c.o:
+ $(CC) -c -o $*.o $^
+
+$(TARGET): $(OBJS)
+ $(LD) -o $(TARGET) $(OBJS)
+
+clean:
+ rm -f $(OBJS)
+ rm -f $(TARGET)
+
+run: $(TARGET)
+ qemu-system-x86_64 -s -kernel $(TARGET)
diff --git a/kernel/boot.o b/kernel/boot.o
new file mode 100644
index 0000000..41427be
--- /dev/null
+++ b/kernel/boot.o
Binary files differ
diff --git a/kernel/boot.s b/kernel/boot.s
new file mode 100644
index 0000000..be68109
--- /dev/null
+++ b/kernel/boot.s
@@ -0,0 +1,127 @@
+global kboot
+extern kmain
+
+; Multiboot header
+section .mboothdr
+mboot_hdr:
+ align 4
+ dd 0x1BADB002
+ dd 0x00
+ dd - (0x1BADB002 + 0x00)
+
+section .text
+
+kboot:
+ cli
+ call flush_gdt
+ call flush_idt
+ call kmain
+ cli
+ hlt
+
+gdt:
+ ; null descriptor
+ dq 0
+ ; kernel code segment
+ dw 0xFFFF ; limit (bits 0-15)
+ dw 0x0000 ; base (bits 0-15)
+ db 0x00 ; base (bits 16-23)
+ db 0x9A ; access byte
+ db 0xCF ; flags / limit (bits 16-19)
+ db 0x00 ; base (bits 24-31)
+ ; kernel data segment
+ dw 0xFFFF
+ dw 0x0000
+ db 0x00
+ db 0x92
+ db 0xCF
+ db 0x00
+ ; userspace code segment
+ dw 0xFFFF
+ dw 0x0000
+ db 0x00
+ db 0xFA
+ db 0xCF
+ db 0x00
+ ; userspace data segment
+ dw 0xFFFF
+ dw 0x0000
+ db 0x00
+ db 0xF2
+ db 0xCF
+ db 0x00
+
+gdtp:
+ dw ($-gdt-1)
+ dd gdt
+
+flush_gdt:
+ push ebp
+ mov ebp, esp
+ lgdt [gdtp]
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ jmp 0x08:.end
+.end:
+ pop ebp
+ ret
+
+idt:
+ times (256*8) db 0
+
+idtp:
+ dw ($-idt-1)
+ dd idt
+
+int_handler:
+ iret
+
+flush_idt:
+ push ebp
+ mov ebp, esp
+ mov ecx, 256
+ mov edx, idt
+.loop:
+ mov eax, int_handler
+ mov [edx], ax
+ mov word [edx+2], 0x08
+ mov byte [edx+4], 0
+ mov byte [edx+5], 0x8E
+ shr eax, 16
+ mov [edx+6], ax
+ add edx, 8
+ dec ecx
+ jz .end
+ jmp .loop
+.end:
+ lidt [idtp]
+ call pic_init
+ sti
+ pop ebp
+ ret
+
+pic_init:
+ push ebp
+ mov ebp, esp
+ mov al, 0x11
+ out 0x20, al
+ out 0xA0, al
+ mov al, 0x20
+ out 0x21, al
+ out 0xA1, al
+ mov al, 0x04
+ out 0x21, al
+ mov al, 0x02
+ out 0xA1, al
+ mov al, 0x01
+ out 0x21, al
+ out 0xA1, al
+ mov al, 0xFF
+ out 0x21, al
+ out 0xA1, al
+ pop ebp
+ ret
diff --git a/kernel/con.c b/kernel/con.c
new file mode 100644
index 0000000..b3d2b9d
--- /dev/null
+++ b/kernel/con.c
@@ -0,0 +1,96 @@
+/*
+ * con.c
+ *
+ * Basic VGA text console
+ */
+
+#include <asm/io.h>
+#include <kernel/vsprintf.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#define COLS 80
+#define ROWS 25
+
+static uint8_t *vram = (uint8_t*) 0xB8000;
+static int pos;
+
+static inline void cursorpos(int pos) {
+ outb(0x3D4, 0x0E);
+ outb(0x3D5, (uint8_t) ((pos >> 9) & 0xFF));
+ outb(0x3D4, 0x0F);
+ outb(0x3D5, (uint8_t) ((pos >> 1) & 0xFF));
+}
+
+/* scrolls the console up one line */
+static void scroll_up(void) {
+ int n = (COLS * (ROWS - 1)) << 1;
+ uint8_t *p = vram;
+
+ while(n--) {
+ *p = p[COLS << 1];
+ p++;
+ }
+
+ p = (uint8_t*) (vram + (COLS * (ROWS - 1) << 1));
+ n = COLS;
+ while(n--) {
+ *p = ' ';
+ p += 2;
+ }
+
+ pos -= COLS << 1;
+ cursorpos(pos);
+}
+
+/* must be called before any console output */
+void con_init(void) {
+ int n = COLS * ROWS;
+ uint8_t *p = vram;
+
+ while(n--) {
+ *(p++) = 0x20;
+ *(p++) = 0x07;
+ }
+
+ pos = 0;
+ cursorpos(0);
+}
+
+/* write a zero-terminated string to console */
+void con_print(char *s) {
+ uint8_t *p = &vram[pos];
+
+ while(*s) {
+ if(*s == '\n') {
+ pos = (int) (p - vram);
+ pos = ((pos / (COLS << 1)) + 1) * (COLS << 1);
+ p = &vram[pos];
+ s++;
+ } else {
+ *p = *(s++);
+ p += 2;
+ }
+
+ pos = (int) (p - vram);
+
+ if(pos >= (COLS * ROWS) << 1)
+ scroll_up();
+ }
+
+ /* update the cursor position */
+ cursorpos(pos);
+}
+
+int printf(char *fmt, ...) {
+ int ret;
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vsprintf(buf, fmt, ap);
+ va_end(ap);
+
+ con_print(buf);
+ return ret;
+}
diff --git a/kernel/con.o b/kernel/con.o
new file mode 100644
index 0000000..49168c9
--- /dev/null
+++ b/kernel/con.o
Binary files differ
diff --git a/kernel/kernel b/kernel/kernel
new file mode 100755
index 0000000..664108b
--- /dev/null
+++ b/kernel/kernel
Binary files differ
diff --git a/kernel/kmain.c b/kernel/kmain.c
new file mode 100644
index 0000000..2dc9e76
--- /dev/null
+++ b/kernel/kmain.c
@@ -0,0 +1,10 @@
+#include <kernel/con.h>
+
+extern int printf(char *fmt, ...);
+
+void kmain(void) {
+ con_init();
+
+ printf("Kernel booting...\n");
+ printf("Kernel booted!\n");
+}
diff --git a/kernel/kmain.o b/kernel/kmain.o
new file mode 100644
index 0000000..9a3a76d
--- /dev/null
+++ b/kernel/kmain.o
Binary files differ
diff --git a/kernel/link.ld b/kernel/link.ld
new file mode 100644
index 0000000..67ae357
--- /dev/null
+++ b/kernel/link.ld
@@ -0,0 +1,11 @@
+OUTPUT_FORMAT(elf32-i386)
+/* OUTPUT_FORMAT(binary) */
+ENTRY(kboot)
+SECTIONS
+{
+ . = 0x100000;
+ .mboothdr : { *(.mboothdr) }
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+}
diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c
new file mode 100644
index 0000000..f3feb43
--- /dev/null
+++ b/kernel/vsprintf.c
@@ -0,0 +1,18 @@
+#include <stdarg.h>
+
+int vsprintf(char *str, char *fmt, va_list ap) {
+ char *start = str;
+
+ while(*fmt) {
+ if(*fmt != '%') {
+ *str++ = *fmt++;
+ continue;
+ }
+
+ fmt++;
+ }
+
+ *str = 0;
+
+ return (str - start);
+}
diff --git a/kernel/vsprintf.o b/kernel/vsprintf.o
new file mode 100644
index 0000000..b5359fe
--- /dev/null
+++ b/kernel/vsprintf.o
Binary files differ