Remove mmio, port io, and debug headers from kernel side, and keep them on the libc. Simplify debugging functions. Add missing comments in several locations. Move ANSI color definitions in a separate file.
This commit is contained in:
+8
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
+32
-24
@@ -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);
|
||||
|
||||
@@ -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_<LEVEL>
|
||||
#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.
|
||||
@@ -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 <debug.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <io/port_io.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/bitops.h>
|
||||
#include <math.h>
|
||||
|
||||
/// 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;
|
||||
}
|
||||
+9
-1
@@ -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;
|
||||
|
||||
@@ -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
|
||||
+6
-6
@@ -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);
|
||||
}
|
||||
|
||||
+33
-23
@@ -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));
|
||||
}
|
||||
|
||||
+4
-1
@@ -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!");
|
||||
|
||||
+3
-1
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
+7
-12
@@ -3,12 +3,11 @@
|
||||
/// @copyright (c) 2014-2022 This file is distributed under the MIT License.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#include <debug.h>
|
||||
#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[])
|
||||
{
|
||||
|
||||
@@ -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",
|
||||
|
||||
+18
-6
@@ -8,7 +8,13 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+11
-1
@@ -3,7 +3,7 @@
|
||||
/// @copyright (c) 2014-2022 This file is distributed under the MIT License.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#include <sys/bitops.h>
|
||||
#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 };
|
||||
|
||||
+80
-80
@@ -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
|
||||
)
|
||||
|
||||
# =============================================================================
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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
|
||||
/// @}
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
|
||||
+1
-56
@@ -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();
|
||||
|
||||
+18
-17
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_<LEVEL>
|
||||
#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.
|
||||
+55
-76
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
#include <termios.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <io/debug.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
#include <limits.h>
|
||||
#include <strerror.h>
|
||||
#include <ctype.h>
|
||||
#include <debug.h>
|
||||
#include <io/debug.h>
|
||||
|
||||
static inline int is_number(char *s)
|
||||
{
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
#include <pwd.h>
|
||||
#include <strerror.h>
|
||||
#include <stdlib.h>
|
||||
#include <debug.h>
|
||||
#include <io/debug.h>
|
||||
|
||||
#include "ansi_colors.h"
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/bitops.h>
|
||||
#include <debug.h>
|
||||
#include <io/debug.h>
|
||||
|
||||
#define FLAG_L (1U << 0U)
|
||||
#define FLAG_A (1U << 1U)
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
#include <libgen.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <debug.h>
|
||||
#include <io/debug.h>
|
||||
#include <sys/bitops.h>
|
||||
#include "stdbool.h"
|
||||
#include "stddef.h"
|
||||
|
||||
Reference in New Issue
Block a user