A => kernel/.gitignore +5 -0
@@ 1,5 @@
+*.o
+
+serial.log
+
+build/
A => kernel/Makefile +57 -0
@@ 1,57 @@
+ARCH = x86_64
+
+CC = cc
+LD = ld
+NASM = nasm
+CFLAGS = -isystem ../mlibc/include/ -nostdlib -nostdinc -ffreestanding -fno-builtin -O3 -m32
+LDFLAGS = -m elf_i386
+NASMFLAGS = -f elf32
+
+KERNEL = build/moss-kernel-$(ARCH).bin
+ISO = build/moss-$(ARCH).iso
+LINKER_SCRIPT = src/arch/$(ARCH)/link.ld
+GRUB_CONFIG = src/arch/$(ARCH)/grub.cfg
+
+ASM_SOURCES =\
+ $(wildcard src/arch/$(ARCH)/boot/*.asm)\
+ $(wildcard src/arch/$(ARCH)/*.asm)
+ASM_OBJECTS = $(patsubst %.asm, %.o, $(ASM_SOURCES))
+C_SOURCES =\
+ $(wildcard src/arch/$(ARCH)/*.c)\
+ $(wildcard src/*.c)
+C_OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES))
+
+.PHONY: all clean iso qemu
+
+all: $(KERNEL)
+
+# the ||: is to ignore failures (: is short for true?)
+clean:
+ @rm -rf build/isofiles ||:
+ @rm -rf $(KERNEL)
+ @rm -rf $(ISO)
+ @rm -rf $(ASM_OBJECTS)
+ @rm -rf $(C_OBJECTS)
+
+qemu: $(ISO)
+ # starting qemu
+ qemu-system-x86_64 -cdrom $(ISO) -vga std -s -serial file:serial.log
+
+iso:
+ $(ISO)
+
+$(ISO): $(KERNEL) $(GRUB_CONFIG)
+ # building iso
+ mkdir -p build/isofiles/boot/grub
+ cp $(KERNEL) build/isofiles/boot/kernel.bin
+ cp $(GRUB_CONFIG) build/isofiles/boot/grub
+ grub-mkrescue -o $(ISO) build/isofiles 2> /dev/null
+
+$(KERNEL): $(C_OBJECTS) $(ASM_OBJECTS) $(LINKER_SCRIPT)
+ $(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $(KERNEL) $(C_OBJECTS) $(ASM_OBJECTS)
+
+$(ASM_OBJECTS): %.o: %.asm
+ $(NASM) $(NASMFLAGS) $< -o $@
+
+$(C_OBJECTS): %.o: %.c
+ $(CC) $(CFLAGS) $< -c -o $@
A => kernel/include/kernel/tty.h +21 -0
@@ 1,21 @@
+/* see LICENSE for copyright information */
+#ifndef _MOSS_TTY_H_
+#define _MOSS_TTY_H_
+
+#include <stdtype.h>
+
+typedef void (*tty_flush_function)(struct tty*);
+
+struct tty {
+ u16 lines;
+ u16 columns;
+ u8 *line_buffer
+ tty_flush_function flush_func;
+};
+
+void tty_print(struct tty*, u16, u16, const char *text);
+void tty_put(struct tty*, const char *text, size_t);
+void tty_putc(struct tty*, const char);
+void tty_puts(struct tty*, const char*);
+
+#endif
A => kernel/src/arch/x86_64/boot/boot.asm +39 -0
@@ 1,39 @@
+section .multiboot
+header_start:
+ dd 0xe85250d6 ; magic number
+ dd 0 ; protected mode code
+ dd header_end - header_start ; header length
+
+ ; checksum
+ dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
+
+ ; required end tag
+ dw 0 ; type
+ dw 0 ; flags
+ dd 8 ; size
+header_end:
+
+section .bss
+align 16
+stack_bottom: ; stack grows from the _bottom_
+ resb 16384 ; 16 KiB
+stack_top:
+
+[GLOBAL start]
+[EXTERN kmain]
+
+section .text
+
+start:
+ mov esp, stack_top
+
+ ; push multiboot parameter to kmain()
+ push ebx
+
+ ; ...and run!
+ cli
+ call kmain
+
+ ;never reach here
+ cli
+ hlt
A => kernel/src/arch/x86_64/grub.cfg +7 -0
@@ 1,7 @@
+set timeout=0
+set default=0
+
+menuentry "moss" {
+ multiboot2 /boot/kernel.bin
+ boot
+}
A => kernel/src/arch/x86_64/link.ld +36 -0
@@ 1,36 @@
+ENTRY(start)
+
+SECTIONS
+{
+ . = 1M;
+
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.multiboot)
+ }
+
+ /* Executable code */
+ .text BLOCK(4K) : ALIGN(4K)
+ {
+ *(.text)
+ }
+
+ /* Read-only data. */
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.rodata)
+ }
+
+ /* Read-write data (initialized) */
+ .data BLOCK(4K) : ALIGN(4K)
+ {
+ *(.data)
+ }
+
+ /* Read-write data (uninitialized) and stack */
+ .bss BLOCK(4K) : ALIGN(4K)
+ {
+ *(COMMON)
+ *(.bss)
+ }
+}
A => kernel/src/arch/x86_64/main.c +70 -0
@@ 1,70 @@
+#include <stdtype.h>
+
+#include "multiboot.h"
+#include "vga.h"
+
+#define VGA_COLS 80
+#define VGA_ROWS 25
+#define TERM_COLOR 0x0F
+
+volatile u16 *vga_buffer = (u16*) 0xB8000;
+
+int term_col = 0;
+int term_row = 0;
+
+void
+term_init(void)
+{
+ for (int i = 0; i < VGA_COLS; i++) {
+ for (int j = 0; j < VGA_ROWS; j++) {
+ vga_buffer[(VGA_COLS * j) + i] = vga_entry(' ', VGA_COLOR_WHITE, VGA_COLOR_BLACK);
+ }
+ }
+}
+
+// This function places a single character onto the screen
+void term_putc(char c)
+{
+ // Remember - we don't want to display ALL characters!
+ switch (c) {
+ case '\n':
+ term_col = 0;
+ term_row ++;
+ break;
+ default:
+ {
+ size_t index = (VGA_COLS * term_row) + term_col;
+ vga_buffer[index] = vga_entry(c, VGA_COLOR_WHITE, VGA_COLOR_BLACK);
+ term_col ++;
+ break;
+ }
+ }
+ if (term_col >= VGA_COLS) {
+ term_col = 0;
+ term_row ++;
+ }
+
+ if (term_row >= VGA_ROWS) {
+ term_col = 0;
+ term_row = 0;
+ }
+}
+
+void term_print(const char* str)
+{
+ for (size_t i = 0; str[i] != '\0'; i ++)
+ term_putc(str[i]);
+}
+
+
+void
+kmain(struct multiboot_header *mbh)
+{
+ term_init();
+ term_print("welcome to...\n\n");
+ term_print("_______ ________________________\n");
+ term_print("__ __ `__ \\ __ \\_ ___/_ ___/\n");
+ term_print("_ / / / / / /_/ /(__ )_(__ ) \n");
+ term_print("/_/ /_/ /_/\\____//____/ /____/ \n\n");
+ term_print("starting up...");
+}
A => kernel/src/arch/x86_64/multiboot.h +45 -0
@@ 1,45 @@
+/* see LICENSE for copyright information */
+#ifndef _MOSS_ARCH_X86_MULTIBOOT_H_
+#define _MOSS_ARCH_X86_MULTIBOOT_H_
+
+#include <stdtype.h>
+
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
+
+struct multiboot_header {
+ u32 flags;
+ u32 mem_lower;
+ u32 mem_upper;
+ u32 boot_device;
+ u32 cmdline;
+ u32 mods_count;
+ u32 mods_addr;
+ u32 num;
+ u32 size;
+ u32 addr;
+ u32 shndx;
+ u32 mmap_length;
+ u32 mmap_addr;
+ u32 drives_length;
+ u32 drives_addr;
+ u32 config_table;
+ u32 boot_loader_name;
+ u32 apm_table;
+ u32 vbe_control_info;
+ u32 vbe_mode_info;
+ u16 vbe_mode;
+ u16 vbe_interface_seg;
+ u16 vbe_interface_off;
+ u16 vbe_interface_len;
+
+ u64 framebuffer_addr;
+ u32 framebuffer_pitch;
+ u32 framebuffer_width;
+ u32 framebuffer_height;
+ u8 framebuffer_bpp;
+ u8 framebuffer_type;
+} __attribute__((packed));
+
+#endif
A => kernel/src/arch/x86_64/vga.c +4 -0
@@ 1,4 @@
+/* see LICENSE for copyright information */
+#include "vga.h"
+
+
A => kernel/src/arch/x86_64/vga.h +32 -0
@@ 1,32 @@
+/* see LICENSE for copyright information */
+#ifndef _MOSS_ARCH_X86_VGA_H_
+#define _MOSS_ARCH_X86_VGA_H_
+
+#include <stdtype.h>
+
+enum vga_color {
+ VGA_COLOR_BLACK = 0,
+ VGA_COLOR_BLUE = 1,
+ VGA_COLOR_GREEN = 2,
+ VGA_COLOR_CYAN = 3,
+ VGA_COLOR_RED = 4,
+ VGA_COLOR_MAGENTA = 5,
+ VGA_COLOR_BROWN = 6,
+ VGA_COLOR_LIGHT_GREY = 7,
+ VGA_COLOR_DARK_GREY = 8,
+ VGA_COLOR_LIGHT_BLUE = 9,
+ VGA_COLOR_LIGHT_GREEN = 10,
+ VGA_COLOR_LIGHT_CYAN = 11,
+ VGA_COLOR_LIGHT_RED = 12,
+ VGA_COLOR_LIGHT_MAGENTA = 13,
+ VGA_COLOR_LIGHT_BROWN = 14,
+ VGA_COLOR_WHITE = 15,
+};
+
+static inline u16
+vga_entry(char c, enum vga_color fg, enum vga_color bg)
+{
+ return (u16) c | (u16) (fg | bg << 4) << 8;
+}
+
+#endif
A => mlibc/.gitignore +2 -0
A => mlibc/Makefile +16 -0
@@ 1,16 @@
+ARCH = x86_64
+
+CC = cc
+LD = ld
+NASM = nasm
+CFLAGS = -nostdlib -nostdinc -ffreestanding -fno-builtin -O3 -m32 -c
+LDFLAGS =
+NASMFLAGS =
+
+ASM_SOURCES=\
+ $(wildcaard src/arch/$(ARCH)/*.asm
+ASM_OBJECTS = $(patsubst %.asm, %.o, $(ASM_SOURCES))
+C_SOURCES =\
+ $(wildcard src/arch/$(ARCH)/*.c)\
+ $(wildcard src/*.c)
+C_OBJECTS = $(patsubst %.c, %.o, $(C_SOURCES))
A => mlibc/include/stdtype.h +26 -0
@@ 1,26 @@
+/* see LICENSE for copyright information */
+#ifndef _MLIBC_STDTYPE_H_
+#define _MLIBC_STDTYPE_H_
+
+#define NULL ((void*)0)
+
+/* size_t */
+typedef unsigned long size_t;
+
+/* bools */
+typedef unsigned char bool;
+#define true 1
+#define false 0
+
+/* fixed width integer types */
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long u64;
+
+typedef signed char i8;
+typedef signed short i16;
+typedef signed int i32;
+typedef signed long i64;
+
+#endif
A => mlibc/include/string.h +12 -0
@@ 1,12 @@
+/* see LICENSE for copyright information */
+#ifndef _MLIBC_STRING_H_
+#define _MLIBC_STRING_H_
+
+/* TODO: Do this later when I have malloc working */
+
+typedef struct {
+ char *buf;
+ size_t size;
+} string;
+
+#endif