Merge branch 'develop' of Zoarial94/ZoarialBareOS into master

This commit is contained in:
Zoarial94 2020-12-13 03:47:36 +00:00 committed by Gogs
commit 75a4436929
31 changed files with 564 additions and 120 deletions

4
.gitignore vendored
View File

@ -1,3 +1,7 @@
bin/
dep/
build/
# ---> C++
# Compiled Object files
*.slo

140
Makefile Normal file
View File

@ -0,0 +1,140 @@
#Standard Compiling Options
ARCH ?= i386
C := i686-elf-gcc
CXX := i686-elf-g++
AS := i686-elf-as
SRCDIR := src
SRCDIRS := src/arch/$(ARCH) src/kernel src/libc
BUILDDIR := build
INCDIR := include
TARGET := bin/ZoarialBareOS.iso
DEPDIR := dep
#Standard Compiling Files and Arguments
CSRCEXT := c
CINCEXT := h
CPPSRCEXT := cpp
CPPINCEXT := hpp
ASSRCEXT := s
CSOURCES := $(shell find $(SRCDIRS) -type f -name "*.$(CSRCEXT)")
CPPSOURCES := $(shell find $(SRCDIRS) -type f -name "*.$(CPPSRCEXT)")
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(CSOURCES:.$(CSRCEXT)=.o)) $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(CPPSOURCES:.$(CPPSRCEXT)=.o))
#$(info OBJECTS is $(OBJECTS))
ASSOURCES := $(shell find $(SRCDIRS) -type f -name "*.$(ASSRCEXT)")
ASOBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(ASSOURCES:.$(ASSRCEXT)=.o))
DEPENDENCIES := $(patsubst $(SRCDIR)/%,$(DEPDIR)/%,$(CSOURCES:.$(CSRCEXT)=.d))
DEPENDENCIES := $(DEPENDENCIES) $(patsubst $(SRCDIR)/%,$(DEPDIR)/%,$(CPPSOURCES:.$(CPPSRCEXT)=.d))
LIB :=
LIBDIR :=
FLAGS := -O2 -Wall -Wextra -g -D__is_kernel -ffreestanding
CFLAGS := $(FLAGS) -std=gnu99
CXXFLAGS := $(FLAGS) -std=c++17
ASFLAGS :=
INC := -I include/ -I include/libc/
#Testing Compiling Files and Arguments
#TESTSOURCES := $(shell find $(TESTSRCDIR) -type f -name "*.$(SRCEXT)")
#TESTOBJECTS := $(patsubst $(TESTSRCDIR)/%,$(TESTBUILDDIR)/%,$(TESTSOURCES:.$(SRCEXT)=.o))
MAINOBJS := $(OBJECTS) $(ASOBJECTS)
$(shell mkdir -p $(BUILDDIR) $(DEPDIR) bin/)
TREE := $(shell find $(SRCDIR) -type d)
$(shell mkdir -p $(patsubst $(SRCDIR)/%, $(BUILDDIR)/%, $(TREE)))
$(shell mkdir -p $(patsubst $(SRCDIR)/%, $(DEPDIR)/%, $(TREE)))
#Compile Target
bin/ZoarialBareOS.iso: bin/ZoarialBareOS.bin bin/grub.cfg
cp bin/ZoarialBareOS.bin $(BUILDDIR)/isodir/boot/
cp $(SRCDIR)/grub.cfg $(BUILDDIR)/isodir/boot/grub/grub.cfg
grub2-mkrescue -o $@ $(BUILDDIR)/isodir
bin/ZoarialBareOS.bin: $(MAINOBJS)
@echo " Linking... $(MAINOBJS)"
$(C) -T $(SRCDIR)/linker.ld $^ -o $@ -ffreestanding -O2 -nostdlib -lgcc
grub2-file --is-x86-multiboot $@
mkdir -p $(BUILDDIR)/isodir/boot/grub
bin/grub.cfg: $(SRCDIR)/grub.cfg
cp $(SRCDIR)/grub.cfg bin/grub.cfg
#Include dependencies which are created
#-include $(DEPENDENCIES:)
include $(wildcard $(DEPENDENCIES))
#Create C++ object files
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(CPPSRCEXT)
#Make build directory
@mkdir -p $(BUILDDIR)
@mkdir -p $(DEPDIR)
#Make Makefiles
$(CXX) $(CXXFLAGS) $(INC) -MT $@ -MM -MP $< > $(DEPDIR)/$*.Td
@cd $(DEPDIR); \
cp $*.Td $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.Td >> $*.d; \
rm -f $*.Td; \
cd ../;
#Compile object
$(CXX) $(CXXFLAGS) $(INC) -c -o $@ $<
#Fancy deleting/copying
#Handles files that no longer exist
@cp -f $(DEPDIR)/$*.d $(DEPDIR)/$*.d.tmp
@sed -e 's/.*://' -e 's/\\$$//' < $(DEPDIR)/$*.d.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPDIR)/$*.d
@rm -f $(DEPDIR)/$*.d.tmp
#Create C object files
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(CSRCEXT)
#Make build directory
@mkdir -p $(BUILDDIR)
@mkdir -p $(DEPDIR)
#Make Makefiles
$(C) $(CFLAGS) $(INC) -MT $@ -MM -MP $< > $(DEPDIR)/$*.Td
@cd $(DEPDIR); \
cp $*.Td $*.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.Td >> $*.d; \
rm -f $*.Td; \
cd ../;
#Compile object
$(C) $(CFLAGS) $(INC) -c -o $@ $<
#Fancy deleting/copying
#Handles files that no longer exist
@cp -f $(DEPDIR)/$*.d $(DEPDIR)/$*.d.tmp
@sed -e 's/.*://' -e 's/\\$$//' < $(DEPDIR)/$*.d.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPDIR)/$*.d
@rm -f $(DEPDIR)/$*.d.tmp
#Create object files
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(ASSRCEXT)
#Make build directory
@mkdir -p $(BUILDDIR)
@mkdir -p $(DEPDIR)
#Compile object
$(AS) $(ASFLAGS) -o $@ $<
#Clean
clean:
@echo " Cleaning...";
$(RM) -r $(BUILDDIR) $(DEPDIR) bin/
.PHONY: clean
#Basic example
Example: $(EXAMOBJS)
#Prevents failure if dependency does not exist
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d

View File

@ -1,3 +0,0 @@
menuentry "myos" {
multiboot /boot/myos.bin
}

37
include/arch/i386/vga.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef ARCH_I386_VGA_H
#define ARCH_I386_VGA_H
#include <stdint.h>
#include <stddef.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 const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) {
return fg | bg << 4;
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
return (uint16_t) uc | (uint16_t) color << 8;
}
#endif

12
include/kernel/tty.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _KERNEL_TTY_H
#define _KERNEL_TTY_H
#include <stddef.h>
#include <stdint.h>
void terminal_initialize(void);
void terminal_putchar(char c);
void terminal_write(const char* data, size_t size);
void terminal_writestring(const char* data);
#endif

20
include/libc/stdio.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _STDIO_H
#define _STDIO_H 1
#include <sys/cdefs.h>
#define EOF (-1)
#ifdef __cplusplus
extern "C" {
#endif
int printf(const char* __restrict, ...);
int putchar(int);
int puts(const char*);
#ifdef __cplusplus
}
#endif
#endif

17
include/libc/stdlib.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _STDLIB_H
#define _STDLIB_H 1
#include <sys/cdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((__noreturn__))
void abort(void);
#ifdef __cplusplus
}
#endif
#endif

22
include/libc/string.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef _STRING_H
#define _STRING_H 1
#include <sys/cdefs.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
int memcmp(const void*, const void*, size_t);
void* memcpy(void* __restrict, const void* __restrict, size_t);
void* memmove(void*, const void*, size_t);
void* memset(void*, int, size_t);
size_t strlen(const char*);
#ifdef __cplusplus
}
#endif
#endif

6
include/libc/sys/cdefs.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _SYS_CDEFS_H
#define _SYS_CDEFS_H 1
#define __myos_libc 1
#endif

View File

@ -1,3 +0,0 @@
menuentry "myos" {
multiboot /boot/myos.bin
}

Binary file not shown.

114
kernel.c
View File

@ -1,114 +0,0 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/* Check if the compiler thinks you are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif
/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif
/* Hardware text mode color constants. */
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 uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
{
return fg | bg << 4;
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
{
return (uint16_t) uc | (uint16_t) color << 8;
}
size_t strlen(const char* str)
{
size_t len = 0;
while (str[len])
len++;
return len;
}
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
void terminal_initialize(void)
{
terminal_row = 0;
terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
terminal_buffer = (uint16_t*) 0xB8000;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
void terminal_setcolor(uint8_t color)
{
terminal_color = color;
}
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(c, color);
}
void terminal_putchar(char c)
{
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH) {
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
terminal_row = 0;
}
}
void terminal_write(const char* data, size_t size)
{
for (size_t i = 0; i < size; i++)
terminal_putchar(data[i]);
}
void terminal_writestring(const char* data)
{
terminal_write(data, strlen(data));
}
void kernel_main(void)
{
/* Initialize terminal interface */
terminal_initialize();
/* Newline support is left as an exercise. */
terminal_writestring("Hello, kernel World!\n");
}

BIN
myos.bin

Binary file not shown.

BIN
myos.iso

Binary file not shown.

View File

@ -75,6 +75,7 @@ _start:
C++ features such as global constructors and exceptions will require
runtime support to work as well.
*/
call _init
/*
Enter the high-level kernel. The ABI requires the stack is 16-byte

16
src/arch/i386/crti.s Normal file
View File

@ -0,0 +1,16 @@
.section .init
.global _init
.type _init, @function
_init:
push %ebp
movl %esp, %ebp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
.section .fini
.global _fini
.type _fini, @function
_fini:
push %ebp
movl %esp, %ebp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */

9
src/arch/i386/crtn.s Normal file
View File

@ -0,0 +1,9 @@
.section .init
/* gcc will nicely put the contents of crtend.o's .init section here. */
popl %ebp
ret
.section .fini
/* gcc will nicely put the contents of crtend.o's .fini section here. */
popl %ebp
ret

2
src/arch/i386/vga.c Normal file
View File

@ -0,0 +1,2 @@
#include <arch/i386/vga.h>

3
src/grub.cfg Normal file
View File

@ -0,0 +1,3 @@
menuentry "ZoarialBareOS" {
multiboot /boot/ZoarialBareOS.bin
}

22
src/kernel/kernel.c Normal file
View File

@ -0,0 +1,22 @@
#include <kernel/tty.h>
#include <stdbool.h>
/* Check if the compiler thinks you are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif
/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif
void kernel_main(void)
{
/* Initialize terminal interface */
terminal_initialize();
/* Newline support is left as an exercise. */
terminal_writestring("Hello, kernel World!\nHello again!!");
}

86
src/kernel/tty.c Normal file
View File

@ -0,0 +1,86 @@
#include <kernel/tty.h>
#include <arch/i386/vga.h>
#include <string.h>
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
static inline void terminal_setcolor(uint8_t color)
{
terminal_color = color;
}
static inline void terminal_incrementrow(void) {
if(++terminal_row == VGA_HEIGHT) {
terminal_row = 0;
}
}
static inline void terminal_resetrow(void) {
terminal_row = 0;
}
static inline void terminal_incrementcolumn(void) {
if(++terminal_column == VGA_WIDTH) {
terminal_column = 0;
}
}
static inline void terminal_resetcolumn(void) {
terminal_column = 0;
}
void terminal_initialize(void)
{
terminal_row = 0;
terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
terminal_buffer = (uint16_t*) 0xB8000;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
switch(c) {
case '\n':
terminal_incrementrow();
terminal_resetcolumn();
break;
default:
terminal_buffer[index] = vga_entry(c, color);
terminal_incrementcolumn();
if(terminal_column == 0) {
terminal_incrementrow();
}
}
}
void terminal_putchar(char c)
{
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
/*if (++terminal_column == VGA_WIDTH) {
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
terminal_row = 0;
}*/
}
void terminal_write(const char* data, size_t size)
{
for (size_t i = 0; i < size; i++)
terminal_putchar(data[i]);
}
void terminal_writestring(const char* data)
{
terminal_write(data, strlen(data));
}

80
src/libc/stdio/printf.c Normal file
View File

@ -0,0 +1,80 @@
#include <limits.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
static bool print(const char* data, size_t length) {
const unsigned char* bytes = (const unsigned char*) data;
for (size_t i = 0; i < length; i++)
if (putchar(bytes[i]) == EOF)
return false;
return true;
}
int printf(const char* restrict format, ...) {
va_list parameters;
va_start(parameters, format);
int written = 0;
while (*format != '\0') {
size_t maxrem = INT_MAX - written;
if (format[0] != '%' || format[1] == '%') {
if (format[0] == '%')
format++;
size_t amount = 1;
while (format[amount] && format[amount] != '%')
amount++;
if (maxrem < amount) {
// TODO: Set errno to EOVERFLOW.
return -1;
}
if (!print(format, amount))
return -1;
format += amount;
written += amount;
continue;
}
const char* format_begun_at = format++;
if (*format == 'c') {
format++;
char c = (char) va_arg(parameters, int /* char promotes to int */);
if (!maxrem) {
// TODO: Set errno to EOVERFLOW.
return -1;
}
if (!print(&c, sizeof(c)))
return -1;
written++;
} else if (*format == 's') {
format++;
const char* str = va_arg(parameters, const char*);
size_t len = strlen(str);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.
return -1;
}
if (!print(str, len))
return -1;
written += len;
} else {
format = format_begun_at;
size_t len = strlen(format);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.
return -1;
}
if (!print(format, len))
return -1;
written += len;
format += len;
}
}
va_end(parameters);
return written;
}

15
src/libc/stdio/putchar.c Normal file
View File

@ -0,0 +1,15 @@
#include <stdio.h>
#if defined(__is_libk)
#include <kernel/tty.h>
#endif
int putchar(int ic) {
#if defined(__is_libk)
char c = (char) ic;
terminal_write(&c, sizeof(c));
#else
// TODO: Implement stdio and the write system call.
#endif
return ic;
}

5
src/libc/stdio/puts.c Normal file
View File

@ -0,0 +1,5 @@
#include <stdio.h>
int puts(const char* string) {
return printf("%s\n", string);
}

15
src/libc/stdlib/abort.c Normal file
View File

@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
__attribute__((__noreturn__))
void abort(void) {
#if defined(__is_libk)
// TODO: Add proper kernel panic.
printf("kernel: panic: abort()\n");
#else
// TODO: Abnormally terminate the process as if by SIGABRT.
printf("abort()\n");
#endif
while (1) { }
__builtin_unreachable();
}

13
src/libc/string/memcmp.c Normal file
View File

@ -0,0 +1,13 @@
#include <string.h>
int memcmp(const void* aptr, const void* bptr, size_t size) {
const unsigned char* a = (const unsigned char*) aptr;
const unsigned char* b = (const unsigned char*) bptr;
for (size_t i = 0; i < size; i++) {
if (a[i] < b[i])
return -1;
else if (b[i] < a[i])
return 1;
}
return 0;
}

9
src/libc/string/memcpy.c Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) {
unsigned char* dst = (unsigned char*) dstptr;
const unsigned char* src = (const unsigned char*) srcptr;
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
return dstptr;
}

14
src/libc/string/memmove.c Normal file
View File

@ -0,0 +1,14 @@
#include <string.h>
void* memmove(void* dstptr, const void* srcptr, size_t size) {
unsigned char* dst = (unsigned char*) dstptr;
const unsigned char* src = (const unsigned char*) srcptr;
if (dst < src) {
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
} else {
for (size_t i = size; i != 0; i--)
dst[i-1] = src[i-1];
}
return dstptr;
}

8
src/libc/string/memset.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
void* memset(void* bufptr, int value, size_t size) {
unsigned char* buf = (unsigned char*) bufptr;
for (size_t i = 0; i < size; i++)
buf[i] = (unsigned char) value;
return bufptr;
}

8
src/libc/string/strlen.c Normal file
View File

@ -0,0 +1,8 @@
#include <string.h>
size_t strlen(const char* str) {
size_t len = 0;
while (str[len])
len++;
return len;
}