summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-06-16 04:49:57 +1000
committerJake Mannens <jake72360@gmail.com>2018-06-16 04:49:57 +1000
commit3e9bdcca84e22c997a071dddf37449ead85aed75 (patch)
tree06def7ef704b348cdef2b704d3357b79d22f00bd
Initial commit
-rw-r--r--Makefile8
-rw-r--r--include/asm/io.h14
-rw-r--r--include/kernel/con.h14
-rw-r--r--include/kernel/vsprintf.h14
-rw-r--r--include/stdarg.h27
-rw-r--r--include/stdbool.h17
-rw-r--r--include/stdint.h19
-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
18 files changed, 408 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4098be7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+all:
+ make -C kernel
+
+run:
+ make -C kernel run
+
+clean:
+ make -C kernel clean
diff --git a/include/asm/io.h b/include/asm/io.h
new file mode 100644
index 0000000..6ca5bbc
--- /dev/null
+++ b/include/asm/io.h
@@ -0,0 +1,14 @@
+/*
+ * asm/io.h
+ *
+ * Provides acces to x86 I/O functions
+ */
+
+#define inb(port) ({ \
+ unsigned char _val; \
+ asm volatile ("inb %%dx, %%al" : "=a" (_val) : "d" (port)); \
+ _val; \
+ })
+
+#define outb(port, val) \
+ asm volatile ("outb %%al, %%dx" : : "d" (port), "a" (val));
diff --git a/include/kernel/con.h b/include/kernel/con.h
new file mode 100644
index 0000000..4e564ed
--- /dev/null
+++ b/include/kernel/con.h
@@ -0,0 +1,14 @@
+/*
+ * con.h
+ *
+ * Basic VGA text console
+ */
+
+#ifndef _CON_H
+#define _CON_H
+
+void con_init(void);
+
+void con_print(char*);
+
+#endif
diff --git a/include/kernel/vsprintf.h b/include/kernel/vsprintf.h
new file mode 100644
index 0000000..08297d6
--- /dev/null
+++ b/include/kernel/vsprintf.h
@@ -0,0 +1,14 @@
+/*
+ * vsprintf.h
+ *
+ * A very basic implmentation of thr vsprintf function
+ */
+
+#ifndef _VSPRINTF_H
+#define _VSPRINTF_H
+
+#include <stdarg.h>
+
+int vsprintf(char*, char*, va_list);
+
+#endif
diff --git a/include/stdarg.h b/include/stdarg.h
new file mode 100644
index 0000000..8eb1341
--- /dev/null
+++ b/include/stdarg.h
@@ -0,0 +1,27 @@
+/*
+ * stdarg.h
+ *
+ * Provides va_list and associated functions
+ */
+
+#ifndef _STDARG_H
+#define _STDARG_H
+
+typedef char* va_list;
+
+#define __va_rounded_size(TYPE) \
+ (((sizeof(TYPE) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
+
+#define va_start(AP, LAST) \
+ (AP = ((char*) &LAST + __va_rounded_size(LAST)))
+
+#define va_arg(AP, TYPE) \
+ (AP += __va_rounded_size(TYPE), \
+ *((TYPE*) (AP - __va_rounded_size(TYPE))))
+
+#define va_end(AP)
+
+#define va_copy(DEST, SRC) \
+ (DEST = SRC)
+
+#endif
diff --git a/include/stdbool.h b/include/stdbool.h
new file mode 100644
index 0000000..f96b223
--- /dev/null
+++ b/include/stdbool.h
@@ -0,0 +1,17 @@
+/*
+ * stdbool.h
+ *
+ * Defines bool, true and false
+ */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+typedef char bool;
+
+#undef false
+#define false 0
+#undef true
+#define true 1
+
+#endif
diff --git a/include/stdint.h b/include/stdint.h
new file mode 100644
index 0000000..3dc068e
--- /dev/null
+++ b/include/stdint.h
@@ -0,0 +1,19 @@
+/*
+ * stdint.h
+ *
+ * Common integer types
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+typedef char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef long int64_t;
+typedef unsigned long uint64_t;
+
+#endif
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