~stilbruch/moss

42188f75ebd06b6731bcefc550a27d9cbdfd08e0 — stilbruch 3 years ago
First commit. Not much to see here now, but maybe someday this will turn
into a cool project!
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
@@ 1,2 @@
*.o
build/

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