Fix merge conflicts

This commit is contained in:
Jenny Curle 2019-04-06 20:06:19 +01:00
commit 913c2d2844
23 changed files with 1331 additions and 1226 deletions

10
.clang-format Normal file
View File

@ -0,0 +1,10 @@
---
DerivePointerAlignment: 'true'
SpaceBeforeParens: ControlStatements
UseTab: ForIndentation
IndentWidth: 2
TabWidth: 2
ColumnLimit: 120
BreakBeforeBraces: Attach
...

59
.gitignore vendored Normal file
View File

@ -0,0 +1,59 @@
# Created by https://www.gitignore.io/api/c
# Edit at https://www.gitignore.io/?templates=c
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# End of https://www.gitignore.io/api/c

627
arch/i386/tty.c Executable file → Normal file
View File

@ -1,294 +1,333 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <kernel/tty.h> #include "kernel/tty.h"
#include <kernel/utils.h> #include "kernel/utils.h"
static const size_t TERM_WIDTH=80; static const size_t TERM_WIDTH = 80;
static const size_t TERM_HEIGHT=25; static const size_t TERM_HEIGHT = 25;
static size_t terminal_row; static size_t terminal_row;
static size_t terminal_column; static size_t terminal_column;
static uint8_t current_color; static uint8_t current_color;
static uint16_t* term_buffer; static uint16_t* term_buffer;
static uint16_t* const vga_buffer = (uint16_t*) 0xB8000; static uint16_t* const vga_buffer = (uint16_t*)0xB8000;
void screen_initialize(void) { void screen_initialize(void) {
terminal_row = 0; terminal_row = 0;
terminal_column = 0; terminal_column = 0;
current_color = vga_color_set(LIGHT_GREY, BLACK); current_color = vga_color_set(LIGHT_GREY, BLACK);
term_buffer = vga_buffer; term_buffer = vga_buffer;
for (size_t y = 0; y < TERM_HEIGHT; y++) { for (size_t y = 0; y < TERM_HEIGHT; y++) {
for(size_t x = 0; x < TERM_WIDTH; x++) { for (size_t x = 0; x < TERM_WIDTH; x++) {
const size_t offset = y * TERM_WIDTH + x; const size_t offset = y * TERM_WIDTH + x;
term_buffer[offset] = vga_entry(' ', current_color); term_buffer[offset] = vga_entry(' ', current_color);
} }
} }
} }
void term_setcolor(enum vga_colors color) { void term_setcolor(enum vga_colors color) { current_color = color; }
current_color = color;
} void term_putentryat(char c, uint8_t color, size_t x, size_t y) {
const size_t offset = y * TERM_WIDTH + x;
void term_putentryat (char c, uint8_t color, size_t x, size_t y) { term_buffer[offset] = vga_entry(c, color);
const size_t offset = y * TERM_WIDTH + x; }
term_buffer[offset] = vga_entry(c, color);
} void term_putchar(char c) {
unsigned char uc = c;
void term_putchar(char c) {
unsigned char uc = c; // Handle escaped characters, such as newline, and crtn.
switch (uc) {
//Handle escaped characters, such as newline, and crtn. case '\n':
switch (uc) { terminal_column = 0;
case '\n': terminal_row += 1;
terminal_column = 0; break;
terminal_row += 1; default:
break; term_putentryat(uc, current_color, terminal_column, terminal_row);
default: if (++terminal_column == TERM_WIDTH) {
term_putentryat(uc, current_color, terminal_column, terminal_row); terminal_column = 0;
break; if (++terminal_row == TERM_HEIGHT) {
} term_scroll(false);
terminal_row = 0;
if(++terminal_column == TERM_WIDTH) }
{ }
terminal_column = 0; break;
if(++terminal_row == TERM_HEIGHT){ }
term_scroll(false); }
terminal_row = 0;
} struct csi_sequence parse_csi(const char* data, size_t size) {
} enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID };
} enum State state = PARAMETER;
void term_write(const char* data, size_t size) { struct csi_sequence sequence = {.parameter = NULL,
for(size_t i = 0; i < size; i++) { .parameter_len = 0,
//Begin handling ANSI escape codes. .intermediate = NULL,
if(data[i] == 0x1B) { //The current character is ESC - the start of ANSI codes. .intermediate_len = 0,
term_writes("ANSI Code encountered: "); .final = NULL,
.valid = false};
bool string_terminated = false; //Flag used in some of the escape codes
switch(data[i+1]) { for (size_t j = 0; j < size; j++) {
case 0x9b/*[*/: //CSI - Control Sequence Introducer (The most common one, hence it comes first) uint8_t c = data[j];
char* controlSequence; if (state == PARAMETER && (c >= 0x30 && c <= 0x3F)) {
if(data[i+2] == NULL) { if (!sequence.parameter)
controlSequence = '\0'; sequence.parameter = data + j;
for(size_t j = 0; j < (strlen(data) - (i+2); j++) { sequence.parameter_len++;
if(data[j] == ' ') } else if (c >= 0x20 && c <= 0x2F) {
break; if (!sequence.intermediate)
controlSequence += data[j]; sequence.intermediate = data + j;
} sequence.intermediate_len++;
handleControlSequence(controlSequence); //Send it off to our handler function to keep this part clean state = INTERMEDIATE;
break; } else if (c >= 0x40 && c <= 0x7F) {
sequence.final = data + j;
//Single shifts are not handled, so just print them and exit sequence.valid = true;
case 0x8e/*N*/: //SS2 - Single Shift Two state = FINAL;
term_writes("Single Shift Two\n"); break;
break; } else {
case 0x8f/*O*/: //SS3 - Single Shift Three // Parameter found in intermediate byte location, or byte out of
term_writes("Single Shift Three\n"); // range
break; state = INVALID;
break;
//Control Strings }
case 0x90/*P*/: //DCS - Device Control String }
term_writes("Device Control String"); return sequence;
string_terminated = false; }
break;
case 0x9c/*\*/: //ST - String Terminator void term_write(const char* data, size_t size) {
term_writes("String Terminator\n"); for (size_t i = 0; i < size; i++) {
string_terminated = true; // Begin handling ANSI escape codes.
break; if (data[i] == 0x1b) { // The current character is ESC - the start of ANSI codes.
case 0x9d/*]*/: //OSC - Operating System Command // term_writes("ANSI Code encountered: ");
term_writes("Operating System Command\n");
string_terminated = false; bool string_terminated = false; // Flag used in some of the escape codes
break;
case 0x98/*X*/: //SOS - Start Of String // TODO: Should only progress if we have at least 2 more bytes
term_writes("Start of String");
string_terminated = false; switch ((uint8_t)data[i + 1]) {
break; case '[': // CSI - Control Sequence Introducer (The most common one, hence it comes first)
case 0x9e/*^*/: //PM - Privacy Message {
term_writes("Privacy Message\n"); struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2));
break; if (sequence.valid) {
case 0x9f/*_*/: //APC - Application Program Command // Send it off to our handler function to keep this part clean
term_writes("Application Program Command\n"); handleControlSequence(sequence);
break; i += sequence.parameter_len + sequence.intermediate_len + 2; // Move past sequence
} }
} break;
} // Single shifts are not handled, so just print them and exit
case 'N': // SS2 - Single Shift Two
term_putchar(data[i]); term_writes("Single Shift Two\n");
} break;
} case 'O': // SS3 - Single Shift Three
term_writes("Single Shift Three\n");
void term_writes(const char* data) { break;
term_write(data, strlen(data));
} // Control Strings
case 'P': // DCS - Device Control String
void puts(const char* string) { term_writes("Device Control String");
term_write(string, strlen(string)); string_terminated = false;
term_putchar('\n'); break;
} case '\\': // ST - String Terminator
term_writes("String Terminator\n");
void handleControlSequence(const char* sequence) { string_terminated = true;
//Check for our failsafes break;
if(sequence) { case ']': // OSC - Operating System Command
if(sequence != '\0') { term_writes("Operating System Command\n");
int n = 0; //Default of the flag used for a few items string_terminated = false;
break;
bool nPresent = false; case 'X': // SOS - Start Of String
bool terminated = false; term_writes("Start of String");
for(size_t i = 0; i < strlen(sequence); i++) { string_terminated = false;
if(isDigit(sequence[i])) { break;
nPresent = true; case '^': // PM - Privacy Message
n = (n*10) + sequence[i]; term_writes("Privacy Message\n");
} else if(n > 80) { break;
n = 80; case '_': // APC - Application Program Command
break; term_writes("Application Program Command\n");
} break;
} }
} else {
if(n == 0) term_putchar(data[i]);
n = 1; }
}
switch(sequence[i]) { }
case ';':
terminated = true; void term_writes(const char* data) { term_write(data, strlen(data)); }
int m = 0;
for(size_t j = 0; j < strlen(sequence - i); j++) { void puts(const char* string) {
if(sequence[j] == 'H' ||sequence[j] == 'f') term_write(string, strlen(string));
break; term_putchar('\n');
}
if(isDigit(sequence[j])) {
m = (m*10) + sequence[j]; void handleControlSequence(struct csi_sequence sequence) {
} else if(j > 80) break; // Check for our failsafes
}
if (sequence.valid) {
if(m == 0) int n = 0; // Default of the flag used for a few items
m = 1;
cursor_pos(n, m); // Parse parameters, we only care about a max 2 of number only parameters
// for now
break; int params[2] = {0};
case 'A': //CUU - Cursor Up int param_count = 0;
//cursor_pos(x, y) if (sequence.parameter_len) {
for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) {
cursor_pos(terminal_column, terminal_row + n); char c = sequence.parameter[i];
break; if (isDigit(c)) {
case 'B': //CUD - Cursor Down n = (n * 10) + (sequence.parameter[i] - '0');
cursor_pos(terminal_column, terminal_row - n); } else if (c == ';') {
break; params[param_count++] = n;
case 'C': //CUF - Cursor Forward }
cursor_pos(terminal_column + n, terminal_row); }
break; params[param_count++] = n;
case 'D': //CUB - Cursor Back }
cursor_pos(terminal_column - n, terminal_row);
break; switch (*(sequence.final)) {
case 'E': //CNL - Cursor Next Line case 'H':
cursor_pos(0, terminal_row + n); case 'f': // CUP - Cursor Position
break; // TODO: Check to see if we have 2 paramaters
case 'F': //CPL - Cursor Previous Line if (params[0])
cursor_pos(0, terminal_row - n); params[0]--;
break; if (params[1])
case 'G': //CHA - Cursor Horizontal Absolute params[1]--;
cursor_pos(n, terminal_row); set_cursor(params[0], params[1]);
case 'J': //ED - Erase in Display break;
//current cursor pos = y * width + x case 'A': // CUU - Cursor Up
int pos = terminal_row * 80 + terminal_column; if (!params[0])
if(!nPresent) { params[0] = 1;
for(pos < (25 * 80); pos++) { set_cursor(terminal_column, terminal_row - params[0]);
vga_buffer[pos] = '\0'; break;
} case 'B': // CUD - Cursor Down
n = 0; if (!params[0])
} else if(nPresent && n == 1) { params[0] = 1;
for(pos > 0; pos--) { set_cursor(terminal_column, terminal_row + params[0]);
vga_buffer[pos] = '\0'; break;
} case 'C': // CUF - Cursor Forward
} else if(n == 2 || n == 3) { if (!params[0])
for(int i = 0; i < (25*80); i++) { params[0] = 1;
vga_buffer[0] = '\0'; set_cursor(terminal_column + params[0], terminal_row);
} break;
} case 'D': // CUB - Cursor Back
break; if (!params[0])
case 'K': //EL - Erase in Line params[0] = 1;
set_cursor(terminal_column - params[0], terminal_row);
int pos = terminal_row * 80 + terminal_column; break;
if(!nPresent) { //From cursor to end of line case 'E': // CNL - Cursor Next Line
int endPos = (terminal_row + 1) * 80 - 1; //End of line = current row + 25 columns = current row + 1 if (!params[0])
for(pos < endPos; pos++) { params[0] = 1;
vga_buffer[pos] = '\0'; set_cursor(0, terminal_row + params[0]);
} break;
} else if(nPresent && n == 1) { //From cursor to start of line case 'F': // CPL - Cursor Previous Line
int endPos = terminal_row * 80; //Start of line = end of previous line + 1 == current line if (!params[0])
for(pos > endPos; pos--) { params[0] = 1;
vga_buffer[pos] = '\0'; set_cursor(0, terminal_row - params[0]);
} break;
} else if(nPresent && n == 2) { //Entire current line case 'G': // CHA - Cursor Horizontal Absolute
pos = terminal_row * 80; if (params[0])
int endPos = (terminal_row + 1) * 80 - 1; params[0]--;
for(pos < endPos; pos++) { set_cursor(params[0], terminal_row);
vga_buffer[pos] = '\0'; break;
} case 'J': // ED - Erase in Display
} {
break; // current cursor pos = y * width + x
case 'S': //SU - Scroll Up int pos = terminal_row * 80 + terminal_column;
term_scroll(true); if (params[0] == 0) { // Clear from cursor to end of screen
break; for (; pos < (25 * 80); pos++) {
case 'T': //SD - Scroll Down vga_buffer[pos] = '\0';
term_scroll(false); }
break; } else if (params[0] == 1) { // Clear from cursor to beginning
} for (; pos > 0; pos--) {
} vga_buffer[pos] = '\0';
} }
} } else if (params[0] == 2 || params[0] == 3) { // Clear entire screen
// TODO: Support scrollback buffer? (n = 3)
} for (int i = 0; i < (25 * 80); i++) {
vga_buffer[0] = '\0';
bool isDigit(const char c) { }
return c == '0' || c == '1' || c == '2' || c == '3' || }
c == '4' || c == '5' || c == '6' || c == '7' || break;
c == '8' || c == '9'; }
} case 'K': // EL - Erase in Line
{
void term_scroll(bool down) { int pos = terminal_row * 80 + terminal_column;
if (params[0] == 0) { // From cursor to end of line
int current_pos; int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1
if(down) { for (; pos < endPos; pos++) {
current_pos = 25 * 80; //Start of the last line. vga_buffer[pos] = '\0';
} else { }
current_pos = 160; //Start of the second line. } else if (params[0] == 1) { // From cursor to start of line
} int endPos = terminal_row * 80; // Start of line = end of previous line + 1 == current line
for (; pos > endPos; pos--) {
unsigned char* term_buffer = (unsigned char*) vga_buffer; vga_buffer[pos] = '\0';
}
if(down) { //To scroll down, move every character into the one below it, or "pull" every character down } else if (params[0] == 2) { // Entire current line
while(current_pos > 80) { pos = terminal_row * 80;
term_buffer[current_pos + 160] = vga_buffer[current_pos]; int endPos = (terminal_row + 1) * 80 - 1;
term_buffer[current_pos + 159] = vga_buffer[current_pos - 1]; for (; pos < endPos; pos++) {
current_pos -= 2; vga_buffer[pos] = '\0';
} else { }
while (current_pos <= 4000) { }
term_buffer[current_pos - 160 /*The character immediately below it*/] = vga_buffer[current_pos]; //Move each character up a line break;
term_buffer[current_pos - 159 /*The color of the character below*/] = vga_buffer[current_pos + 1]; //As well as its color }
current_pos += 2; //Move to next char case 'S': // SU - Scroll Up
} term_scroll(true);
} break;
case 'T': // SD - Scroll Down
if(down) { term_scroll(false);
current_pos = 0; //Start of first line break;
for(current_pos < 80; current_pos++) { }
term_buffer[current_pos] = '\0'; }
current_pos += 2; }
} else {
; //Start of the last line bool isDigit(char c) { return c >= '0' && c <= '9'; }
//Wipe out the bottom line
for(current_pos = 3840; current_pos <= 3920; i++) { void set_cursor(int n, int m) {
term_buffer[current_pos] = 0; terminal_column = n;
current_pos += 2; terminal_row = m;
} }
}
void term_scroll(bool down) {
terminal_row = 24; //Start writing on the last line
terminal_column = 0; int current_pos;
} if (down) {
current_pos = 25 * 80; // Start of the last line.
} else {
current_pos = 160; // Start of the second line.
}
unsigned char* term_buffer = (unsigned char*)vga_buffer;
if (down) { // To scroll down, move every character into the one below it, or "pull" every character down
while (current_pos > 80) {
term_buffer[current_pos + 160] = vga_buffer[current_pos];
term_buffer[current_pos + 159] = vga_buffer[current_pos - 1];
current_pos -= 2;
}
} else {
while (current_pos <= 4000) {
term_buffer[current_pos - 160 /*The character immediately below it*/] =
vga_buffer[current_pos]; // Move each character up a line
term_buffer[current_pos - 159 /*The color of the character below*/] =
vga_buffer[current_pos + 1]; // As well as its color
current_pos += 2; // Move to next char
}
}
if (down) {
current_pos = 0; // Start of first line
for (; current_pos < 80; current_pos++) {
term_buffer[current_pos] = '\0';
current_pos += 2;
}
} else {
; // Start of the last line
// Wipe out the bottom line
for (current_pos = 3840; current_pos <= 3920; current_pos += 2) {
term_buffer[current_pos] = 0;
}
}
terminal_row = 24; // Start writing on the last line
terminal_column = 0;
}

61
include/arch/i386/vga.h Executable file → Normal file
View File

@ -1,34 +1,29 @@
#ifndef ARCH_I386_VGA_H #ifndef ARCH_I386_VGA_H
#define ARCH_I386_VGA_H #define ARCH_I386_VGA_H
#include <stdint.h> #include <stdint.h>
enum vga_colors {
enum vga_colors { BLACK = 0,
BLACK = 0, BLUE = 1,
BLUE = 1, GREEN = 2,
GREEN = 2, CYAN = 3,
CYAN = 3, RED = 4,
RED = 4, MAGENTA = 5,
MAGENTA = 5, BROWN = 6,
BROWN = 6, LIGHT_GREY = 7,
LIGHT_GREY = 7, DARK_GREY = 8,
DARK_GREY = 8, LIGHT_BLUE = 9,
LIGHT_BLUE = 9, LIGHT_GREEN = 10,
LIGHT_GREEN = 10, LIGHT_CYAN = 11,
LIGHT_CYAN = 11, LIGHT_RED = 12,
LIGHT_RED = 12, LIGHT_MAGENTA = 13,
LIGHT_MAGENTA = 13, LIGHT_BROWN = 14,
LIGHT_BROWN = 14, WHITE = 15
WHITE = 15 };
};
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; }
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors 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; }
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
return (uint16_t) uc | (uint16_t) color << 8;
}
#endif #endif

50
include/kernel/tty.h Executable file → Normal file
View File

@ -1,18 +1,32 @@
#pragma once #pragma once
#include <stddef.h> #include <stdbool.h>
#include <stdint.h> #include <stddef.h>
#include <vga.h> #include <stdint.h>
void term_setcolor(enum vga_colors); #include "vga.h"
void screen_initialize(void);
void term_putentryat(char, uint8_t, size_t, size_t); struct csi_sequence {
void term_putchar(char); const char* parameter;
void term_write(const char*, size_t); size_t parameter_len;
void term_writes(const char*); const char* intermediate;
void puts(const char*); size_t intermediate_len;
void set_cursor(int, int); const char* final;
void term_scroll(void); bool valid;
void int_to_ascii(int, char*); };
void int_to_hex(int, char*);
void empty_string(char*); void term_setcolor(enum vga_colors);
void screen_initialize(void);
void term_putentryat(char, uint8_t, size_t, size_t);
void term_putchar(char);
void term_write(const char*, size_t);
void term_writes(const char*);
void puts(const char*);
void handleControlSequence(struct csi_sequence);
void set_cursor(int, int);
void term_scroll(bool);
void int_to_ascii(int, char*);
void int_to_hex(int, char*);
void empty_string(char*);
bool isDigit(char c);

View File

@ -1,3 +1,4 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
@ -7,4 +8,4 @@ size_t strlen(const char*);
unsigned char inb(unsigned short); unsigned char inb(unsigned short);
void outb(unsigned short, unsigned char); void outb(unsigned short, unsigned char);

57
include/vga.h Executable file → Normal file
View File

@ -1,31 +1,26 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
enum vga_colors {
enum vga_colors { BLACK = 0,
BLACK = 0, BLUE = 1,
BLUE = 1, GREEN = 2,
GREEN = 2, CYAN = 3,
CYAN = 3, RED = 4,
RED = 4, MAGENTA = 5,
MAGENTA = 5, BROWN = 6,
BROWN = 6, LIGHT_GREY = 7,
LIGHT_GREY = 7, DARK_GREY = 8,
DARK_GREY = 8, LIGHT_BLUE = 9,
LIGHT_BLUE = 9, LIGHT_GREEN = 10,
LIGHT_GREEN = 10, LIGHT_CYAN = 11,
LIGHT_CYAN = 11, LIGHT_RED = 12,
LIGHT_RED = 12, LIGHT_MAGENTA = 13,
LIGHT_MAGENTA = 13, LIGHT_BROWN = 14,
LIGHT_BROWN = 14, WHITE = 15
WHITE = 15 };
};
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; }
static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors 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; }
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
return (uint16_t) uc | (uint16_t) color << 8;
}

Binary file not shown.

3
kernel/kernel.c Executable file → Normal file
View File

@ -1,3 +1,4 @@
//#include <stdio.h> //#include <stdio.h>
#include <kernel/tty.h> #include <kernel/tty.h>
@ -20,4 +21,4 @@ int kernel_main(void) {
for(;;) {} for(;;) {}
return 0; return 0;
} }

94
kernel/syscalls.c Executable file → Normal file
View File

@ -1,48 +1,48 @@
/*#include <sys/stat.h> /*#include <sys/stat.h>
#include <sys/types.h> #include <stdio.h>
#include <sys/fcntl.h> #include <sys/errno.h>
#include <sys/times.h> #include <sys/fcntl.h>
#include <sys/errno.h> #include <sys/time.h>
#include <sys/time.h> #include <sys/times.h>
#include <stdio.h> #include <sys/types.h>
//prototypes; these are the bare minimum for newlib to compile. //prototypes; these are the bare minimum for newlib to compile.
void _exit(); void _exit();
int close(int file); int close(int file);
char **environ; char **environ;
int execve(char *name, char **argv, char **env); int execve(char *name, char **argv, char **env);
int fork(); int fork();
int fstat(int file, struct stat *st); int fstat(int file, struct stat *st);
int getpid(); int getpid();
int isatty(int file); int isatty(int file);
int kill(int pid, int sig); int kill(int pid, int sig);
int link(char *old, char *new); int link(char *old, char *new);
int lseek(int file, int ptr, int dir); int lseek(int file, int ptr, int dir);
int open(const char* name, int flags, ...); int open(const char* name, int flags, ...);
int read(int file, char* ptr, int len); int read(int file, char* ptr, int len);
caddr_t sbrk(int incr); caddr_t sbrk(int incr);
int stat(const char* file, struct stat *st); int stat(const char* file, struct stat *st);
clock_t times(struct tms* buf); clock_t times(struct tms* buf);
int unlink(char* name); int unlink(char* name);
int wait(int file, char* ptr, int len); int wait(int file, char* ptr, int len);
int gettimeofday(struct timeval* p, struct timezone* z); int gettimeofday(struct timeval* p, struct timezone* z);
*/ */

2
kernel/utils.c Executable file → Normal file
View File

@ -16,4 +16,4 @@ unsigned char inb(unsigned short port) {
void outb(unsigned short port, unsigned char data) { void outb(unsigned short port, unsigned char data) {
asm volatile("outb %1, %0" : : "dN" (port), "a" (data)); asm volatile("outb %1, %0" : : "dN" (port), "a" (data));
} }

View File

@ -1,19 +1,19 @@
#ifndef _STDIO_H #ifndef _STDIO_H
#define _STDIO_H 1 #define _STDIO_H 1
#include <sys/cdefs.h> #include <sys/cdefs.h>
#define EOF (-1) #define EOF (-1)
struct __sFile { struct __sFile {
int unused; int unused;
}; };
typedef struct __sFile FILE; typedef struct __sFile FILE;
#define stderr (_impure_ptr->_stderr) #define stderr (_impure_ptr->_stderr)
int printf(const char* __restrict, ...); int printf(const char* __restrict, ...);
int putchar(int); int putchar(int);
int puts(const char*); int puts(const char*);
#endif #endif

1195
libc/include/stdlib.h Executable file → Normal file

File diff suppressed because it is too large Load Diff

24
libc/include/string.h Executable file → Normal file
View File

@ -1,13 +1,13 @@
#ifndef _STRING_H #ifndef _STRING_H
#define _STRING_H 1 #define _STRING_H 1
#include <sys/cdefs.h> #include <stddef.h>
#include <stddef.h> #include <sys/cdefs.h>
int memcmp(const void*, const void*, size_t); int memcmp(const void*, const void*, size_t);
void* memcpy(void* __restrict, const void* __restrict, size_t); void* memcpy(void* __restrict, const void* __restrict, size_t);
void* memmove(void*, const void*, size_t); void* memmove(void*, const void*, size_t);
void* memset(void*, int, size_t); void* memset(void*, int, size_t);
size_t strlen(const char*); size_t strlen(const char*);
#endif #endif

View File

@ -1,5 +1,5 @@
#ifndef _SYS_CDEFS_H #ifndef _SYS_CDEFS_H
#define _SYS_CDEFS_H 1 #define _SYS_CDEFS_H 1
#define __red_libc 1 #define __red_libc 1
#endif #endif

187
libc/stdio/printf.c Executable file → Normal file
View File

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

28
libc/stdio/putchar.c Executable file → Normal file
View File

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

View File

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

28
libc/stdlib/abort.c Executable file → Normal file
View File

@ -1,15 +1,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
__attribute__((__noreturn__)) __attribute__((__noreturn__)) void abort(void) {
void abort(void) {
#if defined(__is_libk)
#if defined(__is_libk) // TODO: Kernel panic.
//TODO: Kernel panic. printf(">>PANIC<<<\n abort() panicked!\n");
printf(">>PANIC<<<\n abort() panicked!\n"); #else
#else printf("abort() called\n");
printf("abort() called\n"); #endif
#endif while (1) {
while(1) {} }
__builtin_unreachable(); __builtin_unreachable();
} }

24
libc/string/memcmp.c Executable file → Normal file
View File

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

26
libc/string/memmove.c Executable file → Normal file
View File

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

14
libc/string/memset.c Executable file → Normal file
View File

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

13
libc/string/strlen.c Executable file → Normal file
View File

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