From bc6f94e353e0d0c0536fa8847f3b8f4734f56007 Mon Sep 17 00:00:00 2001 From: Jessica Creighton Date: Wed, 3 Apr 2019 16:44:48 -0400 Subject: [PATCH 1/3] Finish initial ANSI Escape Sequence support - basic CSI sequences (cursor moving, line erasing) work --- arch/i386/tty.c | 626 +++++++++++++++++++++++-------------------- include/kernel/tty.h | 51 ++-- 2 files changed, 365 insertions(+), 312 deletions(-) diff --git a/arch/i386/tty.c b/arch/i386/tty.c index c37516d..94b9940 100755 --- a/arch/i386/tty.c +++ b/arch/i386/tty.c @@ -1,294 +1,332 @@ -#include -#include -#include -#include - -#include -#include - -static const size_t TERM_WIDTH=80; -static const size_t TERM_HEIGHT=25; - -static size_t terminal_row; -static size_t terminal_column; - -static uint8_t current_color; -static uint16_t* term_buffer; -static uint16_t* const vga_buffer = (uint16_t*) 0xB8000; - -void screen_initialize(void) { - - terminal_row = 0; - terminal_column = 0; - current_color = vga_color_set(LIGHT_GREY, BLACK); - term_buffer = vga_buffer; - - for (size_t y = 0; y < TERM_HEIGHT; y++) { - for(size_t x = 0; x < TERM_WIDTH; x++) { - const size_t offset = y * TERM_WIDTH + x; - term_buffer[offset] = vga_entry(' ', current_color); - } - } -} - -void term_setcolor(enum vga_colors 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; - term_buffer[offset] = vga_entry(c, color); -} - -void term_putchar(char c) { - unsigned char uc = c; - - //Handle escaped characters, such as newline, and crtn. - switch (uc) { - case '\n': - terminal_column = 0; - terminal_row += 1; - break; - default: - term_putentryat(uc, current_color, terminal_column, terminal_row); - break; - } - - if(++terminal_column == TERM_WIDTH) - { - terminal_column = 0; - if(++terminal_row == TERM_HEIGHT){ - term_scroll(false); - terminal_row = 0; - } - } -} - -void term_write(const char* data, size_t size) { - for(size_t i = 0; i < size; i++) { - //Begin handling ANSI escape codes. - if(data[i] == 0x1B) { //The current character is ESC - the start of ANSI codes. - term_writes("ANSI Code encountered: "); - - bool string_terminated = false; //Flag used in some of the escape codes - switch(data[i+1]) { - case 0x9b/*[*/: //CSI - Control Sequence Introducer (The most common one, hence it comes first) - char* controlSequence; - if(data[i+2] == NULL) { - controlSequence = '\0'; - for(size_t j = 0; j < (strlen(data) - (i+2); j++) { - if(data[j] == ' ') - break; - controlSequence += data[j]; - } - handleControlSequence(controlSequence); //Send it off to our handler function to keep this part clean - break; - - //Single shifts are not handled, so just print them and exit - case 0x8e/*N*/: //SS2 - Single Shift Two - term_writes("Single Shift Two\n"); - break; - case 0x8f/*O*/: //SS3 - Single Shift Three - term_writes("Single Shift Three\n"); - break; - - //Control Strings - case 0x90/*P*/: //DCS - Device Control String - term_writes("Device Control String"); - string_terminated = false; - break; - case 0x9c/*\*/: //ST - String Terminator - term_writes("String Terminator\n"); - string_terminated = true; - break; - case 0x9d/*]*/: //OSC - Operating System Command - term_writes("Operating System Command\n"); - string_terminated = false; - break; - case 0x98/*X*/: //SOS - Start Of String - term_writes("Start of String"); - string_terminated = false; - break; - case 0x9e/*^*/: //PM - Privacy Message - term_writes("Privacy Message\n"); - break; - case 0x9f/*_*/: //APC - Application Program Command - term_writes("Application Program Command\n"); - break; - } - - } - - term_putchar(data[i]); - } -} - -void term_writes(const char* data) { - term_write(data, strlen(data)); -} - -void puts(const char* string) { - term_write(string, strlen(string)); - term_putchar('\n'); -} - -void handleControlSequence(const char* sequence) { - //Check for our failsafes - if(sequence) { - if(sequence != '\0') { - int n = 0; //Default of the flag used for a few items - - bool nPresent = false; - bool terminated = false; - for(size_t i = 0; i < strlen(sequence); i++) { - if(isDigit(sequence[i])) { - nPresent = true; - n = (n*10) + sequence[i]; - } else if(n > 80) { - n = 80; - break; - } - } - - if(n == 0) - n = 1; - - switch(sequence[i]) { - case ';': - terminated = true; - int m = 0; - for(size_t j = 0; j < strlen(sequence - i); j++) { - if(sequence[j] == 'H' ||sequence[j] == 'f') - break; - - if(isDigit(sequence[j])) { - m = (m*10) + sequence[j]; - } else if(j > 80) break; - } - - if(m == 0) - m = 1; - cursor_pos(n, m); - - break; - case 'A': //CUU - Cursor Up - //cursor_pos(x, y) - - cursor_pos(terminal_column, terminal_row + n); - break; - case 'B': //CUD - Cursor Down - cursor_pos(terminal_column, terminal_row - n); - break; - case 'C': //CUF - Cursor Forward - cursor_pos(terminal_column + n, terminal_row); - break; - case 'D': //CUB - Cursor Back - cursor_pos(terminal_column - n, terminal_row); - break; - case 'E': //CNL - Cursor Next Line - cursor_pos(0, terminal_row + n); - break; - case 'F': //CPL - Cursor Previous Line - cursor_pos(0, terminal_row - n); - break; - case 'G': //CHA - Cursor Horizontal Absolute - cursor_pos(n, terminal_row); - case 'J': //ED - Erase in Display - //current cursor pos = y * width + x - int pos = terminal_row * 80 + terminal_column; - if(!nPresent) { - for(pos < (25 * 80); pos++) { - vga_buffer[pos] = '\0'; - } - n = 0; - } else if(nPresent && n == 1) { - for(pos > 0; pos--) { - vga_buffer[pos] = '\0'; - } - } else if(n == 2 || n == 3) { - for(int i = 0; i < (25*80); i++) { - vga_buffer[0] = '\0'; - } - } - break; - case 'K': //EL - Erase in Line - - int pos = terminal_row * 80 + terminal_column; - if(!nPresent) { //From cursor to end of line - int endPos = (terminal_row + 1) * 80 - 1; //End of line = current row + 25 columns = current row + 1 - for(pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } else if(nPresent && n == 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--) { - vga_buffer[pos] = '\0'; - } - } else if(nPresent && n == 2) { //Entire current line - pos = terminal_row * 80; - int endPos = (terminal_row + 1) * 80 - 1; - for(pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } - break; - case 'S': //SU - Scroll Up - term_scroll(true); - break; - case 'T': //SD - Scroll Down - term_scroll(false); - break; - } - } - } - } - -} - -bool isDigit(const char c) { - return c == '0' || c == '1' || c == '2' || c == '3' || - c == '4' || c == '5' || c == '6' || c == '7' || - c == '8' || c == '9'; -} - -void term_scroll(bool down) { - - 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; i++) { - term_buffer[current_pos] = 0; - current_pos += 2; - } - } - - terminal_row = 24; //Start writing on the last line - terminal_column = 0; -} \ No newline at end of file +#include +#include +#include +#include + +#include "kernel/tty.h" +#include "kernel/utils.h" + +static const size_t TERM_WIDTH=80; +static const size_t TERM_HEIGHT=25; + +static size_t terminal_row; +static size_t terminal_column; + +static uint8_t current_color; +static uint16_t* term_buffer; +static uint16_t* const vga_buffer = (uint16_t*) 0xB8000; + +void screen_initialize(void) { + + terminal_row = 0; + terminal_column = 0; + current_color = vga_color_set(LIGHT_GREY, BLACK); + term_buffer = vga_buffer; + + for (size_t y = 0; y < TERM_HEIGHT; y++) { + for(size_t x = 0; x < TERM_WIDTH; x++) { + const size_t offset = y * TERM_WIDTH + x; + term_buffer[offset] = vga_entry(' ', current_color); + } + } +} + +void term_setcolor(enum vga_colors 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; + term_buffer[offset] = vga_entry(c, color); +} + +void term_putchar(char c) { + unsigned char uc = c; + + //Handle escaped characters, such as newline, and crtn. + switch (uc) { + case '\n': + terminal_column = 0; + terminal_row += 1; + break; + default: + term_putentryat(uc, current_color, terminal_column, terminal_row); + if (++terminal_column == TERM_WIDTH) { + terminal_column = 0; + if (++terminal_row == TERM_HEIGHT) { + term_scroll(false); + terminal_row = 0; + } + } + break; + } + +} + +struct csi_sequence parse_csi(const char* data, size_t size) { + enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID }; + enum State state = PARAMETER; + + struct csi_sequence sequence = { + .parameter = NULL, + .parameter_len = 0, + .intermediate = NULL, + .intermediate_len = 0, + .final = NULL, + .valid = false + }; + + for (size_t j = 0; j < size; j++) { + uint8_t c = data[j]; + if (state == PARAMETER && (c >= 0x30 && c <= 0x3F)) { + if (!sequence.parameter) + sequence.parameter = data + j; + sequence.parameter_len++; + } else if (c >= 0x20 && c <= 0x2F) { + if (!sequence.intermediate) + sequence.intermediate = data + j; + sequence.intermediate_len++; + state = INTERMEDIATE; + } else if (c >= 0x40 && c <= 0x7F) { + sequence.final = data + j; + sequence.valid = true; + state = FINAL; + break; + } else { + // Parameter found in intermediate byte location, or byte out of + // range + state = INVALID; + break; + } + } + return sequence; +} + +void term_write(const char* data, size_t size) { + for(size_t i = 0; i < size; i++) { + //Begin handling ANSI escape codes. + if(data[i] == 0x1b) { //The current character is ESC - the start of ANSI codes. + //term_writes("ANSI Code encountered: "); + + bool string_terminated = false; //Flag used in some of the escape codes + + // TODO: Should only progress if we have at least 2 more bytes + + switch ((uint8_t)data[i + 1]) { + case '[': //CSI - Control Sequence Introducer (The most common one, hence it comes first) + { + struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2)); + if (sequence.valid) { + // Send it off to our handler function to keep this part clean + handleControlSequence(sequence); + 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_writes("Single Shift Two\n"); + break; + case 'O': //SS3 - Single Shift Three + term_writes("Single Shift Three\n"); + break; + + //Control Strings + case 'P': //DCS - Device Control String + term_writes("Device Control String"); + string_terminated = false; + break; + case '\\': //ST - String Terminator + term_writes("String Terminator\n"); + string_terminated = true; + break; + case ']': //OSC - Operating System Command + term_writes("Operating System Command\n"); + string_terminated = false; + break; + case 'X': //SOS - Start Of String + term_writes("Start of String"); + string_terminated = false; + break; + case '^': //PM - Privacy Message + term_writes("Privacy Message\n"); + break; + case '_': //APC - Application Program Command + term_writes("Application Program Command\n"); + break; + } + } else { + term_putchar(data[i]); + } + } +} + +void term_writes(const char* data) { + term_write(data, strlen(data)); +} + +void puts(const char* string) { + term_write(string, strlen(string)); + term_putchar('\n'); +} + +void handleControlSequence(struct csi_sequence sequence) { + //Check for our failsafes + + if (sequence.valid) { + int n = 0; //Default of the flag used for a few items + + // Parse parameters, we only care about a max 2 of number only parameters + // for now + int params[2] = {0}; + int param_count = 0; + if (sequence.parameter_len) { + for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) { + char c = sequence.parameter[i]; + if (isDigit(c)) { + n = (n*10) + (sequence.parameter[i] - '0'); + } else if (c == ';') { + params[param_count++] = n; + } + } + params[param_count++] = n; + } + + switch (*(sequence.final)) { + case 'H': case 'f': // CUP - Cursor Position + // TODO: Check to see if we have 2 paramaters + if (params[0]) params[0]--; + if (params[1]) params[1]--; + set_cursor(params[0], params[1]); + break; + case 'A': //CUU - Cursor Up + if (!params[0]) params[0] = 1; + set_cursor(terminal_column, terminal_row - params[0]); + break; + case 'B': //CUD - Cursor Down + if (!params[0]) params[0] = 1; + set_cursor(terminal_column, terminal_row + params[0]); + break; + case 'C': //CUF - Cursor Forward + if (!params[0]) params[0] = 1; + set_cursor(terminal_column + params[0], terminal_row); + break; + case 'D': //CUB - Cursor Back + if (!params[0]) params[0] = 1; + set_cursor(terminal_column - params[0], terminal_row); + break; + case 'E': //CNL - Cursor Next Line + if (!params[0]) params[0] = 1; + set_cursor(0, terminal_row + params[0]); + break; + case 'F': //CPL - Cursor Previous Line + if (!params[0]) params[0] = 1; + set_cursor(0, terminal_row - params[0]); + break; + case 'G': //CHA - Cursor Horizontal Absolute + if (params[0]) params[0]--; + set_cursor(params[0], terminal_row); + break; + case 'J': //ED - Erase in Display + //current cursor pos = y * width + x + { + int pos = terminal_row * 80 + terminal_column; + if (params[0] == 0) { // Clear from cursor to end of screen + for(; pos < (25 * 80); pos++) { + vga_buffer[pos] = '\0'; + } + } 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'; + } + } + } + break; + case 'K': //EL - Erase in Line + { + int pos = terminal_row * 80 + terminal_column; + if(params[0] == 0) { // From cursor to end of line + int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1 + for(; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } 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--) { + vga_buffer[pos] = '\0'; + } + } else if(params[0] == 2) { // Entire current line + pos = terminal_row * 80; + int endPos = (terminal_row + 1) * 80 - 1; + for(; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } + } + break; + case 'S': //SU - Scroll Up + term_scroll(true); + break; + case 'T': //SD - Scroll Down + term_scroll(false); + break; + } + } + +} + +bool isDigit(char c) { + return c >= '0' && c <= '9'; +} + +void set_cursor(int n, int m) { + terminal_column = n; + terminal_row = m; +} + +void term_scroll(bool down) { + + 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; +} diff --git a/include/kernel/tty.h b/include/kernel/tty.h index 25f63cf..503f424 100755 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -1,18 +1,33 @@ -#pragma once - -#include -#include -#include - -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 set_cursor(int, int); -void term_scroll(void); -void int_to_ascii(int, char*); -void int_to_hex(int, char*); -void empty_string(char*); +#pragma once + +#include +#include +#include + +#include "vga.h" + +struct csi_sequence { + const char* parameter; + size_t parameter_len; + const char* intermediate; + size_t intermediate_len; + const char* final; + bool valid; +}; + + +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); From 3fe2d7aa33db11dd45b55f7b143a87cf1268f164 Mon Sep 17 00:00:00 2001 From: Jessica Creighton Date: Wed, 3 Apr 2019 17:46:58 -0400 Subject: [PATCH 2/3] Format files --- .clang-format | 10 + arch/i386/tty.c | 365 ++++++------ include/arch/i386/vga.h | 61 +- include/kernel/tty.h | 1 - include/kernel/utils.h | 8 +- include/vga.h | 57 +- kernel/kernel.c | 41 +- kernel/syscalls.c | 94 +-- kernel/utils.c | 14 +- libc/include/stdio.h | 36 +- libc/include/stdlib.h | 1195 +++++++++++++++++++------------------- libc/include/string.h | 24 +- libc/include/sys/cdefs.h | 8 +- libc/stdio/printf.c | 187 +++--- libc/stdio/putchar.c | 28 +- libc/stdio/puts.c | 8 +- libc/stdlib/abort.c | 28 +- libc/string/memcmp.c | 24 +- libc/string/memmove.c | 26 +- libc/string/memset.c | 14 +- libc/string/strlen.c | 13 +- 21 files changed, 1117 insertions(+), 1125 deletions(-) create mode 100644 .clang-format mode change 100755 => 100644 arch/i386/tty.c mode change 100755 => 100644 include/arch/i386/vga.h mode change 100755 => 100644 include/kernel/tty.h mode change 100755 => 100644 include/vga.h mode change 100755 => 100644 kernel/kernel.c mode change 100755 => 100644 kernel/syscalls.c mode change 100755 => 100644 kernel/utils.c mode change 100755 => 100644 libc/include/stdlib.h mode change 100755 => 100644 libc/include/string.h mode change 100755 => 100644 libc/stdio/printf.c mode change 100755 => 100644 libc/stdio/putchar.c mode change 100755 => 100644 libc/stdlib/abort.c mode change 100755 => 100644 libc/string/memcmp.c mode change 100755 => 100644 libc/string/memmove.c mode change 100755 => 100644 libc/string/memset.c mode change 100755 => 100644 libc/string/strlen.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..61ce89f --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +--- +DerivePointerAlignment: 'true' +SpaceBeforeParens: ControlStatements +UseTab: ForIndentation +IndentWidth: 2 +TabWidth: 2 +ColumnLimit: 120 +BreakBeforeBraces: Attach + +... diff --git a/arch/i386/tty.c b/arch/i386/tty.c old mode 100755 new mode 100644 index 94b9940..7774c35 --- a/arch/i386/tty.c +++ b/arch/i386/tty.c @@ -6,15 +6,15 @@ #include "kernel/tty.h" #include "kernel/utils.h" -static const size_t TERM_WIDTH=80; -static const size_t TERM_HEIGHT=25; +static const size_t TERM_WIDTH = 80; +static const size_t TERM_HEIGHT = 25; static size_t terminal_row; static size_t terminal_column; static uint8_t current_color; 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) { @@ -24,18 +24,16 @@ void screen_initialize(void) { term_buffer = vga_buffer; 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; term_buffer[offset] = vga_entry(' ', current_color); } } } -void term_setcolor(enum vga_colors color) { - current_color = color; -} +void term_setcolor(enum vga_colors color) { current_color = color; } -void term_putentryat (char c, uint8_t color, size_t x, size_t y) { +void term_putentryat(char c, uint8_t color, size_t x, size_t y) { const size_t offset = y * TERM_WIDTH + x; term_buffer[offset] = vga_entry(c, color); } @@ -43,38 +41,35 @@ void term_putentryat (char c, uint8_t color, size_t x, size_t y) { void term_putchar(char c) { unsigned char uc = c; - //Handle escaped characters, such as newline, and crtn. + // Handle escaped characters, such as newline, and crtn. switch (uc) { - case '\n': + case '\n': + terminal_column = 0; + terminal_row += 1; + break; + default: + term_putentryat(uc, current_color, terminal_column, terminal_row); + if (++terminal_column == TERM_WIDTH) { terminal_column = 0; - terminal_row += 1; - break; - default: - term_putentryat(uc, current_color, terminal_column, terminal_row); - if (++terminal_column == TERM_WIDTH) { - terminal_column = 0; - if (++terminal_row == TERM_HEIGHT) { - term_scroll(false); - terminal_row = 0; - } + if (++terminal_row == TERM_HEIGHT) { + term_scroll(false); + terminal_row = 0; } - break; + } + break; } - } struct csi_sequence parse_csi(const char* data, size_t size) { enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID }; enum State state = PARAMETER; - struct csi_sequence sequence = { - .parameter = NULL, - .parameter_len = 0, - .intermediate = NULL, - .intermediate_len = 0, - .final = NULL, - .valid = false - }; + struct csi_sequence sequence = {.parameter = NULL, + .parameter_len = 0, + .intermediate = NULL, + .intermediate_len = 0, + .final = NULL, + .valid = false}; for (size_t j = 0; j < size; j++) { uint8_t c = data[j]; @@ -103,57 +98,56 @@ struct csi_sequence parse_csi(const char* data, size_t size) { } void term_write(const char* data, size_t size) { - for(size_t i = 0; i < size; i++) { - //Begin handling ANSI escape codes. - if(data[i] == 0x1b) { //The current character is ESC - the start of ANSI codes. - //term_writes("ANSI Code encountered: "); + for (size_t i = 0; i < size; i++) { + // Begin handling ANSI escape codes. + if (data[i] == 0x1b) { // The current character is ESC - the start of ANSI codes. + // term_writes("ANSI Code encountered: "); - bool string_terminated = false; //Flag used in some of the escape codes + bool string_terminated = false; // Flag used in some of the escape codes // TODO: Should only progress if we have at least 2 more bytes switch ((uint8_t)data[i + 1]) { - case '[': //CSI - Control Sequence Introducer (The most common one, hence it comes first) - { - struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2)); - if (sequence.valid) { - // Send it off to our handler function to keep this part clean - handleControlSequence(sequence); - 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_writes("Single Shift Two\n"); - break; - case 'O': //SS3 - Single Shift Three - term_writes("Single Shift Three\n"); - break; + case '[': // CSI - Control Sequence Introducer (The most common one, hence it comes first) + { + struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2)); + if (sequence.valid) { + // Send it off to our handler function to keep this part clean + handleControlSequence(sequence); + 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_writes("Single Shift Two\n"); + break; + case 'O': // SS3 - Single Shift Three + term_writes("Single Shift Three\n"); + break; - //Control Strings - case 'P': //DCS - Device Control String - term_writes("Device Control String"); - string_terminated = false; - break; - case '\\': //ST - String Terminator - term_writes("String Terminator\n"); - string_terminated = true; - break; - case ']': //OSC - Operating System Command - term_writes("Operating System Command\n"); - string_terminated = false; - break; - case 'X': //SOS - Start Of String - term_writes("Start of String"); - string_terminated = false; - break; - case '^': //PM - Privacy Message - term_writes("Privacy Message\n"); - break; - case '_': //APC - Application Program Command - term_writes("Application Program Command\n"); - break; + // Control Strings + case 'P': // DCS - Device Control String + term_writes("Device Control String"); + string_terminated = false; + break; + case '\\': // ST - String Terminator + term_writes("String Terminator\n"); + string_terminated = true; + break; + case ']': // OSC - Operating System Command + term_writes("Operating System Command\n"); + string_terminated = false; + break; + case 'X': // SOS - Start Of String + term_writes("Start of String"); + string_terminated = false; + break; + case '^': // PM - Privacy Message + term_writes("Privacy Message\n"); + break; + case '_': // APC - Application Program Command + term_writes("Application Program Command\n"); + break; } } else { term_putchar(data[i]); @@ -161,9 +155,7 @@ void term_write(const char* data, size_t size) { } } -void term_writes(const char* data) { - term_write(data, strlen(data)); -} +void term_writes(const char* data) { term_write(data, strlen(data)); } void puts(const char* string) { term_write(string, strlen(string)); @@ -171,10 +163,10 @@ void puts(const char* string) { } void handleControlSequence(struct csi_sequence sequence) { - //Check for our failsafes + // Check for our failsafes if (sequence.valid) { - int n = 0; //Default of the flag used for a few items + int n = 0; // Default of the flag used for a few items // Parse parameters, we only care about a max 2 of number only parameters // for now @@ -184,7 +176,7 @@ void handleControlSequence(struct csi_sequence sequence) { for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) { char c = sequence.parameter[i]; if (isDigit(c)) { - n = (n*10) + (sequence.parameter[i] - '0'); + n = (n * 10) + (sequence.parameter[i] - '0'); } else if (c == ';') { params[param_count++] = n; } @@ -193,96 +185,103 @@ void handleControlSequence(struct csi_sequence sequence) { } switch (*(sequence.final)) { - case 'H': case 'f': // CUP - Cursor Position - // TODO: Check to see if we have 2 paramaters - if (params[0]) params[0]--; - if (params[1]) params[1]--; - set_cursor(params[0], params[1]); - break; - case 'A': //CUU - Cursor Up - if (!params[0]) params[0] = 1; - set_cursor(terminal_column, terminal_row - params[0]); - break; - case 'B': //CUD - Cursor Down - if (!params[0]) params[0] = 1; - set_cursor(terminal_column, terminal_row + params[0]); - break; - case 'C': //CUF - Cursor Forward - if (!params[0]) params[0] = 1; - set_cursor(terminal_column + params[0], terminal_row); - break; - case 'D': //CUB - Cursor Back - if (!params[0]) params[0] = 1; - set_cursor(terminal_column - params[0], terminal_row); - break; - case 'E': //CNL - Cursor Next Line - if (!params[0]) params[0] = 1; - set_cursor(0, terminal_row + params[0]); - break; - case 'F': //CPL - Cursor Previous Line - if (!params[0]) params[0] = 1; - set_cursor(0, terminal_row - params[0]); - break; - case 'G': //CHA - Cursor Horizontal Absolute - if (params[0]) params[0]--; - set_cursor(params[0], terminal_row); - break; - case 'J': //ED - Erase in Display - //current cursor pos = y * width + x - { - int pos = terminal_row * 80 + terminal_column; - if (params[0] == 0) { // Clear from cursor to end of screen - for(; pos < (25 * 80); pos++) { - vga_buffer[pos] = '\0'; - } - } 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'; - } - } + case 'H': + case 'f': // CUP - Cursor Position + // TODO: Check to see if we have 2 paramaters + if (params[0]) + params[0]--; + if (params[1]) + params[1]--; + set_cursor(params[0], params[1]); + break; + case 'A': // CUU - Cursor Up + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column, terminal_row - params[0]); + break; + case 'B': // CUD - Cursor Down + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column, terminal_row + params[0]); + break; + case 'C': // CUF - Cursor Forward + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column + params[0], terminal_row); + break; + case 'D': // CUB - Cursor Back + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column - params[0], terminal_row); + break; + case 'E': // CNL - Cursor Next Line + if (!params[0]) + params[0] = 1; + set_cursor(0, terminal_row + params[0]); + break; + case 'F': // CPL - Cursor Previous Line + if (!params[0]) + params[0] = 1; + set_cursor(0, terminal_row - params[0]); + break; + case 'G': // CHA - Cursor Horizontal Absolute + if (params[0]) + params[0]--; + set_cursor(params[0], terminal_row); + break; + case 'J': // ED - Erase in Display + { + // current cursor pos = y * width + x + int pos = terminal_row * 80 + terminal_column; + if (params[0] == 0) { // Clear from cursor to end of screen + for (; pos < (25 * 80); pos++) { + vga_buffer[pos] = '\0'; } - break; - case 'K': //EL - Erase in Line - { - int pos = terminal_row * 80 + terminal_column; - if(params[0] == 0) { // From cursor to end of line - int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1 - for(; pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } 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--) { - vga_buffer[pos] = '\0'; - } - } else if(params[0] == 2) { // Entire current line - pos = terminal_row * 80; - int endPos = (terminal_row + 1) * 80 - 1; - for(; pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } + } else if (params[0] == 1) { // Clear from cursor to beginning + for (; pos > 0; pos--) { + vga_buffer[pos] = '\0'; } - break; - case 'S': //SU - Scroll Up - term_scroll(true); - break; - case 'T': //SD - Scroll Down - term_scroll(false); - break; + } 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'; + } + } + break; + } + case 'K': // EL - Erase in Line + { + int pos = terminal_row * 80 + terminal_column; + if (params[0] == 0) { // From cursor to end of line + int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1 + for (; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } 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--) { + vga_buffer[pos] = '\0'; + } + } else if (params[0] == 2) { // Entire current line + pos = terminal_row * 80; + int endPos = (terminal_row + 1) * 80 - 1; + for (; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } + break; + } + case 'S': // SU - Scroll Up + term_scroll(true); + break; + case 'T': // SD - Scroll Down + term_scroll(false); + break; } } - } -bool isDigit(char c) { - return c >= '0' && c <= '9'; -} +bool isDigit(char c) { return c >= '0' && c <= '9'; } void set_cursor(int n, int m) { terminal_column = n; @@ -292,41 +291,43 @@ void set_cursor(int n, int m) { void term_scroll(bool down) { int current_pos; - if(down) { - current_pos = 25 * 80; //Start of the last line. + if (down) { + current_pos = 25 * 80; // Start of the last line. } else { - current_pos = 160; //Start of the second line. + current_pos = 160; // Start of the second line. } - unsigned char* term_buffer = (unsigned char*) vga_buffer; + 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) { + 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 + 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++) { + + 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) { + ; // 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_row = 24; // Start writing on the last line terminal_column = 0; } diff --git a/include/arch/i386/vga.h b/include/arch/i386/vga.h old mode 100755 new mode 100644 index 8dcf15a..e8f3fb7 --- a/include/arch/i386/vga.h +++ b/include/arch/i386/vga.h @@ -1,34 +1,29 @@ -#ifndef ARCH_I386_VGA_H -#define ARCH_I386_VGA_H - -#include - - -enum vga_colors { - BLACK = 0, - BLUE = 1, - GREEN = 2, - CYAN = 3, - RED = 4, - MAGENTA = 5, - BROWN = 6, - LIGHT_GREY = 7, - DARK_GREY = 8, - LIGHT_BLUE = 9, - LIGHT_GREEN = 10, - LIGHT_CYAN = 11, - LIGHT_RED = 12, - LIGHT_MAGENTA = 13, - LIGHT_BROWN = 14, - WHITE = 15 -}; - -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; -} - +#ifndef ARCH_I386_VGA_H +#define ARCH_I386_VGA_H + +#include + +enum vga_colors { + BLACK = 0, + BLUE = 1, + GREEN = 2, + CYAN = 3, + RED = 4, + MAGENTA = 5, + BROWN = 6, + LIGHT_GREY = 7, + DARK_GREY = 8, + LIGHT_BLUE = 9, + LIGHT_GREEN = 10, + LIGHT_CYAN = 11, + LIGHT_RED = 12, + LIGHT_MAGENTA = 13, + LIGHT_BROWN = 14, + WHITE = 15 +}; + +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; } + #endif \ No newline at end of file diff --git a/include/kernel/tty.h b/include/kernel/tty.h old mode 100755 new mode 100644 index 503f424..46f62c2 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -15,7 +15,6 @@ struct csi_sequence { bool valid; }; - void term_setcolor(enum vga_colors); void screen_initialize(void); void term_putentryat(char, uint8_t, size_t, size_t); diff --git a/include/kernel/utils.h b/include/kernel/utils.h index eb23480..7222974 100755 --- a/include/kernel/utils.h +++ b/include/kernel/utils.h @@ -1,5 +1,5 @@ -#include - -/* A temporary file, to get the system compiling. */ - +#include + +/* A temporary file, to get the system compiling. */ + size_t strlen(const char*); \ No newline at end of file diff --git a/include/vga.h b/include/vga.h old mode 100755 new mode 100644 index f69ba70..bdbe852 --- a/include/vga.h +++ b/include/vga.h @@ -1,31 +1,26 @@ -#pragma once - -#include - - -enum vga_colors { - BLACK = 0, - BLUE = 1, - GREEN = 2, - CYAN = 3, - RED = 4, - MAGENTA = 5, - BROWN = 6, - LIGHT_GREY = 7, - DARK_GREY = 8, - LIGHT_BLUE = 9, - LIGHT_GREEN = 10, - LIGHT_CYAN = 11, - LIGHT_RED = 12, - LIGHT_MAGENTA = 13, - LIGHT_BROWN = 14, - WHITE = 15 -}; - -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; -} +#pragma once + +#include + +enum vga_colors { + BLACK = 0, + BLUE = 1, + GREEN = 2, + CYAN = 3, + RED = 4, + MAGENTA = 5, + BROWN = 6, + LIGHT_GREY = 7, + DARK_GREY = 8, + LIGHT_BLUE = 9, + LIGHT_GREEN = 10, + LIGHT_CYAN = 11, + LIGHT_RED = 12, + LIGHT_MAGENTA = 13, + LIGHT_BROWN = 14, + WHITE = 15 +}; + +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; } diff --git a/kernel/kernel.c b/kernel/kernel.c old mode 100755 new mode 100644 index 893c8b3..942601a --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,20 +1,21 @@ -//#include - -#include "kernel/tty.h" - -int kernel_main(void) { - //Prepare the screen, and blank it out. - screen_initialize(); - - //Print a copyright message. - term_writes("(c)"); - term_setcolor(GREEN); - term_writes(" Project"); - term_setcolor(RED); - term_writes("RED"); - term_setcolor(WHITE); - term_writes(", 2019\n"); - - for(;;) {} - return 0; -} \ No newline at end of file +//#include + +#include "kernel/tty.h" + +int kernel_main(void) { + // Prepare the screen, and blank it out. + screen_initialize(); + + // Print a copyright message. + term_writes("(c)"); + term_setcolor(GREEN); + term_writes(" Project"); + term_setcolor(RED); + term_writes("RED"); + term_setcolor(WHITE); + term_writes(", 2019\n"); + + for (;;) { + } + return 0; +} diff --git a/kernel/syscalls.c b/kernel/syscalls.c old mode 100755 new mode 100644 index cfa788c..b7c6994 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -1,48 +1,48 @@ -/*#include -#include -#include -#include -#include -#include -#include - -//prototypes; these are the bare minimum for newlib to compile. - -void _exit(); - -int close(int file); - -char **environ; - -int execve(char *name, char **argv, char **env); - -int fork(); - -int fstat(int file, struct stat *st); - -int getpid(); - -int isatty(int file); - -int kill(int pid, int sig); - -int link(char *old, char *new); - -int lseek(int file, int ptr, int dir); - -int open(const char* name, int flags, ...); - -int read(int file, char* ptr, int len); - -caddr_t sbrk(int incr); - -int stat(const char* file, struct stat *st); - -clock_t times(struct tms* buf); - -int unlink(char* name); - -int wait(int file, char* ptr, int len); - -int gettimeofday(struct timeval* p, struct timezone* z); +/*#include +#include +#include +#include +#include +#include +#include + +//prototypes; these are the bare minimum for newlib to compile. + +void _exit(); + +int close(int file); + +char **environ; + +int execve(char *name, char **argv, char **env); + +int fork(); + +int fstat(int file, struct stat *st); + +int getpid(); + +int isatty(int file); + +int kill(int pid, int sig); + +int link(char *old, char *new); + +int lseek(int file, int ptr, int dir); + +int open(const char* name, int flags, ...); + +int read(int file, char* ptr, int len); + +caddr_t sbrk(int incr); + +int stat(const char* file, struct stat *st); + +clock_t times(struct tms* buf); + +int unlink(char* name); + +int wait(int file, char* ptr, int len); + +int gettimeofday(struct timeval* p, struct timezone* z); */ \ No newline at end of file diff --git a/kernel/utils.c b/kernel/utils.c old mode 100755 new mode 100644 index 739d608..818989b --- a/kernel/utils.c +++ b/kernel/utils.c @@ -1,8 +1,8 @@ -#include - -size_t strlen(const char* string) { - size_t size = 0; - while (string[size]) - size++; - return size; +#include + +size_t strlen(const char* string) { + size_t size = 0; + while (string[size]) + size++; + return size; } \ No newline at end of file diff --git a/libc/include/stdio.h b/libc/include/stdio.h index ba4721d..86d8480 100755 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -1,19 +1,19 @@ -#ifndef _STDIO_H -#define _STDIO_H 1 - -#include - -#define EOF (-1) - -struct __sFile { - int unused; -}; - -typedef struct __sFile FILE; - -#define stderr (_impure_ptr->_stderr) - -int printf(const char* __restrict, ...); -int putchar(int); -int puts(const char*); +#ifndef _STDIO_H +#define _STDIO_H 1 + +#include + +#define EOF (-1) + +struct __sFile { + int unused; +}; + +typedef struct __sFile FILE; + +#define stderr (_impure_ptr->_stderr) + +int printf(const char* __restrict, ...); +int putchar(int); +int puts(const char*); #endif \ No newline at end of file diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h old mode 100755 new mode 100644 index 5a0bc70..f343d50 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -1,601 +1,594 @@ -#ifndef _STDLIB_H -#define _STDLIB_H 1 - -#include - -__attribute__((__noreturn__)) -void abort(void); - -/* - Default header file for malloc-2.8.x, written by Doug Lea - and released to the public domain, as explained at - http://creativecommons.org/publicdomain/zero/1.0/ - - This header is for ANSI C/C++ only. You can set any of - the following #defines before including: - - * If USE_DL_PREFIX is defined, it is assumed that malloc.c - was also compiled with this option, so all routines - have names starting with "dl". - - * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this - file will be #included AFTER . This is needed only if - your system defines a struct mallinfo that is incompatible with the - standard one declared here. Otherwise, you can include this file - INSTEAD of your system system . At least on ANSI, all - declarations should be compatible with system versions - - * If MSPACES is defined, declarations for mspace versions are included. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include /* for size_t */ - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 /* define to a value */ -#elif ONLY_MSPACES != 0 -#define ONLY_MSPACES 1 -#endif /* ONLY_MSPACES */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ - -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ - -#if !ONLY_MSPACES - -#if !NO_MALLINFO -#ifndef HAVE_USR_INCLUDE_MALLOC_H -#ifndef _MALLOC_H -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef STRUCT_MALLINFO_DECLARED -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* _MALLOC_H */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* !NO_MALLINFO */ - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* malloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cuase the current program to abort. -*/ -void free(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* calloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ -void* realloc(void*, size_t); - -/* - realloc_in_place(void* p, size_t n) - Resizes the space allocated for p to size n, only if this can be - done without moving p (i.e., only if there is adjacent space - available if n is greater than p's current allocated size, or n is - less than or equal to p's size). This may be used instead of plain - realloc if an alternative allocation strategy is needed upon failure - to expand space; for example, reallocation of a buffer that must be - memory-aligned or cleared. You can use realloc_in_place to trigger - these alternatives only when needed. - - Returns p if successful; otherwise null. -*/ -void* realloc_in_place(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* memalign(size_t, size_t); - -/* - int posix_memalign(void** pp, size_t alignment, size_t n); - Allocates a chunk of n bytes, aligned in accord with the alignment - argument. Differs from memalign only in that it (1) assigns the - allocated memory to *pp rather than returning it, (2) fails and - returns EINVAL if the alignment is not a power of two (3) fails and - returns ENOMEM if memory cannot be allocated. -*/ -int posix_memalign(void**, size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* valloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt: - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int mallopt(int, int); - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t malloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t malloc_max_footprint(void); - -/* - malloc_footprint_limit(); - Returns the number of bytes that the heap is allowed to obtain from - the system, returning the last value returned by - malloc_set_footprint_limit, or the maximum size_t value if - never set. The returned value reflects a permission. There is no - guarantee that this number of bytes can actually be obtained from - the system. -*/ -size_t malloc_footprint_limit(void); - -/* - malloc_set_footprint_limit(); - Sets the maximum number of bytes to obtain from the system, causing - failure returns from malloc and related functions upon attempts to - exceed this value. The argument value may be subject to page - rounding to an enforceable limit; this actual value is returned. - Using an argument of the maximum possible size_t effectively - disables checks. If the argument is less than or equal to the - current malloc_footprint, then all future allocations that require - additional system memory will fail. However, invocation cannot - retroactively deallocate existing used memory. -*/ -size_t malloc_set_footprint_limit(size_t bytes); - -/* - malloc_inspect_all(void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg); - Traverses the heap and calls the given handler for each managed - region, skipping all bytes that are (or may be) used for bookkeeping - purposes. Traversal does not include include chunks that have been - directly memory mapped. Each reported region begins at the start - address, and continues up to but not including the end address. The - first used_bytes of the region contain allocated data. If - used_bytes is zero, the region is unallocated. The handler is - invoked with the given callback argument. If locks are defined, they - are held during the entire traversal. It is a bad idea to invoke - other malloc functions from within the handler. - - For example, to count the number of in-use chunks with size greater - than 1000, you could write: - static int count = 0; - void count_chunks(void* start, void* end, size_t used, void* arg) { - if (used >= 1000) ++count; - } - then: - malloc_inspect_all(count_chunks, NULL); - - malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. -*/ -void malloc_inspect_all(void(*handler)(void*, void *, size_t, void*), - void* arg); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ - -struct mallinfo mallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** independent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** independent_comalloc(size_t, size_t*, void**); - -/* - bulk_free(void* array[], size_t n_elements) - Frees and clears (sets to null) each non-null pointer in the given - array. This is likely to be faster than freeing them one-by-one. - If footers are used, pointers that have been allocated in different - mspaces are not freed or cleared, and the count of all such pointers - is returned. For large arrays of pointers with poor locality, it - may be worthwhile to sort this array before calling bulk_free. -*/ -size_t bulk_free(void**, size_t n_elements); - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* pvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int malloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. - - malloc_stats is not compiled if NO_MALLOC_STATS is defined. -*/ -void malloc_stats(void); - -#endif /* !ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t malloc_usable_size(const void*); - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_track_large_chunks controls whether requests for large chunks - are allocated in their own untracked mmapped regions, separate from - others in this mspace. By default large chunks are not tracked, - which reduces fragmentation. However, such chunks are not - necessarily released to the system upon destroy_mspace. Enabling - tracking by setting to true may increase fragmentation, but avoids - leakage when relying on destroy_mspace to release all memory - allocated using this space. The function returns the previous - setting. -*/ -int mspace_track_large_chunks(mspace msp, int enable); - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -/* - The following operate identically to their malloc counterparts - but operate only for the given mspace argument -*/ -void* mspace_malloc(mspace msp, size_t bytes); -void mspace_free(mspace msp, void* mem); -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); -void* mspace_realloc(mspace msp, void* mem, size_t newsize); -void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize); -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); -size_t mspace_bulk_free(mspace msp, void**, size_t n_elements); -size_t mspace_usable_size(const void* mem); -void mspace_malloc_stats(mspace msp); -int mspace_trim(mspace msp, size_t pad); -size_t mspace_footprint(mspace msp); -size_t mspace_max_footprint(mspace msp); -size_t mspace_footprint_limit(mspace msp); -size_t mspace_set_footprint_limit(mspace msp, size_t bytes); -void mspace_inspect_all(mspace msp, - void(*handler)(void *, void *, size_t, void*), - void* arg); -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif - -#endif /* MALLOC_280_H */ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#include + +__attribute__((__noreturn__)) void abort(void); + +/* + Default header file for malloc-2.8.x, written by Doug Lea + and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ + + This header is for ANSI C/C++ only. You can set any of + the following #defines before including: + + * If USE_DL_PREFIX is defined, it is assumed that malloc.c + was also compiled with this option, so all routines + have names starting with "dl". + + * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this + file will be #included AFTER . This is needed only if + your system defines a struct mallinfo that is incompatible with the + standard one declared here. Otherwise, you can include this file + INSTEAD of your system system . At least on ANSI, all + declarations should be compatible with system versions + + * If MSPACES is defined, declarations for mspace versions are included. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* for size_t */ + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 /* define to a value */ +#elif ONLY_MSPACES != 0 +#define ONLY_MSPACES 1 +#endif /* ONLY_MSPACES */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ + +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ + +#if !ONLY_MSPACES + +#if !NO_MALLINFO +#ifndef HAVE_USR_INCLUDE_MALLOC_H +#ifndef _MALLOC_H +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ +#ifndef STRUCT_MALLINFO_DECLARED +#define STRUCT_MALLINFO_DECLARED 1 +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +}; +#endif /* STRUCT_MALLINFO_DECLARED */ +#endif /* _MALLOC_H */ +#endif /* HAVE_USR_INCLUDE_MALLOC_H */ +#endif /* !NO_MALLINFO */ + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +void* malloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cuase the current program to abort. +*/ +void free(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void* calloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ +void* realloc(void*, size_t); + +/* + realloc_in_place(void* p, size_t n) + Resizes the space allocated for p to size n, only if this can be + done without moving p (i.e., only if there is adjacent space + available if n is greater than p's current allocated size, or n is + less than or equal to p's size). This may be used instead of plain + realloc if an alternative allocation strategy is needed upon failure + to expand space; for example, reallocation of a buffer that must be + memory-aligned or cleared. You can use realloc_in_place to trigger + these alternatives only when needed. + + Returns p if successful; otherwise null. +*/ +void* realloc_in_place(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void* memalign(size_t, size_t); + +/* + int posix_memalign(void** pp, size_t alignment, size_t n); + Allocates a chunk of n bytes, aligned in accord with the alignment + argument. Differs from memalign only in that it (1) assigns the + allocated memory to *pp rather than returning it, (2) fails and + returns EINVAL if the alignment is not a power of two (3) fails and + returns ENOMEM if memory cannot be allocated. +*/ +int posix_memalign(void**, size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void* valloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt: + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +int mallopt(int, int); + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +size_t malloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +size_t malloc_max_footprint(void); + +/* + malloc_footprint_limit(); + Returns the number of bytes that the heap is allowed to obtain from + the system, returning the last value returned by + malloc_set_footprint_limit, or the maximum size_t value if + never set. The returned value reflects a permission. There is no + guarantee that this number of bytes can actually be obtained from + the system. +*/ +size_t malloc_footprint_limit(void); + +/* + malloc_set_footprint_limit(); + Sets the maximum number of bytes to obtain from the system, causing + failure returns from malloc and related functions upon attempts to + exceed this value. The argument value may be subject to page + rounding to an enforceable limit; this actual value is returned. + Using an argument of the maximum possible size_t effectively + disables checks. If the argument is less than or equal to the + current malloc_footprint, then all future allocations that require + additional system memory will fail. However, invocation cannot + retroactively deallocate existing used memory. +*/ +size_t malloc_set_footprint_limit(size_t bytes); + +/* + malloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg); + Traverses the heap and calls the given handler for each managed + region, skipping all bytes that are (or may be) used for bookkeeping + purposes. Traversal does not include include chunks that have been + directly memory mapped. Each reported region begins at the start + address, and continues up to but not including the end address. The + first used_bytes of the region contain allocated data. If + used_bytes is zero, the region is unallocated. The handler is + invoked with the given callback argument. If locks are defined, they + are held during the entire traversal. It is a bad idea to invoke + other malloc functions from within the handler. + + For example, to count the number of in-use chunks with size greater + than 1000, you could write: + static int count = 0; + void count_chunks(void* start, void* end, size_t used, void* arg) { + if (used >= 1000) ++count; + } + then: + malloc_inspect_all(count_chunks, NULL); + + malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. +*/ +void malloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg); + +#if !NO_MALLINFO +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ + +struct mallinfo mallinfo(void); +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +void** independent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +void** independent_comalloc(size_t, size_t*, void**); + +/* + bulk_free(void* array[], size_t n_elements) + Frees and clears (sets to null) each non-null pointer in the given + array. This is likely to be faster than freeing them one-by-one. + If footers are used, pointers that have been allocated in different + mspaces are not freed or cleared, and the count of all such pointers + is returned. For large arrays of pointers with poor locality, it + may be worthwhile to sort this array before calling bulk_free. +*/ +size_t bulk_free(void**, size_t n_elements); + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void* pvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +int malloc_trim(size_t); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. + + malloc_stats is not compiled if NO_MALLOC_STATS is defined. +*/ +void malloc_stats(void); + +#endif /* !ONLY_MSPACES */ + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t malloc_usable_size(const void*); + +#if MSPACES + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_track_large_chunks controls whether requests for large chunks + are allocated in their own untracked mmapped regions, separate from + others in this mspace. By default large chunks are not tracked, + which reduces fragmentation. However, such chunks are not + necessarily released to the system upon destroy_mspace. Enabling + tracking by setting to true may increase fragmentation, but avoids + leakage when relying on destroy_mspace to release all memory + allocated using this space. The function returns the previous + setting. +*/ +int mspace_track_large_chunks(mspace msp, int enable); + +#if !NO_MALLINFO +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ + +/* + An alias for mallopt. +*/ +int mspace_mallopt(int, int); + +/* + The following operate identically to their malloc counterparts + but operate only for the given mspace argument +*/ +void* mspace_malloc(mspace msp, size_t bytes); +void mspace_free(mspace msp, void* mem); +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); +void* mspace_realloc(mspace msp, void* mem, size_t newsize); +void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize); +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); +void** mspace_independent_calloc(mspace msp, size_t n_elements, size_t elem_size, void* chunks[]); +void** mspace_independent_comalloc(mspace msp, size_t n_elements, size_t sizes[], void* chunks[]); +size_t mspace_bulk_free(mspace msp, void**, size_t n_elements); +size_t mspace_usable_size(const void* mem); +void mspace_malloc_stats(mspace msp); +int mspace_trim(mspace msp, size_t pad); +size_t mspace_footprint(mspace msp); +size_t mspace_max_footprint(mspace msp); +size_t mspace_footprint_limit(mspace msp); +size_t mspace_set_footprint_limit(mspace msp, size_t bytes); +void mspace_inspect_all(mspace msp, void (*handler)(void*, void*, size_t, void*), void* arg); +#endif /* MSPACES */ + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif + +#endif /* MALLOC_280_H */ diff --git a/libc/include/string.h b/libc/include/string.h old mode 100755 new mode 100644 index e33fa44..5fde42f --- a/libc/include/string.h +++ b/libc/include/string.h @@ -1,13 +1,13 @@ -#ifndef _STRING_H -#define _STRING_H 1 - -#include -#include - -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*); - +#ifndef _STRING_H +#define _STRING_H 1 + +#include +#include + +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*); + #endif \ No newline at end of file diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index 2d557b4..4ef309d 100755 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -1,5 +1,5 @@ -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H 1 - -#define __red_libc 1 +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H 1 + +#define __red_libc 1 #endif \ No newline at end of file diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c old mode 100755 new mode 100644 index caee4b3..71d4ee8 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -1,94 +1,93 @@ -#include -#include -#include -#include -#include - -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 - writen; - - if(format[0] != '%' || format[1] == '%') { - if(format[0] == '%') - format++; - size_t amount = 1; - - while (format[amount] && format[amount] != '%') - amount++; - - if(maxrem < amount) { - //TODO: Set an OVERFLOW error - return -1; - } - - if ((!print(format, amount)) - return -1; - - format += amount; - written += amount; - continue; - } - - const char* first_format = format++; - - switch(*format) { - case 'c': - format++; - char c = (char) va_arg(parameters, int); - if(!maxrem) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(&c, sizeof(c))) - return -1; - written++; - break; - case 's': - format++; - - const char* str = va_arg(parameters, const char*); - size_t len = strlen(str); - - if(maxrem < len) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(str, len)) - return -1; - - written += len; - break; - default: - format = first_format; - size_t len = strlen(format); - if(maxrem < len) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(format, len)) - return -1; - written += len; - format += len; - break; - } - } - - va_end(parameters); - return written; -} +#include +#include +#include +#include +#include + +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 - writen; + + if (format[0] != '%' || format[1] == '%') { + if (format[0] == '%') + format++; + size_t amount = 1; + + while (format[amount] && format[amount] != '%') + amount++; + + if (maxrem < amount) { + // TODO: Set an OVERFLOW error + return -1; + } + + if ((!print(format, amount)) + return -1; + + format += amount; + written += amount; + continue; + } + + const char* first_format = format++; + + switch (*format) { + case 'c': + format++; + char c = (char)va_arg(parameters, int); + if (!maxrem) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(&c, sizeof(c))) + return -1; + written++; + break; + case 's': + format++; + + const char* str = va_arg(parameters, const char*); + size_t len = strlen(str); + + if (maxrem < len) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(str, len)) + return -1; + + written += len; + break; + default: + format = first_format; + size_t len = strlen(format); + if (maxrem < len) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(format, len)) + return -1; + written += len; + format += len; + break; + } + } + + va_end(parameters); + return written; +} diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c old mode 100755 new mode 100644 index eba2d17..a969318 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -1,15 +1,15 @@ -#include - -#if defined(__is_libk) -#include -#endif - -int putchar(int ic) { -#if defined(__is_libk) - char c = (char) ic; - term_write(&c, sizeof(c)); -#else - //TODO: Implement stdio & the write call -#endif - return ic; +#include + +#if defined(__is_libk) +#include +#endif + +int putchar(int ic) { +#if defined(__is_libk) + char c = (char)ic; + term_write(&c, sizeof(c)); +#else + // TODO: Implement stdio & the write call +#endif + return ic; } \ No newline at end of file diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c index ea900cb..54a7185 100755 --- a/libc/stdio/puts.c +++ b/libc/stdio/puts.c @@ -1,5 +1,5 @@ -#include - -int puts(const char* string) { - return printf("%s\n"), string); +#include + +int puts(const char* string) { + return printf("%s\n"), string); } \ No newline at end of file diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c old mode 100755 new mode 100644 index 8bf0f45..3537af8 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -1,15 +1,15 @@ -#include -#include - -__attribute__((__noreturn__)) -void abort(void) { - -#if defined(__is_libk) - //TODO: Kernel panic. - printf(">>PANIC<<<\n abort() panicked!\n"); -#else - printf("abort() called\n"); -#endif - while(1) {} - __builtin_unreachable(); +#include +#include + +__attribute__((__noreturn__)) void abort(void) { + +#if defined(__is_libk) + // TODO: Kernel panic. + printf(">>PANIC<<<\n abort() panicked!\n"); +#else + printf("abort() called\n"); +#endif + while (1) { + } + __builtin_unreachable(); } \ No newline at end of file diff --git a/libc/string/memcmp.c b/libc/string/memcmp.c old mode 100755 new mode 100644 index b060501..dfb04f0 --- a/libc/string/memcmp.c +++ b/libc/string/memcmp.c @@ -1,13 +1,13 @@ -#include - -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; - } +#include + +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; \ No newline at end of file diff --git a/libc/string/memmove.c b/libc/string/memmove.c old mode 100755 new mode 100644 index 87c171f..7d3ea22 --- a/libc/string/memmove.c +++ b/libc/string/memmove.c @@ -1,14 +1,14 @@ -#include - -void* memmove(void* dstptr, const void* srcptr, size_t size) { - unsigned char* dst = (unsigned char*) dstptr; - const unsigned char* stc = (const unsigned char*) srcptr; - if(dst < src) { - for(size_t i = o; i < size; i++) - dst[i] = src[i]; - } else { - for(size_t i = size; i != 0; i--) - dst[i-1] = src[i-1]; - } - return dstptr; +#include + +void* memmove(void* dstptr, const void* srcptr, size_t size) { + unsigned char* dst = (unsigned char*)dstptr; + const unsigned char* stc = (const unsigned char*)srcptr; + if (dst < src) { + for (size_t i = o; i < size; i++) + dst[i] = src[i]; + } else { + for (size_t i = size; i != 0; i--) + dst[i - 1] = src[i - 1]; + } + return dstptr; } \ No newline at end of file diff --git a/libc/string/memset.c b/libc/string/memset.c old mode 100755 new mode 100644 index f16ce62..4481c30 --- a/libc/string/memset.c +++ b/libc/string/memset.c @@ -1,8 +1,8 @@ -#include - -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; +#include + +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; } \ No newline at end of file diff --git a/libc/string/strlen.c b/libc/string/strlen.c old mode 100755 new mode 100644 index 998b46d..dfc005c --- a/libc/string/strlen.c +++ b/libc/string/strlen.c @@ -1,8 +1,7 @@ -#include - -size_t strlen(const char* str) { - size_t len = 0; - while (str[len]) - len++ - return len; +#include + +size_t strlen(const char* str) { + size_t len = 0; + while (str[len]) + len++ return len; } \ No newline at end of file From 92a1a2fb80a9f3e7de25ce1e4f6ff593d865b884 Mon Sep 17 00:00:00 2001 From: Jessica Creighton Date: Wed, 3 Apr 2019 17:49:38 -0400 Subject: [PATCH 3/3] Add .gitignore and remove ignored files --- .gitignore | 59 ++++++++++++++++++++++++++++++++++++++++++++ iso/boot/kernel.elf | Bin 20844 -> 0 bytes 2 files changed, 59 insertions(+) create mode 100644 .gitignore delete mode 100755 iso/boot/kernel.elf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5cdcfc8 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/iso/boot/kernel.elf b/iso/boot/kernel.elf deleted file mode 100755 index 6e87838f52d2e1f9067959dc1078f4eba0146433..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20844 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