diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index f8f5048..323b431 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -20,6 +20,14 @@ if (DOXYGEN_FOUND) set(DOXYGEN_SHOW_INCLUDE_FILES NO) set(DOXYGEN_GENERATE_TREEVIEW NO) set(DOXYGEN_WARN_NO_PARAMDOC YES) + + set(DOXYGEN_ENABLE_PREPROCESSING YES) + set(DOXYGEN_EXTRACT_STATIC YES) + set(DOXYGEN_MACRO_EXPANSION YES) + set(DOXYGEN_EXPAND_ONLY_PREDEF YES) + set(DOXYGEN_PREDEFINED "__attribute__((x))= _syscall0= _syscall0(x)= _syscall1(x)= _syscall2(x)= _syscall3(x)=") + + set(DOXYGEN_WARN_FORMAT "$file($line): $text") set(DOXYGEN_HTML_STYLESHEET ${PROJECT_SOURCE_DIR}/doc/doxygen.css) doxygen_add_docs( ${PROJECT_NAME}_documentation @@ -164,8 +172,6 @@ if (DOXYGEN_FOUND) ${PROJECT_SOURCE_DIR}/mentos/inc/hardware/pic8259.h ${PROJECT_SOURCE_DIR}/mentos/inc/hardware/timer.h ${PROJECT_SOURCE_DIR}/mentos/inc/io/debug.h - ${PROJECT_SOURCE_DIR}/mentos/inc/io/mm_io.h - ${PROJECT_SOURCE_DIR}/mentos/inc/io/port_io.h ${PROJECT_SOURCE_DIR}/mentos/inc/io/proc_modules.h ${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga.h ${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga_font.h diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index ac759d2..bd8ae41 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -99,6 +99,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/abort.c ${PROJECT_SOURCE_DIR}/src/io/mm_io.c ${PROJECT_SOURCE_DIR}/src/io/port_io.c + ${PROJECT_SOURCE_DIR}/src/io/debug.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc.c ${PROJECT_SOURCE_DIR}/src/sys/unistd.c ${PROJECT_SOURCE_DIR}/src/sys/errno.c @@ -137,7 +138,6 @@ add_library( ${PROJECT_SOURCE_DIR}/src/unistd/signal.c ${PROJECT_SOURCE_DIR}/src/unistd/interval.c ${PROJECT_SOURCE_DIR}/src/libc_start.c - ${PROJECT_SOURCE_DIR}/src/debug.c ${PROJECT_SOURCE_DIR}/src/crt0.S ) diff --git a/libc/inc/debug.h b/libc/inc/debug.h deleted file mode 100644 index 39c52fc..0000000 --- a/libc/inc/debug.h +++ /dev/null @@ -1,44 +0,0 @@ -/// @file debug.h -/// @brief Debugging primitives. -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. - -#pragma once - -#ifndef __DEBUG_HEADER__ -/// Header for identifying outputs coming from a mechanism. -#define __DEBUG_HEADER__ -#endif - -/// @brief Extract the filename from the full path provided by __FILE__. -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) - -/// @brief Prints the given character to debug output. -/// @param c The character to print. -void dbg_putchar(char c); - -/// @brief Prints the given string to debug output. -/// @param s The string to print. -void dbg_puts(const char *s); - -/// @brief Prints the given string to the debug output. -/// @param file The name of the file. -/// @param fun The name of the function. -/// @param line The line inside the file. -/// @param format The format to used, see printf. -/// @param ... The list of arguments. -void dbg_printf(const char *file, const char *fun, int line, const char *format, ...); - -/// @brief Transforms the given amount of bytes to a readable string. -/// @param bytes The bytes to turn to string. -/// @return String representing the bytes in human readable form. -const char *to_human_size(unsigned long bytes); - -/// @brief Transforms the given value to a binary string. -/// @param value to print. -/// @param length of the binary output. -/// @return String representing the binary value. -const char *dec_to_binary(unsigned long value, unsigned length); - -/// Prints a debugging message. -#define pr_debug(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__ __VA_ARGS__) diff --git a/libc/inc/io/ansi_colors.h b/libc/inc/io/ansi_colors.h new file mode 100644 index 0000000..d4189d7 --- /dev/null +++ b/libc/inc/io/ansi_colors.h @@ -0,0 +1,63 @@ +/// @file ansi_colors.h +/// @author Enrico Fraccaroli (enry.frak@gmail.com) +/// @brief List of ANSI colors. +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#pragma once + +#define FG_RESET "\033[0m" ///< ANSI code for resetting. + +#define FG_BLACK "\033[30m" ///< ANSI code for setting a BLACK foreground. +#define FG_RED "\033[31m" ///< ANSI code for setting a RED foreground. +#define FG_GREEN "\033[32m" ///< ANSI code for setting a GREEN foreground. +#define FG_YELLOW "\033[33m" ///< ANSI code for setting a YELLOW foreground. +#define FG_BLUE "\033[34m" ///< ANSI code for setting a BLUE foreground. +#define FG_MAGENTA "\033[35m" ///< ANSI code for setting a MAGENTA foreground. +#define FG_CYAN "\033[36m" ///< ANSI code for setting a CYAN foreground. +#define FG_WHITE "\033[37m" ///< ANSI code for setting a WHITE foreground. + +#define FG_BLACK_BOLD "\033[1;30m" ///< ANSI code for setting a BLACK foreground. +#define FG_RED_BOLD "\033[1;31m" ///< ANSI code for setting a RED foreground. +#define FG_GREEN_BOLD "\033[1;32m" ///< ANSI code for setting a GREEN foreground. +#define FG_YELLOW_BOLD "\033[1;33m" ///< ANSI code for setting a YELLOW foreground. +#define FG_BLUE_BOLD "\033[1;34m" ///< ANSI code for setting a BLUE foreground. +#define FG_MAGENTA_BOLD "\033[1;35m" ///< ANSI code for setting a MAGENTA foreground. +#define FG_CYAN_BOLD "\033[1;36m" ///< ANSI code for setting a CYAN foreground. +#define FG_WHITE_BOLD "\033[1;37m" ///< ANSI code for setting a WHITE foreground. + +#define FG_BLACK_BRIGHT "\033[90m" ///< ANSI code for setting a BRIGHT_BLACK foreground. +#define FG_RED_BRIGHT "\033[91m" ///< ANSI code for setting a BRIGHT_RED foreground. +#define FG_GREEN_BRIGHT "\033[92m" ///< ANSI code for setting a BRIGHT_GREEN foreground. +#define FG_YELLOW_BRIGHT "\033[93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground. +#define FG_BLUE_BRIGHT "\033[94m" ///< ANSI code for setting a BRIGHT_BLUE foreground. +#define FG_MAGENTA_BRIGHT "\033[95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground. +#define FG_CYAN_BRIGHT "\033[96m" ///< ANSI code for setting a BRIGHT_CYAN foreground. +#define FG_WHITE_BRIGHT "\033[97m" ///< ANSI code for setting a BRIGHT_WHITE foreground. + +#define FG_BLACK_BRIGHT_BOLD "\033[1;90m" ///< ANSI code for setting a BRIGHT_BLACK foreground. +#define FG_RED_BRIGHT_BOLD "\033[1;91m" ///< ANSI code for setting a BRIGHT_RED foreground. +#define FG_GREEN_BRIGHT_BOLD "\033[1;92m" ///< ANSI code for setting a BRIGHT_GREEN foreground. +#define FG_YELLOW_BRIGHT_BOLD "\033[1;93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground. +#define FG_BLUE_BRIGHT_BOLD "\033[1;94m" ///< ANSI code for setting a BRIGHT_BLUE foreground. +#define FG_MAGENTA_BRIGHT_BOLD "\033[1;95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground. +#define FG_CYAN_BRIGHT_BOLD "\033[1;96m" ///< ANSI code for setting a BRIGHT_CYAN foreground. +#define FG_WHITE_BRIGHT_BOLD "\033[1;97m" ///< ANSI code for setting a BRIGHT_WHITE foreground. + +#define BG_BLACK "\033[40m" ///< ANSI code for setting a BLACK background. +#define BG_RED "\033[41m" ///< ANSI code for setting a RED background. +#define BG_GREEN "\033[42m" ///< ANSI code for setting a GREEN background. +#define BG_YELLOW "\033[43m" ///< ANSI code for setting a YELLOW background. +#define BG_BLUE "\033[44m" ///< ANSI code for setting a BLUE background. +#define BG_MAGENTA "\033[45m" ///< ANSI code for setting a MAGENTA background. +#define BG_CYAN "\033[46m" ///< ANSI code for setting a CYAN background. +#define BG_WHITE "\033[47m" ///< ANSI code for setting a WHITE background. + +#define BG_BRIGHT_BLACK "\033[100m" ///< ANSI code for setting a BRIGHT_BLACK background. +#define BG_BRIGHT_RED "\033[101m" ///< ANSI code for setting a BRIGHT_RED background. +#define BG_BRIGHT_GREEN "\033[102m" ///< ANSI code for setting a BRIGHT_GREEN background. +#define BG_BRIGHT_YELLOW "\033[103m" ///< ANSI code for setting a BRIGHT_YELLOW background. +#define BG_BRIGHT_BLUE "\033[104m" ///< ANSI code for setting a BRIGHT_BLUE background. +#define BG_BRIGHT_MAGENTA "\033[105m" ///< ANSI code for setting a BRIGHT_MAGENTA background. +#define BG_BRIGHT_CYAN "\033[106m" ///< ANSI code for setting a BRIGHT_CYAN background. +#define BG_BRIGHT_WHITE "\033[107m" ///< ANSI code for setting a BRIGHT_WHITE background. diff --git a/mentos/inc/io/debug.h b/libc/inc/io/debug.h similarity index 71% rename from mentos/inc/io/debug.h rename to libc/inc/io/debug.h index 45dac64..f53938e 100644 --- a/mentos/inc/io/debug.h +++ b/libc/inc/io/debug.h @@ -7,10 +7,8 @@ #include "sys/kernel_levels.h" -struct pt_regs; - #ifndef __DEBUG_LEVEL__ -/// Defines the debug level. +/// Defines the debug level, by default we set it to notice. #define __DEBUG_LEVEL__ LOGLEVEL_NOTICE #endif @@ -39,17 +37,14 @@ void dbg_putchar(char c); void dbg_puts(const char *s); /// @brief Prints the given string to the debug output. -/// @param file The name of the file. -/// @param fun The name of the function. -/// @param line The line inside the file. -/// @param header The header to print. -/// @param format The format to used, see printf. -/// @param ... The list of arguments. -void dbg_printf(const char *file, const char *fun, int line, char *header, const char *format, ...); - -/// @brief Prints the registers on debug output. -/// @param frame Pointer to the register. -void dbg_print_regs(struct pt_regs *frame); +/// @param file the name of the file. +/// @param fun the name of the function. +/// @param line the line inside the file. +/// @param header the header to print. +/// @param log_level the log level. +/// @param format the format to used, see printf. +/// @param ... the list of arguments. +void dbg_printf(const char *file, const char *fun, int line, char *header, short log_level, const char *format, ...); /// @brief Transforms the given amount of bytes to a readable string. /// @param bytes The bytes to turn to string. @@ -62,53 +57,71 @@ const char *to_human_size(unsigned long bytes); /// @return String representing the binary value. const char *dec_to_binary(unsigned long value, unsigned length); -/// Prints a KERN_DEFAULT. -#define pr_default(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_DEFAULT __VA_ARGS__) -/// Prints a KERN_EMERG. +/// Prints a default message, which is always shown. +#define pr_default(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_DEFAULT, __VA_ARGS__) + +/// Prints an emergency message. #if __DEBUG_LEVEL__ >= LOGLEVEL_EMERG -#define pr_emerg(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_EMERG __VA_ARGS__) +#define pr_emerg(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_EMERG, __VA_ARGS__) #else #define pr_emerg(...) #endif -/// Prints a KERN_ALERT. + +/// Prints an alert message. #if __DEBUG_LEVEL__ >= LOGLEVEL_ALERT -#define pr_alert(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_ALERT __VA_ARGS__) +#define pr_alert(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_ALERT, __VA_ARGS__) #else #define pr_alert(...) #endif -/// Prints a KERN_CRIT. + +/// Prints a critical message. #if __DEBUG_LEVEL__ >= LOGLEVEL_CRIT -#define pr_crit(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_CRIT __VA_ARGS__) +#define pr_crit(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_CRIT, __VA_ARGS__) #else #define pr_crit(...) #endif -/// Prints a KERN_ERR. + +/// Prints an error message. #if __DEBUG_LEVEL__ >= LOGLEVEL_ERR -#define pr_err(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_ERR __VA_ARGS__) +#define pr_err(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_ERR, __VA_ARGS__) #else #define pr_err(...) #endif -/// Prints a KERN_WARNING. + +/// Prints a warning message. #if __DEBUG_LEVEL__ >= LOGLEVEL_WARNING -#define pr_warning(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_WARNING __VA_ARGS__) +#define pr_warning(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_WARNING, __VA_ARGS__) #else #define pr_warning(...) #endif -/// Prints a KERN_NOTICE. + +/// Prints a notice message. #if __DEBUG_LEVEL__ >= LOGLEVEL_NOTICE -#define pr_notice(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_NOTICE __VA_ARGS__) +#define pr_notice(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_NOTICE, __VA_ARGS__) #else #define pr_notice(...) #endif -/// Prints a KERN_INFO. + +/// Prints a info message. #if __DEBUG_LEVEL__ >= LOGLEVEL_INFO -#define pr_info(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_INFO __VA_ARGS__) +#define pr_info(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_INFO, __VA_ARGS__) #else #define pr_info(...) #endif -/// Prints a KERN_DEBUG. + +/// Prints a debug message. #if __DEBUG_LEVEL__ >= LOGLEVEL_DEBUG -#define pr_debug(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, KERN_DEBUG __VA_ARGS__) +#define pr_debug(...) dbg_printf(__FILENAME__, __func__, __LINE__, __DEBUG_HEADER__, LOGLEVEL_DEBUG, __VA_ARGS__) #else #define pr_debug(...) #endif + +#ifdef __KERNEL__ + +struct pt_regs; + +/// @brief Prints the registers on debug output. +/// @param frame Pointer to the register. +void dbg_print_regs(struct pt_regs *frame); + +#endif \ No newline at end of file diff --git a/libc/inc/io/mm_io.h b/libc/inc/io/mm_io.h index 1eecdae..b64cf46 100644 --- a/libc/inc/io/mm_io.h +++ b/libc/inc/io/mm_io.h @@ -8,19 +8,31 @@ #include "stdint.h" /// @brief Reads a 8-bit value from the given address. +/// @param addr the address we want to read from. +/// @return the value we read. uint8_t in_memb(uint32_t addr); /// @brief Reads a 16-bit value from the given address. +/// @param addr the address we want to read from. +/// @return the value we read. uint16_t in_mems(uint32_t addr); /// @brief Reads a 32-bit value from the given address. +/// @param addr the address we want to read from. +/// @return the value we read. uint32_t in_meml(uint32_t addr); /// @brief Writes a 8-bit value at the given address. +/// @param addr the address we want to write to. +/// @param value the value we want to write. void out_memb(uint32_t addr, uint8_t value); /// @brief Writes a 16-bit value at the given address. +/// @param addr the address we want to write to. +/// @param value the value we want to write. void out_mems(uint32_t addr, uint16_t value); /// @brief Writes a 32-bit value at the given address. +/// @param addr the address we want to write to. +/// @param value the value we want to write. void out_meml(uint32_t addr, uint32_t value); diff --git a/libc/inc/io/port_io.h b/libc/inc/io/port_io.h index 2f6871c..9094640 100644 --- a/libc/inc/io/port_io.h +++ b/libc/inc/io/port_io.h @@ -7,36 +7,44 @@ #include "stdint.h" -/// @brief Used for reading from the I/O ports. -/// @param port The input port. -/// @return The read value. +/// @brief Reads a 8-bit value from the given port. +/// @param port the port we want to read from. +/// @return the value we read. uint8_t inportb(uint16_t port); -/// @brief Used for reading 2 bytes from the I/O ports. -/// @param port The input port. -/// @return The read value. +/// @brief Reads a 16-bit value from the given port. +/// @param port the port we want to read from. +/// @return the value we read. uint16_t inports(uint16_t port); -void inportsm(uint16_t port, uint8_t *data, unsigned long size); - -/// @brief Used for reading 4 bytes from the I/O ports. -/// @param port The input port. -/// @return The read value. +/// @brief Reads a 32-bit value from the given port. +/// @param port the port we want to read from. +/// @return the value we read. uint32_t inportl(uint16_t port); -/// @brief Use this to write to I/O ports to send bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outportb(uint16_t port, uint8_t data); +/// @brief Writes a 8-bit value at the given port. +/// @param port the port we want to write to. +/// @param value the value we want to write. +void outportb(uint16_t port, uint8_t value); -/// @brief Use this to write to I/O ports to send 2 bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outports(uint16_t port, uint16_t data); +/// @brief Writes a 16-bit value at the given port. +/// @param port the port we want to write to. +/// @param value the value we want to write. +void outports(uint16_t port, uint16_t value); -void outportsm(uint16_t port, uint8_t *data, uint16_t size); +/// @brief Writes a 32-bit value at the given port. +/// @param port the port we want to write to. +/// @param value the value we want to write. +void outportl(uint16_t port, uint32_t value); -/// @brief Use this to write to I/O ports to send 4 bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outportl(uint16_t port, uint32_t data); +/// @brief Reads multiple 16-bit values from the given port. +/// @param port the port we want to read from. +/// @param value the location where we store the values we read. +/// @param size the amount of values we want to read. +void inportsm(uint16_t port, uint8_t *value, unsigned long size); + +/// @brief Writes multiple 16-bit values to the given port. +/// @param port the port we want to write to. +/// @param value the location where we get the values we need to write. +/// @param size the amount of values we want to write. +void outportsm(uint16_t port, uint8_t *value, uint16_t size); diff --git a/libc/inc/sys/kernel_levels.h b/libc/inc/sys/kernel_levels.h new file mode 100644 index 0000000..b089021 --- /dev/null +++ b/libc/inc/sys/kernel_levels.h @@ -0,0 +1,17 @@ +/// @file kernel_levels.h +/// @brief +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#pragma once + +// Integer equivalents of KERN_ +#define LOGLEVEL_DEFAULT (-1) ///< default-level messages. +#define LOGLEVEL_EMERG 0 ///< system is unusable. +#define LOGLEVEL_ALERT 1 ///< action must be taken immediately. +#define LOGLEVEL_CRIT 2 ///< critical conditions. +#define LOGLEVEL_ERR 3 ///< error conditions. +#define LOGLEVEL_WARNING 4 ///< warning conditions. +#define LOGLEVEL_NOTICE 5 ///< normal but significant condition. +#define LOGLEVEL_INFO 6 ///< informational. +#define LOGLEVEL_DEBUG 7 ///< debug-level messages. diff --git a/libc/src/debug.c b/libc/src/debug.c deleted file mode 100644 index 8682c38..0000000 --- a/libc/src/debug.c +++ /dev/null @@ -1,108 +0,0 @@ -/// @file debug.c -/// @brief Debugging primitives. -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. - -#include - -#include -#include -#include -#include -#include -#include - -/// Serial port for QEMU. -#define SERIAL_COM1 (0x03F8) - -#define FG_RESET "\033[0m" ///< ANSI code for resetting. - -void dbg_putchar(char c) -{ - outportb(SERIAL_COM1, (uint8_t)c); -} - -void dbg_puts(const char *s) -{ - while ((*s) != 0) - dbg_putchar(*s++); -} - -static inline void __debug_print_header(const char *file, const char *fun, int line) -{ - static char tmp_prefix[BUFSIZ], final_prefix[BUFSIZ]; - dbg_puts(FG_RESET); - dbg_puts("[ LB |"); - sprintf(tmp_prefix, "%s:%d", file, line); - sprintf(final_prefix, " %-20s ", tmp_prefix); - dbg_puts(final_prefix); -#if 0 - dbg_putchar('|'); - sprintf(final_prefix, " %-25s ]", fun); - dbg_puts(final_prefix); -#else - dbg_putchar(']'); -#endif -} - -void dbg_printf(const char *file, const char *fun, int line, const char *format, ...) -{ - // Define a buffer for the formatted string. - static char formatted[BUFSIZ]; - static short new_line = 1; - - // Stage 1: FORMAT - if (strlen(format) >= BUFSIZ) - return; - - // Start variabile argument's list. - va_list ap; - va_start(ap, format); - // Format the message. - vsprintf(formatted, format, ap); - // End the list of arguments. - va_end(ap); - - // Stage 2: SEND - if (new_line) { - __debug_print_header(file, fun, line); - new_line = 0; - } - for (size_t it = 0; (formatted[it] != 0) && (it < BUFSIZ); ++it) { - dbg_putchar(formatted[it]); - if (formatted[it] != '\n') { - continue; - } - if ((it + 1) >= BUFSIZ) { - continue; - } - if (formatted[it + 1] == 0) { - new_line = 1; - } else { - __debug_print_header(file, fun, line); - } - } -} - -const char *to_human_size(unsigned long bytes) -{ - static char output[200]; - const char *suffix[] = { "B", "KB", "MB", "GB", "TB" }; - char length = sizeof(suffix) / sizeof(suffix[0]); - int i = 0; - double dblBytes = bytes; - if (bytes > 1024) { - for (i = 0; (bytes / 1024) > 0 && i < length - 1; i++, bytes /= 1024) - dblBytes = bytes / 1024.0; - } - sprintf(output, "%.03lf %2s", dblBytes, suffix[i]); - return output; -} - -const char *dec_to_binary(unsigned long value, unsigned length) -{ - static char buffer[33]; - for (int i = 0, j = 32 - min(max(0, length), 32); j < 32; ++i, ++j) - buffer[i] = bit_check(value, 31 - j) ? '1' : '0'; - return buffer; -} diff --git a/libc/src/grp.c b/libc/src/grp.c index 1a55bc8..ba208f2 100644 --- a/libc/src/grp.c +++ b/libc/src/grp.c @@ -6,12 +6,13 @@ #include "grp.h" #include "sys/unistd.h" #include "sys/errno.h" +#include "io/debug.h" #include "assert.h" #include "string.h" #include "stdio.h" -#include "debug.h" #include "fcntl.h" +/// Holds the file descriptor while we are working with `/etc/group`. static int __fd = -1; /// @brief It parses the line (as string) and saves its content inside the @@ -42,6 +43,13 @@ static inline void __parse_line(group_t *grp, char *buf) grp->gr_mem[found_users] = "\0"; } +/// @brief Searches an entry in `/etc/group`. +/// @param fd the file descriptor pointing to `/etc/group`. +/// @param buf the buffer we are going to use to search the entry. +/// @param buflen the length of the buffer. +/// @param name the name we are looking for. +/// @param gid the group id we must match. +/// @return a pointer to the filled input buffer on success, NULL on failure. static inline char *__search_entry(int fd, char *buf, int buflen, const char *name, gid_t gid) { int ret; diff --git a/libc/src/io/debug.c b/libc/src/io/debug.c new file mode 100644 index 0000000..75fad52 --- /dev/null +++ b/libc/src/io/debug.c @@ -0,0 +1,179 @@ +/// @file debug.c +/// @brief Debugging primitives. +/// @copyright (c) 2014-2022 This file is distributed under the MIT License. +/// See LICENSE.md for details. + +#include "io/debug.h" +#include "io/port_io.h" +#include "io/ansi_colors.h" +#include "sys/bitops.h" +#include "string.h" +#include "stdio.h" +#include "math.h" + +/// Serial port for QEMU. +#define SERIAL_COM1 (0x03F8) +/// Determines the log level. +static int max_log_level = LOGLEVEL_DEBUG; + +void dbg_putchar(char c) +{ + outportb(SERIAL_COM1, (uint8_t)c); +} + +void dbg_puts(const char *s) +{ + while ((*s) != 0) + dbg_putchar(*s++); +} + +static inline void __debug_print_header(const char *file, const char *fun, int line, short log_level, char *header) +{ + // "EMERG ", "ALERT ", "CRIT ", "ERR ", "WARNING", "NOTICE ", "INFO ", "DEBUG ", "DEFAULT", + static const char *log_level_label[] = { " EM ", " AL ", " CR ", " ER ", " WR ", " NT ", " IN ", " DB ", " DF " }; + static const char *log_level_color[] = { + FG_RED_BRIGHT, // "EMERG " + FG_RED_BRIGHT, // "ALERT " + FG_RED, // "CRIT " + FG_RED, // "ERR " + FG_YELLOW_BRIGHT, // "WARNING" + FG_RESET, // "NOTICE " + FG_CYAN, // "INFO " + FG_YELLOW, // "DEBUG " + FG_RESET // "DEFAULT" + }; + static char tmp_prefix[BUFSIZ], final_prefix[BUFSIZ]; + // Check the log level. + if ((log_level < LOGLEVEL_EMERG) || (log_level > LOGLEVEL_DEBUG)) { + // Set it to default. + log_level = 8; + } + // Set the color. + dbg_puts(log_level_color[log_level]); + dbg_putchar('['); + // Set the label. + dbg_puts(log_level_label[log_level]); + dbg_putchar('|'); + // Print the file and line. + sprintf(tmp_prefix, "%s:%d", file, line); + // Print the message. + sprintf(final_prefix, " %-20s ", tmp_prefix); + // Print the actual message. + dbg_puts(final_prefix); +#if 0 + dbg_putchar('|'); + sprintf(final_prefix, " %-25s ]", fun); + dbg_puts(final_prefix); +#else + dbg_putchar(']'); +#endif + dbg_putchar(' '); + if (header) { + dbg_puts(header); + dbg_putchar(' '); + } +} + +void set_log_level(int level) +{ + if ((level >= LOGLEVEL_EMERG) && (level <= LOGLEVEL_DEBUG)) + max_log_level = level; +} + +int get_log_level() +{ + return max_log_level; +} + +void dbg_printf(const char *file, const char *fun, int line, char *header, short log_level, const char *format, ...) +{ + // Define a buffer for the formatted string. + static char formatted[BUFSIZ]; + static short new_line = 1; + + // Stage 1: FORMAT + if (strlen(format) >= BUFSIZ) + return; + + // Start variabile argument's list. + va_list ap; + va_start(ap, format); + // Format the message. + vsprintf(formatted, format, ap); + // End the list of arguments. + va_end(ap); + + // Stage 2: SEND + if (new_line) { + __debug_print_header(file, fun, line, log_level, header); + new_line = 0; + } + for (int it = 0; (formatted[it] != 0) && (it < BUFSIZ); ++it) { + dbg_putchar(formatted[it]); + if (formatted[it] != '\n') { + continue; + } + if ((it + 1) >= BUFSIZ) { + continue; + } + if (formatted[it + 1] == 0) { + new_line = 1; + } else { + __debug_print_header(file, fun, line, log_level, header); + } + } +} + +const char *to_human_size(unsigned long bytes) +{ + static char output[200]; + const char *suffix[] = { "B", "KB", "MB", "GB", "TB" }; + char length = sizeof(suffix) / sizeof(suffix[0]); + int i = 0; + double dblBytes = bytes; + if (bytes > 1024) { + for (i = 0; (bytes / 1024) > 0 && i < length - 1; i++, bytes /= 1024) + dblBytes = bytes / 1024.0; + } + sprintf(output, "%.02lf %2s", dblBytes, suffix[i]); + return output; +} + +const char *dec_to_binary(unsigned long value, unsigned length) +{ + static char buffer[33]; + memset(buffer, 0, 33); + for (int i = 0, j = 32 - min(max(0, length), 32); j < 32; ++i, ++j) + buffer[i] = bit_check(value, 31 - j) ? '1' : '0'; + return buffer; +} + +#ifdef __KERNEL__ + +#include "kernel.h" + +void dbg_print_regs(pt_regs *frame) +{ + pr_debug("Interrupt stack frame:\n"); + pr_debug("GS = 0x%-04x\n", frame->gs); + pr_debug("FS = 0x%-04x\n", frame->fs); + pr_debug("ES = 0x%-04x\n", frame->es); + pr_debug("DS = 0x%-04x\n", frame->ds); + pr_debug("EDI = 0x%-09x\n", frame->edi); + pr_debug("ESI = 0x%-09x\n", frame->esi); + pr_debug("EBP = 0x%-09x\n", frame->ebp); + pr_debug("ESP = 0x%-09x\n", frame->esp); + pr_debug("EBX = 0x%-09x\n", frame->ebx); + pr_debug("EDX = 0x%-09x\n", frame->edx); + pr_debug("ECX = 0x%-09x\n", frame->ecx); + pr_debug("EAX = 0x%-09x\n", frame->eax); + pr_debug("INT_NO = %-9d\n", frame->int_no); + pr_debug("ERR_CD = %-9d\n", frame->err_code); + pr_debug("EIP = 0x%-09x\n", frame->eip); + pr_debug("CS = 0x%-04x\n", frame->cs); + pr_debug("EFLAGS = 0x%-09x\n", frame->eflags); + pr_debug("UESP = 0x%-09x\n", frame->useresp); + pr_debug("SS = 0x%-04x\n", frame->ss); +} + +#endif \ No newline at end of file diff --git a/libc/src/io/mm_io.c b/libc/src/io/mm_io.c index 1271c45..e523b6f 100644 --- a/libc/src/io/mm_io.c +++ b/libc/src/io/mm_io.c @@ -5,32 +5,32 @@ #include "io/mm_io.h" -uint8_t in_memb(uint32_t addr) +inline uint8_t in_memb(uint32_t addr) { return *((uint8_t *) (addr)); } -uint16_t in_mems(uint32_t addr) +inline uint16_t in_mems(uint32_t addr) { return *((uint16_t *) (addr)); } -uint32_t in_meml(uint32_t addr) +inline uint32_t in_meml(uint32_t addr) { return *((uint32_t *) (addr)); } -void out_memb(uint32_t addr, uint8_t value) +inline void out_memb(uint32_t addr, uint8_t value) { (*((uint8_t *) (addr))) = (value); } -void out_mems(uint32_t addr, uint16_t value) +inline void out_mems(uint32_t addr, uint16_t value) { (*((uint16_t *) (addr))) = (value); } -void out_meml(uint32_t addr, uint32_t value) +inline void out_meml(uint32_t addr, uint32_t value) { (*((uint32_t *) (addr))) = (value); } diff --git a/libc/src/io/port_io.c b/libc/src/io/port_io.c index a2011c1..c8d8f99 100644 --- a/libc/src/io/port_io.c +++ b/libc/src/io/port_io.c @@ -7,51 +7,61 @@ inline uint8_t inportb(uint16_t port) { - unsigned char data = 0; - __asm__ __volatile__("inb %%dx, %%al" : "=a"(data) : "d"(port)); - - return data; + unsigned char value = 0; + __asm__ __volatile__("inb %%dx, %%al" + : "=a"(value) + : "d"(port)); + return value; } inline uint16_t inports(uint16_t port) { uint16_t rv; - __asm__ __volatile__("inw %1, %0" : "=a"(rv) : "dN"(port)); - + __asm__ __volatile__("inw %1, %0" + : "=a"(rv) + : "dN"(port)); return rv; } -void inportsm(uint16_t port, uint8_t *data, unsigned long size) -{ - __asm__ __volatile__("rep insw" - : "+D"(data), "+c"(size) - : "d"(port) - : "memory"); -} - inline uint32_t inportl(uint16_t port) { uint32_t rv; - __asm__ __volatile__("inl %%dx, %%eax" : "=a"(rv) : "dN"(port)); + __asm__ __volatile__("inl %%dx, %%eax" + : "=a"(rv) + : "dN"(port)); return rv; } -inline void outportb(uint16_t port, uint8_t data) +inline void outportb(uint16_t port, uint8_t value) { - __asm__ __volatile__("outb %%al, %%dx" ::"a"(data), "d"(port)); + __asm__ __volatile__("outb %%al, %%dx" ::"a"(value), "d"(port)); } -inline void outports(uint16_t port, uint16_t data) +inline void outports(uint16_t port, uint16_t value) { - __asm__ __volatile__("outw %1, %0" : : "dN"(port), "a"(data)); + __asm__ __volatile__("outw %1, %0" + : + : "dN"(port), "a"(value)); } -void outportsm(uint16_t port, uint8_t *data, uint16_t size) +inline void outportl(uint16_t port, uint32_t value) { - __asm__ __volatile__("rep outsw" : "+S"(data), "+c"(size) : "d"(port)); + __asm__ __volatile__("outl %%eax, %%dx" + : + : "dN"(port), "a"(value)); } -inline void outportl(uint16_t port, uint32_t data) +void inportsm(uint16_t port, uint8_t *value, unsigned long size) { - __asm__ __volatile__("outl %%eax, %%dx" : : "dN"(port), "a"(data)); + __asm__ __volatile__("rep insw" + : "+D"(value), "+c"(size) + : "d"(port) + : "memory"); +} + +void outportsm(uint16_t port, uint8_t *value, uint16_t size) +{ + __asm__ __volatile__("rep outsw" + : "+S"(value), "+c"(size) + : "d"(port)); } diff --git a/libc/src/pwd.c b/libc/src/pwd.c index 5127048..b29ede3 100644 --- a/libc/src/pwd.c +++ b/libc/src/pwd.c @@ -6,12 +6,15 @@ #include "pwd.h" #include "sys/unistd.h" #include "sys/errno.h" +#include "io/debug.h" #include "assert.h" #include "string.h" #include "stdio.h" #include "fcntl.h" -#include "debug.h" +/// @brief Parses the input buffer and fills pwd with its details. +/// @param pwd the structure we need to fill. +/// @param buf the buffer from which we extract the information. static inline void __parse_line(passwd_t *pwd, char *buf) { assert(pwd && "Received null pwd!"); diff --git a/libc/src/setenv.c b/libc/src/setenv.c index 2e7386a..350d193 100644 --- a/libc/src/setenv.c +++ b/libc/src/setenv.c @@ -10,7 +10,9 @@ char **environ; -static char **__environ = NULL; +/// @brief Global environ list. +static char **__environ = NULL; +/// @brief Size of the global environ list. static size_t __environ_size = 0; /// @brief Finds the entry in the environ. diff --git a/libc/src/time.c b/libc/src/time.c index 7a11ae0..d5a7fea 100644 --- a/libc/src/time.c +++ b/libc/src/time.c @@ -9,10 +9,12 @@ #include "string.h" #include "stdio.h" +/// @brief List of week days name. static const char *weekdays[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; +/// @brief List of months name. static const char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" diff --git a/libc/src/unistd/exec.c b/libc/src/unistd/exec.c index ac08c32..acfe35d 100644 --- a/libc/src/unistd/exec.c +++ b/libc/src/unistd/exec.c @@ -3,12 +3,11 @@ /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. -#include #include "sys/unistd.h" #include "system/syscall_types.h" #include "sys/errno.h" - #include "sys/stat.h" +#include "io/debug.h" #include "stdlib.h" #include "string.h" #include "stdarg.h" @@ -59,16 +58,12 @@ static inline int __find_in_path(const char *file, char *buf, size_t buf_len) return -1; } -/// @brief Replaces the current process image with a new process -/// image (argument vector), allows the caller to specify -/// the environment of the executed program via `envp`. -/// @param path The absolute path to the binary file to execute. -/// @param argv A vector of one or more pointers to null-terminated strings that represent -/// the argument list available to the executed program. -/// @param envp A vector of one or more pointers to null-terminated strings that represent -/// the environment list available to the executed program. -/// @return Returns -1 only if an error has occurred, and sets errno. -_syscall3(int, execve, const char *, path, char *const *, argv, char *const *, envp) +int execve(const char *path, char *const argv[], char *const envp[]) +{ + long __res; + __inline_syscall3(__res, execve, path, argv, envp); + __syscall_return(int, __res); +} int execv(const char *path, char *const argv[]) { diff --git a/libc/src/unistd/signal.c b/libc/src/unistd/signal.c index 281e412..b551c6f 100644 --- a/libc/src/unistd/signal.c +++ b/libc/src/unistd/signal.c @@ -10,10 +10,13 @@ #include "signal.h" #include "sys/bitops.h" +/// @brief Implement the sigreturn function. _syscall0(int, sigreturn) +/// @brief Implement the sigprocmask function. _syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset) +/// @brief List of signals names. static const char *sys_siglist[] = { "HUP", "INT", diff --git a/libc/src/vscanf.c b/libc/src/vscanf.c index c4b0933..d365af1 100644 --- a/libc/src/vscanf.c +++ b/libc/src/vscanf.c @@ -8,7 +8,13 @@ #include #include -static int vsscanf(const char *buf, const char *s, va_list ap) +/// @brief Read formatted data from string. +/// @param buf String processed as source to retrieve the data. +/// @param s Format string, following the same specifications as printf. +/// @param ap The list of arguments where the values are stored. +/// @return On success, the function returns the number of items of the +/// argument list successfully filled. EOF otherwise. +static int __vsscanf(const char *buf, const char *s, va_list ap) { int count = 0, noassign = 0, width = 0, base = 0; const char *tc; @@ -92,14 +98,20 @@ static int vsscanf(const char *buf, const char *s, va_list ap) return (count); } -static int vfscanf(int fd, const char *fmt, va_list ap) +/// @brief Read formatted data from file. +/// @param fd the file descriptor associated with the file. +/// @param fmt format string, following the same specifications as printf. +/// @param ap the list of arguments where the values are stored. +/// @return On success, the function returns the number of items of the +/// argument list successfully filled. EOF otherwise. +static int __vfscanf(int fd, const char *fmt, va_list ap) { int count; char buf[BUFSIZ + 1]; if (fgets(buf, BUFSIZ, fd) == 0) return (-1); - count = vsscanf(buf, fmt, ap); + count = __vsscanf(buf, fmt, ap); return (count); } @@ -109,7 +121,7 @@ int scanf(const char *fmt, ...) va_list ap; va_start(ap, fmt); - count = vfscanf(STDIN_FILENO, fmt, ap); + count = __vfscanf(STDIN_FILENO, fmt, ap); va_end(ap); return (count); } @@ -120,7 +132,7 @@ int fscanf(int fd, const char *fmt, ...) va_list ap; va_start(ap, fmt); - count = vfscanf(fd, fmt, ap); + count = __vfscanf(fd, fmt, ap); va_end(ap); return (count); } @@ -131,7 +143,7 @@ int sscanf(const char *buf, const char *fmt, ...) va_list ap; va_start(ap, fmt); - count = vsscanf(buf, fmt, ap); + count = __vsscanf(buf, fmt, ap); va_end(ap); return (count); } diff --git a/libc/src/vsprintf.c b/libc/src/vsprintf.c index 8fd8da6..2e4fd3c 100644 --- a/libc/src/vsprintf.c +++ b/libc/src/vsprintf.c @@ -3,7 +3,7 @@ /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. -#include +#include "sys/bitops.h" #include "fcvt.h" #include "ctype.h" #include "string.h" @@ -30,6 +30,8 @@ static char *_digits = "0123456789abcdefghijklmnopqrstuvwxyz"; static char *_upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /// @brief Returns the index of the first non-integer character. +/// @param s the string we need to analyze. +/// @return the index of the first non-integer character. static inline int skip_atoi(const char **s) { int i = 0; @@ -38,6 +40,14 @@ static inline int skip_atoi(const char **s) return i; } +/// @brief Transforms the number into a string. +/// @param str the output string. +/// @param num the number to transform to string. +/// @param base the base to use for number transformation. +/// @param size the size of the output string. +/// @param precision the precision for floating point numbers. +/// @param flags control flags. +/// @return the number turned into a string. static char *number(char *str, long num, int base, int size, int32_t precision, unsigned flags) { char c, tmp[66] = { 0 }; diff --git a/mentos/CMakeLists.txt b/mentos/CMakeLists.txt index af565fa..31d54d8 100644 --- a/mentos/CMakeLists.txt +++ b/mentos/CMakeLists.txt @@ -97,86 +97,86 @@ endif(CMAKE_BUILD_TYPE STREQUAL "Debug") # Define the list of files. set(KERNEL_SOURCES - src/kernel.c - src/multiboot.c - src/devices/pci.c - src/devices/fpu.c - src/drivers/ata.c - src/drivers/rtc.c - src/drivers/fdc.c - src/drivers/mouse.c - src/drivers/ps2.c - src/drivers/keyboard/keyboard.c - src/drivers/keyboard/keymap.c - src/fs/vfs.c - src/fs/read_write.c - src/fs/open.c - src/fs/stat.c - src/fs/readdir.c - src/fs/procfs.c - src/fs/ioctl.c - src/fs/namei.c - src/fs/ext2.c - src/hardware/timer.c - src/hardware/cpuid.c - src/hardware/pic8259.c - src/io/port_io.c - src/io/mm_io.c - src/io/video.c - src/io/stdio.c - src/io/debug.c - src/io/proc_video.c - src/io/proc_running.c - src/io/proc_system.c - src/io/vga/vga.c - src/ipc/msg.c - src/ipc/sem.c - src/ipc/shm.c - src/kernel/sys.c - src/klib/assert.c - src/klib/ctype.c - src/klib/mutex.c - src/klib/string.c - src/klib/vsprintf.c - src/klib/vscanf.c - src/klib/time.c - src/klib/libgen.c - src/klib/strerror.c - src/klib/math.c - src/klib/fcvt.c - src/klib/spinlock.c - src/klib/rbtree.c - src/klib/ndtree.c - src/klib/hashmap.c - src/klib/list.c - src/mem/kheap.c - src/mem/paging.c - src/mem/slab.c - src/mem/vmem_map.c - src/mem/zone_allocator.c - src/elf/elf.c - src/descriptor_tables/gdt.c - src/descriptor_tables/gdt.S - src/descriptor_tables/interrupt.c - src/descriptor_tables/exception.c - src/descriptor_tables/interrupt.S - src/descriptor_tables/exception.S - src/descriptor_tables/idt.c - src/descriptor_tables/idt.S - src/descriptor_tables/tss.c - src/descriptor_tables/tss.S - src/process/scheduler_algorithm.c - src/process/scheduler.c - src/process/process.c - src/process/wait.c - src/process/user.S - src/sys/utsname.c - src/sys/module.c - src/system/errno.c - src/system/panic.c - src/system/printk.c - src/system/signal.c - src/system/syscall.c + ${PROJECT_SOURCE_DIR}/src/kernel.c + ${PROJECT_SOURCE_DIR}/src/multiboot.c + ${PROJECT_SOURCE_DIR}/src/devices/pci.c + ${PROJECT_SOURCE_DIR}/src/devices/fpu.c + ${PROJECT_SOURCE_DIR}/src/drivers/ata.c + ${PROJECT_SOURCE_DIR}/src/drivers/rtc.c + ${PROJECT_SOURCE_DIR}/src/drivers/fdc.c + ${PROJECT_SOURCE_DIR}/src/drivers/mouse.c + ${PROJECT_SOURCE_DIR}/src/drivers/ps2.c + ${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keyboard.c + ${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keymap.c + ${PROJECT_SOURCE_DIR}/src/fs/vfs.c + ${PROJECT_SOURCE_DIR}/src/fs/read_write.c + ${PROJECT_SOURCE_DIR}/src/fs/open.c + ${PROJECT_SOURCE_DIR}/src/fs/stat.c + ${PROJECT_SOURCE_DIR}/src/fs/readdir.c + ${PROJECT_SOURCE_DIR}/src/fs/procfs.c + ${PROJECT_SOURCE_DIR}/src/fs/ioctl.c + ${PROJECT_SOURCE_DIR}/src/fs/namei.c + ${PROJECT_SOURCE_DIR}/src/fs/ext2.c + ${PROJECT_SOURCE_DIR}/src/hardware/timer.c + ${PROJECT_SOURCE_DIR}/src/hardware/cpuid.c + ${PROJECT_SOURCE_DIR}/src/hardware/pic8259.c + ${PROJECT_SOURCE_DIR}/src/io/debug.c + ${PROJECT_SOURCE_DIR}/src/io/port_io.c + ${PROJECT_SOURCE_DIR}/src/io/mm_io.c + ${PROJECT_SOURCE_DIR}/src/io/video.c + ${PROJECT_SOURCE_DIR}/src/io/stdio.c + ${PROJECT_SOURCE_DIR}/src/io/proc_video.c + ${PROJECT_SOURCE_DIR}/src/io/proc_running.c + ${PROJECT_SOURCE_DIR}/src/io/proc_system.c + ${PROJECT_SOURCE_DIR}/src/io/vga/vga.c + ${PROJECT_SOURCE_DIR}/src/ipc/msg.c + ${PROJECT_SOURCE_DIR}/src/ipc/sem.c + ${PROJECT_SOURCE_DIR}/src/ipc/shm.c + ${PROJECT_SOURCE_DIR}/src/kernel/sys.c + ${PROJECT_SOURCE_DIR}/src/klib/assert.c + ${PROJECT_SOURCE_DIR}/src/klib/ctype.c + ${PROJECT_SOURCE_DIR}/src/klib/mutex.c + ${PROJECT_SOURCE_DIR}/src/klib/string.c + ${PROJECT_SOURCE_DIR}/src/klib/vsprintf.c + ${PROJECT_SOURCE_DIR}/src/klib/vscanf.c + ${PROJECT_SOURCE_DIR}/src/klib/time.c + ${PROJECT_SOURCE_DIR}/src/klib/libgen.c + ${PROJECT_SOURCE_DIR}/src/klib/strerror.c + ${PROJECT_SOURCE_DIR}/src/klib/math.c + ${PROJECT_SOURCE_DIR}/src/klib/fcvt.c + ${PROJECT_SOURCE_DIR}/src/klib/spinlock.c + ${PROJECT_SOURCE_DIR}/src/klib/rbtree.c + ${PROJECT_SOURCE_DIR}/src/klib/ndtree.c + ${PROJECT_SOURCE_DIR}/src/klib/hashmap.c + ${PROJECT_SOURCE_DIR}/src/klib/list.c + ${PROJECT_SOURCE_DIR}/src/mem/kheap.c + ${PROJECT_SOURCE_DIR}/src/mem/paging.c + ${PROJECT_SOURCE_DIR}/src/mem/slab.c + ${PROJECT_SOURCE_DIR}/src/mem/vmem_map.c + ${PROJECT_SOURCE_DIR}/src/mem/zone_allocator.c + ${PROJECT_SOURCE_DIR}/src/elf/elf.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.S + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.S + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.S + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.S + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.c + ${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.S + ${PROJECT_SOURCE_DIR}/src/process/scheduler_algorithm.c + ${PROJECT_SOURCE_DIR}/src/process/scheduler.c + ${PROJECT_SOURCE_DIR}/src/process/process.c + ${PROJECT_SOURCE_DIR}/src/process/wait.c + ${PROJECT_SOURCE_DIR}/src/process/user.S + ${PROJECT_SOURCE_DIR}/src/sys/utsname.c + ${PROJECT_SOURCE_DIR}/src/sys/module.c + ${PROJECT_SOURCE_DIR}/src/system/errno.c + ${PROJECT_SOURCE_DIR}/src/system/panic.c + ${PROJECT_SOURCE_DIR}/src/system/printk.c + ${PROJECT_SOURCE_DIR}/src/system/signal.c + ${PROJECT_SOURCE_DIR}/src/system/syscall.c ) # ============================================================================= diff --git a/mentos/inc/devices/pci.h b/mentos/inc/devices/pci.h index 562892d..ce28750 100644 --- a/mentos/inc/devices/pci.h +++ b/mentos/inc/devices/pci.h @@ -233,24 +233,33 @@ typedef enum { typedef void (*pci_scan_func_t)(uint32_t device, uint16_t vendor_id, uint16_t device_id, void *extra); /// @brief Extract the `bus` from the device. +/// @param device the device details. +/// @return the `bus` value. static inline int pci_extract_bus(uint32_t device) { return (uint8_t)((device >> 16)); } /// @brief Extract the `slot` from the device. +/// @param device the device details. +/// @return the `slot` value. static inline int pci_extract_slot(uint32_t device) { return (uint8_t)((device >> 8)); } /// @brief Extract the `func` from the device. +/// @param device the device details. +/// @return the `func` value. static inline int pci_extract_func(uint32_t device) { return (uint8_t)(device); } -/// @brief TODO: doxygen comment. +/// @brief TODO: Comment. +/// @param device +/// @param field +/// @return static inline uint32_t pci_get_addr(uint32_t device, int field) { return 0x80000000 | (pci_extract_bus(device) << 16) | diff --git a/mentos/inc/drivers/keyboard/keymap.h b/mentos/inc/drivers/keyboard/keymap.h index 65abd2c..71f6437 100644 --- a/mentos/inc/drivers/keyboard/keymap.h +++ b/mentos/inc/drivers/keyboard/keymap.h @@ -157,7 +157,6 @@ void init_keymaps(); #define KEY_DOWN_ARROW 0xE050U ///< Down Arrow 57424 #define CODE_BREAK 0x0080U ///< Code break code -#define MULTIMEDIA_SCAN_CODE 0xE0 /// @} /// @} diff --git a/mentos/inc/io/mm_io.h b/mentos/inc/io/mm_io.h deleted file mode 100644 index 75f9084..0000000 --- a/mentos/inc/io/mm_io.h +++ /dev/null @@ -1,38 +0,0 @@ -/// @file mm_io.h -/// @brief Memory Mapped IO functions. -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. - -#pragma once - -#include "stdint.h" - -/// @brief Reads a 8-bit value from the given address. -/// @param addr The address from which we read. -/// @return The content read from the address. -uint8_t in_memb(uint32_t addr); - -/// @brief Reads a 16-bit value from the given address. -/// @param addr The address from which we read. -/// @return The content read from the address. -uint16_t in_mems(uint32_t addr); - -/// @brief Reads a 32-bit value from the given address. -/// @param addr The address from which we read. -/// @return The content read from the address. -uint32_t in_meml(uint32_t addr); - -/// @brief Writes a 8-bit value at the given address. -/// @param addr The address where we want to write. -/// @param value The value we want to write. -void out_memb(uint32_t addr, uint8_t value); - -/// @brief Writes a 16-bit value at the given address. -/// @param addr The address where we want to write. -/// @param value The value we want to write. -void out_mems(uint32_t addr, uint16_t value); - -/// @brief Writes a 32-bit value at the given address. -/// @param addr The address where we want to write. -/// @param value The value we want to write. -void out_meml(uint32_t addr, uint32_t value); diff --git a/mentos/inc/io/port_io.h b/mentos/inc/io/port_io.h deleted file mode 100644 index c151556..0000000 --- a/mentos/inc/io/port_io.h +++ /dev/null @@ -1,50 +0,0 @@ -/// @file port_io.h -/// @brief Byte I/O on ports prototypes. -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. - -#pragma once - -#include "stdint.h" - -/// @brief Used for reading from the I/O ports. -/// @param port The input port. -/// @return The read value. -uint8_t inportb(uint16_t port); - -/// @brief Used for reading 2 bytes from the I/O ports. -/// @param port The input port. -/// @return The read value. -uint16_t inports(uint16_t port); - -/// @brief Read from the given port and store what we read in `data`. -/// @param port The input port. -/// @param data The buffer where we store what we read. -/// @param size The dimension of the buffer. -void inportsm(uint16_t port, uint8_t *data, unsigned long size); - -/// @brief Used for reading 4 bytes from the I/O ports. -/// @param port The input port. -/// @return The read value. -uint32_t inportl(uint16_t port); - -/// @brief Use this to write to I/O ports to send bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outportb(uint16_t port, uint8_t data); - -/// @brief Use this to write to I/O ports to send 2 bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outports(uint16_t port, uint16_t data); - -/// @brief Write to the given port what it is stored inside `data`. -/// @param port The output port. -/// @param data The buffer where we have the data. -/// @param size The dimension of the buffer. -void outportsm(uint16_t port, uint8_t *data, uint16_t size); - -/// @brief Use this to write to I/O ports to send 4 bytes to devices. -/// @param port The output port. -/// @param data The data to write. -void outportl(uint16_t port, uint32_t data); diff --git a/mentos/inc/io/vga/vga.h b/mentos/inc/io/vga/vga.h index 4e04a28..1e7120f 100644 --- a/mentos/inc/io/vga/vga.h +++ b/mentos/inc/io/vga/vga.h @@ -38,6 +38,7 @@ void vga_draw_pixel(int x, int y, unsigned char color); /// @brief Reads a pixel at the given position. /// @param x x-axis position. /// @param y y-axis position. +/// @return the pixel we read. unsigned int vga_read_pixel(int x, int y); /// @brief Draws a character at the given position. @@ -114,6 +115,8 @@ void vga_get_screen_size(unsigned int * width, unsigned int * height); void vga_new_line(); /// @brief Change the color. +/// @param color the color to set. void vga_set_color(unsigned int color); +/// @brief Run some VGA tests. void vga_run_test(); diff --git a/mentos/inc/io/video.h b/mentos/inc/io/video.h index 8924071..771a28c 100644 --- a/mentos/inc/io/video.h +++ b/mentos/inc/io/video.h @@ -6,62 +6,7 @@ #pragma once #include "stdint.h" - -#define FG_RESET "\033[0m" ///< ANSI code for resetting. - -#define FG_BLACK "\033[30m" ///< ANSI code for setting a BLACK foreground. -#define FG_RED "\033[31m" ///< ANSI code for setting a RED foreground. -#define FG_GREEN "\033[32m" ///< ANSI code for setting a GREEN foreground. -#define FG_YELLOW "\033[33m" ///< ANSI code for setting a YELLOW foreground. -#define FG_BLUE "\033[34m" ///< ANSI code for setting a BLUE foreground. -#define FG_MAGENTA "\033[35m" ///< ANSI code for setting a MAGENTA foreground. -#define FG_CYAN "\033[36m" ///< ANSI code for setting a CYAN foreground. -#define FG_WHITE "\033[37m" ///< ANSI code for setting a WHITE foreground. - -#define FG_BLACK_BOLD "\033[1;30m" ///< ANSI code for setting a BLACK foreground. -#define FG_RED_BOLD "\033[1;31m" ///< ANSI code for setting a RED foreground. -#define FG_GREEN_BOLD "\033[1;32m" ///< ANSI code for setting a GREEN foreground. -#define FG_YELLOW_BOLD "\033[1;33m" ///< ANSI code for setting a YELLOW foreground. -#define FG_BLUE_BOLD "\033[1;34m" ///< ANSI code for setting a BLUE foreground. -#define FG_MAGENTA_BOLD "\033[1;35m" ///< ANSI code for setting a MAGENTA foreground. -#define FG_CYAN_BOLD "\033[1;36m" ///< ANSI code for setting a CYAN foreground. -#define FG_WHITE_BOLD "\033[1;37m" ///< ANSI code for setting a WHITE foreground. - -#define FG_BLACK_BRIGHT "\033[90m" ///< ANSI code for setting a BRIGHT_BLACK foreground. -#define FG_RED_BRIGHT "\033[91m" ///< ANSI code for setting a BRIGHT_RED foreground. -#define FG_GREEN_BRIGHT "\033[92m" ///< ANSI code for setting a BRIGHT_GREEN foreground. -#define FG_YELLOW_BRIGHT "\033[93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground. -#define FG_BLUE_BRIGHT "\033[94m" ///< ANSI code for setting a BRIGHT_BLUE foreground. -#define FG_MAGENTA_BRIGHT "\033[95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground. -#define FG_CYAN_BRIGHT "\033[96m" ///< ANSI code for setting a BRIGHT_CYAN foreground. -#define FG_WHITE_BRIGHT "\033[97m" ///< ANSI code for setting a BRIGHT_WHITE foreground. - -#define FG_BLACK_BRIGHT_BOLD "\033[1;90m" ///< ANSI code for setting a BRIGHT_BLACK foreground. -#define FG_RED_BRIGHT_BOLD "\033[1;91m" ///< ANSI code for setting a BRIGHT_RED foreground. -#define FG_GREEN_BRIGHT_BOLD "\033[1;92m" ///< ANSI code for setting a BRIGHT_GREEN foreground. -#define FG_YELLOW_BRIGHT_BOLD "\033[1;93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground. -#define FG_BLUE_BRIGHT_BOLD "\033[1;94m" ///< ANSI code for setting a BRIGHT_BLUE foreground. -#define FG_MAGENTA_BRIGHT_BOLD "\033[1;95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground. -#define FG_CYAN_BRIGHT_BOLD "\033[1;96m" ///< ANSI code for setting a BRIGHT_CYAN foreground. -#define FG_WHITE_BRIGHT_BOLD "\033[1;97m" ///< ANSI code for setting a BRIGHT_WHITE foreground. - -#define BG_BLACK "\033[40m" ///< ANSI code for setting a BLACK background. -#define BG_RED "\033[41m" ///< ANSI code for setting a RED background. -#define BG_GREEN "\033[42m" ///< ANSI code for setting a GREEN background. -#define BG_YELLOW "\033[43m" ///< ANSI code for setting a YELLOW background. -#define BG_BLUE "\033[44m" ///< ANSI code for setting a BLUE background. -#define BG_MAGENTA "\033[45m" ///< ANSI code for setting a MAGENTA background. -#define BG_CYAN "\033[46m" ///< ANSI code for setting a CYAN background. -#define BG_WHITE "\033[47m" ///< ANSI code for setting a WHITE background. - -#define BG_BRIGHT_BLACK "\033[100m" ///< ANSI code for setting a BRIGHT_BLACK background. -#define BG_BRIGHT_RED "\033[101m" ///< ANSI code for setting a BRIGHT_RED background. -#define BG_BRIGHT_GREEN "\033[102m" ///< ANSI code for setting a BRIGHT_GREEN background. -#define BG_BRIGHT_YELLOW "\033[103m" ///< ANSI code for setting a BRIGHT_YELLOW background. -#define BG_BRIGHT_BLUE "\033[104m" ///< ANSI code for setting a BRIGHT_BLUE background. -#define BG_BRIGHT_MAGENTA "\033[105m" ///< ANSI code for setting a BRIGHT_MAGENTA background. -#define BG_BRIGHT_CYAN "\033[106m" ///< ANSI code for setting a BRIGHT_CYAN background. -#define BG_BRIGHT_WHITE "\033[107m" ///< ANSI code for setting a BRIGHT_WHITE background. +#include "io/ansi_colors.h" /// @brief Initialize the video. void video_init(); diff --git a/mentos/inc/klib/irqflags.h b/mentos/inc/klib/irqflags.h index 6aba60e..2a22ddb 100644 --- a/mentos/inc/klib/irqflags.h +++ b/mentos/inc/klib/irqflags.h @@ -10,9 +10,10 @@ #include "stdint.h" /// @brief Enable IRQs (nested). -/// @details If called after calling irq_nested_disable, this function will -/// not activate IRQs if they were not active before. -inline static void irq_nested_enable(uint8_t flags) +/// @details If called after calling irq_disable, this function will not +/// activate IRQs if they were not active before. +/// @param flags the flags to control this behaviour. +inline static void irq_enable(uint8_t flags) { if (flags) { sti(); @@ -20,32 +21,32 @@ inline static void irq_nested_enable(uint8_t flags) } /// @brief Disable IRQs (nested). -/// @details Disable IRQs when unsure if IRQs were enabled at all. -/// This function together with irq_nested_enable can be used in -/// situations when interrupts shouldn't be activated if they were not -/// activated before calling this function. -inline static uint8_t irq_nested_disable() +/// @details Disable IRQs when unsure if IRQs were enabled at all. This function +/// together with irq_enable can be used in situations when interrupts +/// shouldn't be activated if they were not activated before calling this +/// function. +/// @return 1 if the IRQ is enable for the CPU. +inline static uint8_t irq_disable() { size_t flags; - __asm__ __volatile__("pushf; cli; pop %0" + // We are pushing the entire contents of the EFLAGS register onto the stack, + // clearing the interrupt line, and with the pop, getting the current status + // of the flags. + __asm__ __volatile__("pushf; cli; pop %0;" : "=r"(flags) : : "memory"); - if (flags & (1 << 9)) - return 1; - return 0; + return flags & (1 << 9); } /// @brief Determines, if the interrupt flags (IF) is set. +/// @return 1 if the IRQ is enable for the CPU. inline static uint8_t is_irq_enabled() { size_t flags; - __asm__ __volatile__("pushf; pop %0" + __asm__ __volatile__("pushf; pop %0;" : "=r"(flags) : : "memory"); - if (flags & (1 << 9)) { - return 1; - } - return 0; + return flags & (1 << 9); } diff --git a/mentos/inc/sys/kernel_levels.h b/mentos/inc/sys/kernel_levels.h deleted file mode 100644 index 3832468..0000000 --- a/mentos/inc/sys/kernel_levels.h +++ /dev/null @@ -1,30 +0,0 @@ -/// @file kernel_levels.h -/// @brief -/// @copyright (c) 2014-2022 This file is distributed under the MIT License. -/// See LICENSE.md for details. - -#pragma once - -#define KERN_SOH "\001" ///< ASCII Start Of Header. -#define KERN_SOH_ASCII '\001' ///< Character version of the SOH. - -#define KERN_EMERG KERN_SOH "0" ///< Emergency messages (precede a crash) -#define KERN_ALERT KERN_SOH "1" ///< Error requiring immediate attention -#define KERN_CRIT KERN_SOH "2" ///< Critical error (hardware or software) -#define KERN_ERR KERN_SOH "3" ///< Error conditions (common in drivers) -#define KERN_WARNING KERN_SOH "4" ///< Warning conditions (could lead to errors) -#define KERN_NOTICE KERN_SOH "5" ///< Not an error but a significant condition -#define KERN_INFO KERN_SOH "6" ///< Informational message -#define KERN_DEBUG KERN_SOH "7" ///< Used only for debug messages -#define KERN_DEFAULT "" ///< Default kernel logging level - -// Integer equivalents of KERN_ -#define LOGLEVEL_DEFAULT (-1) ///< default-level messages. -#define LOGLEVEL_EMERG 0 ///< system is unusable. -#define LOGLEVEL_ALERT 1 ///< action must be taken immediately. -#define LOGLEVEL_CRIT 2 ///< critical conditions. -#define LOGLEVEL_ERR 3 ///< error conditions. -#define LOGLEVEL_WARNING 4 ///< warning conditions. -#define LOGLEVEL_NOTICE 5 ///< normal but significant condition. -#define LOGLEVEL_INFO 6 ///< informational. -#define LOGLEVEL_DEBUG 7 ///< debug-level messages. diff --git a/mentos/src/io/debug.c b/mentos/src/io/debug.c index 0bb7d4d..35ab7f1 100644 --- a/mentos/src/io/debug.c +++ b/mentos/src/io/debug.c @@ -3,14 +3,13 @@ /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. -#include "sys/bitops.h" #include "io/debug.h" -#include "klib/spinlock.h" #include "io/port_io.h" +#include "io/ansi_colors.h" +#include "sys/bitops.h" #include "kernel.h" #include "string.h" #include "stdio.h" -#include "io/video.h" #include "math.h" /// Serial port for QEMU. @@ -29,41 +28,38 @@ void dbg_puts(const char *s) dbg_putchar(*s++); } -static inline void __debug_print_header(const char *file, const char *fun, int line, int log_level, char *header) +static inline void __debug_print_header(const char *file, const char *fun, int line, short log_level, char *header) { + // "EMERG ", "ALERT ", "CRIT ", "ERR ", "WARNING", "NOTICE ", "INFO ", "DEBUG ", "DEFAULT", + static const char *log_level_label[] = { " EM ", " AL ", " CR ", " ER ", " WR ", " NT ", " IN ", " DB ", " DF " }; + static const char *log_level_color[] = { + FG_RED_BRIGHT, // "EMERG " + FG_RED_BRIGHT, // "ALERT " + FG_RED, // "CRIT " + FG_RED, // "ERR " + FG_YELLOW_BRIGHT, // "WARNING" + FG_RESET, // "NOTICE " + FG_CYAN, // "INFO " + FG_YELLOW, // "DEBUG " + FG_RESET // "DEFAULT" + }; static char tmp_prefix[BUFSIZ], final_prefix[BUFSIZ]; - if (log_level == LOGLEVEL_EMERG) - dbg_puts(FG_RED_BRIGHT); - else if (log_level == LOGLEVEL_ALERT) - dbg_puts(FG_RED_BRIGHT); - else if (log_level == LOGLEVEL_CRIT) - dbg_puts(FG_RED); - else if (log_level == LOGLEVEL_ERR) - dbg_puts(FG_RED); - else if (log_level == LOGLEVEL_WARNING) - dbg_puts(FG_YELLOW_BRIGHT); - else if (log_level == LOGLEVEL_DEBUG) - dbg_puts(FG_CYAN); - else if (log_level == LOGLEVEL_NOTICE) - dbg_puts(FG_RESET); - else if (log_level == LOGLEVEL_INFO) - dbg_puts(FG_RESET); - else - dbg_puts(FG_RESET); + // Check the log level. + if ((log_level < LOGLEVEL_EMERG) || (log_level > LOGLEVEL_DEBUG)) { + // Set it to default. + log_level = 8; + } + // Set the color. + dbg_puts(log_level_color[log_level]); dbg_putchar('['); - dbg_puts( - (log_level == LOGLEVEL_EMERG) ? " EM " /*"EMERG "*/ : - (log_level == LOGLEVEL_ALERT) ? " AL " /*"ALERT "*/ : - (log_level == LOGLEVEL_CRIT) ? " CR " /*"CRIT "*/ : - (log_level == LOGLEVEL_ERR) ? " ER " /*"ERR "*/ : - (log_level == LOGLEVEL_WARNING) ? " WR " /*"WARNING"*/ : - (log_level == LOGLEVEL_NOTICE) ? " NT " /*"NOTICE "*/ : - (log_level == LOGLEVEL_INFO) ? " IN " /*"INFO "*/ : - (log_level == LOGLEVEL_DEBUG) ? " DB " /*"DEBUG "*/ : - " DF " /*"DEFAULT*/); + // Set the label. + dbg_puts(log_level_label[log_level]); dbg_putchar('|'); + // Print the file and line. sprintf(tmp_prefix, "%s:%d", file, line); + // Print the message. sprintf(final_prefix, " %-20s ", tmp_prefix); + // Print the actual message. dbg_puts(final_prefix); #if 0 dbg_putchar('|'); @@ -90,7 +86,7 @@ int get_log_level() return max_log_level; } -void dbg_printf(const char *file, const char *fun, int line, char *header, const char *format, ...) +void dbg_printf(const char *file, const char *fun, int line, char *header, short log_level, const char *format, ...) { // Define a buffer for the formatted string. static char formatted[BUFSIZ]; @@ -100,23 +96,6 @@ void dbg_printf(const char *file, const char *fun, int line, char *header, const if (strlen(format) >= BUFSIZ) return; - // Check the log level. - int log_level = LOGLEVEL_DEFAULT; - if ((format[0] != '\0') && (format[0] == KERN_SOH_ASCII)) { - // Remove the Start Of Header. - ++format; - // Compute the log level. - log_level = (format[0] - '0'); - // Check the log_level. - if ((log_level < LOGLEVEL_EMERG) || (log_level > LOGLEVEL_DEBUG)) - log_level = 8; - // Remove the log_level; - ++format; - } - if (log_level > max_log_level) { - return; - } - // Start variabile argument's list. va_list ap; va_start(ap, format); @@ -128,7 +107,7 @@ void dbg_printf(const char *file, const char *fun, int line, char *header, const // Stage 2: SEND if (new_line) { __debug_print_header(file, fun, line, log_level, header); - new_line = false; + new_line = 0; } for (int it = 0; (formatted[it] != 0) && (it < BUFSIZ); ++it) { dbg_putchar(formatted[it]); @@ -139,37 +118,13 @@ void dbg_printf(const char *file, const char *fun, int line, char *header, const continue; } if (formatted[it + 1] == 0) { - new_line = true; + new_line = 1; } else { __debug_print_header(file, fun, line, log_level, header); } } } -void dbg_print_regs(pt_regs *frame) -{ - pr_debug("Interrupt stack frame:\n"); - pr_debug("GS = 0x%-04x\n", frame->gs); - pr_debug("FS = 0x%-04x\n", frame->fs); - pr_debug("ES = 0x%-04x\n", frame->es); - pr_debug("DS = 0x%-04x\n", frame->ds); - pr_debug("EDI = 0x%-09x\n", frame->edi); - pr_debug("ESI = 0x%-09x\n", frame->esi); - pr_debug("EBP = 0x%-09x\n", frame->ebp); - pr_debug("ESP = 0x%-09x\n", frame->esp); - pr_debug("EBX = 0x%-09x\n", frame->ebx); - pr_debug("EDX = 0x%-09x\n", frame->edx); - pr_debug("ECX = 0x%-09x\n", frame->ecx); - pr_debug("EAX = 0x%-09x\n", frame->eax); - pr_debug("INT_NO = %-9d\n", frame->int_no); - pr_debug("ERR_CD = %-9d\n", frame->err_code); - pr_debug("EIP = 0x%-09x\n", frame->eip); - pr_debug("CS = 0x%-04x\n", frame->cs); - pr_debug("EFLAGS = 0x%-09x\n", frame->eflags); - pr_debug("UESP = 0x%-09x\n", frame->useresp); - pr_debug("SS = 0x%-04x\n", frame->ss); -} - const char *to_human_size(unsigned long bytes) { static char output[200]; @@ -193,3 +148,27 @@ const char *dec_to_binary(unsigned long value, unsigned length) buffer[i] = bit_check(value, 31 - j) ? '1' : '0'; return buffer; } + +void dbg_print_regs(pt_regs *frame) +{ + pr_debug("Interrupt stack frame:\n"); + pr_debug("GS = 0x%-04x\n", frame->gs); + pr_debug("FS = 0x%-04x\n", frame->fs); + pr_debug("ES = 0x%-04x\n", frame->es); + pr_debug("DS = 0x%-04x\n", frame->ds); + pr_debug("EDI = 0x%-09x\n", frame->edi); + pr_debug("ESI = 0x%-09x\n", frame->esi); + pr_debug("EBP = 0x%-09x\n", frame->ebp); + pr_debug("ESP = 0x%-09x\n", frame->esp); + pr_debug("EBX = 0x%-09x\n", frame->ebx); + pr_debug("EDX = 0x%-09x\n", frame->edx); + pr_debug("ECX = 0x%-09x\n", frame->ecx); + pr_debug("EAX = 0x%-09x\n", frame->eax); + pr_debug("INT_NO = %-9d\n", frame->int_no); + pr_debug("ERR_CD = %-9d\n", frame->err_code); + pr_debug("EIP = 0x%-09x\n", frame->eip); + pr_debug("CS = 0x%-04x\n", frame->cs); + pr_debug("EFLAGS = 0x%-09x\n", frame->eflags); + pr_debug("UESP = 0x%-09x\n", frame->useresp); + pr_debug("SS = 0x%-04x\n", frame->ss); +} diff --git a/programs/edit.c b/programs/edit.c index 4166a53..2aee8e0 100644 --- a/programs/edit.c +++ b/programs/edit.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/programs/kill.c b/programs/kill.c index 5b11b2e..75bc657 100644 --- a/programs/kill.c +++ b/programs/kill.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include static inline int is_number(char *s) { diff --git a/programs/login.c b/programs/login.c index 51e1f86..04740ed 100644 --- a/programs/login.c +++ b/programs/login.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "ansi_colors.h" diff --git a/programs/ls.c b/programs/ls.c index 60fafdc..bbca5c2 100644 --- a/programs/ls.c +++ b/programs/ls.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define FLAG_L (1U << 0U) #define FLAG_A (1U << 1U) diff --git a/programs/shell.c b/programs/shell.c index a0605fa..57af18e 100644 --- a/programs/shell.c +++ b/programs/shell.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include "stdbool.h" #include "stddef.h"