Merge branch 'develop' of Zoarial94/ZoarialBareOS into master
This commit is contained in:
commit
75a4436929
|
@ -1,3 +1,7 @@
|
|||
bin/
|
||||
dep/
|
||||
build/
|
||||
|
||||
# ---> C++
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _SYS_CDEFS_H
|
||||
#define _SYS_CDEFS_H 1
|
||||
|
||||
#define __myos_libc 1
|
||||
|
||||
#endif
|
|
@ -1,3 +0,0 @@
|
|||
menuentry "myos" {
|
||||
multiboot /boot/myos.bin
|
||||
}
|
Binary file not shown.
114
kernel.c
114
kernel.c
|
@ -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");
|
||||
}
|
|
@ -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
|
|
@ -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. */
|
||||
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
#include <arch/i386/vga.h>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
menuentry "ZoarialBareOS" {
|
||||
multiboot /boot/ZoarialBareOS.bin
|
||||
}
|
|
@ -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!!");
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int puts(const char* string) {
|
||||
return printf("%s\n", string);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <string.h>
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
while (str[len])
|
||||
len++;
|
||||
return len;
|
||||
}
|
Loading…
Reference in New Issue