Add skeleton code for deadlock prevention.

This commit is contained in:
Enrico Fraccaroli
2021-03-23 13:32:46 +01:00
parent 6fd063984a
commit 05c3f2c033
229 changed files with 25648 additions and 23945 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"files.associations": {
"errno.h": "c"
}
}
+78 -77
View File
@@ -1,77 +1,78 @@
cmake_minimum_required(VERSION 2.8.4)
# ------------------------------------------------------------------------------
# Add the debugging option.
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
"Chose the type of debugging: DEBUG_STDIO DEBUG_LOG")
set_property(
CACHE DEBUGGING_TYPE PROPERTY STRINGS
DEBUG_STDIO
DEBUG_LOG)
if ("${DEBUGGING_TYPE}" STREQUAL "DEBUG_STDIO" OR
"${DEBUGGING_TYPE}" STREQUAL "DEBUG_LOG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${DEBUGGING_TYPE}")
message(STATUS "Setting debugging type to ${DEBUGGING_TYPE}.")
else ()
message(FATAL_ERROR "Debugging type ${DEBUGGING_TYPE} is not valid.")
endif ()
# ------------------------------------------------------------------------------
# Add the sub-directories.
add_subdirectory(mentos)
add_subdirectory(initscp)
# ------------------------------------------------------------------------------
# Generate the initrd filesystem.
add_custom_target(
initfs
COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initfs'..."
COMMAND echo "---------------------------------------------"
COMMAND initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
COMMAND echo "---------------------------------------------"
COMMAND echo "Done!"
COMMAND echo "---------------------------------------------"
DEPENDS initfscp
)
# ------------------------------------------------------------------------------
# Set memory size.
SET(MEMORY_SIZE 1096M)
# ------------------------------------------------------------------------------
# Builds the code and runs qemu with the built Os.
SET(EMULATOR qemu-system-i386)
if (${DEBUGGING_TYPE} STREQUAL DEBUG_LOG)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial file:serial.log)
elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial stdio)
endif ()
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
SET(EMULATOR_FS -initrd initfs)
add_custom_target(
qemu
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} ${EMULATOR_KERNEL} ${EMULATOR_FS}
DEPENDS MentOs
DEPENDS initfs
)
# ------------------------------------------------------------------------------
# Builds the code and runs qemu with the built Os.
SET(EMULATOR_FLAGS_GDB ${EMULATOR_FLAGS} -s -S)
SET(GDB_PROG cgdb)
SET(GDB_ARGS -x ${CMAKE_SOURCE_DIR}/.gdb.debug)
add_custom_target(
qemu-gdb
COMMAND xterm -geometry 160x30-0-0 -e ${EMULATOR} ${EMULATOR_FLAGS_GDB} ${EMULATOR_KERNEL} ${EMULATOR_FS} &
COMMAND xterm -geometry 160x30-0+0 -e ${GDB_PROG} ${GDB_ARGS} &
DEPENDS MentOs
DEPENDS initfs
)
cmake_minimum_required(VERSION 2.8.4)
project(MentOsProject)
# ------------------------------------------------------------------------------
# Add the debugging option.
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
"Chose the type of debugging: DEBUG_STDIO DEBUG_LOG")
set_property(
CACHE DEBUGGING_TYPE PROPERTY STRINGS
DEBUG_STDIO
DEBUG_LOG)
if ("${DEBUGGING_TYPE}" STREQUAL "DEBUG_STDIO" OR
"${DEBUGGING_TYPE}" STREQUAL "DEBUG_LOG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${DEBUGGING_TYPE}")
message(STATUS "Setting debugging type to ${DEBUGGING_TYPE}.")
else ()
message(FATAL_ERROR "Debugging type ${DEBUGGING_TYPE} is not valid.")
endif ()
# ------------------------------------------------------------------------------
# Add the sub-directories.
add_subdirectory(mentos)
add_subdirectory(initscp)
# ------------------------------------------------------------------------------
# Generate the initrd filesystem.
add_custom_target(
initfs
COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initfs'..."
COMMAND echo "---------------------------------------------"
COMMAND initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
COMMAND echo "---------------------------------------------"
COMMAND echo "Done!"
COMMAND echo "---------------------------------------------"
DEPENDS initfscp
)
# ------------------------------------------------------------------------------
# Set memory size.
SET(MEMORY_SIZE 1096M)
# ------------------------------------------------------------------------------
# Builds the code and runs qemu with the built Os.
SET(EMULATOR qemu-system-i386)
if (${DEBUGGING_TYPE} STREQUAL DEBUG_LOG)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial file:serial.log)
elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -serial stdio)
endif ()
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
SET(EMULATOR_FS -initrd initfs)
add_custom_target(
qemu
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} ${EMULATOR_KERNEL} ${EMULATOR_FS}
DEPENDS MentOs
DEPENDS initfs
)
# ------------------------------------------------------------------------------
# Builds the code and runs qemu with the built Os.
SET(EMULATOR_FLAGS_GDB ${EMULATOR_FLAGS} -s -S)
SET(GDB_PROG cgdb)
SET(GDB_ARGS -x ${CMAKE_SOURCE_DIR}/.gdb.debug)
add_custom_target(
qemu-gdb
COMMAND xterm -geometry 160x30-0-0 -e ${EMULATOR} ${EMULATOR_FLAGS_GDB} ${EMULATOR_KERNEL} ${EMULATOR_FS} &
COMMAND xterm -geometry 160x30-0+0 -e ${GDB_PROG} ${GDB_ARGS} &
DEPENDS MentOs
DEPENDS initfs
)
+9 -9
View File
@@ -1,9 +1,9 @@
MentOS 0.1
Welcome to the MentOS, the Mentoring Operating System.
If you want some help enter the "help" command into the cli.
Bye,
The Ment(OS) Team
MentOS 0.1
Welcome to the MentOS, the Mentoring Operating System.
If you want some help enter the "help" command into the cli.
Bye,
The Ment(OS) Team
+1 -1
View File
@@ -1 +1 @@
io ti vi bi!
io ti vi bi!
+1 -1
View File
@@ -1 +1 @@
tanto questa e' solo una prova :\
tanto questa e' solo una prova :\
+3 -3
View File
@@ -1,3 +1,3 @@
root:password
user:computer
asd:asd
root:password
user:computer
asd:asd
+27 -27
View File
@@ -1,28 +1,28 @@
#include <stdio.h>
#include <fcntl.h>
void main(int argc, char ** argv)
{
if (argc == 2)
{
// Try to open the file.
int fd = open(argv[1], O_RDONLY, 42);
if (fd > -1)
{
char c;
// Put on the standard output the characters.
while (read(fd, &c, 1)) putchar(c);
putchar('\n');
putchar('\n');
close(fd);
}
else
{
printf("%s: cannot find the file.\n\n", argv[1]);
}
}
else
{
printf("Usage: more file\n\n");
}
#include <stdio.h>
#include <fcntl.h>
void main(int argc, char ** argv)
{
if (argc == 2)
{
// Try to open the file.
int fd = open(argv[1], O_RDONLY, 42);
if (fd > -1)
{
char c;
// Put on the standard output the characters.
while (read(fd, &c, 1)) putchar(c);
putchar('\n');
putchar('\n');
close(fd);
}
else
{
printf("%s: cannot find the file.\n\n", argv[1]);
}
}
else
{
printf("Usage: more file\n\n");
}
}
+1 -1
View File
@@ -1 +1 @@
ciao mondo
ciao mondo
+1 -1
View File
@@ -1 +1 @@
come va ?
come va ?
+1 -1
View File
@@ -1 +1 @@
bho, io credo bene eh eh eh
bho, io credo bene eh eh eh
+1 -1
View File
@@ -1 +1 @@
tanto questa e' solo una prova :\
tanto questa e' solo una prova :\
+1 -1
View File
@@ -1 +1 @@
io ti vi bi!
io ti vi bi!
+361 -336
View File
@@ -1,336 +1,361 @@
# ------------------------------------------------------------------------------
# Initialize the project.
project(MentOs C ASM)
# ------------------------------------------------------------------------------
# Set the project name.
set(PROJECT_NAME MentOs)
# ------------------------------------------------------------------------------
# Find doxygen
find_package(Doxygen)
# Add option to generate documentation.
option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
if (BUILD_DOCUMENTATION)
if (NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif (NOT DOXYGEN_FOUND)
set(doxyfile_in ${CMAKE_SOURCE_DIR}/doc/dreamos.doxyfile)
set(doxyfile ${CMAKE_BINARY_DIR}/doxyfile)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)
add_custom_target(
doc
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
install(DIRECTORY ${CMAKE_BINARY_DIR}/html DESTINATION share/doc)
endif (BUILD_DOCUMENTATION)
# ------------------------------------------------------------------------------
# Add the scheduling option.
set(SCHEDULER_TYPE
"SCHEDULER_RR"
CACHE STRING
"Chose the type of scheduler: SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS")
set_property(
CACHE SCHEDULER_TYPE PROPERTY STRINGS
SCHEDULER_RR
SCHEDULER_PRIORITY
SCHEDULER_CFS)
if ("${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_RR" OR
"${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_PRIORITY" OR
"${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_CFS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${SCHEDULER_TYPE}")
message(STATUS "Setting scheduler type to ${SCHEDULER_TYPE}.")
else ()
message(FATAL_ERROR "Scheduler type ${SCHEDULER_TYPE} is not valid.")
endif ()
# ------------------------------------------------------------------------------
# Add the option to enable buddy system.
option(ENABLE_BUDDY_SYSTEM "Enables the buddy system" OFF)
if (ENABLE_BUDDY_SYSTEM)
message(STATUS "Enabling buddy system.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_BUDDYSYSTEM")
else (ENABLE_BUDDY_SYSTEM)
message(STATUS "Buddy system disabled.")
endif (ENABLE_BUDDY_SYSTEM)
# ------------------------------------------------------------------------------
# Set the compiler options (original).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
# ------------------------------------------------------------------------------
# Set the compiler options (extra).
set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wall")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wpedantic")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -pedantic-errors")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wextra")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdisabled-optimization")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-equal")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-conversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-nonliteral")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-security")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-y2k")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wimport")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winit-self")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winline")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winvalid-pch")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-field-initializers")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-include-dirs")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpacked")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wredundant-decls")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstack-protector")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-aliasing=2")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-default")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-enum")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunreachable-code")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-function")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-label")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-parameter")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-value")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-variable")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvariadic-macros")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wwrite-strings")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-conversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
# ------------------------------------------------------------------------------
if (CMAKE_BUILD_TYPE MATCHES "Release")
elseif (CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG")
endif (CMAKE_BUILD_TYPE MATCHES "Release")
# ------------------------------------------------------------------------------
# Set the assembly flags.
enable_language(ASM)
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
# ------------------------------------------------------------------------------
# Add the includes.
include_directories(
inc
inc/descriptor_tables
inc/devices
inc/drivers
inc/drivers/keyboard
inc/fs
inc/hardware
inc/io
inc/kernel
inc/libc
inc/lng
inc/mem
inc/misc
inc/sys
inc/system
inc/process
inc/elf
inc/ui
inc/ui/shell
inc/ui/command
inc/ui/init
)
# ------------------------------------------------------------------------------
# Add the source files.
set(SOURCE_FILES
boot.asm
src/kernel.c
src/multiboot.c
src/devices/pci.c
src/devices/fpu.c
src/drivers/ata.c
src/drivers/fdc.c
src/drivers/mouse.c
src/drivers/keyboard/keyboard.c
src/drivers/keyboard/keymap.c
src/fs/fcntl.c
src/fs/initrd.c
src/fs/vfs.c
src/fs/read_write.c
src/fs/open.c
src/fs/stat.c
src/fs/readdir.c
src/sys/module.c
src/sys/unistd.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/kernel/sys.c
src/libc/assert.c
src/libc/ctype.c
src/libc/stdio.c
src/libc/string.c
src/libc/vsprintf.c
src/libc/queue.c
src/libc/stdlib.c
src/libc/spinlock.c
src/libc/list.c
src/libc/ordered_array.c
src/libc/mutex.c
src/libc/libgen.c
src/libc/strerror.c
src/libc/tree.c
src/libc/bitset.c
src/libc/fcvt.c
src/libc/rbtree.c
src/libc/math.c
src/libc/hashmap.c
src/libc/unistd/getppid.c
src/libc/unistd/getpid.c
src/libc/unistd/exit.c
src/libc/unistd/vfork.c
src/libc/unistd/read.c
src/libc/unistd/write.c
src/libc/unistd/execve.c
src/libc/unistd/nice.c
src/libc/unistd/open.c
src/libc/unistd/reboot.c
src/libc/unistd/waitpid.c
src/libc/unistd/chdir.c
src/libc/unistd/getcwd.c
src/libc/unistd/close.c
src/libc/unistd/stat.c
src/libc/unistd/mkdir.c
src/mem/kheap.c
src/mem/paging.c
src/mem/zone_allocator.c
src/misc/bitops.c
src/misc/clock.c
src/misc/debug.c
src/sys/dirent.c
src/sys/utsname.c
src/elf/elf.c
src/descriptor_tables/gdt.c
src/descriptor_tables/gdt.asm
src/descriptor_tables/interrupt.c
src/descriptor_tables/exception.c
src/descriptor_tables/interrupt.asm
src/descriptor_tables/exception.asm
src/descriptor_tables/idt.c
src/descriptor_tables/idt.asm
src/descriptor_tables/tss.c
src/descriptor_tables/tss.asm
src/process/scheduler.c
src/process/scheduler_algorithm.c
src/process/process.c
src/process/user.asm
src/system/errno.c
src/system/panic.c
src/system/syscall.c
src/system/printk.c
src/ui/command/cmd_cd.c
src/ui/command/cmd_clear.c
src/ui/command/cmd_cpuid.c
src/ui/command/cmd_credits.c
src/ui/command/cmd_date.c
src/ui/command/cmd_drv_load.c
src/ui/command/cmd_echo.c
src/ui/command/cmd_logo.c
src/ui/command/cmd_ls.c
src/ui/command/cmd_mkdir.c
src/ui/command/cmd_more.c
src/ui/command/cmd_newfile.c
src/ui/command/cmd_poweroff.c
src/ui/command/cmd_ps.c
src/ui/command/cmd_pwd.c
src/ui/command/cmd_rm.c
src/ui/command/cmd_rmdir.c
src/ui/command/cmd_showpid.c
src/ui/command/cmd_sleep.c
#src/ui/command/cmd_tester.c
src/ui/command/cmd_touch.c
src/ui/command/cmd_uname.c
src/ui/command/cmd_whoami.c
src/ui/command/cmd_ipcs.c
src/ui/command/cmd_ipcrm.c
src/ui/command/cmd_nice.c
src/ui/init/init.c
src/ui/shell/shell.c
src/ui/shell/shell_login.c
)
if (ENABLE_BUDDY_SYSTEM MATCHES "ON")
set(SOURCE_FILES
${SOURCE_FILES}
src/mem/buddysystem.c)
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
# ------------------------------------------------------------------------------
# Add the executable.
add_library(${PROJECT_NAME} ${SOURCE_FILES})
# ------------------------------------------------------------------------------
# Build the kernel.
add_custom_command(
TARGET MentOs
POST_BUILD
COMMAND $(LD)
-melf_i386
-static
--oformat elf32-i386
-Ttext 0x100000
--output=${CMAKE_CURRENT_BINARY_DIR}/kernel.bin
--script=${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds
${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.a
-Map ${CMAKE_CURRENT_BINARY_DIR}/kernel.map
)
# ------------------------------------------------------------------------------
# Initialize the project.
project(MentOs C ASM)
# ------------------------------------------------------------------------------
# Set the project name.
set(PROJECT_NAME MentOs)
# ------------------------------------------------------------------------------
# Find doxygen
find_package(Doxygen)
# Add option to generate documentation.
option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
if (BUILD_DOCUMENTATION)
if (NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif (NOT DOXYGEN_FOUND)
set(doxyfile_in ${CMAKE_SOURCE_DIR}/doc/dreamos.doxyfile)
set(doxyfile ${CMAKE_BINARY_DIR}/doxyfile)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)
add_custom_target(
doc
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
install(DIRECTORY ${CMAKE_BINARY_DIR}/html DESTINATION share/doc)
endif (BUILD_DOCUMENTATION)
# ------------------------------------------------------------------------------
# Add the scheduling option.
set(SCHEDULER_TYPE
"SCHEDULER_RR"
CACHE STRING
"Chose the type of scheduler: SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS")
set_property(
CACHE SCHEDULER_TYPE PROPERTY STRINGS
SCHEDULER_RR
SCHEDULER_PRIORITY
SCHEDULER_CFS)
if ("${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_RR" OR
"${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_PRIORITY" OR
"${SCHEDULER_TYPE}" STREQUAL "SCHEDULER_CFS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${SCHEDULER_TYPE}")
message(STATUS "Setting scheduler type to ${SCHEDULER_TYPE}.")
else ()
message(FATAL_ERROR "Scheduler type ${SCHEDULER_TYPE} is not valid.")
endif ()
# ------------------------------------------------------------------------------
# Add the option to enable buddy system.
option(ENABLE_BUDDY_SYSTEM "Enables the buddy system" OFF)
if (ENABLE_BUDDY_SYSTEM)
message(STATUS "Enabling buddy system.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_BUDDYSYSTEM")
else (ENABLE_BUDDY_SYSTEM)
message(STATUS "Buddy system disabled.")
endif (ENABLE_BUDDY_SYSTEM)
# ------------------------------------------------------------------------------
# Add the option to enable deadlock prevention.
option(ENABLE_DEADLOCK_PREVENTION "Enables the buddy system" OFF)
if (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Enabling deadlock prevention.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_DEADLOCK_PREVENTION")
else (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Deadlock prevention disabled.")
endif (ENABLE_DEADLOCK_PREVENTION)
# ------------------------------------------------------------------------------
# Set the compiler options (original).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
# ------------------------------------------------------------------------------
# Set the compiler options (extra).
set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wall")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wpedantic")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -pedantic-errors")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Wextra")
#set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdisabled-optimization")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-equal")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wfloat-conversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-nonliteral")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-security")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-y2k")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wimport")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winit-self")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winline")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winvalid-pch")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-field-initializers")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-include-dirs")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpacked")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wredundant-decls")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstack-protector")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-aliasing=2")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-default")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-enum")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunreachable-code")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-function")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-label")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-parameter")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-value")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused-variable")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvariadic-macros")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wwrite-strings")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-compare")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wsign-conversion")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
# ------------------------------------------------------------------------------
if (CMAKE_BUILD_TYPE MATCHES "Release")
elseif (CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG")
endif (CMAKE_BUILD_TYPE MATCHES "Release")
# ------------------------------------------------------------------------------
# Set the assembly flags.
enable_language(ASM)
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
# ------------------------------------------------------------------------------
# Add the includes.
include_directories(
inc
inc/descriptor_tables
inc/devices
inc/drivers
inc/drivers/keyboard
inc/fs
inc/hardware
inc/io
inc/kernel
inc/libc
inc/lng
inc/mem
inc/misc
inc/sys
inc/experimental
inc/experimental/math
inc/system
inc/process
inc/elf
inc/ui
inc/ui/shell
inc/ui/command
inc/ui/init
)
# ------------------------------------------------------------------------------
# Add the source files.
set(SOURCE_FILES
boot.asm
src/kernel.c
src/multiboot.c
src/devices/pci.c
src/devices/fpu.c
src/drivers/ata.c
src/drivers/fdc.c
src/drivers/mouse.c
src/drivers/keyboard/keyboard.c
src/drivers/keyboard/keymap.c
src/experimental/smart_sem_kernel.c
src/experimental/smart_sem_user.c
src/experimental/resource.c
src/experimental/math/arr_math.c
src/fs/fcntl.c
src/fs/initrd.c
src/fs/vfs.c
src/fs/read_write.c
src/fs/open.c
src/fs/stat.c
src/fs/readdir.c
src/sys/module.c
src/sys/unistd.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/kernel/sys.c
src/libc/assert.c
src/libc/ctype.c
src/libc/stdio.c
src/libc/string.c
src/libc/vsprintf.c
src/libc/queue.c
src/libc/stdlib.c
src/libc/spinlock.c
src/libc/list.c
src/libc/ordered_array.c
src/libc/mutex.c
src/libc/libgen.c
src/libc/strerror.c
src/libc/tree.c
src/libc/bitset.c
src/libc/fcvt.c
src/libc/rbtree.c
src/libc/math.c
src/libc/hashmap.c
src/libc/unistd/getppid.c
src/libc/unistd/getpid.c
src/libc/unistd/exit.c
src/libc/unistd/vfork.c
src/libc/unistd/read.c
src/libc/unistd/write.c
src/libc/unistd/execve.c
src/libc/unistd/nice.c
src/libc/unistd/open.c
src/libc/unistd/reboot.c
src/libc/unistd/waitpid.c
src/libc/unistd/chdir.c
src/libc/unistd/getcwd.c
src/libc/unistd/close.c
src/libc/unistd/stat.c
src/libc/unistd/mkdir.c
src/mem/kheap.c
src/mem/paging.c
src/mem/zone_allocator.c
src/misc/bitops.c
src/misc/clock.c
src/misc/debug.c
src/sys/dirent.c
src/sys/utsname.c
src/elf/elf.c
src/descriptor_tables/gdt.c
src/descriptor_tables/gdt.asm
src/descriptor_tables/interrupt.c
src/descriptor_tables/exception.c
src/descriptor_tables/interrupt.asm
src/descriptor_tables/exception.asm
src/descriptor_tables/idt.c
src/descriptor_tables/idt.asm
src/descriptor_tables/tss.c
src/descriptor_tables/tss.asm
src/process/scheduler.c
src/process/scheduler_algorithm.c
src/process/process.c
src/process/user.asm
src/system/errno.c
src/system/panic.c
src/system/syscall.c
src/system/printk.c
src/ui/command/cmd_cd.c
src/ui/command/cmd_clear.c
src/ui/command/cmd_cpuid.c
src/ui/command/cmd_credits.c
src/ui/command/cmd_date.c
src/ui/command/cmd_drv_load.c
src/ui/command/cmd_echo.c
src/ui/command/cmd_logo.c
src/ui/command/cmd_ls.c
src/ui/command/cmd_mkdir.c
src/ui/command/cmd_more.c
src/ui/command/cmd_newfile.c
src/ui/command/cmd_poweroff.c
src/ui/command/cmd_ps.c
src/ui/command/cmd_pwd.c
src/ui/command/cmd_rm.c
src/ui/command/cmd_rmdir.c
src/ui/command/cmd_showpid.c
src/ui/command/cmd_sleep.c
#src/ui/command/cmd_tester.c
src/ui/command/cmd_touch.c
src/ui/command/cmd_uname.c
src/ui/command/cmd_whoami.c
src/ui/command/cmd_ipcs.c
src/ui/command/cmd_ipcrm.c
src/ui/command/cmd_nice.c
src/ui/command/cmd_deadlock.c
src/ui/init/init.c
src/ui/shell/shell.c
src/ui/shell/shell_login.c
)
if (ENABLE_BUDDY_SYSTEM MATCHES "ON")
set(SOURCE_FILES
${SOURCE_FILES}
src/mem/buddysystem.c)
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
if (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
set(SOURCE_FILES
${SOURCE_FILES}
src/experimental/deadlock_prevention.c
src/experimental/deadlock_simulation.c)
endif (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
# ------------------------------------------------------------------------------
# Add the executable.
add_library(${PROJECT_NAME} ${SOURCE_FILES})
# ------------------------------------------------------------------------------
# Build the kernel.
add_custom_command(
TARGET MentOs
POST_BUILD
COMMAND $(LD)
-melf_i386
-static
--oformat elf32-i386
-Ttext 0x100000
--output=${CMAKE_CURRENT_BINARY_DIR}/kernel.bin
--script=${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds
${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.a
-Map ${CMAKE_CURRENT_BINARY_DIR}/kernel.map
)
+97 -97
View File
@@ -1,97 +1,97 @@
; MentOS, The Mentoring Operating system project
; @file boot.asm
; @brief Kernel start location, multiboot header
; @copyright (c) 2019 This file is distributed under the MIT License.
; See LICENSE.md for details.
[BITS 32] ; All instructions should be 32-bit.
[EXTERN kmain] ; The start point of our C code
; The magic field should contain this.
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
; This should be in %eax.
MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
; = Specify what GRUB should PROVIDE =========================================
; Align the kernel and kernel modules on i386 page (4KB) boundaries.
MULTIBOOT_PAGE_ALIGN equ 0x00000001
; Provide the kernel with memory information.
MULTIBOOT_MEMORY_INFO equ 0x00000002
; Must pass video information to OS.
MULTIBOOT_VIDEO_MODE equ 0x00000004
; -----------------------------------------------------------------------------
; This is the flag combination that we prepare for Grub
; to read at kernel load time.
MULTIBOOT_HEADER_FLAGS equ (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE)
; Grub reads this value to make sure it loads a kernel
; and not just garbage.
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
LOAD_MEMORY_ADDRESS equ 0x00000000
; reserve (1024*1024) for the stack on a doubleword boundary
KERNEL_STACK_SIZE equ 0x100000
; -----------------------------------------------------------------------------
; SECTION (multiboot_header)
; -----------------------------------------------------------------------------
section .multiboot_header
align 4
; This is the GRUB Multiboot header.
multiboot_header:
; magic
dd MULTIBOOT_HEADER_MAGIC
; flags
dd MULTIBOOT_HEADER_FLAGS
; checksum
dd MULTIBOOT_CHECKSUM
; -----------------------------------------------------------------------------
; SECTION (data)
; -----------------------------------------------------------------------------
section .data, nobits
align 4096
[GLOBAL boot_page_dir]
boot_page_dir:
resb 0x1000
boot_page_tabl:
resb 0x1000
; -----------------------------------------------------------------------------
; SECTION (text)
; -----------------------------------------------------------------------------
section .text
[GLOBAL kernel_entry]
kernel_entry:
; Clear interrupt flag [IF = 0]; 0xFA
cli
; To set up a stack, we simply set the esp register to point to the top of
; our stack (as it grows downwards).
mov esp, stack_top
; pass the initial ESP
push esp
; pass Multiboot info structure
push ebx
; pass Multiboot magic number
push eax
; Call the kmain() function inside kernel.c
call kmain
; Set interrupt flag [IF = 1]; 0xFA
; Clear interrupts and hang if we return from kmain
cli
hang:
hlt
jmp hang
; -----------------------------------------------------------------------------
; SECTION (bss)
; -----------------------------------------------------------------------------
section .bss
[GLOBAL stack_bottom]
[GLOBAL stack_top]
align 16
stack_bottom:
resb KERNEL_STACK_SIZE
stack_top:
; the top of the stack is the bottom because the stack counts down
; MentOS, The Mentoring Operating system project
; @file boot.asm
; @brief Kernel start location, multiboot header
; @copyright (c) 2019 This file is distributed under the MIT License.
; See LICENSE.md for details.
[BITS 32] ; All instructions should be 32-bit.
[EXTERN kmain] ; The start point of our C code
; The magic field should contain this.
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
; This should be in %eax.
MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
; = Specify what GRUB should PROVIDE =========================================
; Align the kernel and kernel modules on i386 page (4KB) boundaries.
MULTIBOOT_PAGE_ALIGN equ 0x00000001
; Provide the kernel with memory information.
MULTIBOOT_MEMORY_INFO equ 0x00000002
; Must pass video information to OS.
MULTIBOOT_VIDEO_MODE equ 0x00000004
; -----------------------------------------------------------------------------
; This is the flag combination that we prepare for Grub
; to read at kernel load time.
MULTIBOOT_HEADER_FLAGS equ (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE)
; Grub reads this value to make sure it loads a kernel
; and not just garbage.
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
LOAD_MEMORY_ADDRESS equ 0x00000000
; reserve (1024*1024) for the stack on a doubleword boundary
KERNEL_STACK_SIZE equ 0x100000
; -----------------------------------------------------------------------------
; SECTION (multiboot_header)
; -----------------------------------------------------------------------------
section .multiboot_header
align 4
; This is the GRUB Multiboot header.
multiboot_header:
; magic
dd MULTIBOOT_HEADER_MAGIC
; flags
dd MULTIBOOT_HEADER_FLAGS
; checksum
dd MULTIBOOT_CHECKSUM
; -----------------------------------------------------------------------------
; SECTION (data)
; -----------------------------------------------------------------------------
section .data, nobits
align 4096
[GLOBAL boot_page_dir]
boot_page_dir:
resb 0x1000
boot_page_tabl:
resb 0x1000
; -----------------------------------------------------------------------------
; SECTION (text)
; -----------------------------------------------------------------------------
section .text
[GLOBAL kernel_entry]
kernel_entry:
; Clear interrupt flag [IF = 0]; 0xFA
cli
; To set up a stack, we simply set the esp register to point to the top of
; our stack (as it grows downwards).
mov esp, stack_top
; pass the initial ESP
push esp
; pass Multiboot info structure
push ebx
; pass Multiboot magic number
push eax
; Call the kmain() function inside kernel.c
call kmain
; Set interrupt flag [IF = 1]; 0xFA
; Clear interrupts and hang if we return from kmain
cli
hang:
hlt
jmp hang
; -----------------------------------------------------------------------------
; SECTION (bss)
; -----------------------------------------------------------------------------
section .bss
[GLOBAL stack_bottom]
[GLOBAL stack_top]
align 16
stack_bottom:
resb KERNEL_STACK_SIZE
stack_top:
; the top of the stack is the bottom because the stack counts down
+79 -79
View File
@@ -1,79 +1,79 @@
/// MentOS, The Mentoring Operating system project
/// @file gdt.h
/// @brief Data structures concerning the Global Descriptor Table (GDT).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Access flags, determines what ring this segment can be used in.
typedef enum gdt_access_option_t
{
/// Identifies a kernel segment.
KERNEL = 0x00,
/// Identifies a user segment.
USER = 0x03,
/// Identifies a code segment.
CODE = 0x10,
/// Identifies a data segment.
DATA = 0x10,
/// Segment is present.
PRESENT = 0x80,
} __attribute__ ((__packed__)) gdt_access_option_t;
/// @brief Options for the second option.
typedef enum gdt_granularity_option_t
{
/// Granularity.
GRANULARITY = 0x80,
/// Szbits.
SZBITS = 0x40
} __attribute__ ((__packed__)) gdt_granularity_option_t;
/// @brief Data structure representing a GDT descriptor.
typedef struct gdt_descriptor_t
{
/// The lower 16 bits of the limit.
uint16_t limit_low;
/// The lower 16 bits of the base.
uint16_t base_low;
/// The next 8 bits of the base.
uint8_t base_middle;
/// Access flags, determine what ring this segment can be used in.
uint8_t access;
/// SegLimit_hi(4 bit) AVL(1 bit) L(1 bit) D/B(1 bit) G(1bit).
uint8_t granularity;
/// The last 8 bits of the base.
uint8_t base_high;
} __attribute__((packed)) gdt_descriptor_t;
/// @brief Data structure used to load the GDT into the GDTR.
typedef struct gdt_pointer_t
{
/// The size of the GDT (entry number).
uint16_t limit;
/// The starting address of the GDT.
uint32_t base;
} __attribute__((packed)) gdt_pointer_t;
/// @brief Initialise the GDT.
/// @details This will setup the special GDT
/// pointer, set up the first 3 entries in our GDT, and then
/// finally call gdt_flush() in our assembler file in order
/// to tell the processor where the new GDT is and update the
/// new segment registers.
void init_gdt();
/// @brief Sets the value of one GDT entry.
/// @param index The index inside the GDT.
/// @param base Memory address where the segment we are defining starts.
/// @param limit The memory address which determines the end of the segnment.
/// @param _access Type (4bit) - S (1) bit -DPL (2 bit) - P(1 bit).
/// @param _granul SegLimit_hi(4 bit) AVL(1 bit) L(1 bit) D/B(1 bit) G(1bit).
void gdt_set_gate(uint8_t index,
uint32_t base,
uint32_t limit,
uint8_t _access,
uint8_t _granul);
/// MentOS, The Mentoring Operating system project
/// @file gdt.h
/// @brief Data structures concerning the Global Descriptor Table (GDT).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Access flags, determines what ring this segment can be used in.
typedef enum gdt_access_option_t
{
/// Identifies a kernel segment.
KERNEL = 0x00,
/// Identifies a user segment.
USER = 0x03,
/// Identifies a code segment.
CODE = 0x10,
/// Identifies a data segment.
DATA = 0x10,
/// Segment is present.
PRESENT = 0x80,
} __attribute__ ((__packed__)) gdt_access_option_t;
/// @brief Options for the second option.
typedef enum gdt_granularity_option_t
{
/// Granularity.
GRANULARITY = 0x80,
/// Szbits.
SZBITS = 0x40
} __attribute__ ((__packed__)) gdt_granularity_option_t;
/// @brief Data structure representing a GDT descriptor.
typedef struct gdt_descriptor_t
{
/// The lower 16 bits of the limit.
uint16_t limit_low;
/// The lower 16 bits of the base.
uint16_t base_low;
/// The next 8 bits of the base.
uint8_t base_middle;
/// Access flags, determine what ring this segment can be used in.
uint8_t access;
/// SegLimit_hi(4 bit) AVL(1 bit) L(1 bit) D/B(1 bit) G(1bit).
uint8_t granularity;
/// The last 8 bits of the base.
uint8_t base_high;
} __attribute__((packed)) gdt_descriptor_t;
/// @brief Data structure used to load the GDT into the GDTR.
typedef struct gdt_pointer_t
{
/// The size of the GDT (entry number).
uint16_t limit;
/// The starting address of the GDT.
uint32_t base;
} __attribute__((packed)) gdt_pointer_t;
/// @brief Initialise the GDT.
/// @details This will setup the special GDT
/// pointer, set up the first 3 entries in our GDT, and then
/// finally call gdt_flush() in our assembler file in order
/// to tell the processor where the new GDT is and update the
/// new segment registers.
void init_gdt();
/// @brief Sets the value of one GDT entry.
/// @param index The index inside the GDT.
/// @param base Memory address where the segment we are defining starts.
/// @param limit The memory address which determines the end of the segnment.
/// @param _access Type (4bit) - S (1) bit -DPL (2 bit) - P(1 bit).
/// @param _granul SegLimit_hi(4 bit) AVL(1 bit) L(1 bit) D/B(1 bit) G(1bit).
void gdt_set_gate(uint8_t index,
uint32_t base,
uint32_t limit,
uint8_t _access,
uint8_t _granul);
+169 -169
View File
@@ -1,169 +1,169 @@
/// MentOS, The Mentoring Operating system project
/// @file idt.h
/// @brief Data structures concerning the Interrupt Descriptor Table (IDT).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "isr.h"
#include "stdint.h"
#include <kernel.h>
/// The maximum dimension of the IDT.
#define IDT_SIZE 256
/// When an exception occurs whose entry is a Task Gate, a task switch results.
#define TASK_GATE 0x5
/// Used to specify an interrupt service routine (16-bit).
#define INT16_GATE 0x6
/// @brief Similar to an Interrupt gate (16-bit).
#define TRAP16_GATE 0x7
/// Used to specify an interrupt service routine (32-bit).
#define INT32_GATE 0xE
/// @brief Similar to an Interrupt gate (32-bit).
#define TRAP32_GATE 0xF
/*
* Trap and Interrupt gates are similar, and their descriptors are
* structurally the same, they differ only in the "type" field. The
* difference is that for interrupt gates, interrupts are automatically
* disabled upon entry and reenabled upon IRET which restores the saved EFLAGS.
*/
/// @brief This structure describes one interrupt gate.
typedef struct idt_descriptor_t {
unsigned short offset_low;
unsigned short seg_selector;
// This will ALWAYS be set to 0.
unsigned char null_par;
// |P|DPL|01110|.
// P present, DPL required Ring (2bits).
unsigned char options;
unsigned short offset_high;
} __attribute__((packed)) idt_descriptor_t;
/// @brief A pointer structure used for informing the CPU about our IDT.
typedef struct idt_pointer_t {
/// The size of the IDT (entry number).
unsigned short int limit;
/// The start address of the IDT.
unsigned int base;
} __attribute__((packed)) idt_pointer_t;
/// @brief Initialise the interrupt descriptor table.
void init_idt();
/// @brief Use this function to set an entry in the IDT.
/// @param index Indice della IDT.
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
/// @param seg_sel Il selettore del segmento della GDT.
void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
uint8_t seg_sel);
//==== List of exceptions generated internally by the CPU ======================
extern void INT_0();
extern void INT_1();
extern void INT_2();
extern void INT_3();
extern void INT_4();
extern void INT_5();
extern void INT_6();
extern void INT_7();
extern void INT_8();
extern void INT_9();
extern void INT_10();
extern void INT_11();
extern void INT_12();
extern void INT_13();
extern void INT_14();
extern void INT_15();
extern void INT_16();
extern void INT_17();
extern void INT_18();
extern void INT_19();
extern void INT_20();
extern void INT_21();
extern void INT_22();
extern void INT_23();
extern void INT_24();
extern void INT_25();
extern void INT_26();
extern void INT_27();
extern void INT_28();
extern void INT_29();
extern void INT_30();
extern void INT_31();
extern void INT_80();
//==============================================================================
//==== List of interrupts generated by PIC =====================================
extern void IRQ_0();
extern void IRQ_1();
extern void IRQ_2();
extern void IRQ_3();
extern void IRQ_4();
extern void IRQ_5();
extern void IRQ_6();
extern void IRQ_7();
extern void IRQ_8();
extern void IRQ_9();
extern void IRQ_10();
extern void IRQ_11();
extern void IRQ_12();
extern void IRQ_13();
extern void IRQ_14();
extern void IRQ_15();
//==============================================================================
/// MentOS, The Mentoring Operating system project
/// @file idt.h
/// @brief Data structures concerning the Interrupt Descriptor Table (IDT).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "isr.h"
#include "stdint.h"
#include <kernel.h>
/// The maximum dimension of the IDT.
#define IDT_SIZE 256
/// When an exception occurs whose entry is a Task Gate, a task switch results.
#define TASK_GATE 0x5
/// Used to specify an interrupt service routine (16-bit).
#define INT16_GATE 0x6
/// @brief Similar to an Interrupt gate (16-bit).
#define TRAP16_GATE 0x7
/// Used to specify an interrupt service routine (32-bit).
#define INT32_GATE 0xE
/// @brief Similar to an Interrupt gate (32-bit).
#define TRAP32_GATE 0xF
/*
* Trap and Interrupt gates are similar, and their descriptors are
* structurally the same, they differ only in the "type" field. The
* difference is that for interrupt gates, interrupts are automatically
* disabled upon entry and reenabled upon IRET which restores the saved EFLAGS.
*/
/// @brief This structure describes one interrupt gate.
typedef struct idt_descriptor_t {
unsigned short offset_low;
unsigned short seg_selector;
// This will ALWAYS be set to 0.
unsigned char null_par;
// |P|DPL|01110|.
// P present, DPL required Ring (2bits).
unsigned char options;
unsigned short offset_high;
} __attribute__((packed)) idt_descriptor_t;
/// @brief A pointer structure used for informing the CPU about our IDT.
typedef struct idt_pointer_t {
/// The size of the IDT (entry number).
unsigned short int limit;
/// The start address of the IDT.
unsigned int base;
} __attribute__((packed)) idt_pointer_t;
/// @brief Initialise the interrupt descriptor table.
void init_idt();
/// @brief Use this function to set an entry in the IDT.
/// @param index Indice della IDT.
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
/// @param seg_sel Il selettore del segmento della GDT.
void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
uint8_t seg_sel);
//==== List of exceptions generated internally by the CPU ======================
extern void INT_0();
extern void INT_1();
extern void INT_2();
extern void INT_3();
extern void INT_4();
extern void INT_5();
extern void INT_6();
extern void INT_7();
extern void INT_8();
extern void INT_9();
extern void INT_10();
extern void INT_11();
extern void INT_12();
extern void INT_13();
extern void INT_14();
extern void INT_15();
extern void INT_16();
extern void INT_17();
extern void INT_18();
extern void INT_19();
extern void INT_20();
extern void INT_21();
extern void INT_22();
extern void INT_23();
extern void INT_24();
extern void INT_25();
extern void INT_26();
extern void INT_27();
extern void INT_28();
extern void INT_29();
extern void INT_30();
extern void INT_31();
extern void INT_80();
//==============================================================================
//==== List of interrupts generated by PIC =====================================
extern void IRQ_0();
extern void IRQ_1();
extern void IRQ_2();
extern void IRQ_3();
extern void IRQ_4();
extern void IRQ_5();
extern void IRQ_6();
extern void IRQ_7();
extern void IRQ_8();
extern void IRQ_9();
extern void IRQ_10();
extern void IRQ_11();
extern void IRQ_12();
extern void IRQ_13();
extern void IRQ_14();
extern void IRQ_15();
//==============================================================================
+129 -129
View File
@@ -1,129 +1,129 @@
/// MentOS, The Mentoring Operating system project
/// @file isr.h
/// @brief Data structures concerning the Interrupt Service Routines (ISRs).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
// TODO: see interrupt_handler_t in Linux, it is quite different.
/// @brief Interrupt handler definition.
/// @details An interrupt handler is an interrupt service routine called
/// to manage interrupt requests, or CPU execptions.
/// @param f An interrupt stack frame.
typedef void (*interrupt_handler_t)(pt_regs *f);
/// @brief For each exceptions isrs_init sets a default handler which
/// prints the rose exceptions and stops kernel execution.
void isrs_init();
/// @brief For each interrupt irqs_init sets a default handler which
/// prints the rose IRQ line and stops kernel execution.
void irqs_init();
/* Even if an interrupt service routine is called for exceptions and
* interrupts, we use two distinct methods to logically setup an ISR to
* handle theme. Tecnically speacking, exceptions are synchronous interrupts
* generated by CPU. For an exception we have an ISR. Interrupts are
* asynchronous events generated by PIC. Furthermore, multiple ISRs can be set
* for a same IRQ.
*/
/// @brief Installs an ISR to handle an exception.
/// @param i Exception identifier.
/// @param handler Exception handler.
/// @return 0 On success, -1 otherwise.
int isr_install_handler(uint32_t i, interrupt_handler_t handler,
char *description);
/// @brief Installs an ISR to handle an interrupt.
/// @param i Interrupt identifier.
/// @param handler Interrupt handler.
/// @return 0 On success, -1 otherwise.
int irq_install_handler(uint32_t i, interrupt_handler_t handler,
char *description);
/// @brief Method called by CPU to handle interrupts.
/// @param f The interrupt stack frame.
extern void irq_handler(pt_regs *f);
/// @brief Method called by CPU to handle exceptions.
/// @param f The interrupt stack frame.
extern void isq_handler(pt_regs *f);
//==== List of exceptions generated internally by the CPU ======================
/// @brief DE Divide Error.
#define DIVIDE_ERROR 0
/// @brief DB Debug.
#define DEBUG_EXC 1
/// @brief Non Mascable Interrupt.
#define NMI_INTERRUPT 2
/// @brief BP Breakpoint.
#define BREAKPOINT 3
/// @brief OF Overflow.
#define OVERFLOW 4
/// @brief BR Bound Range Exception.
#define BOUND_RANGE_EXCEED 5
/// @brief UD Invalid OpCode Exception.
#define INVALID_OPCODE 6
/// @brief NM Device Not Available.
#define DEV_NOT_AVL 7
/// @brief DF Double Fault.
#define DOUBLE_FAULT 8
/// @brief Coprocessor Segment Overrun.
#define COPROC_SEG_OVERRUN 9
/// @brief TS Invalid TSS.
#define INVALID_TSS 10
/// @brief NP Segment Not Present.
#define SEGMENT_NOT_PRESENT 11
/// @brief SS Stack Segment Fault.
#define STACK_SEGMENT_FAULT 12
/// @brief GP General Protection.
#define GENERAL_PROTECTION 13
/// @brief PF Page Fault.
#define PAGE_FAULT 14
/// @brief XX Reserverd.
#define INT_RSV 15
/// @brief MF Floating Point.
#define FLOATING_POINT_ERR 16
/// @brief AC Alignment Check.
#define ALIGNMENT_CHECK 17
/// @brief MC Machine Check.
#define MACHINE_CHECK 18
/// @brief XF Streaming SIMD Exception.
#define SIMD_FP_EXC 19
/// @brief Virtualization Exception.
#define VIRT_EXC 20
/// @brief Reserved [21-29].
/// @brief Security Exception.
#define SECURITY_EXC 30
/// @brief Triple Fault
#define TRIPLE_FAULT 31
/// @brief System call interrupt.
#define SYSTEM_CALL 80
//==============================================================================
/// MentOS, The Mentoring Operating system project
/// @file isr.h
/// @brief Data structures concerning the Interrupt Service Routines (ISRs).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
// TODO: see interrupt_handler_t in Linux, it is quite different.
/// @brief Interrupt handler definition.
/// @details An interrupt handler is an interrupt service routine called
/// to manage interrupt requests, or CPU execptions.
/// @param f An interrupt stack frame.
typedef void (*interrupt_handler_t)(pt_regs *f);
/// @brief For each exceptions isrs_init sets a default handler which
/// prints the rose exceptions and stops kernel execution.
void isrs_init();
/// @brief For each interrupt irqs_init sets a default handler which
/// prints the rose IRQ line and stops kernel execution.
void irqs_init();
/* Even if an interrupt service routine is called for exceptions and
* interrupts, we use two distinct methods to logically setup an ISR to
* handle theme. Tecnically speacking, exceptions are synchronous interrupts
* generated by CPU. For an exception we have an ISR. Interrupts are
* asynchronous events generated by PIC. Furthermore, multiple ISRs can be set
* for a same IRQ.
*/
/// @brief Installs an ISR to handle an exception.
/// @param i Exception identifier.
/// @param handler Exception handler.
/// @return 0 On success, -1 otherwise.
int isr_install_handler(uint32_t i, interrupt_handler_t handler,
char *description);
/// @brief Installs an ISR to handle an interrupt.
/// @param i Interrupt identifier.
/// @param handler Interrupt handler.
/// @return 0 On success, -1 otherwise.
int irq_install_handler(uint32_t i, interrupt_handler_t handler,
char *description);
/// @brief Method called by CPU to handle interrupts.
/// @param f The interrupt stack frame.
extern void irq_handler(pt_regs *f);
/// @brief Method called by CPU to handle exceptions.
/// @param f The interrupt stack frame.
extern void isq_handler(pt_regs *f);
//==== List of exceptions generated internally by the CPU ======================
/// @brief DE Divide Error.
#define DIVIDE_ERROR 0
/// @brief DB Debug.
#define DEBUG_EXC 1
/// @brief Non Mascable Interrupt.
#define NMI_INTERRUPT 2
/// @brief BP Breakpoint.
#define BREAKPOINT 3
/// @brief OF Overflow.
#define OVERFLOW 4
/// @brief BR Bound Range Exception.
#define BOUND_RANGE_EXCEED 5
/// @brief UD Invalid OpCode Exception.
#define INVALID_OPCODE 6
/// @brief NM Device Not Available.
#define DEV_NOT_AVL 7
/// @brief DF Double Fault.
#define DOUBLE_FAULT 8
/// @brief Coprocessor Segment Overrun.
#define COPROC_SEG_OVERRUN 9
/// @brief TS Invalid TSS.
#define INVALID_TSS 10
/// @brief NP Segment Not Present.
#define SEGMENT_NOT_PRESENT 11
/// @brief SS Stack Segment Fault.
#define STACK_SEGMENT_FAULT 12
/// @brief GP General Protection.
#define GENERAL_PROTECTION 13
/// @brief PF Page Fault.
#define PAGE_FAULT 14
/// @brief XX Reserverd.
#define INT_RSV 15
/// @brief MF Floating Point.
#define FLOATING_POINT_ERR 16
/// @brief AC Alignment Check.
#define ALIGNMENT_CHECK 17
/// @brief MC Machine Check.
#define MACHINE_CHECK 18
/// @brief XF Streaming SIMD Exception.
#define SIMD_FP_EXC 19
/// @brief Virtualization Exception.
#define VIRT_EXC 20
/// @brief Reserved [21-29].
/// @brief Security Exception.
#define SECURITY_EXC 30
/// @brief Triple Fault
#define TRIPLE_FAULT 31
/// @brief System call interrupt.
#define SYSTEM_CALL 80
//==============================================================================
+61 -61
View File
@@ -1,61 +1,61 @@
/// MentOS, The Mentoring Operating system project
/// @file tss.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "gdt.h"
#include "stdio.h"
#include "kernel.h"
// TODO: doxygen comment.
typedef struct tss_entry {
uint32_t prevTss;
uint32_t esp0;
uint32_t ss0;
uint32_t esp1;
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap;
} tss_entry_t;
extern void tss_flush();
/// @brief We don't need tss to assist task switching, but it's required to
/// have one tss for switching back to kernel mode(system call for
/// example).
/// @param idx
/// @param kss
/// @param kesp
void tss_init(uint8_t idx, uint32_t kss, uint32_t kesp);
// esp the kernel should be using.
/// @brief This function is used to set the tss's esp, so that CPU knows what.
/// @param kss
/// @param kesp
void tss_set_stack(uint32_t kss, uint32_t kesp);
// TODO: doxygen comment.
void print_tss();
/// MentOS, The Mentoring Operating system project
/// @file tss.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "gdt.h"
#include "stdio.h"
#include "kernel.h"
// TODO: doxygen comment.
typedef struct tss_entry {
uint32_t prevTss;
uint32_t esp0;
uint32_t ss0;
uint32_t esp1;
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap;
} tss_entry_t;
extern void tss_flush();
/// @brief We don't need tss to assist task switching, but it's required to
/// have one tss for switching back to kernel mode(system call for
/// example).
/// @param idx
/// @param kss
/// @param kesp
void tss_init(uint8_t idx, uint32_t kss, uint32_t kesp);
// esp the kernel should be using.
/// @brief This function is used to set the tss's esp, so that CPU knows what.
/// @param kss
/// @param kesp
void tss_set_stack(uint32_t kss, uint32_t kesp);
// TODO: doxygen comment.
void print_tss();
+21 -21
View File
@@ -1,21 +1,21 @@
/// MentOS, The Mentoring Operating system project
/// @file fpu.h
/// @brief Floating Point Unit (FPU).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stdint.h"
#include "stdbool.h"
// TODO: doxygen comment.
/// @brief
void switch_fpu();
// TODO: doxygen comment.
/// @brief
void unswitch_fpu();
// TODO: doxygen comment.
/// @brief
/// @return
bool_t fpu_install();
/// MentOS, The Mentoring Operating system project
/// @file fpu.h
/// @brief Floating Point Unit (FPU).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stdint.h"
#include "stdbool.h"
// TODO: doxygen comment.
/// @brief
void switch_fpu();
// TODO: doxygen comment.
/// @brief
void unswitch_fpu();
// TODO: doxygen comment.
/// @brief
/// @return
bool_t fpu_install();
+247 -247
View File
@@ -1,247 +1,247 @@
/// MentOS, The Mentoring Operating system project
/// @file pci.h
/// @brief Routines for PCI initialization.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup pci_configuration_space The PCI configuration space.
/// The PCI Specification defines the organization of the 256-byte.
/// Configuration Space registers and imposes a specific template for the
/// space. Figures 2 & 3 show the layout of the 256-byte Configuration space.
/// All PCI compliant devices must support the Vendor ID, Device ID, Command
/// and Status, Revision ID, Class Code and Header Type fields. Implementation
/// of the other registers is optional, depending upon the devices
/// functionality.
/// @{
/// 16 bits - Identifies the manufacturer of the device. Where valid IDs are
/// allocated by PCI-SIG (the list is here) to ensure uniqueness and 0xFFFF is
/// an invalid value that will be returned on read accesses to Configuration
/// Space registers of non-existent devices.
#define PCI_VENDOR_ID 0x00
/// 16 bits - Identifies the particular device. Where valid IDs are allocated
/// by the vendor.
#define PCI_DEVICE_ID 0x02
/// 16 bits - Provides control over a device's ability to generate and
/// respond to PCI cycles. Where the only functionality guaranteed to be
/// supported by all devices is, when a 0 is written to this register, the
/// device is disconnected from the PCI bus for all accesses except
/// Configuration Space access.
#define PCI_COMMAND 0x04
/// 16 bits - A register used to record status information for PCI bus
/// related events.
#define PCI_STATUS 0x06
/// 8 bits - Specifies a revision identifier for a particular device. Where
/// valid IDs are allocated by the vendor.
#define PCI_REVISION_ID 0x08
/// 8 bits - A read-only register that specifies a register-level
/// programming interface the device has, if it has any at all.
#define PCI_PROG_IF 0x09
/// 8 bits - A read-only register that specifies the specific function the
/// device performs.
#define PCI_SUBCLASS 0x0a
/// 8 bits - A read-only register that specifies the type of function the
/// device performs.
#define PCI_CLASS 0x0b
/// 8 bits - Specifies the system cache line size in 32-bit units. A device
/// can limit the number of cacheline sizes it can support, if a unsupported
/// value is written to this field, the device will behave as if a value of 0
/// was written.
#define PCI_CACHE_LINE_SIZE 0x0c
/// 8 bits - Specifies the latency timer in units of PCI bus clocks.
#define PCI_LATENCY_TIMER 0x0d
/// 8 bits - Identifies the layout of the rest of the header beginning at
/// byte 0x10 of the header and also specifies whether or not the device has
/// multiple functions. Where a value of 0x00 specifies a general device, a
/// value of 0x01 specifies a PCI-to-PCI bridge, and a value of 0x02 specifies
/// a CardBus bridge. If bit 7 of this register is set, the device has
/// multiple functions; otherwise, it is a single function device.
#define PCI_HEADER_TYPE 0x0e
/// 8 bits - Represents that status and allows control of a devices BIST
/// (built-in self test).
#define PCI_BIST 0x0f
/// @defgroup pci_base_addresses The PCI base addresses.
/// Base addresses specify locations in memory or I/O space.
/// Decoded size can be determined by writing a value of 0xffffffff to the
/// register, and reading it back. Only 1 bits are decoded.
/// @{
#define PCI_BASE_ADDRESS_0 0x10
#define PCI_BASE_ADDRESS_1 0x14
#define PCI_BASE_ADDRESS_2 0x18
#define PCI_BASE_ADDRESS_3 0x1c
#define PCI_BASE_ADDRESS_4 0x20
#define PCI_BASE_ADDRESS_5 0x24
/// @} pci_base_addresses
/// Points to the Card Information Structure and is used by devices that
/// share silicon between CardBus and PCI.
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30
/// Points to a linked list of new capabilities implemented by the device.
/// Used if bit 4 of the status register (Capabilities List bit) is set to 1.
/// The bottom two bits are reserved and should be masked before the Pointer
/// is used to access the Configuration Space.
#define PCI_CAPABILITY_LIST 0x34
/// Specifies which input of the system interrupt controllers the device's
/// interrupt pin is connected to and is implemented by any device that makes
/// use of an interrupt pin. For the x86 architecture this register
/// corresponds to the PIC IRQ numbers 0-15 (and not I/O APIC IRQ numbers) and
/// a value of 0xFF defines no connection.
#define PCI_INTERRUPT_LINE 0x3c
/// Specifies which interrupt pin the device uses. Where a value of 0x01 is
/// INTA#, 0x02 is INTB#, 0x03 is INTC#, 0x04 is INTD#, and 0x00 means the
/// device does not use an interrupt pin.
#define PCI_INTERRUPT_PIN 0x3d
/// A read-only register that specifies the burst period length, in 1/4
/// microsecond units, that the device needs (assuming a 33 MHz clock rate).
#define PCI_MIN_GNT 0x3e
/// A read-only register that specifies how often the device needs access to
/// the PCI bus (in 1/4 microsecond units).
#define PCI_MAX_LAT 0x3f
/// @} pci_configuration_space
#define PCI_SECONDARY_BUS 0x19
#define PCI_HEADER_TYPE_DEVICE 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_TYPE_BRIDGE 0x060400
#define PCI_TYPE_SATA 0x010600
#define PCI_ADDRESS_PORT 0xCF8
#define PCI_VALUE_PORT 0xCFC
#define PCI_NONE 0xFFFF
// TODO: doxygen comment.
/// @brief
typedef void (*pci_func_t)(uint32_t device, uint16_t vendor_id,
uint16_t device_id, void *extra);
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_bus(uint32_t device)
{
return (uint8_t)((device >> 16));
}
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_slot(uint32_t device)
{
return (uint8_t)((device >> 8));
}
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_func(uint32_t device)
{
return (uint8_t)(device);
}
// TODO: doxygen comment.
/// @brief
static inline uint32_t pci_get_addr(uint32_t device, int field)
{
return 0x80000000 | (pci_extract_bus(device) << 16) |
(pci_extract_slot(device) << 11) | (pci_extract_func(device) << 8) |
((field)&0xFC);
}
// TODO: doxygen comment.
/// @brief
static inline uint32_t pci_box_device(int bus, int slot, int func)
{
return (uint32_t)((bus << 16) | (slot << 8) | func);
}
/// @brief Reads a field from the given PCI device.
uint32_t pci_read_field(uint32_t device, int field, int size);
// TODO: doxygen comment.
/// @brief
void pci_write_field(uint32_t device, int field, int size, uint32_t value);
// TODO: doxygen comment.
/// @brief
uint32_t pci_find_type(uint32_t device);
// TODO: doxygen comment.
/// @brief
const char *pci_vendor_lookup(unsigned short vendor_id);
// TODO: doxygen comment.
/// @brief
const char *pci_device_lookup(unsigned short vendor_id,
unsigned short device_id);
// TODO: doxygen comment.
/// @brief
void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_slot(pci_func_t f, int type, int bus, int slot, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_bus(pci_func_t f, int type, int bus, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan(pci_func_t f, int type, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_remap(void);
// TODO: doxygen comment.
/// @brief
int pci_get_interrupt(uint32_t device);
// TODO: doxygen comment.
/// @brief
void pci_debug_scan();
/// MentOS, The Mentoring Operating system project
/// @file pci.h
/// @brief Routines for PCI initialization.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup pci_configuration_space The PCI configuration space.
/// The PCI Specification defines the organization of the 256-byte.
/// Configuration Space registers and imposes a specific template for the
/// space. Figures 2 & 3 show the layout of the 256-byte Configuration space.
/// All PCI compliant devices must support the Vendor ID, Device ID, Command
/// and Status, Revision ID, Class Code and Header Type fields. Implementation
/// of the other registers is optional, depending upon the devices
/// functionality.
/// @{
/// 16 bits - Identifies the manufacturer of the device. Where valid IDs are
/// allocated by PCI-SIG (the list is here) to ensure uniqueness and 0xFFFF is
/// an invalid value that will be returned on read accesses to Configuration
/// Space registers of non-existent devices.
#define PCI_VENDOR_ID 0x00
/// 16 bits - Identifies the particular device. Where valid IDs are allocated
/// by the vendor.
#define PCI_DEVICE_ID 0x02
/// 16 bits - Provides control over a device's ability to generate and
/// respond to PCI cycles. Where the only functionality guaranteed to be
/// supported by all devices is, when a 0 is written to this register, the
/// device is disconnected from the PCI bus for all accesses except
/// Configuration Space access.
#define PCI_COMMAND 0x04
/// 16 bits - A register used to record status information for PCI bus
/// related events.
#define PCI_STATUS 0x06
/// 8 bits - Specifies a revision identifier for a particular device. Where
/// valid IDs are allocated by the vendor.
#define PCI_REVISION_ID 0x08
/// 8 bits - A read-only register that specifies a register-level
/// programming interface the device has, if it has any at all.
#define PCI_PROG_IF 0x09
/// 8 bits - A read-only register that specifies the specific function the
/// device performs.
#define PCI_SUBCLASS 0x0a
/// 8 bits - A read-only register that specifies the type of function the
/// device performs.
#define PCI_CLASS 0x0b
/// 8 bits - Specifies the system cache line size in 32-bit units. A device
/// can limit the number of cacheline sizes it can support, if a unsupported
/// value is written to this field, the device will behave as if a value of 0
/// was written.
#define PCI_CACHE_LINE_SIZE 0x0c
/// 8 bits - Specifies the latency timer in units of PCI bus clocks.
#define PCI_LATENCY_TIMER 0x0d
/// 8 bits - Identifies the layout of the rest of the header beginning at
/// byte 0x10 of the header and also specifies whether or not the device has
/// multiple functions. Where a value of 0x00 specifies a general device, a
/// value of 0x01 specifies a PCI-to-PCI bridge, and a value of 0x02 specifies
/// a CardBus bridge. If bit 7 of this register is set, the device has
/// multiple functions; otherwise, it is a single function device.
#define PCI_HEADER_TYPE 0x0e
/// 8 bits - Represents that status and allows control of a devices BIST
/// (built-in self test).
#define PCI_BIST 0x0f
/// @defgroup pci_base_addresses The PCI base addresses.
/// Base addresses specify locations in memory or I/O space.
/// Decoded size can be determined by writing a value of 0xffffffff to the
/// register, and reading it back. Only 1 bits are decoded.
/// @{
#define PCI_BASE_ADDRESS_0 0x10
#define PCI_BASE_ADDRESS_1 0x14
#define PCI_BASE_ADDRESS_2 0x18
#define PCI_BASE_ADDRESS_3 0x1c
#define PCI_BASE_ADDRESS_4 0x20
#define PCI_BASE_ADDRESS_5 0x24
/// @} pci_base_addresses
/// Points to the Card Information Structure and is used by devices that
/// share silicon between CardBus and PCI.
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30
/// Points to a linked list of new capabilities implemented by the device.
/// Used if bit 4 of the status register (Capabilities List bit) is set to 1.
/// The bottom two bits are reserved and should be masked before the Pointer
/// is used to access the Configuration Space.
#define PCI_CAPABILITY_LIST 0x34
/// Specifies which input of the system interrupt controllers the device's
/// interrupt pin is connected to and is implemented by any device that makes
/// use of an interrupt pin. For the x86 architecture this register
/// corresponds to the PIC IRQ numbers 0-15 (and not I/O APIC IRQ numbers) and
/// a value of 0xFF defines no connection.
#define PCI_INTERRUPT_LINE 0x3c
/// Specifies which interrupt pin the device uses. Where a value of 0x01 is
/// INTA#, 0x02 is INTB#, 0x03 is INTC#, 0x04 is INTD#, and 0x00 means the
/// device does not use an interrupt pin.
#define PCI_INTERRUPT_PIN 0x3d
/// A read-only register that specifies the burst period length, in 1/4
/// microsecond units, that the device needs (assuming a 33 MHz clock rate).
#define PCI_MIN_GNT 0x3e
/// A read-only register that specifies how often the device needs access to
/// the PCI bus (in 1/4 microsecond units).
#define PCI_MAX_LAT 0x3f
/// @} pci_configuration_space
#define PCI_SECONDARY_BUS 0x19
#define PCI_HEADER_TYPE_DEVICE 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_TYPE_BRIDGE 0x060400
#define PCI_TYPE_SATA 0x010600
#define PCI_ADDRESS_PORT 0xCF8
#define PCI_VALUE_PORT 0xCFC
#define PCI_NONE 0xFFFF
// TODO: doxygen comment.
/// @brief
typedef void (*pci_func_t)(uint32_t device, uint16_t vendor_id,
uint16_t device_id, void *extra);
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_bus(uint32_t device)
{
return (uint8_t)((device >> 16));
}
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_slot(uint32_t device)
{
return (uint8_t)((device >> 8));
}
// TODO: doxygen comment.
/// @brief
static inline int pci_extract_func(uint32_t device)
{
return (uint8_t)(device);
}
// TODO: doxygen comment.
/// @brief
static inline uint32_t pci_get_addr(uint32_t device, int field)
{
return 0x80000000 | (pci_extract_bus(device) << 16) |
(pci_extract_slot(device) << 11) | (pci_extract_func(device) << 8) |
((field)&0xFC);
}
// TODO: doxygen comment.
/// @brief
static inline uint32_t pci_box_device(int bus, int slot, int func)
{
return (uint32_t)((bus << 16) | (slot << 8) | func);
}
/// @brief Reads a field from the given PCI device.
uint32_t pci_read_field(uint32_t device, int field, int size);
// TODO: doxygen comment.
/// @brief
void pci_write_field(uint32_t device, int field, int size, uint32_t value);
// TODO: doxygen comment.
/// @brief
uint32_t pci_find_type(uint32_t device);
// TODO: doxygen comment.
/// @brief
const char *pci_vendor_lookup(unsigned short vendor_id);
// TODO: doxygen comment.
/// @brief
const char *pci_device_lookup(unsigned short vendor_id,
unsigned short device_id);
// TODO: doxygen comment.
/// @brief
void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_slot(pci_func_t f, int type, int bus, int slot, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan_bus(pci_func_t f, int type, int bus, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_scan(pci_func_t f, int type, void *extra);
// TODO: doxygen comment.
/// @brief
void pci_remap(void);
// TODO: doxygen comment.
/// @brief
int pci_get_interrupt(uint32_t device);
// TODO: doxygen comment.
/// @brief
void pci_debug_scan();
+199 -199
View File
@@ -1,199 +1,199 @@
/// MentOS, The Mentoring Operating system project
// @file ata.h
/// @brief ATA values and data structures.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup ata_defines The ATA configuration registers.
/// @{
/// @defgroup status_register Status register bits
/// @{
/// Device Busy
#define ATA_STAT_BUSY 0x80
/// Device Ready
#define ATA_STAT_READY 0x40
/// Device Fault
#define ATA_STAT_FAULT 0x20
/// Device Seek Complete
#define ATA_STAT_SEEK 0x10
/// Data Request (ready)
#define ATA_STAT_DRQ 0x08
/// Corrected Data Error
#define ATA_STAT_CORR 0x04
/// Vendor specific
#define ATA_STAT_INDEX 0x02
/// Error
#define ATA_STAT_ERR 0x01
/// @}
/// @defgroup device_registers Device / Head Register Bits
/// @{
#define ATA_DEVICE(x) ((x & 1) << 4)
#define ATA_LBA 0xE0
/// @}
/// @defgroup ata_commands ATA Commands
/// @{
/// Read Sectors (with retries)
#define ATA_CMD_READ 0x20
/// Read Sectors (no retries)
#define ATA_CMD_READN 0x21
/// Write Sectores (with retries)
#define ATA_CMD_WRITE 0x30
/// Write Sectors (no retries)
#define ATA_CMD_WRITEN 0x31
/// Read Verify (with retries)
#define ATA_CMD_VRFY 0x40
/// Read verify (no retries)
#define ATA_CMD_VRFYN 0x41
/// Seek
#define ATA_CMD_SEEK 0x70
/// Execute Device Diagnostic
#define ATA_CMD_DIAG 0x90
/// Initialize Device Parameters
#define ATA_CMD_INIT 0x91
/// Read Multiple
#define ATA_CMD_RD_MULT 0xC4
/// Write Multiple
#define ATA_CMD_WR_MULT 0xC5
/// Set Multiple Mode
#define ATA_CMD_SETMULT 0xC6
/// Read DMA (with retries)
#define ATA_CMD_RD_DMA 0xC8
/// Read DMS (no retries)
#define ATA_CMD_RD_DMAN 0xC9
/// Write DMA (with retries)
#define ATA_CMD_WR_DMA 0xCA
/// Write DMA (no retires)
#define ATA_CMD_WR_DMAN 0xCB
/// Identify Device
#define ATA_CMD_IDENT 0xEC
#define ATA_CMD_CH_FLSH 0xE7
/// Set Features
#define ATA_CMD_SETF 0xEF
/// Check Power Mode
#define ATA_CMD_CHK_PWR 0xE5
/// @}
/// @defgroup atapi_commands ATAPI Commands
/// @{
#define ATAPI_CMD_PACKET 0xA0
#define ATAPI_CMD_ID_PCKT 0xA1
/// @}
#define ATA_IDENT_DEVICETYPE 0
#define ATA_IDENT_CYLINDERS 2
#define ATA_IDENT_HEADS 6
#define ATA_IDENT_SECTORS 12
#define ATA_IDENT_SERIAL 20
#define ATA_IDENT_MODEL 54
#define ATA_IDENT_CAPABILITIES 98
#define ATA_IDENT_FIELDVALID 106
#define ATA_IDENT_MAX_LBA 120
#define ATA_IDENT_COMMANDSETS 164
#define ATA_IDENT_MAX_LBA_EXT 200
#define IDE_ATA 0x00
#define IDE_ATAPI 0x01
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
#define ATA_REG_DATA 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECCOUNT0 0x02
#define ATA_REG_LBA0 0x03
#define ATA_REG_LBA1 0x04
#define ATA_REG_LBA2 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
#define ATA_REG_SECCOUNT1 0x08
#define ATA_REG_LBA3 0x09
#define ATA_REG_LBA4 0x0A
#define ATA_REG_LBA5 0x0B
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ALTSTATUS 0x0C
#define ATA_REG_DEVADDRESS 0x0D
// Channels:
#define ATA_PRIMARY 0x00
#define ATA_SECONDARY 0x01
// Directions:
#define ATA_READ 0x00
#define ATA_WRITE 0x01
/// @}
typedef struct {
uint16_t base;
uint16_t ctrl;
uint16_t bmide;
uint16_t nien;
} ide_channel_regs_t;
typedef struct {
uint8_t reserved;
uint8_t channel;
uint8_t drive;
uint16_t type;
uint16_t signature;
uint16_t capabilities;
uint32_t command_sets;
uint32_t size;
uint8_t model[41];
} ide_device_t;
typedef struct {
uint8_t status;
uint8_t chs_first_sector[3];
uint8_t type;
uint8_t chs_last_sector[3];
uint32_t lba_first_sector;
uint32_t sector_count;
} partition_t;
typedef struct {
uint16_t flags;
uint16_t unused1[9];
char serial[20];
uint16_t unused2[3];
char firmware[8];
char model[40];
uint16_t sectors_per_int;
uint16_t unused3;
uint16_t capabilities[2];
uint16_t unused4[2];
uint16_t valid_ext_data;
uint16_t unused5[5];
uint16_t size_of_rw_mult;
uint32_t sectors_28;
uint16_t unused6[38];
uint64_t sectors_48;
uint16_t unused7[152];
} __attribute__((packed)) ata_identify_t;
typedef struct {
uint8_t boostrap[446];
partition_t partitions[4];
uint8_t signature[2];
} __attribute__((packed)) mbr_t;
int ata_initialize();
int ata_finalize();
/// MentOS, The Mentoring Operating system project
// @file ata.h
/// @brief ATA values and data structures.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup ata_defines The ATA configuration registers.
/// @{
/// @defgroup status_register Status register bits
/// @{
/// Device Busy
#define ATA_STAT_BUSY 0x80
/// Device Ready
#define ATA_STAT_READY 0x40
/// Device Fault
#define ATA_STAT_FAULT 0x20
/// Device Seek Complete
#define ATA_STAT_SEEK 0x10
/// Data Request (ready)
#define ATA_STAT_DRQ 0x08
/// Corrected Data Error
#define ATA_STAT_CORR 0x04
/// Vendor specific
#define ATA_STAT_INDEX 0x02
/// Error
#define ATA_STAT_ERR 0x01
/// @}
/// @defgroup device_registers Device / Head Register Bits
/// @{
#define ATA_DEVICE(x) ((x & 1) << 4)
#define ATA_LBA 0xE0
/// @}
/// @defgroup ata_commands ATA Commands
/// @{
/// Read Sectors (with retries)
#define ATA_CMD_READ 0x20
/// Read Sectors (no retries)
#define ATA_CMD_READN 0x21
/// Write Sectores (with retries)
#define ATA_CMD_WRITE 0x30
/// Write Sectors (no retries)
#define ATA_CMD_WRITEN 0x31
/// Read Verify (with retries)
#define ATA_CMD_VRFY 0x40
/// Read verify (no retries)
#define ATA_CMD_VRFYN 0x41
/// Seek
#define ATA_CMD_SEEK 0x70
/// Execute Device Diagnostic
#define ATA_CMD_DIAG 0x90
/// Initialize Device Parameters
#define ATA_CMD_INIT 0x91
/// Read Multiple
#define ATA_CMD_RD_MULT 0xC4
/// Write Multiple
#define ATA_CMD_WR_MULT 0xC5
/// Set Multiple Mode
#define ATA_CMD_SETMULT 0xC6
/// Read DMA (with retries)
#define ATA_CMD_RD_DMA 0xC8
/// Read DMS (no retries)
#define ATA_CMD_RD_DMAN 0xC9
/// Write DMA (with retries)
#define ATA_CMD_WR_DMA 0xCA
/// Write DMA (no retires)
#define ATA_CMD_WR_DMAN 0xCB
/// Identify Device
#define ATA_CMD_IDENT 0xEC
#define ATA_CMD_CH_FLSH 0xE7
/// Set Features
#define ATA_CMD_SETF 0xEF
/// Check Power Mode
#define ATA_CMD_CHK_PWR 0xE5
/// @}
/// @defgroup atapi_commands ATAPI Commands
/// @{
#define ATAPI_CMD_PACKET 0xA0
#define ATAPI_CMD_ID_PCKT 0xA1
/// @}
#define ATA_IDENT_DEVICETYPE 0
#define ATA_IDENT_CYLINDERS 2
#define ATA_IDENT_HEADS 6
#define ATA_IDENT_SECTORS 12
#define ATA_IDENT_SERIAL 20
#define ATA_IDENT_MODEL 54
#define ATA_IDENT_CAPABILITIES 98
#define ATA_IDENT_FIELDVALID 106
#define ATA_IDENT_MAX_LBA 120
#define ATA_IDENT_COMMANDSETS 164
#define ATA_IDENT_MAX_LBA_EXT 200
#define IDE_ATA 0x00
#define IDE_ATAPI 0x01
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
#define ATA_REG_DATA 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECCOUNT0 0x02
#define ATA_REG_LBA0 0x03
#define ATA_REG_LBA1 0x04
#define ATA_REG_LBA2 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
#define ATA_REG_SECCOUNT1 0x08
#define ATA_REG_LBA3 0x09
#define ATA_REG_LBA4 0x0A
#define ATA_REG_LBA5 0x0B
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ALTSTATUS 0x0C
#define ATA_REG_DEVADDRESS 0x0D
// Channels:
#define ATA_PRIMARY 0x00
#define ATA_SECONDARY 0x01
// Directions:
#define ATA_READ 0x00
#define ATA_WRITE 0x01
/// @}
typedef struct {
uint16_t base;
uint16_t ctrl;
uint16_t bmide;
uint16_t nien;
} ide_channel_regs_t;
typedef struct {
uint8_t reserved;
uint8_t channel;
uint8_t drive;
uint16_t type;
uint16_t signature;
uint16_t capabilities;
uint32_t command_sets;
uint32_t size;
uint8_t model[41];
} ide_device_t;
typedef struct {
uint8_t status;
uint8_t chs_first_sector[3];
uint8_t type;
uint8_t chs_last_sector[3];
uint32_t lba_first_sector;
uint32_t sector_count;
} partition_t;
typedef struct {
uint16_t flags;
uint16_t unused1[9];
char serial[20];
uint16_t unused2[3];
char firmware[8];
char model[40];
uint16_t sectors_per_int;
uint16_t unused3;
uint16_t capabilities[2];
uint16_t unused4[2];
uint16_t valid_ext_data;
uint16_t unused5[5];
uint16_t size_of_rw_mult;
uint32_t sectors_28;
uint16_t unused6[38];
uint64_t sectors_48;
uint16_t unused7[152];
} __attribute__((packed)) ata_identify_t;
typedef struct {
uint8_t boostrap[446];
partition_t partitions[4];
uint8_t signature[2];
} __attribute__((packed)) mbr_t;
int ata_initialize();
int ata_finalize();
+45 -45
View File
@@ -1,45 +1,45 @@
/// MentOS, The Mentoring Operating system project
/// @file fdc.h
/// @brief Definitions about the floppy.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Floppy Disk Controller (FDC) registers.
typedef enum fdc_registers_t
{
STATUS_REGISTER_A = 0x3F0,
///< This register is read-only and monitors the state of the
///< interrupt pin and several disk interface pins.
STATUS_REGISTER_B = 0x3F1,
///< This register is read-only and monitors the state of several
///< isk interface pins.
DOR = 0x3F2,
///< The Digital Output Register contains the drive select and
///< motor enable bits, a reset bit and a DMA GATE bit.
TAPE_DRIVE_REGISTER = 0x3F3,
///< This register allows the user to assign tape support to a
///< particular drive during initialization.
MAIN_STATUS_REGISTER = 0x3F4,
///< The Main Status Register is a read-only register and is used
///< for controlling command input and result output for all commands.
DATARATE_SELECT_REGISTER = 0x3F4,
///< This register is included for compatibility with the 82072
///< floppy controller and is write-only.
DATA_FIFO = 0x3F5,
///< All command parameter information and disk data transfers go
///< through the FIFO.
DIGITAL_INPUT_REGISTER = 0x3F7,
///< This register is read only in all modes.
CONFIGURATION_CONTROL_REGISTER = 0x3F7
///< This register sets the datarate and is write only.
} fdc_registers_t;
/// @brief Allows to enable the motor.
/// @details The motor enable pins are directly controlled via the DOR and
/// are a function of the mapping based on BOOTSEL bits in the TDR.
void fdc_enable_motor(void);
/// @brief Allows to disable the motor.
void fdc_disable_motor(void);
/// MentOS, The Mentoring Operating system project
/// @file fdc.h
/// @brief Definitions about the floppy.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Floppy Disk Controller (FDC) registers.
typedef enum fdc_registers_t
{
STATUS_REGISTER_A = 0x3F0,
///< This register is read-only and monitors the state of the
///< interrupt pin and several disk interface pins.
STATUS_REGISTER_B = 0x3F1,
///< This register is read-only and monitors the state of several
///< isk interface pins.
DOR = 0x3F2,
///< The Digital Output Register contains the drive select and
///< motor enable bits, a reset bit and a DMA GATE bit.
TAPE_DRIVE_REGISTER = 0x3F3,
///< This register allows the user to assign tape support to a
///< particular drive during initialization.
MAIN_STATUS_REGISTER = 0x3F4,
///< The Main Status Register is a read-only register and is used
///< for controlling command input and result output for all commands.
DATARATE_SELECT_REGISTER = 0x3F4,
///< This register is included for compatibility with the 82072
///< floppy controller and is write-only.
DATA_FIFO = 0x3F5,
///< All command parameter information and disk data transfers go
///< through the FIFO.
DIGITAL_INPUT_REGISTER = 0x3F7,
///< This register is read only in all modes.
CONFIGURATION_CONTROL_REGISTER = 0x3F7
///< This register sets the datarate and is write only.
} fdc_registers_t;
/// @brief Allows to enable the motor.
/// @details The motor enable pins are directly controlled via the DOR and
/// are a function of the mapping based on BOOTSEL bits in the TDR.
void fdc_enable_motor(void);
/// @brief Allows to disable the motor.
void fdc_disable_motor(void);
+51 -51
View File
@@ -1,51 +1,51 @@
/// MentOS, The Mentoring Operating system project
/// @file keyboard.h
/// @brief Definitions about the keyboard.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "stdint.h"
#include "stdbool.h"
/// @brief The dimension of the circular buffer used to store video history.
#define BUFSIZE 256
/// @brief Function used to install the keyboard.
void keyboard_install();
/// @brief The keyboard handler.
void keyboard_isr(pt_regs *r);
/// @brief Enable the keyboard.
void keyboard_enable();
/// @brief Disable the keyboard.
void keyboard_disable();
/// @brief Leds handler.
void keyboard_update_leds();
/// @brief Get a char from the buffer.
/// @details It loops until there is something new to read.
/// @return The read character.
int keyboard_getc();
/// @brief Set Keyboard echo Shadow.
/// @param value 1 if you want enable shadow, 0 otherwise.
void keyboard_set_shadow(const bool_t value);
/// @brief Set Keyboard echo Shadow character.
/// @param value 1 if you want enable shadow, 0 otherwise.
void keyboard_set_shadow_character(const char _shadow_character);
/// @brief Get Keyboard Shadow information.
bool_t keyboard_get_shadow();
/// @brief Get ctrl status.
bool_t keyboard_is_ctrl_pressed();
/// @brief Get shift status.
bool_t keyboard_is_shifted();
/// MentOS, The Mentoring Operating system project
/// @file keyboard.h
/// @brief Definitions about the keyboard.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "stdint.h"
#include "stdbool.h"
/// @brief The dimension of the circular buffer used to store video history.
#define BUFSIZE 256
/// @brief Function used to install the keyboard.
void keyboard_install();
/// @brief The keyboard handler.
void keyboard_isr(pt_regs *r);
/// @brief Enable the keyboard.
void keyboard_enable();
/// @brief Disable the keyboard.
void keyboard_disable();
/// @brief Leds handler.
void keyboard_update_leds();
/// @brief Get a char from the buffer.
/// @details It loops until there is something new to read.
/// @return The read character.
int keyboard_getc();
/// @brief Set Keyboard echo Shadow.
/// @param value 1 if you want enable shadow, 0 otherwise.
void keyboard_set_shadow(const bool_t value);
/// @brief Set Keyboard echo Shadow character.
/// @param value 1 if you want enable shadow, 0 otherwise.
void keyboard_set_shadow_character(const char _shadow_character);
/// @brief Get Keyboard Shadow information.
bool_t keyboard_get_shadow();
/// @brief Get ctrl status.
bool_t keyboard_is_ctrl_pressed();
/// @brief Get shift status.
bool_t keyboard_is_shifted();
+242 -242
View File
@@ -1,242 +1,242 @@
/// MentOS, The Mentoring Operating system project
/// @file keymap.h
/// @brief Keymap for keyboard.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup keyboardcodes Keyboard Codes
/// @brief This is the list of keyboard codes.
/// @{
/// Escape character.
#define KEY_ESCAPE 0x01
/// 1.
#define KEY_ONE 0x02
/// 2.
#define KEY_TWO 0x03
/// 3.
#define KEY_THREE 0x04
/// 4.
#define KEY_FOUR 0x05
/// 5.
#define KEY_FIVE 0x06
/// 6.
#define KEY_SIX 0x07
/// 7.
#define KEY_SEVEN 0x08
/// 8.
#define KEY_EIGHT 0x09
/// 9.
#define KEY_NINE 0x0A
/// 0.
#define KEY_ZERO 0x0B
/// '.
#define KEY_APOSTROPHE 0x0C
/// i'.
#define KEY_I_ACC 0x0D
/// Backspace.
#define KEY_BACKSPACE 0x0E
/// Tabular.
#define KEY_TAB 0x0F
/// q.
#define KEY_Q 0x10
/// w.
#define KEY_W 0x11
/// e.
#define KEY_E 0x12
/// r.
#define KEY_R 0x13
/// t.
#define KEY_T 0x14
/// y.
#define KEY_Y 0x15
/// u.
#define KEY_U 0x16
/// i.
#define KEY_I 0x17
/// o.
#define KEY_O 0x18
/// p.
#define KEY_P 0x19
/// (.
#define KEY_LEFT_BRAKET 0x1A
/// ).
#define KEY_RIGHT_BRAKET 0x1B
/// Enter.
#define KEY_ENTER 0x1C
/// Left-ctrl.
#define KEY_LEFT_CONTROL 0x1D
/// a.
#define KEY_A 0x1E
/// s.
#define KEY_S 0x1F
/// d.
#define KEY_D 0x20
/// f.
#define KEY_F 0x21
/// g.
#define KEY_G 0x22
/// h.
#define KEY_H 0x23
/// j.
#define KEY_J 0x24
/// k.
#define KEY_K 0x25
/// l.
#define KEY_L 0x26
/// '.
#define KEY_SEMICOLON 0x27
/// ".
#define KEY_DOUBLE_QUOTES 0x28
///` or ~.
#define KEY_GRAVE 0x29
/// LShift.
#define KEY_LEFT_SHIFT 0x2A
/// \ or |.
#define KEY_BACKSLASH 0x2B
/// Z.
#define KEY_Z 0x2c
/// X.
#define KEY_X 0x2d
/// C.
#define KEY_C 0x2e
/// V.
#define KEY_V 0x2f
/// B.
#define KEY_B 0x30
/// N.
#define KEY_N 0x31
/// M.
#define KEY_M 0x32
/// , or <.
#define KEY_COMMA 0x33
/// . or >.
#define KEY_PERIOD 0x34
/// - or _.
#define KEY_MINUS 0x35
/// RShift.
#define KEY_RIGHT_SHIFT 0x36
/// NP - *.
#define KEY_KP_MUL 0x37
/// LAlt.
#define KEY_LEFT_ALT 0x38
/// Space.
#define KEY_SPACE 0x39
/// Caps Lock.
#define KEY_CAPS_LOCK 0x3a
/// Function 1.
#define KEY_F1 0x3B
/// Function 2.
#define KEY_F2 0x3C
/// Function 3.
#define KEY_F3 0x3D
/// Function 4.
#define KEY_F4 0x3E
/// Function 5.
#define KEY_F5 0x3F
/// Function 6.
#define KEY_F6 0x40
/// Function 7.
#define KEY_F7 0x41
/// Function 8.
#define KEY_F8 0x42
/// Function 9.
#define KEY_F9 0x43
/// Function 10.
#define KEY_F10 0x44
/// Num Lock.
#define KEY_NUM_LOCK 0x45
/// Scroll Lock.
#define KEY_SCROLL_LOCK 0x46
/// NP - Home.
#define KEY_KP7 0x47
/// NP - UpArrow.
#define KEY_KP8 0x48
/// NP - Pgup.
#define KEY_KP9 0x49
/// NP - Grey.
#define KEY_KP_SUB 0x4A
/// NP - LArrow.
#define KEY_KP4 0x4B
/// NP - Center.
#define KEY_KP5 0x4C
/// NP - RArrow.
#define KEY_KP6 0x4D
/// NP - Grey +.
#define KEY_KP_ADD 0x4E
/// NP - End.
#define KEY_KP1 0x4F
/// NP - DArrow.
#define KEY_KP2 0x50
/// NP - Pgdn.
#define KEY_KP3 0x51
/// NP - Ins.
#define KEY_KP0 0x52
/// NP - Del.
#define KEY_KP_DEC 0x53
/// NP - Del.
#define KEY_KP_LESS 0x56
/// NP - Enter 57372.
#define KEY_KP_RETURN 0xe01c
/// Right Ctrl 57373.
#define KEY_RIGHT_CONTROL 0xE01D
/// Divide 57397.
#define KEY_KP_DIV 0xE035
/// Right Alt 57400.
#define KEY_RIGHT_ALT 0xe038
/// F11 57431.
#define KEY_F11 0xe057
/// F12 57432.
#define KEY_F12 0xe058
/// Left Winkey 57435.
#define KEY_LEFT_WIN 0xe05b
/// Right Winkey 57436.
#define KEY_RIGHT_WIN 0xe05c
/// Ins 57426.
#define KEY_INSERT 0xe052
/// Home 57415.
#define KEY_HOME 0xe047
/// Up Arrow 57416.
#define KEY_UP_ARROW 0xe048
/// Pgup 57417.
#define KEY_PAGE_UP 0xe049
/// Left Arrow 57419.
#define KEY_LEFT_ARROW 0xe04b
/// Del 57427.
#define KEY_DELETE 0xe053
/// End 57423.
#define KEY_END 0xe04f
/// Pgdn 57425.
#define KEY_PAGE_DOWN 0xe051
/// Right Arrow 57421.
#define KEY_RIGHT_ARROW 0xe04d
/// Down Arrow 57424.
#define KEY_DOWN_ARROW 0xe050
///< Code break code.
#define CODE_BREAK 0x80
/// @}
/// Num Pad Led.
#define NUM_LED 0x45
/// Scroll Lock Led.
#define SCROLL_LED 0x46
/// Caps Lock Led.
#define CAPS_LED 0x3a
/// @brief Defines a set of arrays used to map key to characters.
typedef struct keymap_t {
/// The basic mapping.
int32_t base[65536];
/// The mapping when shifted.
int32_t shift[65536];
/// The mapping when numlock is active.
uint32_t numlock[65536];
} keymap_t;
/// @brief Italian keymap.
extern const keymap_t keymap_it;
/// MentOS, The Mentoring Operating system project
/// @file keymap.h
/// @brief Keymap for keyboard.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @defgroup keyboardcodes Keyboard Codes
/// @brief This is the list of keyboard codes.
/// @{
/// Escape character.
#define KEY_ESCAPE 0x01
/// 1.
#define KEY_ONE 0x02
/// 2.
#define KEY_TWO 0x03
/// 3.
#define KEY_THREE 0x04
/// 4.
#define KEY_FOUR 0x05
/// 5.
#define KEY_FIVE 0x06
/// 6.
#define KEY_SIX 0x07
/// 7.
#define KEY_SEVEN 0x08
/// 8.
#define KEY_EIGHT 0x09
/// 9.
#define KEY_NINE 0x0A
/// 0.
#define KEY_ZERO 0x0B
/// '.
#define KEY_APOSTROPHE 0x0C
/// i'.
#define KEY_I_ACC 0x0D
/// Backspace.
#define KEY_BACKSPACE 0x0E
/// Tabular.
#define KEY_TAB 0x0F
/// q.
#define KEY_Q 0x10
/// w.
#define KEY_W 0x11
/// e.
#define KEY_E 0x12
/// r.
#define KEY_R 0x13
/// t.
#define KEY_T 0x14
/// y.
#define KEY_Y 0x15
/// u.
#define KEY_U 0x16
/// i.
#define KEY_I 0x17
/// o.
#define KEY_O 0x18
/// p.
#define KEY_P 0x19
/// (.
#define KEY_LEFT_BRAKET 0x1A
/// ).
#define KEY_RIGHT_BRAKET 0x1B
/// Enter.
#define KEY_ENTER 0x1C
/// Left-ctrl.
#define KEY_LEFT_CONTROL 0x1D
/// a.
#define KEY_A 0x1E
/// s.
#define KEY_S 0x1F
/// d.
#define KEY_D 0x20
/// f.
#define KEY_F 0x21
/// g.
#define KEY_G 0x22
/// h.
#define KEY_H 0x23
/// j.
#define KEY_J 0x24
/// k.
#define KEY_K 0x25
/// l.
#define KEY_L 0x26
/// '.
#define KEY_SEMICOLON 0x27
/// ".
#define KEY_DOUBLE_QUOTES 0x28
///` or ~.
#define KEY_GRAVE 0x29
/// LShift.
#define KEY_LEFT_SHIFT 0x2A
/// \ or |.
#define KEY_BACKSLASH 0x2B
/// Z.
#define KEY_Z 0x2c
/// X.
#define KEY_X 0x2d
/// C.
#define KEY_C 0x2e
/// V.
#define KEY_V 0x2f
/// B.
#define KEY_B 0x30
/// N.
#define KEY_N 0x31
/// M.
#define KEY_M 0x32
/// , or <.
#define KEY_COMMA 0x33
/// . or >.
#define KEY_PERIOD 0x34
/// - or _.
#define KEY_MINUS 0x35
/// RShift.
#define KEY_RIGHT_SHIFT 0x36
/// NP - *.
#define KEY_KP_MUL 0x37
/// LAlt.
#define KEY_LEFT_ALT 0x38
/// Space.
#define KEY_SPACE 0x39
/// Caps Lock.
#define KEY_CAPS_LOCK 0x3a
/// Function 1.
#define KEY_F1 0x3B
/// Function 2.
#define KEY_F2 0x3C
/// Function 3.
#define KEY_F3 0x3D
/// Function 4.
#define KEY_F4 0x3E
/// Function 5.
#define KEY_F5 0x3F
/// Function 6.
#define KEY_F6 0x40
/// Function 7.
#define KEY_F7 0x41
/// Function 8.
#define KEY_F8 0x42
/// Function 9.
#define KEY_F9 0x43
/// Function 10.
#define KEY_F10 0x44
/// Num Lock.
#define KEY_NUM_LOCK 0x45
/// Scroll Lock.
#define KEY_SCROLL_LOCK 0x46
/// NP - Home.
#define KEY_KP7 0x47
/// NP - UpArrow.
#define KEY_KP8 0x48
/// NP - Pgup.
#define KEY_KP9 0x49
/// NP - Grey.
#define KEY_KP_SUB 0x4A
/// NP - LArrow.
#define KEY_KP4 0x4B
/// NP - Center.
#define KEY_KP5 0x4C
/// NP - RArrow.
#define KEY_KP6 0x4D
/// NP - Grey +.
#define KEY_KP_ADD 0x4E
/// NP - End.
#define KEY_KP1 0x4F
/// NP - DArrow.
#define KEY_KP2 0x50
/// NP - Pgdn.
#define KEY_KP3 0x51
/// NP - Ins.
#define KEY_KP0 0x52
/// NP - Del.
#define KEY_KP_DEC 0x53
/// NP - Del.
#define KEY_KP_LESS 0x56
/// NP - Enter 57372.
#define KEY_KP_RETURN 0xe01c
/// Right Ctrl 57373.
#define KEY_RIGHT_CONTROL 0xE01D
/// Divide 57397.
#define KEY_KP_DIV 0xE035
/// Right Alt 57400.
#define KEY_RIGHT_ALT 0xe038
/// F11 57431.
#define KEY_F11 0xe057
/// F12 57432.
#define KEY_F12 0xe058
/// Left Winkey 57435.
#define KEY_LEFT_WIN 0xe05b
/// Right Winkey 57436.
#define KEY_RIGHT_WIN 0xe05c
/// Ins 57426.
#define KEY_INSERT 0xe052
/// Home 57415.
#define KEY_HOME 0xe047
/// Up Arrow 57416.
#define KEY_UP_ARROW 0xe048
/// Pgup 57417.
#define KEY_PAGE_UP 0xe049
/// Left Arrow 57419.
#define KEY_LEFT_ARROW 0xe04b
/// Del 57427.
#define KEY_DELETE 0xe053
/// End 57423.
#define KEY_END 0xe04f
/// Pgdn 57425.
#define KEY_PAGE_DOWN 0xe051
/// Right Arrow 57421.
#define KEY_RIGHT_ARROW 0xe04d
/// Down Arrow 57424.
#define KEY_DOWN_ARROW 0xe050
///< Code break code.
#define CODE_BREAK 0x80
/// @}
/// Num Pad Led.
#define NUM_LED 0x45
/// Scroll Lock Led.
#define SCROLL_LED 0x46
/// Caps Lock Led.
#define CAPS_LED 0x3a
/// @brief Defines a set of arrays used to map key to characters.
typedef struct keymap_t {
/// The basic mapping.
int32_t base[65536];
/// The mapping when shifted.
int32_t shift[65536];
/// The mapping when numlock is active.
uint32_t numlock[65536];
} keymap_t;
/// @brief Italian keymap.
extern const keymap_t keymap_it;
+45 -45
View File
@@ -1,45 +1,45 @@
/// MentOS, The Mentoring Operating system project
/// @file mouse.h
/// @brief Driver for *PS2* Mouses.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/* The mouse starts sending automatic packets when the mouse moves or is
* clicked.
*/
#include <kernel.h>
#define MOUSE_ENABLE_PACKET 0xF4
/// The mouse stops sending automatic packets.
#define MOUSE_DISABLE_PACKET 0xF5
/// Disables streaming, sets the packet rate to 100 per second, and
/// resolution to 4 pixels per mm.
#define MOUSE_USE_DEFAULT_SETTINGS 0xF6
/// @brief Sets up the mouse by installing the mouse handler into IRQ12.
void mouse_install();
/// @brief Enable the mouse driver.
void mouse_enable();
/// @brief Disable the mouse driver.
void mouse_disable();
/// @brief Mouse wait for a command.
/// @param type 1 for sending - 0 for receiving.
void mouse_waitcmd(unsigned char type);
/// @brief Send data to mouse.
/// @param data The data to send.
void mouse_write(unsigned char data);
/// @brief Read data from mouse.
/// @return The data received from mouse.
unsigned char mouse_read();
/// @brief The mouse handler.
void mouse_isr(register_t *r);
/// MentOS, The Mentoring Operating system project
/// @file mouse.h
/// @brief Driver for *PS2* Mouses.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/* The mouse starts sending automatic packets when the mouse moves or is
* clicked.
*/
#include <kernel.h>
#define MOUSE_ENABLE_PACKET 0xF4
/// The mouse stops sending automatic packets.
#define MOUSE_DISABLE_PACKET 0xF5
/// Disables streaming, sets the packet rate to 100 per second, and
/// resolution to 4 pixels per mm.
#define MOUSE_USE_DEFAULT_SETTINGS 0xF6
/// @brief Sets up the mouse by installing the mouse handler into IRQ12.
void mouse_install();
/// @brief Enable the mouse driver.
void mouse_enable();
/// @brief Disable the mouse driver.
void mouse_disable();
/// @brief Mouse wait for a command.
/// @param type 1 for sending - 0 for receiving.
void mouse_waitcmd(unsigned char type);
/// @brief Send data to mouse.
/// @param data The data to send.
void mouse_write(unsigned char data);
/// @brief Read data from mouse.
/// @return The data received from mouse.
unsigned char mouse_read();
/// @brief The mouse handler.
void mouse_isr(register_t *r);
+60 -60
View File
@@ -1,60 +1,60 @@
/// MentOS, The Mentoring Operating system project
/// @file elf.h
/// @brief Function for multiboot support.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "multiboot.h"
// Used to get the symbol type.
#define ELF32_ST_TYPE(i) ((i)&0xf)
// List of symbol types.
#define ELF32_TYPE_FUNCTION (0x02)
/// @brief A section header with all kinds of useful information.
typedef struct elf_section_header
{
uint32_t name_offset_in_shstrtab;
uint32_t type;
uint32_t flags;
uint32_t addr;
uint32_t offset;
uint32_t size;
uint32_t link;
uint32_t info;
uint32_t addralign;
uint32_t entsize;
} __attribute__((packed)) elf_section_header_t;
/// @brief A symbol itself.
typedef struct elf_symbol
{
uint32_t name_offset_in_strtab;
uint32_t value;
uint32_t size;
uint8_t info;
uint8_t other;
uint16_t shndx;
} __attribute__((packed)) elf_symbol_t;
// Will hold the array of symbols and their names for us.
typedef struct elf_symbols
{
elf_symbol_t *symtab;
uint32_t symtab_size;
const char *strtab;
uint32_t strtab_size;
} elf_symbols_t;
/// @brief Builds as the set of elf symbols from a multiboot scructure.
void build_elf_symbols_from_multiboot (multiboot_info_t* mb);
/* Locate a symbol (only functions) in the following elf symbols
* Note that, for now, we'll only use this for the kernel (no other elf things..)
*/
const char *elf_lookup_symbol (uint32_t addr, elf_symbols_t *elf);
/// MentOS, The Mentoring Operating system project
/// @file elf.h
/// @brief Function for multiboot support.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "multiboot.h"
// Used to get the symbol type.
#define ELF32_ST_TYPE(i) ((i)&0xf)
// List of symbol types.
#define ELF32_TYPE_FUNCTION (0x02)
/// @brief A section header with all kinds of useful information.
typedef struct elf_section_header
{
uint32_t name_offset_in_shstrtab;
uint32_t type;
uint32_t flags;
uint32_t addr;
uint32_t offset;
uint32_t size;
uint32_t link;
uint32_t info;
uint32_t addralign;
uint32_t entsize;
} __attribute__((packed)) elf_section_header_t;
/// @brief A symbol itself.
typedef struct elf_symbol
{
uint32_t name_offset_in_strtab;
uint32_t value;
uint32_t size;
uint8_t info;
uint8_t other;
uint16_t shndx;
} __attribute__((packed)) elf_symbol_t;
// Will hold the array of symbols and their names for us.
typedef struct elf_symbols
{
elf_symbol_t *symtab;
uint32_t symtab_size;
const char *strtab;
uint32_t strtab_size;
} elf_symbols_t;
/// @brief Builds as the set of elf symbols from a multiboot scructure.
void build_elf_symbols_from_multiboot (multiboot_info_t* mb);
/* Locate a symbol (only functions) in the following elf symbols
* Note that, for now, we'll only use this for the kernel (no other elf things..)
*/
const char *elf_lookup_symbol (uint32_t addr, elf_symbols_t *elf);
@@ -0,0 +1,31 @@
/**
* @author Mirco De Marchi
* @date 2/02/2021
* @brief Header file for deadlock prevention algorithms.
* @copyright (c) University of Verona
*/
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdbool.h"
#include "string.h"
/// @brief Resource allocation request status enumeration.
typedef enum {
SAFE, ///< State safe.
WAIT, ///< State waiting.
WAIT_UNSAFE, ///< State waiting for unsafe detection.
ERROR, ///< State error.
} deadlock_status_t;
/// @brief Request of resources perfomed by a task.
/// @param req_vec Array pointer of resource request for each task in the
/// system.
/// @param task_i Index of task that perform the request to use as array index.
/// @param n Number of tasks currently in the system.
/// @param m Number of resource types in the system (length of req_vec).
/// @return Status of the request (see status_t enum).
deadlock_status_t request(uint32_t *req_vec, size_t task_i, size_t n, size_t m);
@@ -0,0 +1,11 @@
/**
* @author Mirco De Marchi
* @date 2/02/2021
* @brief Header file for deadlock deterministic simulation.
* @copyright (c) University of Verona
*/
#pragma once
/// @brief Deadlock deterministic simulation start function.
void deadlock_simulation();
+150
View File
@@ -0,0 +1,150 @@
/// MentOS, The Mentoring Operating system project
/// @file arr_math.h
/// @brief Array arithmetic operations source file-
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdint.h"
#include "stdbool.h"
/// @brief Initialize all memory cells of destination array with a value.
/// @param dst Pointer of destination array.
/// @param value Value to use for array inizialization.
/// @param length Length of destination array.
/// @return The pointer of the destination array.
uint32_t *all(uint32_t *dst, uint32_t value, size_t length);
/// @brief Element wise array subtraction.
/// @param left Pointer of left operator and destination array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return The pointer of the destination array.
/// E.g. [4, 5, 6] - [1, 2, 3] = [3, 3, 3]
uint32_t *arr_sub(uint32_t *left, const uint32_t *right, size_t length);
/// @brief Element wise array addition.
/// @param left Pointer of left operator and destination array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return The pointer of the destination array.
/// E.g. [4, 5, 6] + [1, 2, 3] = [5, 7, 9]
uint32_t *arr_add(uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is greater than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array greater than the
/// respective right one, otherwise false.
/// E.g. [1, 1, 6] g_any [1, 2, 3] = true
/// [1, 1, 3] g_any [1, 2, 3] = false
bool_t arr_g_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is greater or equal than
/// another array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array greater or equal than
/// the respective right one, otherwise false.
/// E.g. [1, 1, 6] ge_any [1, 2, 3] = true
/// [0, 1, 3] ge_any [1, 2, 3] = true
/// [0, 1, 2] ge_any [1, 2, 3] = false
bool_t arr_ge_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is less than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array less than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] l_any [1, 1, 6] = true
/// [1, 2, 3] l_any [0, 1, 3] = false
bool_t arr_l_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is less or equal than
/// another array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array less or equal than
/// the respective right one, otherwise false.
/// E.g. [1, 2, 3] le_any [1, 1, 6] = true
/// [1, 2, 3] le_any [0, 1, 3] = true
/// [1, 2, 3] le_any [0, 1, 2] = false
bool_t arr_le_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is greater than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are greater than the
/// respective right one, otherwise false.
/// E.g. [2, 3, 4] g_all [1, 2, 3] = true
/// [2, 3, 3] g_all [1, 2, 3] = false
bool_t arr_g(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is greater or equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are greater or equal than the
/// respective right one, otherwise false.
/// E.g. [2, 3, 4] ge_all [1, 2, 3] = true
/// [2, 3, 3] ge_all [1, 2, 3] = true
/// [2, 3, 3] ge_all [1, 2, 4] = false
bool_t arr_ge(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is less than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are less than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] l_all [2, 3, 4] = true
/// [1, 2, 3] l_all [2, 3, 3] = false
bool_t arr_l(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is less or equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are less or equal than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] le_all [2, 3, 4] = true
/// [1, 2, 3] le_all [2, 3, 3] = true
/// [1, 2, 4] le_all [2, 3, 3] = false
bool_t arr_le(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is equal than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are equal than the respective
/// right one, otherwise false.
/// E.g. [1, 2, 3] e_all [1, 2, 3] = true
/// [1, 2, 3] e_all [1, 2, 1] = false
bool_t arr_e(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is not equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array not equal than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] e_all [1, 2, 1] = true
/// [1, 2, 3] e_all [1, 2, 3] = false
bool_t arr_ne(const uint32_t *left, const uint32_t *right, size_t length);
+111
View File
@@ -0,0 +1,111 @@
/// MentOS, The Mentoring Operating system project
/// @file resource.h
/// @brief Resource definition header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "process.h"
#include "stdint.h"
#include "types.h"
#include "list_head.h"
/// @brief Resource descriptor.
typedef struct resource {
/// Resource index. The resources indexes has to be continuous: 0, 1, ... M.
size_t rid;
/// List head for tasks that share this resource.
list_head resources_list;
/// Number of instances of this resource. For now, always 1.
size_t n_instances;
/// The category of the resource (added for debug purpose).
const char *category;
/// If the resource has been assigned, it points to the task assigned,
/// otherwise NULL.
task_struct *assigned_task;
/// Number of instances assigned to assigned task.
size_t assigned_instances;
} resource_t;
/// @brief Structure that maintains information about resources currently
/// allocated in the system.
typedef struct resource_list {
/// Number of queued resources.
size_t num_active;
/// Head of resources.
list_head head;
} resource_list_t;
/// @brief Number of instances of each resources currently available.
extern uint32_t * available;
/// @brief Matrix of maximum resources instances that each task may need.
extern uint32_t ** max;
/// @brief Matrix of current resource allocation for each task.
extern uint32_t ** alloc;
/// @brief Matrix of current resource needs for each task.
/// need[i][j] = max[i][j] - alloc[i][j]
extern uint32_t ** need;
/// @brief Resource creation.
/// @param category Resource category string, used to group resources.
/// @return The pointer to the resource created.
resource_t *resource_create(const char *category);
/// @brief Resource initialization.
/// @param r Pointer to a resource created.
void resource_init(resource_t *r);
/// @brief Resource destruction.
/// @param r Pointer to a resource created.
void resource_destroy(resource_t *r);
/// @brief Assign the ownership of a resource to the current calling task.
/// @param r Pointer to a resource created.
void resource_assign(resource_t *r);
/// @brief Remove the ownership of a resource from the current calling task.
/// @param r Pointer to a resource created.
void resource_deassign(resource_t *r);
/// @brief Initialize deadlock prevention structures.
/// @param available Array of resources instances currently available;
/// @param max Matrix of the maximum resources instances that each
/// task may require;
/// @param alloc Matrix of current resources instances allocation of
/// each task.
/// @param need Matrix of current resources instances need of each task.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
void init_deadlock_structures(uint32_t *available, uint32_t **max,
uint32_t **alloc, uint32_t **need,
task_struct *idx_map_task_struct[]);
/// @brief Reset to zero deadlock prevention structures.
/// @param available Array of resources instances currently available;
/// @param max Matrix of the maximum resources instances that each
/// task may require;
/// @param alloc Matrix of current resources instances allocation of
/// each task.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// There is no need to reset the need matrix because it has to be calculated
/// starting from max matrix, which is clean.
void reset_deadlock_structures(uint32_t *available, uint32_t **max,
uint32_t **alloc, task_struct *idx_map_task_struct[]);
/// @brief Get the number of total resources allocated in the system.
/// @return The number of resources.
size_t kernel_get_active_resources();
/// @brief Return the index of the current task contained in the array of index
/// and processes mapping.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// @return The index that maps with the current task in the
/// idx_map_task_struct array, or -1 if not found the mapping task.
int32_t get_current_task_idx_from(task_struct *idx_map_task_struct[]);
@@ -0,0 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_kernel.h
/// @brief Smart semaphore semaphore kernel-side implementation header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
/// N.B. Header to use only in kernel space.
#pragma once
#include "stdatomic.h"
/// @brief Smart semaphore creation.
/// @return The semaphore id or -1 if creation failed.
int sys_sem_create();
/// @brief Destruction of a created smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if destroy failed, otherwise 0.
int sys_sem_destroy(int id);
/// @brief Initialization of a created smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if initialization failed, otherwise 0.
int sys_sem_init(int id);
/// @brief Tries a safety acquisition of a smart semaphore identified by
/// an ID and, if available, takes the ownership.
/// @param id Smart semaphore ID.
/// @return Return -1 if creation failed, return 0 if semaphore busy or
/// the acquisition is unsafe, otherwise return 1 if semaphore has been
/// acquired.
int sys_sem_try_acquire(int id);
/// @brief Release the ownership of a smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if release failed, otherwise 0.
int sys_sem_release(int id);
+35
View File
@@ -0,0 +1,35 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_user.h
/// @brief Semaphore user-side implementation header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
/// N.B. Header to use only in user space.
#pragma once
/// @brief Semaphore creation.
/// @return The semaphore id or -1 if creation failed.
/// Set the errno code if failed.
int sem_create();
/// @brief Destruction of a created semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if destroy failed, otherwise 0.
int sem_destroy(int id);
/// @brief Initialization of a created semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if initialization failed, otherwise 0.
int sem_init(int id);
/// @brief Acquire the semaphore ownership if available, otherwise waits that
/// becomes available.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if creation failed, otherwise 0 if
/// semaphore has been successfully acquired.
int sem_acquire(int id);
/// @brief Release the ownership of a Semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if release failed, otherwise 0.
int sem_release(int id);
+26 -26
View File
@@ -1,26 +1,26 @@
/// MentOS, The Mentoring Operating system project
/// @file fcntl.h
/// @brief Headers of functions fcntl() and open().
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Open for reading only.
#define O_RDONLY 0x00
/// Open for writing only.
#define O_WRONLY 0x01
/// Open for reading and writing.
#define O_RDWR 0x02
/// If the file exists, this flag has no effect. Otherwise, the file is created.
#define O_CREAT 0x40
/// The file offset will be set to the end of the file prior to each write.
#define O_APPEND 0x400
/// @brief Deletes the file whose name is specified in filename.
/// @param pathname A path to a file.
/// @return On success, zero is returned. On error, -1 is returned,
/// and errno is set appropriately.
int remove(const char *pathname);
/// MentOS, The Mentoring Operating system project
/// @file fcntl.h
/// @brief Headers of functions fcntl() and open().
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Open for reading only.
#define O_RDONLY 0x00
/// Open for writing only.
#define O_WRONLY 0x01
/// Open for reading and writing.
#define O_RDWR 0x02
/// If the file exists, this flag has no effect. Otherwise, the file is created.
#define O_CREAT 0x40
/// The file offset will be set to the end of the file prior to each write.
#define O_APPEND 0x400
/// @brief Deletes the file whose name is specified in filename.
/// @param pathname A path to a file.
/// @return On success, zero is returned. On error, -1 is returned,
/// and errno is set appropriately.
int remove(const char *pathname);
+131 -131
View File
@@ -1,131 +1,131 @@
/// MentOS, The Mentoring Operating system project
/// @file initrd.h
/// @brief Headers of functions for initrd filesystem.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stat.h"
#include "dirent.h"
#include "unistd.h"
#include "stdint.h"
#include "kernel.h"
/// The maximum number of files.
#define MAX_FILES 32
/// The maximum number of file descriptors.
#define MAX_INITRD_DESCRIPTORS MAX_OPEN_FD
/// @brief Contains the number of files inside the initrd filesystem.
typedef struct initrd_t {
/// Number of files.
uint32_t nfiles;
} initrd_t;
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The name of the file.
char fileName[NAME_MAX];
/// The type of the file.
short int file_type;
/// The uid of the owner.
int uid;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} initrd_file_t;
/// @brief Descriptor linked to open files.
typedef struct initrd_fd {
/// Id of the open file inside the file system. More precisely, its index
/// inside the vector of files.
int file_descriptor;
/// The current position inside the file. Used for writing/reading
/// opeations.
int cur_pos;
} initrd_fd;
// TODO: doxygen comment.
/// @brief
extern initrd_t *fs_specs;
/// @brief File system headers.
extern initrd_file_t *fs_headers;
// TODO: doxygen comment.
/// @brief
extern unsigned int fs_end;
/// Initializes the initrd file system.
uint32_t initfs_init();
/// @brief Opens a directory at the given path.
/// @param path The path where the directory resides.
/// @return Structure used to access the directory.
DIR *initfs_opendir(const char *path);
/// @brief Closes the directory stream associated with dirp.
/// @param dirp The directory handler.
/// @return 0 on success. On error, -1 is returned, and errno is set.
int initfs_closedir(DIR *dirp);
/// @brief Moves the position of the currently readed entry inside the
/// directory.
/// @param dirp The directory handler.
/// @return A pointer to the next entry inside the directory.
dirent_t *initrd_readdir(DIR *dirp);
/// @brief Creates a new directory.
/// @param path The path to the new directory.
/// @param mode The file mode.
/// @return 0 if success.
int initrd_mkdir(const char *path, mode_t mode);
/// @brief Removes a directory.
/// @param path The path to the directory.
/// @return 0 if success.
int initrd_rmdir(const char *path);
/// @brief Open the file at the given path and returns its file descriptor.
/// @param path The path to the file.
/// @param flags The flags used to determine the behavior of the function.
/// @return The file descriptor of the opened file, otherwise returns -1.
int initfs_open(const char *path, int flags, ...);
/// @brief Deletes the file at the given path.
/// @param path The path to the file.
/// @return On success, zero is returned. On error, -1 is returned.
int initfs_remove(const char *path);
/// @brief Reads from the file identified by the file descriptor.
/// @param fildes The file descriptor of the file.
/// @param buf Buffer where the read content must be placed.
/// @param nbyte The number of bytes to read.
/// @return T The number of red bytes.
ssize_t initfs_read(int fildes, char *buf, size_t nbyte);
/// @brief Retrieves information concerning the file at the given position.
/// @param path The path where the file resides.
/// @param stat The structure where the information are stored.
/// @return 0 if success.
int initrd_stat(const char *path, stat_t *stat);
/// @brief Writes the given content inside the file.
/// @param fildes The file descriptor of the file.
/// @param buf The content to write.
/// @param nbyte The number of bytes to write.
/// @return T The number of written bytes.
ssize_t initrd_write(int fildes, const void *buf, size_t nbyte);
/// @brief Closes the given file.
/// @param fildes The file descriptor of the file.
int initrd_close(int fildes);
// TODO: doxygen comment.
size_t initrd_nfiles();
// TODO: doxygen comment.
void dump_initrd_fs();
/// MentOS, The Mentoring Operating system project
/// @file initrd.h
/// @brief Headers of functions for initrd filesystem.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stat.h"
#include "dirent.h"
#include "unistd.h"
#include "stdint.h"
#include "kernel.h"
/// The maximum number of files.
#define MAX_FILES 32
/// The maximum number of file descriptors.
#define MAX_INITRD_DESCRIPTORS MAX_OPEN_FD
/// @brief Contains the number of files inside the initrd filesystem.
typedef struct initrd_t {
/// Number of files.
uint32_t nfiles;
} initrd_t;
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The name of the file.
char fileName[NAME_MAX];
/// The type of the file.
short int file_type;
/// The uid of the owner.
int uid;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} initrd_file_t;
/// @brief Descriptor linked to open files.
typedef struct initrd_fd {
/// Id of the open file inside the file system. More precisely, its index
/// inside the vector of files.
int file_descriptor;
/// The current position inside the file. Used for writing/reading
/// opeations.
int cur_pos;
} initrd_fd;
// TODO: doxygen comment.
/// @brief
extern initrd_t *fs_specs;
/// @brief File system headers.
extern initrd_file_t *fs_headers;
// TODO: doxygen comment.
/// @brief
extern unsigned int fs_end;
/// Initializes the initrd file system.
uint32_t initfs_init();
/// @brief Opens a directory at the given path.
/// @param path The path where the directory resides.
/// @return Structure used to access the directory.
DIR *initfs_opendir(const char *path);
/// @brief Closes the directory stream associated with dirp.
/// @param dirp The directory handler.
/// @return 0 on success. On error, -1 is returned, and errno is set.
int initfs_closedir(DIR *dirp);
/// @brief Moves the position of the currently readed entry inside the
/// directory.
/// @param dirp The directory handler.
/// @return A pointer to the next entry inside the directory.
dirent_t *initrd_readdir(DIR *dirp);
/// @brief Creates a new directory.
/// @param path The path to the new directory.
/// @param mode The file mode.
/// @return 0 if success.
int initrd_mkdir(const char *path, mode_t mode);
/// @brief Removes a directory.
/// @param path The path to the directory.
/// @return 0 if success.
int initrd_rmdir(const char *path);
/// @brief Open the file at the given path and returns its file descriptor.
/// @param path The path to the file.
/// @param flags The flags used to determine the behavior of the function.
/// @return The file descriptor of the opened file, otherwise returns -1.
int initfs_open(const char *path, int flags, ...);
/// @brief Deletes the file at the given path.
/// @param path The path to the file.
/// @return On success, zero is returned. On error, -1 is returned.
int initfs_remove(const char *path);
/// @brief Reads from the file identified by the file descriptor.
/// @param fildes The file descriptor of the file.
/// @param buf Buffer where the read content must be placed.
/// @param nbyte The number of bytes to read.
/// @return T The number of red bytes.
ssize_t initfs_read(int fildes, char *buf, size_t nbyte);
/// @brief Retrieves information concerning the file at the given position.
/// @param path The path where the file resides.
/// @param stat The structure where the information are stored.
/// @return 0 if success.
int initrd_stat(const char *path, stat_t *stat);
/// @brief Writes the given content inside the file.
/// @param fildes The file descriptor of the file.
/// @param buf The content to write.
/// @param nbyte The number of bytes to write.
/// @return T The number of written bytes.
ssize_t initrd_write(int fildes, const void *buf, size_t nbyte);
/// @brief Closes the given file.
/// @param fildes The file descriptor of the file.
int initrd_close(int fildes);
// TODO: doxygen comment.
size_t initrd_nfiles();
// TODO: doxygen comment.
void dump_initrd_fs();
+52 -52
View File
@@ -1,52 +1,52 @@
/// MentOS, The Mentoring Operating system project
/// @file vfs.h
/// @brief Headers for Virtual File System (VFS).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "unistd.h"
#include "vfs_types.h"
/// The maximum number of mount points.
#define MAX_MOUNTPOINT 10
/// The currently opened file descriptor.
extern int current_fd;
/// The list of file descriptors.
extern file_descriptor_t fd_list[MAX_OPEN_FD];
/// The list of mount points.
extern mountpoint_t mountpoint_list[MAX_MOUNTPOINT];
/// @brief Initialize the Virtual File System (VFS).
void vfs_init();
/// @brief Retrieves the id of the mount point where the path resides.
/// @param path The path to the mountpoint.
/// @return The id of the mountpoint.
int32_t get_mountpoint_id(const char *path);
// TODO: doxigen comment.
mountpoint_t * get_mountpoint(const char *path);
// TODO: doxigen comment.
mountpoint_t * get_mountpoint_from_id(int32_t mp_id);
/// @brief A path is extracted from the relative path, excluding the
/// mountpoint.
/// @param mp_id Id of the mountpoint point of the file.
/// @param path Path to the file to be opened.
/// @return Path without the mountpoint part.
int get_relative_path(uint32_t mp_id, char *path);
/// @brief Given a path, it extracts its absolute path (starting from
/// the current one).
/// @param path Path to the file to be opened.
/// @return Error code.
int get_absolute_path(char *path);
/// @brief Dumps the list of file descriptors.
void vfs_dump();
/// MentOS, The Mentoring Operating system project
/// @file vfs.h
/// @brief Headers for Virtual File System (VFS).
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "unistd.h"
#include "vfs_types.h"
/// The maximum number of mount points.
#define MAX_MOUNTPOINT 10
/// The currently opened file descriptor.
extern int current_fd;
/// The list of file descriptors.
extern file_descriptor_t fd_list[MAX_OPEN_FD];
/// The list of mount points.
extern mountpoint_t mountpoint_list[MAX_MOUNTPOINT];
/// @brief Initialize the Virtual File System (VFS).
void vfs_init();
/// @brief Retrieves the id of the mount point where the path resides.
/// @param path The path to the mountpoint.
/// @return The id of the mountpoint.
int32_t get_mountpoint_id(const char *path);
// TODO: doxigen comment.
mountpoint_t * get_mountpoint(const char *path);
// TODO: doxigen comment.
mountpoint_t * get_mountpoint_from_id(int32_t mp_id);
/// @brief A path is extracted from the relative path, excluding the
/// mountpoint.
/// @param mp_id Id of the mountpoint point of the file.
/// @param path Path to the file to be opened.
/// @return Path without the mountpoint part.
int get_relative_path(uint32_t mp_id, char *path);
/// @brief Given a path, it extracts its absolute path (starting from
/// the current one).
/// @param path Path to the file to be opened.
/// @return Error code.
int get_absolute_path(char *path);
/// @brief Dumps the list of file descriptors.
void vfs_dump();
+136 -136
View File
@@ -1,136 +1,136 @@
/// MentOS, The Mentoring Operating system project
/// @file vfs_types.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stat.h"
#include "kernel.h"
#include "dirent.h"
#define PATH_SEPARATOR '/'
#define PATH_SEPARATOR_STRING "/"
#define PATH_UP ".."
#define PATH_DOT "."
/// Identifies a file.
#define FS_FILE 0x01U
/// Identifies a directory.
#define FS_DIRECTORY 0x02U
/// Identifies a character devies.
#define FS_CHARDEVICE 0x04U
/// Identifies a block devies.
#define FS_BLOCKDEVICE 0x08U
/// Identifies a pipe.
#define FS_PIPE 0x10U
/// Identifies a symbolic link.
#define FS_SYMLINK 0x20U
/// Identifies a mount-point.
#define FS_MOUNTPOINT 0x40U
/// Function used to open a directory.
typedef DIR *(*opendir_callback)(const char *);
/// Function used to close a directory.
typedef int (*closedir_callback)(DIR *);
/// Function used to create a directory.
typedef int (*mkdir_callback)(const char *, mode_t);
/// Function used to remove a directory.
typedef int (*rmdir_callback)(const char *);
/// Function used to read the next entry of a directory.
typedef dirent_t *(*readdir_callback)(DIR *);
/// Function used to open a file.
typedef int (*open_callback)(const char *, int, ...);
/// Function used to remove a file.
typedef int (*remove_callback)(const char *);
/// Function used to close a file.
typedef int (*close_callback)(int);
/// Function used to read from a file.
typedef ssize_t (*read_callback)(int, char *, size_t);
/// Function used to write inside a file.
typedef ssize_t (*write_callback)(int, const void *, size_t);
/// Function used to stat fs entries.
typedef int (*stat_callback)(const char *, stat_t *);
/// @brief Set of functions used to perform operations on directories.
typedef struct directory_operations_t {
/// Identifies a mount-point.
opendir_callback opendir_f;
/// Closes a directory.
closedir_callback closedir_f;
/// Creates a directory.
mkdir_callback mkdir_f;
/// Removes a directory.
rmdir_callback rmdir_f;
/// Read next entry inside the directory.
readdir_callback readdir_f;
} directory_operations_t;
/// @brief Set of functions used to perform operations on files.
typedef struct super_node_operations_t {
/// Open a file.
open_callback open_f;
/// Remove a file.
remove_callback remove_f;
/// Close a file.
close_callback close_f;
/// Read from a file.
read_callback read_f;
/// Write inside a file.
write_callback write_f;
} super_node_operations_t;
/// @brief Stat operations.
typedef struct stat_operations_t {
/// Stat function.
stat_callback stat_f;
} stat_operations_t;
/// @brief Data structure that contains information about the mounted filesystems.
typedef struct mountpoint_t {
/// The id of the mountpoint.
int32_t mp_id;
/// Name of the mountpoint.
char mountpoint[NAME_MAX];
/// Maschera dei permessi.
unsigned int pmask;
/// User ID.
unsigned int uid;
/// Group ID.
unsigned int gid;
/// Starting address of the FileSystem.
unsigned int start_address;
/// Ending address of the FileSystem.
unsigned int end_address;
/// Device ID.
int dev_id;
/// Operations on files.
super_node_operations_t operations;
/// Operations on directories.
directory_operations_t dir_op;
/// Stat operations.
stat_operations_t stat_op;
} mountpoint_t;
/// @brief Data structure containing information about an open file.
typedef struct file_descriptor_t {
/// The descriptor of the internal file of the FileSystem.
int fs_spec_id;
/// The id of the mountpoint where the.
int mountpoint_id;
/// Offset for file reading, for the next read.
int offset;
/// Flags for file opening modes.
int flags_mask;
} file_descriptor_t;
/// MentOS, The Mentoring Operating system project
/// @file vfs_types.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stat.h"
#include "kernel.h"
#include "dirent.h"
#define PATH_SEPARATOR '/'
#define PATH_SEPARATOR_STRING "/"
#define PATH_UP ".."
#define PATH_DOT "."
/// Identifies a file.
#define FS_FILE 0x01U
/// Identifies a directory.
#define FS_DIRECTORY 0x02U
/// Identifies a character devies.
#define FS_CHARDEVICE 0x04U
/// Identifies a block devies.
#define FS_BLOCKDEVICE 0x08U
/// Identifies a pipe.
#define FS_PIPE 0x10U
/// Identifies a symbolic link.
#define FS_SYMLINK 0x20U
/// Identifies a mount-point.
#define FS_MOUNTPOINT 0x40U
/// Function used to open a directory.
typedef DIR *(*opendir_callback)(const char *);
/// Function used to close a directory.
typedef int (*closedir_callback)(DIR *);
/// Function used to create a directory.
typedef int (*mkdir_callback)(const char *, mode_t);
/// Function used to remove a directory.
typedef int (*rmdir_callback)(const char *);
/// Function used to read the next entry of a directory.
typedef dirent_t *(*readdir_callback)(DIR *);
/// Function used to open a file.
typedef int (*open_callback)(const char *, int, ...);
/// Function used to remove a file.
typedef int (*remove_callback)(const char *);
/// Function used to close a file.
typedef int (*close_callback)(int);
/// Function used to read from a file.
typedef ssize_t (*read_callback)(int, char *, size_t);
/// Function used to write inside a file.
typedef ssize_t (*write_callback)(int, const void *, size_t);
/// Function used to stat fs entries.
typedef int (*stat_callback)(const char *, stat_t *);
/// @brief Set of functions used to perform operations on directories.
typedef struct directory_operations_t {
/// Identifies a mount-point.
opendir_callback opendir_f;
/// Closes a directory.
closedir_callback closedir_f;
/// Creates a directory.
mkdir_callback mkdir_f;
/// Removes a directory.
rmdir_callback rmdir_f;
/// Read next entry inside the directory.
readdir_callback readdir_f;
} directory_operations_t;
/// @brief Set of functions used to perform operations on files.
typedef struct super_node_operations_t {
/// Open a file.
open_callback open_f;
/// Remove a file.
remove_callback remove_f;
/// Close a file.
close_callback close_f;
/// Read from a file.
read_callback read_f;
/// Write inside a file.
write_callback write_f;
} super_node_operations_t;
/// @brief Stat operations.
typedef struct stat_operations_t {
/// Stat function.
stat_callback stat_f;
} stat_operations_t;
/// @brief Data structure that contains information about the mounted filesystems.
typedef struct mountpoint_t {
/// The id of the mountpoint.
int32_t mp_id;
/// Name of the mountpoint.
char mountpoint[NAME_MAX];
/// Maschera dei permessi.
unsigned int pmask;
/// User ID.
unsigned int uid;
/// Group ID.
unsigned int gid;
/// Starting address of the FileSystem.
unsigned int start_address;
/// Ending address of the FileSystem.
unsigned int end_address;
/// Device ID.
int dev_id;
/// Operations on files.
super_node_operations_t operations;
/// Operations on directories.
directory_operations_t dir_op;
/// Stat operations.
stat_operations_t stat_op;
} mountpoint_t;
/// @brief Data structure containing information about an open file.
typedef struct file_descriptor_t {
/// The descriptor of the internal file of the FileSystem.
int fs_spec_id;
/// The id of the mountpoint where the.
int mountpoint_id;
/// Offset for file reading, for the next read.
int offset;
/// Flags for file opening modes.
int flags_mask;
} file_descriptor_t;
+86 -86
View File
@@ -1,86 +1,86 @@
/// MentOS, The Mentoring Operating system project
/// @file cpuid.h
/// @brief CPUID definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdint.h"
#include "kernel.h"
/// Dimension of the exc flags.
#define ECX_FLAGS_SIZE 24
/// Dimension of the edx flags.
#define EDX_FLAGS_SIZE 32
/// @brief Contains the information concerning the CPU.
typedef struct cpuinfo_t {
/// The name of the vendor.
char cpu_vendor[13];
/// The type of the CPU.
char *cpu_type;
/// The family of the CPU.
uint32_t cpu_family;
/// The model of the CPU.
uint32_t cpu_model;
/// Identifier for individual cores when the CPU is interrogated by the
/// CPUID instruction.
uint32_t apic_id;
/// Ecx flags.
uint32_t cpuid_ecx_flags[ECX_FLAGS_SIZE];
/// Edx flags.
uint32_t cpuid_edx_flags[EDX_FLAGS_SIZE];
// TODO: doxygen comment.
int is_brand_string;
// TODO: doxygen comment.
char *brand_string;
} cpuinfo_t;
/// This will be populated with the information concerning the CPU.
cpuinfo_t sinfo;
/// @brief Main CPUID procedure.
/// @param cpuinfo Structure to fill with CPUID information.
void get_cpuid(cpuinfo_t *cpuinfo);
/// @brief Actual CPUID call.
/// @param registers The registers to fill with the result of the call.
void call_cpuid(register_t *registers);
/// @brief Extract vendor string.
/// @param cpuinfo The struct containing the CPUID infos.
/// @param registers The registers.
void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers);
// TODO: doxygen documentation.
/// @brief CPUID is called with EAX=1
/// EAX contains Type, Family, Model and Stepping ID
/// EBX contains the Brand Index if supported, and the APIC ID
/// ECX/EDX contains feature information
/// @param cpuinfo
/// @param registers
void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers);
/// @brief EAX=1, ECX contains a list of supported features.
void cpuid_feature_ecx(cpuinfo_t *, uint32_t);
/// @brief EAX=1, EDX contains a list of supported features.
void cpuid_feature_edx(cpuinfo_t *, uint32_t);
// TODO: doxygen documentation.
/// @brief Extract single byte from a register.
/// @param reg
/// @param position
/// @param value
/// @return
uint32_t cpuid_get_byte(const uint32_t reg, const uint32_t position,
const uint32_t value);
/// @brief Index of brand strings.
char *cpuid_brand_index(register_t *);
/// @brief Brand string is contained in EAX, EBX, ECX and EDX.
char *cpuid_brand_string(register_t *);
/// MentOS, The Mentoring Operating system project
/// @file cpuid.h
/// @brief CPUID definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdint.h"
#include "kernel.h"
/// Dimension of the exc flags.
#define ECX_FLAGS_SIZE 24
/// Dimension of the edx flags.
#define EDX_FLAGS_SIZE 32
/// @brief Contains the information concerning the CPU.
typedef struct cpuinfo_t {
/// The name of the vendor.
char cpu_vendor[13];
/// The type of the CPU.
char *cpu_type;
/// The family of the CPU.
uint32_t cpu_family;
/// The model of the CPU.
uint32_t cpu_model;
/// Identifier for individual cores when the CPU is interrogated by the
/// CPUID instruction.
uint32_t apic_id;
/// Ecx flags.
uint32_t cpuid_ecx_flags[ECX_FLAGS_SIZE];
/// Edx flags.
uint32_t cpuid_edx_flags[EDX_FLAGS_SIZE];
// TODO: doxygen comment.
int is_brand_string;
// TODO: doxygen comment.
char *brand_string;
} cpuinfo_t;
/// This will be populated with the information concerning the CPU.
cpuinfo_t sinfo;
/// @brief Main CPUID procedure.
/// @param cpuinfo Structure to fill with CPUID information.
void get_cpuid(cpuinfo_t *cpuinfo);
/// @brief Actual CPUID call.
/// @param registers The registers to fill with the result of the call.
void call_cpuid(register_t *registers);
/// @brief Extract vendor string.
/// @param cpuinfo The struct containing the CPUID infos.
/// @param registers The registers.
void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers);
// TODO: doxygen documentation.
/// @brief CPUID is called with EAX=1
/// EAX contains Type, Family, Model and Stepping ID
/// EBX contains the Brand Index if supported, and the APIC ID
/// ECX/EDX contains feature information
/// @param cpuinfo
/// @param registers
void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers);
/// @brief EAX=1, ECX contains a list of supported features.
void cpuid_feature_ecx(cpuinfo_t *, uint32_t);
/// @brief EAX=1, EDX contains a list of supported features.
void cpuid_feature_edx(cpuinfo_t *, uint32_t);
// TODO: doxygen documentation.
/// @brief Extract single byte from a register.
/// @param reg
/// @param position
/// @param value
/// @return
uint32_t cpuid_get_byte(const uint32_t reg, const uint32_t position,
const uint32_t value);
/// @brief Index of brand strings.
char *cpuid_brand_index(register_t *);
/// @brief Brand string is contained in EAX, EBX, ECX and EDX.
char *cpuid_brand_string(register_t *);
+110 -110
View File
@@ -1,110 +1,110 @@
/// MentOS, The Mentoring Operating system project
/// @file pic8259.h
/// @brief Pic8259 definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "idt.h"
#include "kheap.h"
#include "debug.h"
#include "stddef.h"
#include "kernel.h"
#include "bitops.h"
#include "port_io.h"
#include "irqflags.h"
#include "scheduler.h"
/// The total number of IRQs.
#define IRQ_NUM 16
/// @defgroup irqs Interrupt Requests (IRQs).
/// @brief This is the list of interrupt requests.
/// @{
/// @brief System timer.
#define IRQ_TIMER 0
/// @brief Keyboard controller.
#define IRQ_KEYBOARD 1
/// @brief cascaded signals from IRQs 815 (any devices configured to use IRQ
/// 2 will actually be using IRQ 9)
#define IRQ_TO_SLAVE_PIC 2
/// @brief Serial port controller for serial port 2 (and 4).
#define IRQ_COM2_4 3
/// @brief Serial port controller for serial port 1 (and 3).
#define IRQ_COM1_3 4
/// @brief Parallel port 2 and 3 (or sound card).
#define IRQ_LPT2 5
/// @brief Floppy disk controller.
#define IRQ_FLOPPY 6
/// @brief Parallel port 1.
#define IRQ_LPT1 7
/// @brief Real-time clock (RTC).
#define IRQ_REAL_TIME_CLOCK 8
/// @brief Advanced Configuration and Power Interface (ACPI)
/// system control interrupt on Intel chipsets.[1] Other chipset
/// manufacturers might use another interrupt for this purpose, or
/// make it available for the use of peripherals (any devices configured
/// to use IRQ 2 will actually be using IRQ 9)
#define IRQ_AVAILABLE_1 9
/// @brief The Interrupt is left open for the use of
/// peripherals (open interrupt/available, SCSI or NIC).
#define IRQ_AVAILABLE_2 10
/// @brief The Interrupt is left open for the use of
/// peripherals (open interrupt/available, SCSI or NIC).
#define IRQ_AVAILABLE_3 11
/// @brief Mouse on PS/2 connector.
#define IRQ_MOUSE 12
/// @brief CPU co-processor or integrated floating point unit
/// or inter-processor interrupt (use depends on OS).
#define IRQ_MATH_CPU 13
/// @brief Primary ATA channel (ATA interface usually serves
/// hard disk drives and CD drives).
#define IRQ_FIRST_HD 14
/// @brief Secondary ATA channel.
#define IRQ_SECOND_HD 15
/// @}
/// @brief Function that initializes the processor pic 8259 that will manage the
/// interruptions.
void pic8259_init_irq();
/// @brief This function, enable irqs on the pic.
/// @details This function provide a tool for enabling irq from the pic
/// processor.
/// @param irq Number of irq to enable.
/// @return 0 If all OK, -1 on errors.
int pic8259_irq_enable(uint32_t irq);
/// @brief This function, disable irqs on the pic.
/// @details This function provide a tool for enabling irq from the pic
/// processor.
/// @param irq Number of irq to enable.
/// @return 0 If all OK, -1 on errors.
int pic8259_irq_disable(uint32_t irq);
/// @brief This is issued to the PIC chips at the end of an IRQ-based
/// interrupt routine.
/// @param irq The interrupt number.
void pic8259_send_eoi(uint32_t irq);
/// @brief This Function return the number of current IRQ Request.
/// @return Number of IRQ + 1 currently serving. If 0 there are no IRQ.
//int pic8259_irq_get_current();
/// MentOS, The Mentoring Operating system project
/// @file pic8259.h
/// @brief Pic8259 definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "idt.h"
#include "kheap.h"
#include "debug.h"
#include "stddef.h"
#include "kernel.h"
#include "bitops.h"
#include "port_io.h"
#include "irqflags.h"
#include "scheduler.h"
/// The total number of IRQs.
#define IRQ_NUM 16
/// @defgroup irqs Interrupt Requests (IRQs).
/// @brief This is the list of interrupt requests.
/// @{
/// @brief System timer.
#define IRQ_TIMER 0
/// @brief Keyboard controller.
#define IRQ_KEYBOARD 1
/// @brief cascaded signals from IRQs 815 (any devices configured to use IRQ
/// 2 will actually be using IRQ 9)
#define IRQ_TO_SLAVE_PIC 2
/// @brief Serial port controller for serial port 2 (and 4).
#define IRQ_COM2_4 3
/// @brief Serial port controller for serial port 1 (and 3).
#define IRQ_COM1_3 4
/// @brief Parallel port 2 and 3 (or sound card).
#define IRQ_LPT2 5
/// @brief Floppy disk controller.
#define IRQ_FLOPPY 6
/// @brief Parallel port 1.
#define IRQ_LPT1 7
/// @brief Real-time clock (RTC).
#define IRQ_REAL_TIME_CLOCK 8
/// @brief Advanced Configuration and Power Interface (ACPI)
/// system control interrupt on Intel chipsets.[1] Other chipset
/// manufacturers might use another interrupt for this purpose, or
/// make it available for the use of peripherals (any devices configured
/// to use IRQ 2 will actually be using IRQ 9)
#define IRQ_AVAILABLE_1 9
/// @brief The Interrupt is left open for the use of
/// peripherals (open interrupt/available, SCSI or NIC).
#define IRQ_AVAILABLE_2 10
/// @brief The Interrupt is left open for the use of
/// peripherals (open interrupt/available, SCSI or NIC).
#define IRQ_AVAILABLE_3 11
/// @brief Mouse on PS/2 connector.
#define IRQ_MOUSE 12
/// @brief CPU co-processor or integrated floating point unit
/// or inter-processor interrupt (use depends on OS).
#define IRQ_MATH_CPU 13
/// @brief Primary ATA channel (ATA interface usually serves
/// hard disk drives and CD drives).
#define IRQ_FIRST_HD 14
/// @brief Secondary ATA channel.
#define IRQ_SECOND_HD 15
/// @}
/// @brief Function that initializes the processor pic 8259 that will manage the
/// interruptions.
void pic8259_init_irq();
/// @brief This function, enable irqs on the pic.
/// @details This function provide a tool for enabling irq from the pic
/// processor.
/// @param irq Number of irq to enable.
/// @return 0 If all OK, -1 on errors.
int pic8259_irq_enable(uint32_t irq);
/// @brief This function, disable irqs on the pic.
/// @details This function provide a tool for enabling irq from the pic
/// processor.
/// @param irq Number of irq to enable.
/// @return 0 If all OK, -1 on errors.
int pic8259_irq_disable(uint32_t irq);
/// @brief This is issued to the PIC chips at the end of an IRQ-based
/// interrupt routine.
/// @param irq The interrupt number.
void pic8259_send_eoi(uint32_t irq);
/// @brief This Function return the number of current IRQ Request.
/// @return Number of IRQ + 1 currently serving. If 0 there are no IRQ.
//int pic8259_irq_get_current();
+85 -85
View File
@@ -1,85 +1,85 @@
/// MentOS, The Mentoring Operating system project
/// @file timer.h
/// @brief Programmable Interval Timer (PIT) definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "stdint.h"
/// @defgroup picregs Programmable Interval Timer Registers
/// @brief The list of registers used to set the PIT.
/// @{
/// Channel 0 data port (read/write).
#define PIT_DATAREG0 0x40
/// Channel 1 data port (read/write).
#define PIT_DATAREG1 0x41
/// Channel 2 data port (read/write).
#define PIT_DATAREG2 0x42
/// Mode/Command register (write only, a read is ignored).
#define PIT_COMREG 0x43
/// @}
/// @brief Frequency divider value (1.193182 MHz).
#define PIT_DIVISOR 1193180
/// @brief Command used to configure the PIT.
/// @details
/// 0x36 = 00110110B.
/// Channel | 00 | Select Channel 0.
/// Access mode | 11 | lobyte/hibyte.
/// Operating mode | 011 | Mode 3 (square wave generator).
/// BCD/Binary mode | 0 | 16-bit binary.
#define PIT_CONFIGURATION 0x36
#define PIT_MASK 0xFF
/// @brief Pointer to a functionality to wake up.
typedef void (*wakeup_callback_t)();
/// @brief Holds the information about a wake-up functionality.
typedef struct wakeup_info {
/// Pointer to the functionality.
wakeup_callback_t func;
/// The tick, in the future, when the functionality must be triggered.
__volatile__ uint32_t wakeup_at_jiffy;
/// The period in seconds.
uint32_t period;
} wakeup_info_t;
/// @brief Handles the timer.
/// @details In this case, it's very simple: We
/// increment the 'timer_ticks' variable every time the
/// timer fires. By default, the timer fires 18.222 times
/// per second. Why 18.222Hz? Some engineer at IBM must've
/// been smoking something funky
void timer_handler(pt_regs *reg);
/// @brief Sets up the system clock by installing the timer handler into IRQ0.
void timer_install();
/// @brief Returns the number of ticks since the system is running.
uint64_t timer_get_ticks();
/// @brief Returns the number of ticks since the system is running.
uint64_t timer_get_subticks();
/// @brief Registers a function which will be waken up at each tick.
/// @param func The functionality which must be triggered.
/// @param period The period in second.
void timer_register_wakeup_call(wakeup_callback_t func, uint32_t period);
/// @brief Makes the process sleep for the given ammount of time.
/// @param seconds The ammount of seconds.
void sleep(unsigned int seconds);
/// @brief Allows to set the timer phase to the given frequency.
/// @param hz The frequency to set.
void timer_phase(const uint32_t hz);
/// MentOS, The Mentoring Operating system project
/// @file timer.h
/// @brief Programmable Interval Timer (PIT) definitions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "stdint.h"
/// @defgroup picregs Programmable Interval Timer Registers
/// @brief The list of registers used to set the PIT.
/// @{
/// Channel 0 data port (read/write).
#define PIT_DATAREG0 0x40
/// Channel 1 data port (read/write).
#define PIT_DATAREG1 0x41
/// Channel 2 data port (read/write).
#define PIT_DATAREG2 0x42
/// Mode/Command register (write only, a read is ignored).
#define PIT_COMREG 0x43
/// @}
/// @brief Frequency divider value (1.193182 MHz).
#define PIT_DIVISOR 1193180
/// @brief Command used to configure the PIT.
/// @details
/// 0x36 = 00110110B.
/// Channel | 00 | Select Channel 0.
/// Access mode | 11 | lobyte/hibyte.
/// Operating mode | 011 | Mode 3 (square wave generator).
/// BCD/Binary mode | 0 | 16-bit binary.
#define PIT_CONFIGURATION 0x36
#define PIT_MASK 0xFF
/// @brief Pointer to a functionality to wake up.
typedef void (*wakeup_callback_t)();
/// @brief Holds the information about a wake-up functionality.
typedef struct wakeup_info {
/// Pointer to the functionality.
wakeup_callback_t func;
/// The tick, in the future, when the functionality must be triggered.
__volatile__ uint32_t wakeup_at_jiffy;
/// The period in seconds.
uint32_t period;
} wakeup_info_t;
/// @brief Handles the timer.
/// @details In this case, it's very simple: We
/// increment the 'timer_ticks' variable every time the
/// timer fires. By default, the timer fires 18.222 times
/// per second. Why 18.222Hz? Some engineer at IBM must've
/// been smoking something funky
void timer_handler(pt_regs *reg);
/// @brief Sets up the system clock by installing the timer handler into IRQ0.
void timer_install();
/// @brief Returns the number of ticks since the system is running.
uint64_t timer_get_ticks();
/// @brief Returns the number of ticks since the system is running.
uint64_t timer_get_subticks();
/// @brief Registers a function which will be waken up at each tick.
/// @param func The functionality which must be triggered.
/// @param period The period in second.
void timer_register_wakeup_call(wakeup_callback_t func, uint32_t period);
/// @brief Makes the process sleep for the given ammount of time.
/// @param seconds The ammount of seconds.
void sleep(unsigned int seconds);
/// @brief Allows to set the timer phase to the given frequency.
/// @param hz The frequency to set.
void timer_phase(const uint32_t hz);
+27 -27
View File
@@ -1,27 +1,27 @@
/// MentOS, The Mentoring Operating system project
/// @file mm_io.h
/// @brief Memory Mapped IO functions.
/// @copyright (c) 2019 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.
uint8_t in_memb(uint32_t addr);
/// @brief Reads a 16-bit value from the given address.
uint16_t in_mems(uint32_t addr);
/// @brief Reads a 32-bit value from the given address.
uint32_t in_meml(uint32_t addr);
/// @brief Writes a 8-bit value at the given address.
void out_memb(uint32_t addr, uint8_t value);
/// @brief Writes a 16-bit value at the given address.
void out_mems(uint32_t addr, uint16_t value);
/// @brief Writes a 32-bit value at the given address.
void out_meml(uint32_t addr, uint32_t value);
/// MentOS, The Mentoring Operating system project
/// @file mm_io.h
/// @brief Memory Mapped IO functions.
/// @copyright (c) 2019 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.
uint8_t in_memb(uint32_t addr);
/// @brief Reads a 16-bit value from the given address.
uint16_t in_mems(uint32_t addr);
/// @brief Reads a 32-bit value from the given address.
uint32_t in_meml(uint32_t addr);
/// @brief Writes a 8-bit value at the given address.
void out_memb(uint32_t addr, uint8_t value);
/// @brief Writes a 16-bit value at the given address.
void out_mems(uint32_t addr, uint16_t value);
/// @brief Writes a 32-bit value at the given address.
void out_meml(uint32_t addr, uint32_t value);
+43 -43
View File
@@ -1,43 +1,43 @@
/// MentOS, The Mentoring Operating system project
/// @file port_io.h
/// @brief Byte I/O on ports prototypes.
/// @copyright (c) 2019 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);
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);
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);
/// MentOS, The Mentoring Operating system project
/// @file port_io.h
/// @brief Byte I/O on ports prototypes.
/// @copyright (c) 2019 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);
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);
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);
+132 -132
View File
@@ -1,132 +1,132 @@
/// MentOS, The Mentoring Operating system project
/// @file video.h
/// @brief Video functions and costants.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief A set of colors.
typedef enum video_color_t {
///0 : Black
BLACK,
/// 1 : Blue
BLUE,
/// 2 : Green
GREEN,
/// 3 : Cyan
CYAN,
/// 4 : Red
RED,
/// 5 : Magenta
MAGENTA,
/// 6 : Brown
BROWN,
/// 7 : Grey
GREY,
/// 8 : Dark Grey
DARK_GREY,
/// 9 : Bright Blue
BRIGHT_BLUE,
/// 10 : Bright Green
BRIGHT_GREEN,
/// 11 : Bright Cyan
BRIGHT_CYAN,
/// 12 : Bright Red
BRIGHT_RED,
/// 13 : Bright Magenta
BRIGHT_MAGENTA,
/// 14 : Yellow
YELLOW,
/// 15 : White
WHITE,
} video_color_t;
/// @brief Initialize the video.
void video_init();
/// @brief Print the given character on the screen.
void video_putc(int);
/// @brief Prints the given string on the screen.
void video_puts(const char *str);
/// @brief Change foreground colour.
void video_set_color(const video_color_t foreground);
/// @brief Change background colour.
void video_set_background(const video_color_t background);
/// @brief Deletes the last inserted character.
void video_delete_last_character();
/// @brief Move the cursor to the given position.
void video_set_cursor(const unsigned int x, const unsigned int y);
/// @brief When something is written in another position, update the cursor.
void video_set_cursor_auto();
/// @brief Move the cursor at the position x, y on the screen.
void video_move_cursor(int, int);
/// @brief Prints a tab on the screen.
void video_put_tab();
/// @brief Clears the screen.
void video_clear();
/// @brief Move to the following line (the effect of \n character).
void video_new_line();
/// @brief Move to the up line (the effect of \n character).
void video_cartridge_return();
/// @brief Get the current column number.
uint32_t video_get_column();
/// @brief Get the current row number.
uint32_t video_get_line();
/// @brief The whole screen is shifted up by one line. Used when the cursor
/// reaches the last position of the screen.
void video_shift_one_line();
/// @brief The scrolling buffer is updated to contain the screen up the
/// current one. The oldest line is lost to make space for the new one.
void video_rotate_scroll_buffer();
/// @brief Called by the pression of the PAGEUP key.
/// The screen aboce the current one is printed and the current one is
/// saved in downbuffer, ready to be restored in future.
void video_scroll_up();
/// @brief Called by the pression of the PAGEDOWN key.
/// The content of downbuffer (that is, the screen present when you
/// pressed PAGEUP) is printed again.
void video_scroll_down();
/// Determines the lower-bound on the x axis for the video.
uint32_t lower_bound_x;
/// Determines the lower-bound on the y axis for the video.
uint32_t lower_bound_y;
/// Determines the current position of the shell cursor on the x axis.
uint32_t shell_current_x;
/// Determines the current position of the shell cursor on the y axis.
uint32_t shell_current_y;
/// Determines the lower-bound on the x axis for the shell.
uint32_t shell_lower_bound_x;
/// Determines the lower-bound on the y axis for the shell.
uint32_t shell_lower_bound_y;
/// @brief Prints [OK] at the current row and column 60.
void video_print_ok();
/// @brief Prints [FAIL] at the current row and column 60.
void video_print_fail();
/// MentOS, The Mentoring Operating system project
/// @file video.h
/// @brief Video functions and costants.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief A set of colors.
typedef enum video_color_t {
///0 : Black
BLACK,
/// 1 : Blue
BLUE,
/// 2 : Green
GREEN,
/// 3 : Cyan
CYAN,
/// 4 : Red
RED,
/// 5 : Magenta
MAGENTA,
/// 6 : Brown
BROWN,
/// 7 : Grey
GREY,
/// 8 : Dark Grey
DARK_GREY,
/// 9 : Bright Blue
BRIGHT_BLUE,
/// 10 : Bright Green
BRIGHT_GREEN,
/// 11 : Bright Cyan
BRIGHT_CYAN,
/// 12 : Bright Red
BRIGHT_RED,
/// 13 : Bright Magenta
BRIGHT_MAGENTA,
/// 14 : Yellow
YELLOW,
/// 15 : White
WHITE,
} video_color_t;
/// @brief Initialize the video.
void video_init();
/// @brief Print the given character on the screen.
void video_putc(int);
/// @brief Prints the given string on the screen.
void video_puts(const char *str);
/// @brief Change foreground colour.
void video_set_color(const video_color_t foreground);
/// @brief Change background colour.
void video_set_background(const video_color_t background);
/// @brief Deletes the last inserted character.
void video_delete_last_character();
/// @brief Move the cursor to the given position.
void video_set_cursor(const unsigned int x, const unsigned int y);
/// @brief When something is written in another position, update the cursor.
void video_set_cursor_auto();
/// @brief Move the cursor at the position x, y on the screen.
void video_move_cursor(int, int);
/// @brief Prints a tab on the screen.
void video_put_tab();
/// @brief Clears the screen.
void video_clear();
/// @brief Move to the following line (the effect of \n character).
void video_new_line();
/// @brief Move to the up line (the effect of \n character).
void video_cartridge_return();
/// @brief Get the current column number.
uint32_t video_get_column();
/// @brief Get the current row number.
uint32_t video_get_line();
/// @brief The whole screen is shifted up by one line. Used when the cursor
/// reaches the last position of the screen.
void video_shift_one_line();
/// @brief The scrolling buffer is updated to contain the screen up the
/// current one. The oldest line is lost to make space for the new one.
void video_rotate_scroll_buffer();
/// @brief Called by the pression of the PAGEUP key.
/// The screen aboce the current one is printed and the current one is
/// saved in downbuffer, ready to be restored in future.
void video_scroll_up();
/// @brief Called by the pression of the PAGEDOWN key.
/// The content of downbuffer (that is, the screen present when you
/// pressed PAGEUP) is printed again.
void video_scroll_down();
/// Determines the lower-bound on the x axis for the video.
uint32_t lower_bound_x;
/// Determines the lower-bound on the y axis for the video.
uint32_t lower_bound_y;
/// Determines the current position of the shell cursor on the x axis.
uint32_t shell_current_x;
/// Determines the current position of the shell cursor on the y axis.
uint32_t shell_current_y;
/// Determines the lower-bound on the x axis for the shell.
uint32_t shell_lower_bound_x;
/// Determines the lower-bound on the y axis for the shell.
uint32_t shell_lower_bound_y;
/// @brief Prints [OK] at the current row and column 60.
void video_print_ok();
/// @brief Prints [FAIL] at the current row and column 60.
void video_print_fail();
+278 -278
View File
@@ -1,278 +1,278 @@
/// MentOS, The Mentoring Operating system project
/// @file kernel.h
/// @brief Kernel generic data structure and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "elf.h"
#include "stddef.h"
#include "stdint.h"
#include "stdbool.h"
#include "multiboot.h"
/// The maximum number of modules.
#define MAX_MODULES 10
/// Our kernel now loads at 0xC0000000, so what low memory address such as
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
#define LOAD_MEMORY_ADDRESS 0x00000000
// TODO: doxygen comment.
extern uintptr_t initial_esp;
/// @brief Halt.
inline static void halt()
{
__asm__ __volatile__("hlt" ::: "memory");
}
/// @brief Pause.
inline static void pause()
{
__asm__ __volatile__("pause" ::: "memory");
}
#define K 1024
#define M (1024 * K)
#define G (1024 * M)
/// Pointer the beging of the module.
extern char *module_start[MAX_MODULES];
/// Address to the end of the module.
extern char *module_end[MAX_MODULES];
/// Elf symbols of the kernel.
extern elf_symbols_t kernel_elf;
/// @brief Entry point of the kernel.
/// @param boot_informations Information concerning the boot.
/// @return The exit status of the kernel.
int kmain(uint32_t magic, multiboot_info_t *header, uintptr_t esp);
/// @brief Register structs for interrupt/exception.
typedef struct register_t {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} register_t;
/*
* /// @brief Register structs for bios service.
* typedef struct register16_t
* {
* /// Destination Index.
* uint16_t di;
* /// Source Index.
* uint16_t si;
* /// Base Pointer.
* uint16_t bp;
* /// Stack Pointer.
* uint16_t sp;
* /// Also known as the base register.
* uint16_t bx;
* /// Also known as the data register.
* uint16_t dx;
* /// Also known as the count register.
* uint16_t cx;
* /// Is the primary accumulator.
* uint16_t ax;
* /// Data Segment.
* uint16_t ds;
* /// Extra Segment determined by the programmer.
* uint16_t es;
* /// FS and GS have no hardware-assigned uses.
* uint16_t fs;
* /// FS and GS have no hardware-assigned uses.
* uint16_t gs;
* /// Stack Segment.
* uint16_t ss;
* /// 32-bit flag register.
* uint16_t eflags;
* } register16_t;
*/
//==== Interrupt stack frame ===================================================
// Interrupt stack frame. When the CPU moves from Ring3 to Ring0 because of
// an interrupt, the following registes/values are moved into the kernel's stack
// TODO: doxygen comment.
typedef struct pt_regs {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} pt_regs;
//==============================================================================
//==== Floating Point Unit (FPU) Register ======================================
// Data structure used to save FPU registers.
/// @brief Environment information of floating point unit.
typedef struct {
/// Control word (16bits).
long en_cw;
/// Status word (16bits).
long en_sw;
/// Tag word (16bits).
long en_tw;
/// Floating point instruction pointer.
long en_fip;
/// Floating code segment selector.
unsigned short en_fcs;
/// Opcode last executed (11 bits).
unsigned short en_opcode;
/// Floating operand offset.
long en_foo;
/// Floating operand segment selector.
long en_fos;
} env87;
/// @brief Contents of each floating point accumulator.
typedef struct {
unsigned char fp_bytes[10];
} fpacc87;
/// @brief Floating point context.
typedef struct {
/// Floating point control/status.
env87 sv_env;
/// Accumulator contents, 0-7.
fpacc87 sv_ac[8];
/// Padding for (now unused) saved status word.
unsigned char sv_pad0[4];
/*
* Bogus padding for emulators. Emulators should use their own
* struct and arrange to store into this struct (ending here)
* before it is inspected for ptracing or for core dumps. Some
* emulators overwrite the whole struct. We have no good way of
* knowing how much padding to leave. Leave just enough for the
* GPL emulator's i387_union (176 bytes total).
*/
unsigned char sv_pad[64]; // Padding; used by emulators
} save87;
// TODO: doxygen comment.
typedef struct {
/// Control word (16bits).
uint16_t en_cw;
/// Status word (16bits).
uint16_t en_sw;
/// Tag word (16bits).
uint16_t en_tw;
/// Opcode last executed (11 bits).
uint16_t en_opcode;
/// Floating point instruction pointer.
uint32_t en_fip;
/// Floating code segment selector.
uint16_t en_fcs;
/// Padding.
uint16_t en_pad0;
/// Floating operand offset.
uint32_t en_foo;
/// Floating operand segment selector.
uint16_t en_fos;
/// Padding.
uint16_t en_pad1;
/// SSE sontorol/status register.
uint32_t en_mxcsr;
/// Valid bits in mxcsr.
uint32_t en_mxcsr_mask;
} envxmm;
/// @brief Contents of each SSE extended accumulator.
typedef struct {
unsigned char xmm_bytes[16];
} xmmacc;
// TODO: doxygen comment.
typedef struct {
envxmm sv_env;
struct {
fpacc87 fp_acc;
/// Padding.
unsigned char fp_pad[6];
} sv_fp[8];
xmmacc sv_xmm[8];
/// Padding.
unsigned char sv_pad[224];
} __attribute__((__aligned__(16))) savexmm;
// TODO: doxygen comment.
typedef union {
save87 sv_87;
savexmm sv_xmm;
} savefpu;
//==============================================================================
/// MentOS, The Mentoring Operating system project
/// @file kernel.h
/// @brief Kernel generic data structure and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "elf.h"
#include "stddef.h"
#include "stdint.h"
#include "stdbool.h"
#include "multiboot.h"
/// The maximum number of modules.
#define MAX_MODULES 10
/// Our kernel now loads at 0xC0000000, so what low memory address such as
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
#define LOAD_MEMORY_ADDRESS 0x00000000
// TODO: doxygen comment.
extern uintptr_t initial_esp;
/// @brief Halt.
inline static void halt()
{
__asm__ __volatile__("hlt" ::: "memory");
}
/// @brief Pause.
inline static void pause()
{
__asm__ __volatile__("pause" ::: "memory");
}
#define K 1024
#define M (1024 * K)
#define G (1024 * M)
/// Pointer the beging of the module.
extern char *module_start[MAX_MODULES];
/// Address to the end of the module.
extern char *module_end[MAX_MODULES];
/// Elf symbols of the kernel.
extern elf_symbols_t kernel_elf;
/// @brief Entry point of the kernel.
/// @param boot_informations Information concerning the boot.
/// @return The exit status of the kernel.
int kmain(uint32_t magic, multiboot_info_t *header, uintptr_t esp);
/// @brief Register structs for interrupt/exception.
typedef struct register_t {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} register_t;
/*
* /// @brief Register structs for bios service.
* typedef struct register16_t
* {
* /// Destination Index.
* uint16_t di;
* /// Source Index.
* uint16_t si;
* /// Base Pointer.
* uint16_t bp;
* /// Stack Pointer.
* uint16_t sp;
* /// Also known as the base register.
* uint16_t bx;
* /// Also known as the data register.
* uint16_t dx;
* /// Also known as the count register.
* uint16_t cx;
* /// Is the primary accumulator.
* uint16_t ax;
* /// Data Segment.
* uint16_t ds;
* /// Extra Segment determined by the programmer.
* uint16_t es;
* /// FS and GS have no hardware-assigned uses.
* uint16_t fs;
* /// FS and GS have no hardware-assigned uses.
* uint16_t gs;
* /// Stack Segment.
* uint16_t ss;
* /// 32-bit flag register.
* uint16_t eflags;
* } register16_t;
*/
//==== Interrupt stack frame ===================================================
// Interrupt stack frame. When the CPU moves from Ring3 to Ring0 because of
// an interrupt, the following registes/values are moved into the kernel's stack
// TODO: doxygen comment.
typedef struct pt_regs {
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t esp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Interrupt number.
uint32_t int_no;
/// Error code.
uint32_t err_code;
/// Instruction Pointer Register.
uint32_t eip;
/// Code Segment.
uint32_t cs;
/// 32-bit flag register.
uint32_t eflags;
// TODO: Check meaning!
uint32_t useresp;
/// Stack Segment.
uint32_t ss;
} pt_regs;
//==============================================================================
//==== Floating Point Unit (FPU) Register ======================================
// Data structure used to save FPU registers.
/// @brief Environment information of floating point unit.
typedef struct {
/// Control word (16bits).
long en_cw;
/// Status word (16bits).
long en_sw;
/// Tag word (16bits).
long en_tw;
/// Floating point instruction pointer.
long en_fip;
/// Floating code segment selector.
unsigned short en_fcs;
/// Opcode last executed (11 bits).
unsigned short en_opcode;
/// Floating operand offset.
long en_foo;
/// Floating operand segment selector.
long en_fos;
} env87;
/// @brief Contents of each floating point accumulator.
typedef struct {
unsigned char fp_bytes[10];
} fpacc87;
/// @brief Floating point context.
typedef struct {
/// Floating point control/status.
env87 sv_env;
/// Accumulator contents, 0-7.
fpacc87 sv_ac[8];
/// Padding for (now unused) saved status word.
unsigned char sv_pad0[4];
/*
* Bogus padding for emulators. Emulators should use their own
* struct and arrange to store into this struct (ending here)
* before it is inspected for ptracing or for core dumps. Some
* emulators overwrite the whole struct. We have no good way of
* knowing how much padding to leave. Leave just enough for the
* GPL emulator's i387_union (176 bytes total).
*/
unsigned char sv_pad[64]; // Padding; used by emulators
} save87;
// TODO: doxygen comment.
typedef struct {
/// Control word (16bits).
uint16_t en_cw;
/// Status word (16bits).
uint16_t en_sw;
/// Tag word (16bits).
uint16_t en_tw;
/// Opcode last executed (11 bits).
uint16_t en_opcode;
/// Floating point instruction pointer.
uint32_t en_fip;
/// Floating code segment selector.
uint16_t en_fcs;
/// Padding.
uint16_t en_pad0;
/// Floating operand offset.
uint32_t en_foo;
/// Floating operand segment selector.
uint16_t en_fos;
/// Padding.
uint16_t en_pad1;
/// SSE sontorol/status register.
uint32_t en_mxcsr;
/// Valid bits in mxcsr.
uint32_t en_mxcsr_mask;
} envxmm;
/// @brief Contents of each SSE extended accumulator.
typedef struct {
unsigned char xmm_bytes[16];
} xmmacc;
// TODO: doxygen comment.
typedef struct {
envxmm sv_env;
struct {
fpacc87 fp_acc;
/// Padding.
unsigned char fp_pad[6];
} sv_fp[8];
xmmacc sv_xmm[8];
/// Padding.
unsigned char sv_pad[224];
} __attribute__((__aligned__(16))) savexmm;
// TODO: doxygen comment.
typedef union {
save87 sv_87;
savexmm sv_xmm;
} savefpu;
//==============================================================================
+24 -24
View File
@@ -1,24 +1,24 @@
/// MentOS, The Mentoring Operating system project
/// @file assert.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdio.h"
#include "panic.h"
#include "stdarg.h"
/// @brief Function used to log the information of a failed assertion.
/// @param assertion The failed assertion.
/// @param file The file where the assertion is located.
/// @param line The line inside the file.
/// @param function The function where the assertion is.
void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *function);
/// @brief Assert function.
#define assert(expression) \
((expression) ? (void)0 : \
__assert_fail(#expression, __FILE__, __LINE__, __func__))
/// MentOS, The Mentoring Operating system project
/// @file assert.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdio.h"
#include "panic.h"
#include "stdarg.h"
/// @brief Function used to log the information of a failed assertion.
/// @param assertion The failed assertion.
/// @param file The file where the assertion is located.
/// @param line The line inside the file.
/// @param function The function where the assertion is.
void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *function);
/// @brief Assert function.
#define assert(expression) \
((expression) ? (void)0 : \
__assert_fail(#expression, __FILE__, __LINE__, __func__))
+42 -42
View File
@@ -1,42 +1,42 @@
/// MentOS, The Mentoring Operating system project
/// @file bitset.h
/// @brief Bitset data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdbool.h"
/// @brief Bitset structure.
typedef struct {
/// The internal data.
unsigned char *data;
/// The size of the bitset.
size_t size;
} bitset_t;
// TODO: doxygen comment.
/// @brief
void bitset_init(bitset_t *set, size_t size);
// TODO: doxygen comment.
/// @brief
void bitset_free(bitset_t *set);
// TODO: doxygen comment.
/// @brief
void bitset_set(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
void bitset_clear(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
bool_t bitset_test(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
signed long bitset_find_first_unset_bit(bitset_t *set);
/// MentOS, The Mentoring Operating system project
/// @file bitset.h
/// @brief Bitset data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdbool.h"
/// @brief Bitset structure.
typedef struct {
/// The internal data.
unsigned char *data;
/// The size of the bitset.
size_t size;
} bitset_t;
// TODO: doxygen comment.
/// @brief
void bitset_init(bitset_t *set, size_t size);
// TODO: doxygen comment.
/// @brief
void bitset_free(bitset_t *set);
// TODO: doxygen comment.
/// @brief
void bitset_set(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
void bitset_clear(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
bool_t bitset_test(bitset_t *set, size_t bit);
// TODO: doxygen comment.
/// @brief
signed long bitset_find_first_unset_bit(bitset_t *set);
+22 -22
View File
@@ -1,22 +1,22 @@
/// MentOS, The Mentoring Operating system project
/// @file compiler.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/*
* Prevent the compiler from merging or refetching reads or writes.
*
* Ensuring that the compiler does not fold, spindle, or otherwise
* mutilate accesses that either do not require ordering or that interact
* with an explicit memory barrier or atomic instruction that provides the
* required ordering.
*/
/// @brief Assign the value to the given variable.
#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val))
/// @brief Read the value from the given variable.
#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
/// MentOS, The Mentoring Operating system project
/// @file compiler.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/*
* Prevent the compiler from merging or refetching reads or writes.
*
* Ensuring that the compiler does not fold, spindle, or otherwise
* mutilate accesses that either do not require ordering or that interact
* with an explicit memory barrier or atomic instruction that provides the
* required ordering.
*/
/// @brief Assign the value to the given variable.
#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val))
/// @brief Read the value from the given variable.
#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
+34 -34
View File
@@ -1,34 +1,34 @@
/// MentOS, The Mentoring Operating system project
/// @file ctype.h
/// @brief Functions related to character handling.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Check if the given value is a digit.
int isdigit(int c);
/// @brief Check if the given value is a letter.
int isalpha(int c);
/// @brief Check if the given value is either a letter or a digit.
int isalnum(int c);
/// @brief Check if the given value is an hexadecimal digit.
int isxdigit(int c);
/// @brief Check if the given value is a lower case letter.
int islower(int c);
/// @brief Check if the given value is an upper case letter.
int isupper(int c);
/// @brief Transforms the given value into a lower case letter.
int tolower(int c);
/// @brief Transforms the given value into an upper case letter.
int toupper(int c);
/// @brief Check if the given value is a whitespace.
int isspace(int c);
/// MentOS, The Mentoring Operating system project
/// @file ctype.h
/// @brief Functions related to character handling.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Check if the given value is a digit.
int isdigit(int c);
/// @brief Check if the given value is a letter.
int isalpha(int c);
/// @brief Check if the given value is either a letter or a digit.
int isalnum(int c);
/// @brief Check if the given value is an hexadecimal digit.
int isxdigit(int c);
/// @brief Check if the given value is a lower case letter.
int islower(int c);
/// @brief Check if the given value is an upper case letter.
int isupper(int c);
/// @brief Transforms the given value into a lower case letter.
int tolower(int c);
/// @brief Transforms the given value into an upper case letter.
int toupper(int c);
/// @brief Check if the given value is a whitespace.
int isspace(int c);
+27 -27
View File
@@ -1,27 +1,27 @@
/// MentOS, The Mentoring Operating system project
/// @file fcvt.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// TODO: doxygen comment.
/// @brief
/// @param arg
/// @param ndigits
/// @param decpt
/// @param sign
/// @param buf
/// @result
char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
// TODO: doxygen comment.
/// @brief
/// @param arg
/// @param ndigits
/// @param decpt
/// @param sign
/// @param buf
/// @result
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
/// MentOS, The Mentoring Operating system project
/// @file fcvt.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// TODO: doxygen comment.
/// @brief
/// @param arg
/// @param ndigits
/// @param decpt
/// @param sign
/// @param buf
/// @result
char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
// TODO: doxygen comment.
/// @brief
/// @param arg
/// @param ndigits
/// @param decpt
/// @param sign
/// @param buf
/// @result
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
+80 -80
View File
@@ -1,80 +1,80 @@
/// MentOS, The Mentoring Operating system project
/// @file hashmap.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "stdbool.h"
//==============================================================================
// Opaque types.
typedef struct hashmap_entry_t hashmap_entry_t;
typedef struct hashmap_t hashmap_t;
//=============================================================================
// Hashmap functions.
// TODO: doxygen comment.
typedef size_t (*hashmap_hash_t)(void *key);
// TODO: doxygen comment.
typedef bool_t (*hashmap_comp_t)(void *a, void *b);
// TODO: doxygen comment.
typedef void (*hashmap_free_t)(void *);
// TODO: doxygen comment.
typedef void *(*hashmap_dupe_t)(void *);
//==============================================================================
// Hashmap creation and destruction.
// TODO: doxygen comment.
extern hashmap_t *hashmap_create(size_t size);
// TODO: doxygen comment.
extern hashmap_t *hashmap_create_int(size_t size);
// TODO: doxygen comment.
extern void hashmap_free(hashmap_t *map);
//==============================================================================
// Hashmap management.
// TODO: doxygen comment.
extern void *hashmap_set(hashmap_t *map, void *key, void *value);
// TODO: doxygen comment.
extern void *hashmap_get(hashmap_t *map, void *key);
// TODO: doxygen comment.
extern void *hashmap_remove(hashmap_t *map, void *key);
//==============================================================================
// Hashmap search.
// TODO: doxygen comment.
extern bool_t hashmap_is_empty(hashmap_t *map);
// TODO: doxygen comment.
extern bool_t hashmap_has(hashmap_t *map, void *key);
// TODO: doxygen comment.
extern list_t *hashmap_keys(hashmap_t *map);
// TODO: doxygen comment.
extern list_t *hashmap_values(hashmap_t *map);
// TODO: doxygen comment.
extern size_t hashmap_string_hash(void *key);
// TODO: doxygen comment.
extern bool_t hashmap_string_comp(void *a, void *b);
// TODO: doxygen comment.
extern void *hashmap_string_dupe(void *key);
//==============================================================================
/// MentOS, The Mentoring Operating system project
/// @file hashmap.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "stdbool.h"
//==============================================================================
// Opaque types.
typedef struct hashmap_entry_t hashmap_entry_t;
typedef struct hashmap_t hashmap_t;
//=============================================================================
// Hashmap functions.
// TODO: doxygen comment.
typedef size_t (*hashmap_hash_t)(void *key);
// TODO: doxygen comment.
typedef bool_t (*hashmap_comp_t)(void *a, void *b);
// TODO: doxygen comment.
typedef void (*hashmap_free_t)(void *);
// TODO: doxygen comment.
typedef void *(*hashmap_dupe_t)(void *);
//==============================================================================
// Hashmap creation and destruction.
// TODO: doxygen comment.
extern hashmap_t *hashmap_create(size_t size);
// TODO: doxygen comment.
extern hashmap_t *hashmap_create_int(size_t size);
// TODO: doxygen comment.
extern void hashmap_free(hashmap_t *map);
//==============================================================================
// Hashmap management.
// TODO: doxygen comment.
extern void *hashmap_set(hashmap_t *map, void *key, void *value);
// TODO: doxygen comment.
extern void *hashmap_get(hashmap_t *map, void *key);
// TODO: doxygen comment.
extern void *hashmap_remove(hashmap_t *map, void *key);
//==============================================================================
// Hashmap search.
// TODO: doxygen comment.
extern bool_t hashmap_is_empty(hashmap_t *map);
// TODO: doxygen comment.
extern bool_t hashmap_has(hashmap_t *map, void *key);
// TODO: doxygen comment.
extern list_t *hashmap_keys(hashmap_t *map);
// TODO: doxygen comment.
extern list_t *hashmap_values(hashmap_t *map);
// TODO: doxygen comment.
extern size_t hashmap_string_hash(void *key);
// TODO: doxygen comment.
extern bool_t hashmap_string_comp(void *a, void *b);
// TODO: doxygen comment.
extern void *hashmap_string_dupe(void *key);
//==============================================================================
+72 -72
View File
@@ -1,72 +1,72 @@
/// MentOS, The Mentoring Operating system project
/// @file irqflags.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdint.h"
/// @brief Enable IRQs.
inline static void irq_enable()
{
__asm__ __volatile__("sti" ::: "memory");
}
// TODO: doxygen comment.
inline unsigned long get_eflags()
{
unsigned long eflags;
/* "=rm" is safe here, because "pop" adjusts the stack before
* it evaluates its effective address -- this is part of the
* documented behavior of the "pop" instruction.
*/
__asm__ __volatile__("pushf ; pop %0"
: "=rm"(eflags)
: /* no input */
: "memory");
return eflags;
}
/// @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)
{
if (flags) {
irq_enable();
}
}
/// @brief Disable IRQs.
inline static void irq_disable()
{
__asm__ __volatile__("cli" ::: "memory");
}
/// @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()
{
size_t flags;
__asm__ __volatile__("pushf; cli; pop %0" : "=r"(flags) : : "memory");
if (flags & (1 << 9))
return 1;
return 0;
}
/// @brief Determines, if the interrupt flags (IF) is set.
inline static uint8_t is_irq_enabled()
{
size_t flags;
__asm__ __volatile__("pushf; pop %0" : "=r"(flags) : : "memory");
if (flags & (1 << 9)) {
return 1;
}
return 0;
}
/// MentOS, The Mentoring Operating system project
/// @file irqflags.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdint.h"
/// @brief Enable IRQs.
inline static void irq_enable()
{
__asm__ __volatile__("sti" ::: "memory");
}
// TODO: doxygen comment.
inline unsigned long get_eflags()
{
unsigned long eflags;
/* "=rm" is safe here, because "pop" adjusts the stack before
* it evaluates its effective address -- this is part of the
* documented behavior of the "pop" instruction.
*/
__asm__ __volatile__("pushf ; pop %0"
: "=rm"(eflags)
: /* no input */
: "memory");
return eflags;
}
/// @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)
{
if (flags) {
irq_enable();
}
}
/// @brief Disable IRQs.
inline static void irq_disable()
{
__asm__ __volatile__("cli" ::: "memory");
}
/// @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()
{
size_t flags;
__asm__ __volatile__("pushf; cli; pop %0" : "=r"(flags) : : "memory");
if (flags & (1 << 9))
return 1;
return 0;
}
/// @brief Determines, if the interrupt flags (IF) is set.
inline static uint8_t is_irq_enabled()
{
size_t flags;
__asm__ __volatile__("pushf; pop %0" : "=r"(flags) : : "memory");
if (flags & (1 << 9)) {
return 1;
}
return 0;
}
+28 -28
View File
@@ -1,28 +1,28 @@
/// MentOS, The Mentoring Operating system project
/// @file libgen.h
/// @brief String routines.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stddef.h"
// TODO: doxygen comment.
/// @brief
/// @param out
/// @param cur
/// @param sep
/// @param max
/// @result
int parse_path(char *out, char **cur, char sep, size_t max);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *dirname(const char *path);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *basename(const char *path);
/// MentOS, The Mentoring Operating system project
/// @file libgen.h
/// @brief String routines.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "stddef.h"
// TODO: doxygen comment.
/// @brief
/// @param out
/// @param cur
/// @param sep
/// @param max
/// @result
int parse_path(char *out, char **cur, char sep, size_t max);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *dirname(const char *path);
// TODO: doxygen comment.
/// @brief
/// @param path
/// @result
char *basename(const char *path);
+46 -46
View File
@@ -1,47 +1,47 @@
/// MentOS, The Mentoring Operating system project
/// @file limits.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Number of bits in a `char'.
#define CHAR_BIT 8
/// Minimum value a `signed char' can hold.
#define SCHAR_MIN (-128)
/// Maximum value a `signed char' can hold.
#define SCHAR_MAX 127
/// Maximum value a `char' can hold. (Minimum is 0.)
#define CHAR_MAX 255
/// Minimum value a `signed short int' can hold.
#define SHRT_MIN (-32768)
/// Maximum value a `signed short int' can hold.
#define SHRT_MAX 32767
/// Minimum value a `signed int' can hold.
#define INT_MIN (-INT_MAX - 1)
/// Maximum values a `signed int' can hold.
#define INT_MAX 2147483647
/// Maximum value an `unsigned int' can hold. (Minimum is 0.)
#define UINT_MAX 4294967295U
/// Minimum value a `signed long int' can hold.
#define LONG_MAX 2147483647L
/// Maximum value a `signed long int' can hold.
#define LONG_MIN (-LONG_MAX - 1L)
/// Maximum number of characters in a file name.
#define NAME_MAX 255
/// Maximum number of characters in a path name.
/// MentOS, The Mentoring Operating system project
/// @file limits.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Number of bits in a `char'.
#define CHAR_BIT 8
/// Minimum value a `signed char' can hold.
#define SCHAR_MIN (-128)
/// Maximum value a `signed char' can hold.
#define SCHAR_MAX 127
/// Maximum value a `char' can hold. (Minimum is 0.)
#define CHAR_MAX 255
/// Minimum value a `signed short int' can hold.
#define SHRT_MIN (-32768)
/// Maximum value a `signed short int' can hold.
#define SHRT_MAX 32767
/// Minimum value a `signed int' can hold.
#define INT_MIN (-INT_MAX - 1)
/// Maximum values a `signed int' can hold.
#define INT_MAX 2147483647
/// Maximum value an `unsigned int' can hold. (Minimum is 0.)
#define UINT_MAX 4294967295U
/// Minimum value a `signed long int' can hold.
#define LONG_MAX 2147483647L
/// Maximum value a `signed long int' can hold.
#define LONG_MIN (-LONG_MAX - 1L)
/// Maximum number of characters in a file name.
#define NAME_MAX 255
/// Maximum number of characters in a path name.
#define PATH_MAX 4096
+107 -107
View File
@@ -1,107 +1,107 @@
/// MentOS, The Mentoring Operating system project
/// @file list.h
/// @brief An implementation for generic list.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stddef.h"
#include "stdbool.h"
/// @brief Represent the node of a list.
typedef struct listnode_t {
/// A pointer to the value.
void *value;
/// The previous node.
struct listnode_t *prev;
/// The next node.
struct listnode_t *next;
} listnode_t;
/// @brief Represent the list.
typedef struct list_t {
/// The first element of the list.
listnode_t *head;
/// The last element of the list.
listnode_t *tail;
/// The size of the list.
size_t size;
} list_t;
/// @brief Macro used to iterate through a list.
#define listnode_foreach(it, list) \
for (listnode_t * (it) = (list)->head; (it) != NULL; (it) = (it)->next)
/// @brief Create a list and set head, tail to NULL, and size to 0.
list_t *list_create();
/// @brief Get list size.
size_t list_size(list_t *list);
/// @brief Checks if the list is empty.
bool_t list_empty(list_t *list);
/// @brief Insert a value at the front of list.
listnode_t *list_insert_front(list_t *list, void *value);
/// @brief Insert a value at the back of list.
listnode_t *list_insert_back(list_t *list, void *value);
/// @brief Insert a value at the back of list.
void list_insert_node_back(list_t *list, listnode_t *item);
/// @brief Given a listnode, remove it from lis.
void *list_remove_node(list_t *list, listnode_t *node);
/// @brief Remove a value at the front of list.
void *list_remove_front(list_t *list);
/// @brief Remove a value at the back of list.
void *list_remove_back(list_t *list);
/// @brief Searches the node of the list which points at the given value.
listnode_t *list_find(list_t *list, void *value);
/// @brief Insert after tail of list(same as insert back).
void list_push(list_t *list, void *value);
/// @brief Remove and return the tail of the list.
/// @details User is responsible for freeing the returned node and the value.
listnode_t *list_pop_back(list_t *list);
/// @brief Remove and return the head of the list.
/// @details User is responsible for freeing the returned node and the value.
listnode_t *list_pop_front(list_t *list);
/// @brief Insert before head of list(same as insert front).
void list_enqueue(list_t *list, void *value);
/// @brief Remove and return tail of list(same as list_pop).
listnode_t *list_dequeue(list_t *list);
/// @brief Get the value of the first element but not remove it.
void *list_peek_front(list_t *list);
/// @brief Get the value of the last element but not remove it.
void *list_peek_back(list_t *list);
/// @brief Destory a list.
void list_destroy(list_t *list);
/// @brief Destroy a node of the list.
void listnode_destroy(listnode_t *node);
/// @brief Does the list contain a value (Return -1 if list element is not
/// found).
int list_contain(list_t *list, void *value);
/// @brief Returns the node at the given index.
listnode_t *list_get_node_by_index(list_t *list, size_t index);
/// @brief Removes a node from the list at the given index.
void *list_remove_by_index(list_t *list, size_t index);
/// @brief Append source at the end of target and DESTROY source.
void list_merge(list_t *target, list_t *source);
/// MentOS, The Mentoring Operating system project
/// @file list.h
/// @brief An implementation for generic list.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stddef.h"
#include "stdbool.h"
/// @brief Represent the node of a list.
typedef struct listnode_t {
/// A pointer to the value.
void *value;
/// The previous node.
struct listnode_t *prev;
/// The next node.
struct listnode_t *next;
} listnode_t;
/// @brief Represent the list.
typedef struct list_t {
/// The first element of the list.
listnode_t *head;
/// The last element of the list.
listnode_t *tail;
/// The size of the list.
size_t size;
} list_t;
/// @brief Macro used to iterate through a list.
#define listnode_foreach(it, list) \
for (listnode_t * (it) = (list)->head; (it) != NULL; (it) = (it)->next)
/// @brief Create a list and set head, tail to NULL, and size to 0.
list_t *list_create();
/// @brief Get list size.
size_t list_size(list_t *list);
/// @brief Checks if the list is empty.
bool_t list_empty(list_t *list);
/// @brief Insert a value at the front of list.
listnode_t *list_insert_front(list_t *list, void *value);
/// @brief Insert a value at the back of list.
listnode_t *list_insert_back(list_t *list, void *value);
/// @brief Insert a value at the back of list.
void list_insert_node_back(list_t *list, listnode_t *item);
/// @brief Given a listnode, remove it from lis.
void *list_remove_node(list_t *list, listnode_t *node);
/// @brief Remove a value at the front of list.
void *list_remove_front(list_t *list);
/// @brief Remove a value at the back of list.
void *list_remove_back(list_t *list);
/// @brief Searches the node of the list which points at the given value.
listnode_t *list_find(list_t *list, void *value);
/// @brief Insert after tail of list(same as insert back).
void list_push(list_t *list, void *value);
/// @brief Remove and return the tail of the list.
/// @details User is responsible for freeing the returned node and the value.
listnode_t *list_pop_back(list_t *list);
/// @brief Remove and return the head of the list.
/// @details User is responsible for freeing the returned node and the value.
listnode_t *list_pop_front(list_t *list);
/// @brief Insert before head of list(same as insert front).
void list_enqueue(list_t *list, void *value);
/// @brief Remove and return tail of list(same as list_pop).
listnode_t *list_dequeue(list_t *list);
/// @brief Get the value of the first element but not remove it.
void *list_peek_front(list_t *list);
/// @brief Get the value of the last element but not remove it.
void *list_peek_back(list_t *list);
/// @brief Destory a list.
void list_destroy(list_t *list);
/// @brief Destroy a node of the list.
void listnode_destroy(listnode_t *node);
/// @brief Does the list contain a value (Return -1 if list element is not
/// found).
int list_contain(list_t *list, void *value);
/// @brief Returns the node at the given index.
listnode_t *list_get_node_by_index(list_t *list, size_t index);
/// @brief Removes a node from the list at the given index.
void *list_remove_by_index(list_t *list, size_t index);
/// @brief Append source at the end of target and DESTROY source.
void list_merge(list_t *target, list_t *source);
+129 -129
View File
@@ -1,129 +1,129 @@
/// MentOS, The Mentoring Operating system project
/// @file list_head.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Structure used to implement the list_head data structure.
typedef struct list_head {
/// @brief The previous element.
struct list_head *prev;
/// @brief The subsequent element.
struct list_head *next;
} list_head;
/// @brief Get the struct for this entry.
/// @param ptr The &struct list_head pointer.
/// @param type The type of the struct this is embedded in.
/// @param member The name of the list_head within the struct.
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/// @brief Iterates over a list.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list.
#define list_for_each(pos, head) \
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
/// @brief Iterates over a list backwards.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list.
#define list_for_each_prev(pos, head) \
for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
/// @brief Iterates over a list safe against removal of list entry.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param store Another &struct list_head to use as temporary storage.
/// @param head The head for your list.
#define list_for_each_safe(pos, store, head) \
for ((pos) = (head)->next, (store) = (pos)->next; (pos) != (head); \
(pos) = (store), (store) = (pos)->next)
/// @brief Initializes the list_head.
/// @param head The head for your list.
#define list_head_init(head) (head)->next = (head)->prev = (head)
/// @brief Insert element l2 after l1.
static inline void list_head_insert_after(list_head *l1, list_head *l2)
{
// [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb]
list_head *l1_next = l1->next;
// [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb]
l1->next = l2;
// [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb]
l2->prev = l1;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb]
l2->next = l1_next;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb]
l1_next->prev = l2;
}
/// @brief Insert element l2 before l1.
static inline void list_head_insert_before(list_head *l1, list_head *l2)
{
// [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb]
list_head *l1_prev = l1->prev;
// [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb]
l1_prev->next = l2;
// [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb]
l2->prev = l1_prev;
// [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb]
l2->next = l1;
// [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb]
l1->prev = l2;
}
/// @brief Remove l from the list.
/// @param l The element to remove.
static inline void list_head_del(list_head *l)
{
// [La]->l La<-[l]->Lb l<-[Lb]
// [La]->Lb La<-[l]->Lb l<-[Lb]
l->prev->next = l->next;
// [La]->Lb La<-[l]->Lb La<-[Lb]
l->next->prev = l->prev;
// [La]->Lb l<-[l]->l La<-[Lb]
l->next = l->prev = l;
}
/// @brief Tests whether the given list is empty.
/// @param head The list to check.
/// @return 1 if empty, 0 otherwise.
static inline int list_head_empty(list_head const *head)
{
return head->next == head;
}
/// Insert a new entry between two known consecutive entries.
static inline void __list_add(list_head *new, list_head *prev, list_head *next)
{
// [prev]-> <-[new]-> <-[next]
// [prev]-> <-[new]-> new<-[next]
next->prev = new;
// [prev]-> <-[new]->next new<-[next]
new->next = next;
// [prev]-> prev<-[new]->next new<-[next]
new->prev = prev;
// [prev]->new prev<-[new]->next new<-[next]
prev->next = new;
}
/// @brief Insert element l2 before l1.
static inline void list_head_add(list_head *new, list_head *head)
{
__list_add(new, head, head->next);
}
/// @brief Insert element l2 before l1.
static inline void list_head_add_tail(list_head *new, list_head *head)
{
__list_add(new, head->prev, head);
}
/// MentOS, The Mentoring Operating system project
/// @file list_head.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Structure used to implement the list_head data structure.
typedef struct list_head {
/// @brief The previous element.
struct list_head *prev;
/// @brief The subsequent element.
struct list_head *next;
} list_head;
/// @brief Get the struct for this entry.
/// @param ptr The &struct list_head pointer.
/// @param type The type of the struct this is embedded in.
/// @param member The name of the list_head within the struct.
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/// @brief Iterates over a list.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list.
#define list_for_each(pos, head) \
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
/// @brief Iterates over a list backwards.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list.
#define list_for_each_prev(pos, head) \
for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
/// @brief Iterates over a list safe against removal of list entry.
/// @param pos The &struct list_head to use as a loop cursor.
/// @param store Another &struct list_head to use as temporary storage.
/// @param head The head for your list.
#define list_for_each_safe(pos, store, head) \
for ((pos) = (head)->next, (store) = (pos)->next; (pos) != (head); \
(pos) = (store), (store) = (pos)->next)
/// @brief Initializes the list_head.
/// @param head The head for your list.
#define list_head_init(head) (head)->next = (head)->prev = (head)
/// @brief Insert element l2 after l1.
static inline void list_head_insert_after(list_head *l1, list_head *l2)
{
// [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb]
list_head *l1_next = l1->next;
// [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb]
l1->next = l2;
// [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb]
l2->prev = l1;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb]
l2->next = l1_next;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb]
l1_next->prev = l2;
}
/// @brief Insert element l2 before l1.
static inline void list_head_insert_before(list_head *l1, list_head *l2)
{
// [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb]
list_head *l1_prev = l1->prev;
// [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb]
l1_prev->next = l2;
// [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb]
l2->prev = l1_prev;
// [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb]
l2->next = l1;
// [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb]
l1->prev = l2;
}
/// @brief Remove l from the list.
/// @param l The element to remove.
static inline void list_head_del(list_head *l)
{
// [La]->l La<-[l]->Lb l<-[Lb]
// [La]->Lb La<-[l]->Lb l<-[Lb]
l->prev->next = l->next;
// [La]->Lb La<-[l]->Lb La<-[Lb]
l->next->prev = l->prev;
// [La]->Lb l<-[l]->l La<-[Lb]
l->next = l->prev = l;
}
/// @brief Tests whether the given list is empty.
/// @param head The list to check.
/// @return 1 if empty, 0 otherwise.
static inline int list_head_empty(list_head const *head)
{
return head->next == head;
}
/// Insert a new entry between two known consecutive entries.
static inline void __list_add(list_head *new, list_head *prev, list_head *next)
{
// [prev]-> <-[new]-> <-[next]
// [prev]-> <-[new]-> new<-[next]
next->prev = new;
// [prev]-> <-[new]->next new<-[next]
new->next = next;
// [prev]-> prev<-[new]->next new<-[next]
new->prev = prev;
// [prev]->new prev<-[new]->next new<-[next]
prev->next = new;
}
/// @brief Insert element l2 before l1.
static inline void list_head_add(list_head *new, list_head *head)
{
__list_add(new, head, head->next);
}
/// @brief Insert element l2 before l1.
static inline void list_head_add_tail(list_head *new, list_head *head)
{
__list_add(new, head->prev, head);
}
+131 -131
View File
@@ -1,131 +1,131 @@
/// MentOS, The Mentoring Operating system project
/// @file math.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief The absolute value.
#define abs(a) (((a) < 0) ? -(a) : (a))
/// @brief The max of the two values.
#define max(a, b) (((a) > (b)) ? (a) : (b))
/// @brief The min of the two values.
#define min(a, b) (((a) < (b)) ? (a) : (b))
/// @brief The sign the the passed value.
#define sign(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
/// @brief Returns a rounded up, away from zero, to the nearest multiple of b.
#define ceil(NUMBER, BASE) (((NUMBER) + (BASE)-1) & ~((BASE)-1))
/// @brief e
#define M_E 2.7182818284590452354
/// @brief log_2 e
#define M_LOG2E 1.4426950408889634074
/// @brief log_10 e
#define M_LOG10E 0.43429448190325182765
/// @brief log_e 2
#define M_LN2 0.69314718055994530942
/// @brief log_e 10
#define M_LN10 2.30258509299404568402
/// @brief pi
#define M_PI 3.14159265358979323846
/// @brief pi / 2
#define M_PI_2 1.57079632679489661923
/// @brief pi / 4
#define M_PI_4 0.78539816339744830962
/// @brief 1 / pi
#define M_1_PI 0.31830988618379067154
/// @brief 2 / pi
#define M_2_PI 0.63661977236758134308
/// @brief 2 / sqrt(pi)
#define M_2_SQRTPI 1.12837916709551257390
/// @brief sqrt(2)
#define M_SQRT2 1.41421356237309504880
/// @brief 1 / sqrt(2)
#define M_SQRT1_2 0.70710678118654752440
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double round(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double floor(double x);
/// @brief Power function.
/// @param x First number.
/// @param y Second number.
/// @result Power between number x and y.
double pow(double x, double y);
// TODO: doxygen comment.
/// @brief
/// @param base
/// @param value
/// @result
long find_nearest_pow_greater(double base, double value);
/// @brief Exponential function.
/// @param x Value of the exponent.
double exp(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double fabs(double x);
/// @brief Square root function.
/// @param x Topic of the square root.
double sqrt(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
int isinf(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
int isnan(double x);
/// @brief Logarithm function in base 10.
/// @param x Topic of the logarithm function.
double log10(double x);
/// @brief Natural logarithm function.
/// @param x Topic of the logarithm function.
double ln(double x);
/// @brief Logarithm function in base x.
/// @brief x Base of the logarithm.
/// @param y Topic of the logarithm function.
double logx(double x, double y);
/// @brief Breaks x into an integral and a fractional part.
/// The integer part is stored in the object pointed by intpart, and the
/// fractional part is returned by the function. Both parts have the same
/// sign as x.
double modf(double x, double *intpart);
/// MentOS, The Mentoring Operating system project
/// @file math.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief The absolute value.
#define abs(a) (((a) < 0) ? -(a) : (a))
/// @brief The max of the two values.
#define max(a, b) (((a) > (b)) ? (a) : (b))
/// @brief The min of the two values.
#define min(a, b) (((a) < (b)) ? (a) : (b))
/// @brief The sign the the passed value.
#define sign(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
/// @brief Returns a rounded up, away from zero, to the nearest multiple of b.
#define ceil(NUMBER, BASE) (((NUMBER) + (BASE)-1) & ~((BASE)-1))
/// @brief e
#define M_E 2.7182818284590452354
/// @brief log_2 e
#define M_LOG2E 1.4426950408889634074
/// @brief log_10 e
#define M_LOG10E 0.43429448190325182765
/// @brief log_e 2
#define M_LN2 0.69314718055994530942
/// @brief log_e 10
#define M_LN10 2.30258509299404568402
/// @brief pi
#define M_PI 3.14159265358979323846
/// @brief pi / 2
#define M_PI_2 1.57079632679489661923
/// @brief pi / 4
#define M_PI_4 0.78539816339744830962
/// @brief 1 / pi
#define M_1_PI 0.31830988618379067154
/// @brief 2 / pi
#define M_2_PI 0.63661977236758134308
/// @brief 2 / sqrt(pi)
#define M_2_SQRTPI 1.12837916709551257390
/// @brief sqrt(2)
#define M_SQRT2 1.41421356237309504880
/// @brief 1 / sqrt(2)
#define M_SQRT1_2 0.70710678118654752440
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double round(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double floor(double x);
/// @brief Power function.
/// @param x First number.
/// @param y Second number.
/// @result Power between number x and y.
double pow(double x, double y);
// TODO: doxygen comment.
/// @brief
/// @param base
/// @param value
/// @result
long find_nearest_pow_greater(double base, double value);
/// @brief Exponential function.
/// @param x Value of the exponent.
double exp(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
double fabs(double x);
/// @brief Square root function.
/// @param x Topic of the square root.
double sqrt(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
int isinf(double x);
// TODO: doxygen comment.
/// @brief
/// @param x
/// @result
int isnan(double x);
/// @brief Logarithm function in base 10.
/// @param x Topic of the logarithm function.
double log10(double x);
/// @brief Natural logarithm function.
/// @param x Topic of the logarithm function.
double ln(double x);
/// @brief Logarithm function in base x.
/// @brief x Base of the logarithm.
/// @param y Topic of the logarithm function.
double logx(double x, double y);
/// @brief Breaks x into an integral and a fractional part.
/// The integer part is stored in the object pointed by intpart, and the
/// fractional part is returned by the function. Both parts have the same
/// sign as x.
double modf(double x, double *intpart);
+26 -26
View File
@@ -1,26 +1,26 @@
/// MentOS, The Mentoring Operating system project
/// @file mutex.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Structure of a mutex.
typedef struct mutex_t {
/// The state of the mutex.
uint8_t state;
/// The owner of the mutex.
uint32_t owner;
} mutex_t;
/// @brief Allows to lock a mutex.
/// @param mutex The mutex to lock.
/// @param owner The one who request the lock.
void mutex_lock(mutex_t *mutex, uint32_t owner);
/// @brief Unlocks the mutex.
/// @param mutex The mutex to unlock.
void mutex_unlock(mutex_t *mutex);
/// MentOS, The Mentoring Operating system project
/// @file mutex.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief Structure of a mutex.
typedef struct mutex_t {
/// The state of the mutex.
uint8_t state;
/// The owner of the mutex.
uint32_t owner;
} mutex_t;
/// @brief Allows to lock a mutex.
/// @param mutex The mutex to lock.
/// @param owner The one who request the lock.
void mutex_lock(mutex_t *mutex, uint32_t owner);
/// @brief Unlocks the mutex.
/// @param mutex The mutex to unlock.
void mutex_unlock(mutex_t *mutex);
+53 -53
View File
@@ -1,53 +1,53 @@
/// MentOS, The Mentoring Operating system project
/// @file ordered_array.h
/// @brief Interface for creating, inserting and deleting from ordered arrays.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief This array is insertion sorted - it always remains in a sorted
/// state (between calls). It can store anything that can be cast to a
/// void* -- so a uint32_t, or any pointer.
typedef void *array_type_t;
/// @brief A predicate should return nonzero if the first argument is less
/// than the second. Else it should return zero.
typedef int8_t (*lessthan_predicate_t)(array_type_t, array_type_t);
/// @brief Structure which holds information concerning an ordered array.
typedef struct ordered_array_t {
/// Pointer to the array.
array_type_t *array;
/// The size of the array.
uint32_t size;
/// The maximum size of the array.
uint32_t max_size;
/// Ordering fucntion.
lessthan_predicate_t less_than;
} ordered_array_t;
/// @brief A standard less than predicate.
int8_t standard_lessthan_predicate(array_type_t a, array_type_t b);
/// @brief Create an ordered array.
ordered_array_t create_ordered_array(uint32_t max_size,
lessthan_predicate_t less_than);
/// @brief Set the ordered array.
ordered_array_t place_ordered_array(void *addr, uint32_t max_size,
lessthan_predicate_t less_than);
/// @brief Destroy an ordered array.
void destroy_ordered_array(ordered_array_t *array);
/// @brief Add an item into the array.
void insert_ordered_array(array_type_t item, ordered_array_t *array);
/// @brief Lookup the item at index i.
array_type_t lookup_ordered_array(uint32_t i, ordered_array_t *array);
/// @brief Deletes the item at location i from the array.
void remove_ordered_array(uint32_t i, ordered_array_t *array);
/// MentOS, The Mentoring Operating system project
/// @file ordered_array.h
/// @brief Interface for creating, inserting and deleting from ordered arrays.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
/// @brief This array is insertion sorted - it always remains in a sorted
/// state (between calls). It can store anything that can be cast to a
/// void* -- so a uint32_t, or any pointer.
typedef void *array_type_t;
/// @brief A predicate should return nonzero if the first argument is less
/// than the second. Else it should return zero.
typedef int8_t (*lessthan_predicate_t)(array_type_t, array_type_t);
/// @brief Structure which holds information concerning an ordered array.
typedef struct ordered_array_t {
/// Pointer to the array.
array_type_t *array;
/// The size of the array.
uint32_t size;
/// The maximum size of the array.
uint32_t max_size;
/// Ordering fucntion.
lessthan_predicate_t less_than;
} ordered_array_t;
/// @brief A standard less than predicate.
int8_t standard_lessthan_predicate(array_type_t a, array_type_t b);
/// @brief Create an ordered array.
ordered_array_t create_ordered_array(uint32_t max_size,
lessthan_predicate_t less_than);
/// @brief Set the ordered array.
ordered_array_t place_ordered_array(void *addr, uint32_t max_size,
lessthan_predicate_t less_than);
/// @brief Destroy an ordered array.
void destroy_ordered_array(ordered_array_t *array);
/// @brief Add an item into the array.
void insert_ordered_array(array_type_t item, ordered_array_t *array);
/// @brief Lookup the item at index i.
array_type_t lookup_ordered_array(uint32_t i, ordered_array_t *array);
/// @brief Deletes the item at location i from the array.
void remove_ordered_array(uint32_t i, ordered_array_t *array);
+76 -76
View File
@@ -1,76 +1,76 @@
/// MentOS, The Mentoring Operating system project
/// @file queue.h
/// @brief Implementation of queue data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdbool.h"
/// @brief A node of the queue.
typedef struct queue_node_t {
/// The wrapped data.
void *data;
/// The next node of the queue.
struct queue_node_t *next;
} queue_node_t;
/// @brief The queue.
typedef struct queue_t {
/// The front of the queue.
queue_node_t *front;
/// The back of the queue.
queue_node_t *back;
/// The size of the data contained inside the queue.
size_t data_size;
} * queue_t;
/// @brief Creates a queue.
/// @param data_size The size of the stored elements.
/// @return The created queue.
queue_t queue_create(size_t data_size);
/// @brief Destroys the queue.
/// @param queue The queue to be destroyed.
/// @return If the queue is destroyed.
bool_t queue_destroy(queue_t queue);
/// @brief Returns if the queue is empty.
/// @param queue The queue.
bool_t queue_is_empty(queue_t queue);
/// @brief Allows to add data to the queue.
/// @param queue The queue.
/// @param data The data to add.
/// @return If the data has been pushed inside the queue.
bool_t queue_enqueue(queue_t queue, void *data);
/// @brief Removes the first element of the queue.
/// @param queue The queue.
/// @return If the data has been removed.
bool_t queue_dequeue(queue_t queue);
/// @brief Returns the first element of the queue.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_front(queue_t queue, void *data);
/// @brief Returns the last element of the queue.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_back(queue_t queue, void *data);
/// @brief Returns the first element of the queue and removes it.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_front_and_dequeue(queue_t queue, void *data);
/// @brief Deletes all the elements inside the queue.
/// @param queue The queue.
/// @return If the queue has been cleared.
bool_t queue_clear(queue_t queue);
/// MentOS, The Mentoring Operating system project
/// @file queue.h
/// @brief Implementation of queue data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "stdbool.h"
/// @brief A node of the queue.
typedef struct queue_node_t {
/// The wrapped data.
void *data;
/// The next node of the queue.
struct queue_node_t *next;
} queue_node_t;
/// @brief The queue.
typedef struct queue_t {
/// The front of the queue.
queue_node_t *front;
/// The back of the queue.
queue_node_t *back;
/// The size of the data contained inside the queue.
size_t data_size;
} * queue_t;
/// @brief Creates a queue.
/// @param data_size The size of the stored elements.
/// @return The created queue.
queue_t queue_create(size_t data_size);
/// @brief Destroys the queue.
/// @param queue The queue to be destroyed.
/// @return If the queue is destroyed.
bool_t queue_destroy(queue_t queue);
/// @brief Returns if the queue is empty.
/// @param queue The queue.
bool_t queue_is_empty(queue_t queue);
/// @brief Allows to add data to the queue.
/// @param queue The queue.
/// @param data The data to add.
/// @return If the data has been pushed inside the queue.
bool_t queue_enqueue(queue_t queue, void *data);
/// @brief Removes the first element of the queue.
/// @param queue The queue.
/// @return If the data has been removed.
bool_t queue_dequeue(queue_t queue);
/// @brief Returns the first element of the queue.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_front(queue_t queue, void *data);
/// @brief Returns the last element of the queue.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_back(queue_t queue, void *data);
/// @brief Returns the first element of the queue and removes it.
/// @param queue The queue.
/// @param data The data.
/// @return If the data has been correctly retrieved.
bool_t queue_front_and_dequeue(queue_t queue, void *data);
/// @brief Deletes all the elements inside the queue.
/// @param queue The queue.
/// @return If the queue has been cleared.
bool_t queue_clear(queue_t queue);
+134 -134
View File
@@ -1,134 +1,134 @@
/// MentOS, The Mentoring Operating system project
/// @file rbtree.h
/// @brief Implementation of red black tree data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#ifndef RBTREE_ITER_MAX_HEIGHT
/// Tallest allowable tree to iterate.
#define RBTREE_ITER_MAX_HEIGHT 64
#endif
//==============================================================================
// Opaque types.
// TODO: doxygen comment.
typedef struct rbtree_t rbtree_t;
// TODO: doxygen comment.
typedef struct rbtree_node_t rbtree_node_t;
// TODO: doxygen comment.
typedef struct rbtree_iter_t rbtree_iter_t;
//==============================================================================
// Comparison functions.
// TODO: doxygen comment.
typedef int (*rbtree_tree_cmp_f)(rbtree_t *self, rbtree_node_t *a, void *arg);
// TODO: doxygen comment.
typedef int (*rbtree_tree_node_cmp_f)(rbtree_t *self, rbtree_node_t *a,
rbtree_node_t *b);
// TODO: doxygen comment.
typedef void (*rbtree_tree_node_f)(rbtree_t *self, rbtree_node_t *node);
//==============================================================================
// Node management functions.
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_alloc();
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_create(void *value);
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_init(rbtree_node_t *self, void *value);
// TODO: doxygen comment.
void *rbtree_node_get_value(rbtree_node_t *self);
// TODO: doxygen comment.
void rbtree_node_dealloc(rbtree_node_t *self);
//==============================================================================
// Tree management functions.
// TODO: doxygen comment.
rbtree_t *rbtree_tree_alloc();
// TODO: doxygen comment.
rbtree_t *rbtree_tree_create(rbtree_tree_node_cmp_f cmp);
// TODO: doxygen comment.
rbtree_t *rbtree_tree_init(rbtree_t *self, rbtree_tree_node_cmp_f cmp);
// TODO: doxygen comment.
void rbtree_tree_dealloc(rbtree_t *self, rbtree_tree_node_f node_cb);
// TODO: doxygen comment.
void *rbtree_tree_find(rbtree_t *self, void *value);
// TODO: doxygen comment.
void *rbtree_tree_find_by_value(rbtree_t *self, rbtree_tree_cmp_f cmp_fun,
void *value);
// TODO: doxygen comment.
int rbtree_tree_insert(rbtree_t *self, void *value);
// TODO: doxygen comment.
int rbtree_tree_remove(rbtree_t *self, void *value);
// TODO: doxygen comment.
size_t rbtree_tree_size(rbtree_t *self);
// TODO: doxygen comment.
int rbtree_tree_insert_node(rbtree_t *self, rbtree_node_t *node);
// TODO: doxygen comment.
int rbtree_tree_remove_with_cb(rbtree_t *self, void *value,
rbtree_tree_node_f node_cb);
//==============================================================================
// Iterators.
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_alloc();
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_init(rbtree_iter_t *self);
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_create();
// TODO: doxygen comment.
void rbtree_iter_dealloc(rbtree_iter_t *self);
// TODO: doxygen comment.
void *rbtree_iter_first(rbtree_iter_t *self, rbtree_t *tree);
// TODO: doxygen comment.
void *rbtree_iter_last(rbtree_iter_t *self, rbtree_t *tree);
// TODO: doxygen comment.
void *rbtree_iter_next(rbtree_iter_t *self);
// TODO: doxygen comment.
void *rbtree_iter_prev(rbtree_iter_t *self);
//==============================================================================
// Tree debugging functions.
// TODO: doxygen comment.
int rbtree_tree_test(rbtree_t *self, rbtree_node_t *root);
// TODO: doxygen comment.
void rbtree_tree_print(rbtree_t *self, rbtree_tree_node_f fun);
//==============================================================================
/// MentOS, The Mentoring Operating system project
/// @file rbtree.h
/// @brief Implementation of red black tree data structure.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#ifndef RBTREE_ITER_MAX_HEIGHT
/// Tallest allowable tree to iterate.
#define RBTREE_ITER_MAX_HEIGHT 64
#endif
//==============================================================================
// Opaque types.
// TODO: doxygen comment.
typedef struct rbtree_t rbtree_t;
// TODO: doxygen comment.
typedef struct rbtree_node_t rbtree_node_t;
// TODO: doxygen comment.
typedef struct rbtree_iter_t rbtree_iter_t;
//==============================================================================
// Comparison functions.
// TODO: doxygen comment.
typedef int (*rbtree_tree_cmp_f)(rbtree_t *self, rbtree_node_t *a, void *arg);
// TODO: doxygen comment.
typedef int (*rbtree_tree_node_cmp_f)(rbtree_t *self, rbtree_node_t *a,
rbtree_node_t *b);
// TODO: doxygen comment.
typedef void (*rbtree_tree_node_f)(rbtree_t *self, rbtree_node_t *node);
//==============================================================================
// Node management functions.
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_alloc();
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_create(void *value);
// TODO: doxygen comment.
rbtree_node_t *rbtree_node_init(rbtree_node_t *self, void *value);
// TODO: doxygen comment.
void *rbtree_node_get_value(rbtree_node_t *self);
// TODO: doxygen comment.
void rbtree_node_dealloc(rbtree_node_t *self);
//==============================================================================
// Tree management functions.
// TODO: doxygen comment.
rbtree_t *rbtree_tree_alloc();
// TODO: doxygen comment.
rbtree_t *rbtree_tree_create(rbtree_tree_node_cmp_f cmp);
// TODO: doxygen comment.
rbtree_t *rbtree_tree_init(rbtree_t *self, rbtree_tree_node_cmp_f cmp);
// TODO: doxygen comment.
void rbtree_tree_dealloc(rbtree_t *self, rbtree_tree_node_f node_cb);
// TODO: doxygen comment.
void *rbtree_tree_find(rbtree_t *self, void *value);
// TODO: doxygen comment.
void *rbtree_tree_find_by_value(rbtree_t *self, rbtree_tree_cmp_f cmp_fun,
void *value);
// TODO: doxygen comment.
int rbtree_tree_insert(rbtree_t *self, void *value);
// TODO: doxygen comment.
int rbtree_tree_remove(rbtree_t *self, void *value);
// TODO: doxygen comment.
size_t rbtree_tree_size(rbtree_t *self);
// TODO: doxygen comment.
int rbtree_tree_insert_node(rbtree_t *self, rbtree_node_t *node);
// TODO: doxygen comment.
int rbtree_tree_remove_with_cb(rbtree_t *self, void *value,
rbtree_tree_node_f node_cb);
//==============================================================================
// Iterators.
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_alloc();
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_init(rbtree_iter_t *self);
// TODO: doxygen comment.
rbtree_iter_t *rbtree_iter_create();
// TODO: doxygen comment.
void rbtree_iter_dealloc(rbtree_iter_t *self);
// TODO: doxygen comment.
void *rbtree_iter_first(rbtree_iter_t *self, rbtree_t *tree);
// TODO: doxygen comment.
void *rbtree_iter_last(rbtree_iter_t *self, rbtree_t *tree);
// TODO: doxygen comment.
void *rbtree_iter_next(rbtree_iter_t *self);
// TODO: doxygen comment.
void *rbtree_iter_prev(rbtree_iter_t *self);
//==============================================================================
// Tree debugging functions.
// TODO: doxygen comment.
int rbtree_tree_test(rbtree_t *self, rbtree_node_t *root);
// TODO: doxygen comment.
void rbtree_tree_print(rbtree_t *self, rbtree_tree_node_f fun);
//==============================================================================
+32 -32
View File
@@ -1,32 +1,32 @@
/// MentOS, The Mentoring Operating system project
/// @file spinlock.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "debug.h"
#include "stddef.h"
#include "irqflags.h"
#include "stdatomic.h"
#include "scheduler.h"
#define SPINLOCK_FREE 0
#define SPINLOCK_BUSY 1
/// @brief Spinlock structure.
typedef atomic_t spinlock_t;
/// @brief Initialize the spinlock.
void spinlock_init(spinlock_t *spinlock);
/// @brief Try to lock the spinlock.
void spinlock_lock(spinlock_t *spinlock);
/// @brief Try to unlock the spinlock.
void spinlock_unlock(spinlock_t *spinlock);
/// @brief Try to unlock the spinlock.
bool_t spinlock_trylock(spinlock_t *spinlock);
/// MentOS, The Mentoring Operating system project
/// @file spinlock.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "debug.h"
#include "stddef.h"
#include "irqflags.h"
#include "stdatomic.h"
#include "scheduler.h"
#define SPINLOCK_FREE 0
#define SPINLOCK_BUSY 1
/// @brief Spinlock structure.
typedef atomic_t spinlock_t;
/// @brief Initialize the spinlock.
void spinlock_init(spinlock_t *spinlock);
/// @brief Try to lock the spinlock.
void spinlock_lock(spinlock_t *spinlock);
/// @brief Try to unlock the spinlock.
void spinlock_unlock(spinlock_t *spinlock);
/// @brief Try to unlock the spinlock.
bool_t spinlock_trylock(spinlock_t *spinlock);
+28 -28
View File
@@ -1,28 +1,28 @@
/// MentOS, The Mentoring Operating system project
/// @file stdarg.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief The va_list type is an array containing a single element of one
/// structure containing the necessary information to implement the
/// va_arg macro.
typedef char *va_list;
/// @brief The type of the item on the stack.
#define va_item int
/// @brief Amount of space required in an argument list (ie. the stack) for an
/// argument of type t.
#define va_size(t) \
(((sizeof(t) + sizeof(va_item) - 1) / sizeof(va_item)) * sizeof(va_item))
/// @brief The start of a variadic list.
#define va_start(ap, last_arg) (ap = ((va_list)(&last_arg) + va_size(last_arg)))
/// @brief The end of a variadic list.
#define va_end(ap) ((void)0)
/// @brief The argument of a variadic list.
#define va_arg(ap, t) (ap += va_size(t), *((t *)(ap - va_size(t))))
/// MentOS, The Mentoring Operating system project
/// @file stdarg.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief The va_list type is an array containing a single element of one
/// structure containing the necessary information to implement the
/// va_arg macro.
typedef char *va_list;
/// @brief The type of the item on the stack.
#define va_item int
/// @brief Amount of space required in an argument list (ie. the stack) for an
/// argument of type t.
#define va_size(t) \
(((sizeof(t) + sizeof(va_item) - 1) / sizeof(va_item)) * sizeof(va_item))
/// @brief The start of a variadic list.
#define va_start(ap, last_arg) (ap = ((va_list)(&last_arg) + va_size(last_arg)))
/// @brief The end of a variadic list.
#define va_end(ap) ((void)0)
/// @brief The argument of a variadic list.
#define va_arg(ap, t) (ap += va_size(t), *((t *)(ap - va_size(t))))
+109 -109
View File
@@ -1,109 +1,109 @@
/// MentOS, The Mentoring Operating system project
/// @file stdatomic.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stdbool.h"
#include "compiler.h"
/// @brief Standard structure for atomic operations.
typedef volatile unsigned atomic_t;
/// @brief At declaration, initialize an atomic_t to i.
#define ATOMIC_INIT(i) \
{ \
(i) \
}
/// @brief The prefix used to lock.
#define LOCK_PREFIX "\n\tlock; "
/// @brief Compile read-write barrier.
#define barrier() asm volatile("" : : : "memory")
/// @brief Pause instruction to prevent excess processor bus usage.
#define cpu_relax() asm volatile("pause\n" : : : "memory")
// TODO: doxygen comment.
inline static int32_t atomic_set_and_test(atomic_t const *ptr, int32_t i)
{
__asm__ __volatile__("xchgl %0,%1"
: "=r"(i)
: "m"(*(volatile unsigned *)ptr), "0"(i)
: "memory");
// __asm__ __volatile__("xchgl %0, %1" : "=r"(i) : "m"(ptr), "0"(i) : "memory");
return i;
}
/// @brief Atomically set ptr equal to i.
inline static void atomic_set(atomic_t *ptr, int32_t i)
{
atomic_set_and_test(ptr, i);
}
/// @brief Atomically read the integer value of ptr.
inline static int32_t atomic_read(const atomic_t *ptr)
{
return READ_ONCE(*ptr);
}
/// @brief Atomically add i to ptr.
inline static int32_t atomic_add(atomic_t const *ptr, int32_t i)
{
int result = i;
asm volatile(LOCK_PREFIX "xaddl %0, %1"
: "=r"(i)
: "m"(ptr), "0"(i)
: "memory", "cc");
return result + i;
}
/// @brief Atomically subtract i from ptr.
inline static int32_t atomic_sub(atomic_t *ptr, int32_t i)
{
return atomic_add(ptr, -i);
}
/// @brief Atomically add one to ptr.
inline static int32_t atomic_inc(atomic_t *ptr)
{
return atomic_add(ptr, 1);
}
/// @brief Atomically subtract one from ptr.
inline static int32_t atomic_dec(atomic_t *ptr)
{
return atomic_add(ptr, -1);
}
/// @brief Atomically add i to ptr and return true if the result is negative;
/// otherwise false.
inline static bool_t atomic_add_negative(atomic_t *ptr, int32_t i)
{
return (bool_t)(atomic_add(ptr, i) < 0);
}
/// @brief Atomically subtract i from ptr and return true if the result is
/// zero; otherwise false.
inline static bool_t atomic_sub_and_test(atomic_t *ptr, int32_t i)
{
return (bool_t)(atomic_sub(ptr, i) == 0);
}
/// @brief Atomically increment ptr by one and return true if the result is
/// zero; false otherwise.
inline static int32_t atomic_inc_and_test(atomic_t *ptr)
{
return (bool_t)(atomic_inc(ptr) == 0);
}
/// @brief Atomically decrement ptr by one and return true if zero; false
/// otherwise.
inline static int32_t atomic_dec_and_test(atomic_t *ptr)
{
return (bool_t)(atomic_dec(ptr) == 0);
}
/// MentOS, The Mentoring Operating system project
/// @file stdatomic.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stdbool.h"
#include "compiler.h"
/// @brief Standard structure for atomic operations.
typedef volatile unsigned atomic_t;
/// @brief At declaration, initialize an atomic_t to i.
#define ATOMIC_INIT(i) \
{ \
(i) \
}
/// @brief The prefix used to lock.
#define LOCK_PREFIX "\n\tlock; "
/// @brief Compile read-write barrier.
#define barrier() asm volatile("" : : : "memory")
/// @brief Pause instruction to prevent excess processor bus usage.
#define cpu_relax() asm volatile("pause\n" : : : "memory")
// TODO: doxygen comment.
inline static int32_t atomic_set_and_test(atomic_t const *ptr, int32_t i)
{
__asm__ __volatile__("xchgl %0,%1"
: "=r"(i)
: "m"(*(volatile unsigned *)ptr), "0"(i)
: "memory");
// __asm__ __volatile__("xchgl %0, %1" : "=r"(i) : "m"(ptr), "0"(i) : "memory");
return i;
}
/// @brief Atomically set ptr equal to i.
inline static void atomic_set(atomic_t *ptr, int32_t i)
{
atomic_set_and_test(ptr, i);
}
/// @brief Atomically read the integer value of ptr.
inline static int32_t atomic_read(const atomic_t *ptr)
{
return READ_ONCE(*ptr);
}
/// @brief Atomically add i to ptr.
inline static int32_t atomic_add(atomic_t const *ptr, int32_t i)
{
int result = i;
asm volatile(LOCK_PREFIX "xaddl %0, %1"
: "=r"(i)
: "m"(ptr), "0"(i)
: "memory", "cc");
return result + i;
}
/// @brief Atomically subtract i from ptr.
inline static int32_t atomic_sub(atomic_t *ptr, int32_t i)
{
return atomic_add(ptr, -i);
}
/// @brief Atomically add one to ptr.
inline static int32_t atomic_inc(atomic_t *ptr)
{
return atomic_add(ptr, 1);
}
/// @brief Atomically subtract one from ptr.
inline static int32_t atomic_dec(atomic_t *ptr)
{
return atomic_add(ptr, -1);
}
/// @brief Atomically add i to ptr and return true if the result is negative;
/// otherwise false.
inline static bool_t atomic_add_negative(atomic_t *ptr, int32_t i)
{
return (bool_t)(atomic_add(ptr, i) < 0);
}
/// @brief Atomically subtract i from ptr and return true if the result is
/// zero; otherwise false.
inline static bool_t atomic_sub_and_test(atomic_t *ptr, int32_t i)
{
return (bool_t)(atomic_sub(ptr, i) == 0);
}
/// @brief Atomically increment ptr by one and return true if the result is
/// zero; false otherwise.
inline static int32_t atomic_inc_and_test(atomic_t *ptr)
{
return (bool_t)(atomic_inc(ptr) == 0);
}
/// @brief Atomically decrement ptr by one and return true if zero; false
/// otherwise.
inline static int32_t atomic_dec_and_test(atomic_t *ptr)
{
return (bool_t)(atomic_dec(ptr) == 0);
}
+16 -16
View File
@@ -1,16 +1,16 @@
/// MentOS, The Mentoring Operating system project
/// @file stdbool.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Define boolean value.
typedef enum bool_t
{
/// [0] False.
false,
/// [1] True.
true
} __attribute__ ((__packed__)) bool_t;
/// MentOS, The Mentoring Operating system project
/// @file stdbool.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Define boolean value.
typedef enum bool_t
{
/// [0] False.
false,
/// [1] True.
true
} __attribute__ ((__packed__)) bool_t;
+87 -87
View File
@@ -1,87 +1,87 @@
/// MentOS, The Mentoring Operating system project
/// @file stddef.h
/// @brief Define basic data types.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#ifndef NULL
/// @brief Define NULL.
#define NULL ((void *)0)
#endif
#ifndef EOF
/// @brief Define End-Of-File.
#define EOF (-1)
#endif
/// @brief Define the size of a buffer.
#define BUFSIZ 512
/// @brief Define the size of the kernel.
#define KERNEL_SIZE 0x200
#ifndef TRUE
/// @brief Define the value of true.
#define TRUE 1
#endif
#ifndef FALSE
/// @brief Define the value of false.
#define FALSE 0
#endif
/// @brief Define the byte type.
typedef unsigned char byte_t;
/// @brief Define the generic size type.
typedef unsigned long size_t;
/// @brief Define the generic signed size type.
typedef long ssize_t;
/// @brief Define the type of an inode.
typedef unsigned int ino_t;
// TODO: doxygen comment.
typedef unsigned int dev_t;
/// @brief The type of user-id.
typedef unsigned int uid_t;
/// @brief The type of group-id.
typedef unsigned int gid_t;
/// @brief The type of offset.
typedef unsigned int off_t;
/// @brief The type of mode.
typedef unsigned int mode_t;
// TODO: doxygen comment.
typedef mode_t pgprot_t;
// TODO: doxygen comment.
typedef unsigned long int ulong;
// TODO: doxygen comment.
typedef unsigned short int ushort;
// TODO: doxygen comment.
typedef unsigned int uint;
// TODO: doxygen comment.
typedef int key_t;
// TODO: doxygen comment.
// Check with clock.h
typedef long __time_t;
/// MentOS, The Mentoring Operating system project
/// @file stddef.h
/// @brief Define basic data types.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#ifndef NULL
/// @brief Define NULL.
#define NULL ((void *)0)
#endif
#ifndef EOF
/// @brief Define End-Of-File.
#define EOF (-1)
#endif
/// @brief Define the size of a buffer.
#define BUFSIZ 512
/// @brief Define the size of the kernel.
#define KERNEL_SIZE 0x200
#ifndef TRUE
/// @brief Define the value of true.
#define TRUE 1
#endif
#ifndef FALSE
/// @brief Define the value of false.
#define FALSE 0
#endif
/// @brief Define the byte type.
typedef unsigned char byte_t;
/// @brief Define the generic size type.
typedef unsigned long size_t;
/// @brief Define the generic signed size type.
typedef long ssize_t;
/// @brief Define the type of an inode.
typedef unsigned int ino_t;
// TODO: doxygen comment.
typedef unsigned int dev_t;
/// @brief The type of user-id.
typedef unsigned int uid_t;
/// @brief The type of group-id.
typedef unsigned int gid_t;
/// @brief The type of offset.
typedef unsigned int off_t;
/// @brief The type of mode.
typedef unsigned int mode_t;
// TODO: doxygen comment.
typedef mode_t pgprot_t;
// TODO: doxygen comment.
typedef unsigned long int ulong;
// TODO: doxygen comment.
typedef unsigned short int ushort;
// TODO: doxygen comment.
typedef unsigned int uint;
// TODO: doxygen comment.
typedef int key_t;
// TODO: doxygen comment.
// Check with clock.h
typedef long __time_t;
+37 -37
View File
@@ -1,37 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file stdint.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Define the signed 64-bit integer.
typedef int int64_t;
/// @brief Define the unsigned 64-bit integer.
typedef unsigned int uint64_t;
/// @brief Define the signed 32-bit integer.
typedef int int32_t;
/// @brief Define the unsigned 32-bit integer.
typedef unsigned int uint32_t;
/// @brief Define the signed 16-bit integer.
typedef short int16_t;
/// @brief Define the unsigned 16-bit integer.
typedef unsigned short uint16_t;
/// @brief Define the signed 8-bit integer.
typedef char int8_t;
/// @brief Define the unsigned 8-bit integer.
typedef unsigned char uint8_t;
/// @brief Define the signed 32-bit pointer.
typedef signed intptr_t;
/// @brief Define the unsigned 32-bit pointer.
typedef unsigned uintptr_t;
/// MentOS, The Mentoring Operating system project
/// @file stdint.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Define the signed 64-bit integer.
typedef int int64_t;
/// @brief Define the unsigned 64-bit integer.
typedef unsigned int uint64_t;
/// @brief Define the signed 32-bit integer.
typedef int int32_t;
/// @brief Define the unsigned 32-bit integer.
typedef unsigned int uint32_t;
/// @brief Define the signed 16-bit integer.
typedef short int16_t;
/// @brief Define the unsigned 16-bit integer.
typedef unsigned short uint16_t;
/// @brief Define the signed 8-bit integer.
typedef char int8_t;
/// @brief Define the unsigned 8-bit integer.
typedef unsigned char uint8_t;
/// @brief Define the signed 32-bit pointer.
typedef signed intptr_t;
/// @brief Define the unsigned 32-bit pointer.
typedef unsigned uintptr_t;
+50 -50
View File
@@ -1,50 +1,50 @@
/// MentOS, The Mentoring Operating system project
/// @file stdio.h
/// @brief Standard I/0 functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdarg.h"
#include "stddef.h"
/// @brief The maximum number of digits of an integer.
#define MAX_DIGITS_IN_INTEGER 11
/// @brief The size of 'gets' buffer.
#define GETS_BUFFERSIZE 255
#ifndef EOF
/// @brief Define the End-Of-File.
#define EOF (-1)
#endif
/// @brief Writes the given character to the standard output (stdout).
void putchar(int character);
/// @brief Writes the string pointed by str to the standard output (stdout)
/// and appends a newline character ('\n').
void puts(char *str);
/// @brief Returns the next character from the standard input (stdin).
int getchar(void);
/// @brief Reads characters from the standard input (stdin) and stores them
/// as a C string into str until a newline character or the end-of-file is
/// reached.
char *gets(char *str);
/// @brief Convert the given string to an integer.
int atoi(const char *str);
/// @brief Write formatted output to stdout.
int printf(const char *, ...);
/// @brief Read formatted input from stdin.
size_t scanf(const char *, ...);
/// @brief Write formatted output to the string str from argument list ARG.
int vsprintf(char *str, const char *fmt, va_list args);
/// @brief Write formatted output to the string str.
int sprintf(char *str, const char *fmt, ...);
/// MentOS, The Mentoring Operating system project
/// @file stdio.h
/// @brief Standard I/0 functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdarg.h"
#include "stddef.h"
/// @brief The maximum number of digits of an integer.
#define MAX_DIGITS_IN_INTEGER 11
/// @brief The size of 'gets' buffer.
#define GETS_BUFFERSIZE 255
#ifndef EOF
/// @brief Define the End-Of-File.
#define EOF (-1)
#endif
/// @brief Writes the given character to the standard output (stdout).
void putchar(int character);
/// @brief Writes the string pointed by str to the standard output (stdout)
/// and appends a newline character ('\n').
void puts(char *str);
/// @brief Returns the next character from the standard input (stdin).
int getchar(void);
/// @brief Reads characters from the standard input (stdin) and stores them
/// as a C string into str until a newline character or the end-of-file is
/// reached.
char *gets(char *str);
/// @brief Convert the given string to an integer.
int atoi(const char *str);
/// @brief Write formatted output to stdout.
int printf(const char *, ...);
/// @brief Read formatted input from stdin.
size_t scanf(const char *, ...);
/// @brief Write formatted output to the string str from argument list ARG.
int vsprintf(char *str, const char *fmt, va_list args);
/// @brief Write formatted output to the string str.
int sprintf(char *str, const char *fmt, ...);
+36 -25
View File
@@ -1,25 +1,36 @@
/// MentOS, The Mentoring Operating system project
/// @file stdlib.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Malloc based on the number of elements.
void *calloc(size_t element_number, size_t element_size);
void *malloc(unsigned int size);
void free(void * p);
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31U) - 1U)
/// @brief Allows to set the seed of the random value generator.
void srand(int x);
/// @brief Generates a random value.
int rand();
/// MentOS, The Mentoring Operating system project
/// @file stdlib.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Malloc based on the number of elements.
void *calloc(size_t element_number, size_t element_size);
void *malloc(unsigned int size);
void free(void * p);
/// @brief Allocate a matrix with n rows of a specific size.
/// @param n Number of matrix rows.
/// @param size Size of each matrix row.
/// @return Matrix pointer.
void **mmalloc(size_t n, size_t size);
/// @brief Free a matrix of n rows.
/// @param src Matrix to free.
/// @param n Number of matrix rows.
void mfree(void **src, size_t n);
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31U) - 1U)
/// @brief Allows to set the seed of the random value generator.
void srand(int x);
/// @brief Generates a random value.
int rand();
+12 -12
View File
@@ -1,12 +1,12 @@
/// MentOS, The Mentoring Operating system project
/// @file strerror.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "errno.h"
// TODO: doxygen comment.
char *strerror(int errnum);
/// MentOS, The Mentoring Operating system project
/// @file strerror.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "errno.h"
// TODO: doxygen comment.
char *strerror(int errnum);
+159 -159
View File
@@ -1,159 +1,159 @@
/// MentOS, The Mentoring Operating system project
/// @file string.h
/// @brief String routines.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "stddef.h"
/// @brief Copies the first num characters of source to destination.
char *strncpy(char *destination, const char *source, size_t num);
/// @brief Compares up to n characters of s1 to those of s2.
int strncmp(const char *s1, const char *s2, size_t n);
/// @brief Case insensitive string compare.
int stricmp(const char *s1, const char *s2);
/// @brief Case-insensitively compare up to n characters of s1 to those of s2.
int strnicmp(const char *s1, const char *s2, size_t n);
/// @brief Returns a pointer to the first occurrence of ch in str.
char *strchr(const char *s, int ch);
/// @brief Returns a pointer to the last occurrence of ch in str.
char *strrchr(const char *s, int ch);
/// @brief Returns a pointer to the first occurrence of s2 in s1, or NULL if
/// s2 is not part of s1.
char *strstr(const char *s1, const char *s2);
/// @brief Returns the length of the initial portion of string which consists
/// only of characters that are part of control.
size_t strspn(const char *string, const char *control);
/// @brief Calculates the length of the initial segment of string which
/// consists entirely of characters not in control.
size_t strcspn(const char *string, const char *control);
/// @brief Finds the first character in the string string that matches any
/// character specified in control.
char *strpbrk(const char *string, const char *control);
/// @brief Make a copy of the given string.
char *strdup(const char *s);
/// @brief Make a copy of the given string.
char *kstrdup(const char *s);
/// @brief Appends the string pointed to, by s2 to the end of the string
/// pointed to, by s1 up to n characters long.
char *strncat(char *s1, const char *s2, size_t n);
/// @brief Fill the string s with the character c, to the given length n.
char *strnset(char *s, int c, size_t n);
/// @brief Fill the string s with the character c.
char *strset(char *s, int c);
/// @brief Reverse the string s.
char *strrev(char *s);
// TODO: Check behaviour & doxygen comment.
char *strtok(char *str, const char *delim);
// TODO: Check behaviour & doxygen comment.
char *strtok_r(char *string, const char *control, char **lasts);
/// @brief Another function to copy n characters from str2 to str1.
void *memmove(void *dst, const void *src, size_t n);
/// @brief Searches for the first occurrence of the character c (an unsigned
/// char) in the first n bytes of the string pointed to, by the
/// argument str.
void *memchr(const void *str, int c, size_t n);
char *strlwr(char *s);
char *strupr(char *s);
/// @brief Copies the first n bytes from memory area src to memory area dest,
/// stopping when the character c is found.
void *memccpy(void *dst, const void *src, int c, size_t n);
/// @brief Copy a block of memory, handling overlap.
/// @param _dst Pointer to the destination.
/// @param _src Pointer to the source.
/// @param num Number of bytes to be copied.
/// @return Pointer to the destination.
void *memcpy(void *_dst, const void *_src, size_t num);
/// @brief Compares the first n bytes of str1 and str2.
int memcmp(const void *str1, const void *str2, size_t n);
/// @brief Sets the first num bytes of the block of memory pointed by ptr
/// to the specified value.
/// @param ptr Pointer to the block of memory to set.
/// @param value Value to be set.
/// @param num Number of bytes to be set to the given value.
/// @return The same ptr.
void *memset(void *ptr, int value, size_t num);
/// @brief Copy the string src into the array dst.
char *strcpy(char *dst, const char *src);
/// @brief Appends a copy of the string src to the string dst.
char *strcat(char *dst, const char *src);
/// @brief Checks if the two strings are equal.
int strcmp(const char *s1, const char *s2);
/// @brief Returns the lenght of the string s.
size_t strlen(const char *s);
/// @brief Returns the number of characters inside s, excluding the
/// terminating null byte ('\0'), but at most count.
size_t strnlen(const char *s, size_t count);
/// @brief Separate a string in token according to the delimiter.
/// If str is NULL, the scanning will continue for the previous string.
/// It can be bettered.
char *strtok(char *str, const char *delim);
/// @brief Compare num characters of s2 and s1.
int _kstrncmp(const char *s1, const char *s2, size_t num);
/// @brief Removes the whitespaces in from of str.
char *trim(char *str);
/// @brief Create a copy of str.
char *strdup(const char *src);
/// @brief Separate stringp based on delim.
char *strsep(char **stringp, const char *delim);
/// @brief Split a string into list of strings.
list_t *str_split(const char *str, const char *delim, unsigned int *num);
/// @brief Reconstruct a string from list using delim as delimiter.
char *list2str(list_t *list, const char *delim);
/// @brief Move the number "num" into a string.
/// @param buffer The string containing the number.
/// @param num The number to convert.
/// @param base The base used to convert.
void int_to_str(char *buffer, unsigned int num, unsigned int base);
/// @brief Transforms num into a string.
void _knntos(char *buffer, int num, int base);
/// @brief Replaces the occurences of find with replace inside str.
char *replace_char(char *str, char find, char replace);
/// @brief Converts a file mode (the type and permission information associated
/// with an inode) into a symbolic string which is stored in the location
/// referenced by p.
void strmode(mode_t mode, char *p);
/// MentOS, The Mentoring Operating system project
/// @file string.h
/// @brief String routines.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "stddef.h"
/// @brief Copies the first num characters of source to destination.
char *strncpy(char *destination, const char *source, size_t num);
/// @brief Compares up to n characters of s1 to those of s2.
int strncmp(const char *s1, const char *s2, size_t n);
/// @brief Case insensitive string compare.
int stricmp(const char *s1, const char *s2);
/// @brief Case-insensitively compare up to n characters of s1 to those of s2.
int strnicmp(const char *s1, const char *s2, size_t n);
/// @brief Returns a pointer to the first occurrence of ch in str.
char *strchr(const char *s, int ch);
/// @brief Returns a pointer to the last occurrence of ch in str.
char *strrchr(const char *s, int ch);
/// @brief Returns a pointer to the first occurrence of s2 in s1, or NULL if
/// s2 is not part of s1.
char *strstr(const char *s1, const char *s2);
/// @brief Returns the length of the initial portion of string which consists
/// only of characters that are part of control.
size_t strspn(const char *string, const char *control);
/// @brief Calculates the length of the initial segment of string which
/// consists entirely of characters not in control.
size_t strcspn(const char *string, const char *control);
/// @brief Finds the first character in the string string that matches any
/// character specified in control.
char *strpbrk(const char *string, const char *control);
/// @brief Make a copy of the given string.
char *strdup(const char *s);
/// @brief Make a copy of the given string.
char *kstrdup(const char *s);
/// @brief Appends the string pointed to, by s2 to the end of the string
/// pointed to, by s1 up to n characters long.
char *strncat(char *s1, const char *s2, size_t n);
/// @brief Fill the string s with the character c, to the given length n.
char *strnset(char *s, int c, size_t n);
/// @brief Fill the string s with the character c.
char *strset(char *s, int c);
/// @brief Reverse the string s.
char *strrev(char *s);
// TODO: Check behaviour & doxygen comment.
char *strtok(char *str, const char *delim);
// TODO: Check behaviour & doxygen comment.
char *strtok_r(char *string, const char *control, char **lasts);
/// @brief Another function to copy n characters from str2 to str1.
void *memmove(void *dst, const void *src, size_t n);
/// @brief Searches for the first occurrence of the character c (an unsigned
/// char) in the first n bytes of the string pointed to, by the
/// argument str.
void *memchr(const void *str, int c, size_t n);
char *strlwr(char *s);
char *strupr(char *s);
/// @brief Copies the first n bytes from memory area src to memory area dest,
/// stopping when the character c is found.
void *memccpy(void *dst, const void *src, int c, size_t n);
/// @brief Copy a block of memory, handling overlap.
/// @param _dst Pointer to the destination.
/// @param _src Pointer to the source.
/// @param num Number of bytes to be copied.
/// @return Pointer to the destination.
void *memcpy(void *_dst, const void *_src, size_t num);
/// @brief Compares the first n bytes of str1 and str2.
int memcmp(const void *str1, const void *str2, size_t n);
/// @brief Sets the first num bytes of the block of memory pointed by ptr
/// to the specified value.
/// @param ptr Pointer to the block of memory to set.
/// @param value Value to be set.
/// @param num Number of bytes to be set to the given value.
/// @return The same ptr.
void *memset(void *ptr, int value, size_t num);
/// @brief Copy the string src into the array dst.
char *strcpy(char *dst, const char *src);
/// @brief Appends a copy of the string src to the string dst.
char *strcat(char *dst, const char *src);
/// @brief Checks if the two strings are equal.
int strcmp(const char *s1, const char *s2);
/// @brief Returns the lenght of the string s.
size_t strlen(const char *s);
/// @brief Returns the number of characters inside s, excluding the
/// terminating null byte ('\0'), but at most count.
size_t strnlen(const char *s, size_t count);
/// @brief Separate a string in token according to the delimiter.
/// If str is NULL, the scanning will continue for the previous string.
/// It can be bettered.
char *strtok(char *str, const char *delim);
/// @brief Compare num characters of s2 and s1.
int _kstrncmp(const char *s1, const char *s2, size_t num);
/// @brief Removes the whitespaces in from of str.
char *trim(char *str);
/// @brief Create a copy of str.
char *strdup(const char *src);
/// @brief Separate stringp based on delim.
char *strsep(char **stringp, const char *delim);
/// @brief Split a string into list of strings.
list_t *str_split(const char *str, const char *delim, unsigned int *num);
/// @brief Reconstruct a string from list using delim as delimiter.
char *list2str(list_t *list, const char *delim);
/// @brief Move the number "num" into a string.
/// @param buffer The string containing the number.
/// @param num The number to convert.
/// @param base The base used to convert.
void int_to_str(char *buffer, unsigned int num, unsigned int base);
/// @brief Transforms num into a string.
void _knntos(char *buffer, int num, int base);
/// @brief Replaces the occurences of find with replace inside str.
char *replace_char(char *str, char find, char replace);
/// @brief Converts a file mode (the type and permission information associated
/// with an inode) into a symbolic string which is stored in the location
/// referenced by p.
void strmode(mode_t mode, char *p);
+77 -77
View File
@@ -1,77 +1,77 @@
/// MentOS, The Mentoring Operating system project
/// @file tree.h
/// @brief General-purpose tree implementation.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
/// @brief A node of the tree.
typedef struct tree_node_t {
/// The value stored by the node.
void *value;
/// Pointer to the list of childrens.
list_t *children;
/// Pointer to the parent.
struct tree_node_t *parent;
} tree_node_t;
/// @brief Represents the tree.
typedef struct tree_t {
/// Number of nodes inside the tree.
size_t nodes;
/// Pointer to the root of the tree.
tree_node_t *root;
} tree_t;
typedef uint8_t (*tree_comparator_t)(void *, void *);
/// @brief Creates a new tree.
tree_t *tree_create();
/// @brief Sets the root node for a new tree.
tree_node_t *tree_set_root(tree_t *tree, void *value);
/// @brief Free the contents of a node and its children,
/// but not the nodes themselves.
void tree_node_destroy(tree_node_t *node);
/// @brief Free the contents of a tree, but not the nodes.
void tree_destroy(tree_t *tree);
/// @brief Free all of the nodes in a tree, but not their contents.
void tree_free(tree_t *tree);
/// @brief Create a new tree node pointing to the given value.
tree_node_t *tree_node_create(void *value);
/// @brief Insert a node as a child of parent.
void tree_node_insert_child_node(tree_t *tree, tree_node_t *parent,
tree_node_t *node);
/// @brief Insert a (fresh) node as a child of parent.
tree_node_t *tree_node_insert_child(tree_t *tree, tree_node_t *parent,
void *value);
/// @brief Recursive node part of tree_find_parent.
tree_node_t *tree_node_find_parent(tree_node_t *haystack, tree_node_t *needle);
/// @brief Remove a node when we know its parent; update node counts for the
/// tree.
void tree_node_parent_remove(tree_t *tree, tree_node_t *parent,
tree_node_t *node);
/// @brief Remove an entire branch given its root.
void tree_node_remove(tree_t *tree, tree_node_t *node);
/// @brief Remove this node and move its children into its parent's
/// list of children.
void tree_remove(tree_t *tree, tree_node_t *node);
// TODO: doxygen comment.
void tree_break_off(tree_t *tree, tree_node_t *node);
/// @brief Searches the given value inside the tree.
tree_node_t *tree_find(tree_t *tree, void *value, tree_comparator_t comparator);
/// MentOS, The Mentoring Operating system project
/// @file tree.h
/// @brief General-purpose tree implementation.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
/// @brief A node of the tree.
typedef struct tree_node_t {
/// The value stored by the node.
void *value;
/// Pointer to the list of childrens.
list_t *children;
/// Pointer to the parent.
struct tree_node_t *parent;
} tree_node_t;
/// @brief Represents the tree.
typedef struct tree_t {
/// Number of nodes inside the tree.
size_t nodes;
/// Pointer to the root of the tree.
tree_node_t *root;
} tree_t;
typedef uint8_t (*tree_comparator_t)(void *, void *);
/// @brief Creates a new tree.
tree_t *tree_create();
/// @brief Sets the root node for a new tree.
tree_node_t *tree_set_root(tree_t *tree, void *value);
/// @brief Free the contents of a node and its children,
/// but not the nodes themselves.
void tree_node_destroy(tree_node_t *node);
/// @brief Free the contents of a tree, but not the nodes.
void tree_destroy(tree_t *tree);
/// @brief Free all of the nodes in a tree, but not their contents.
void tree_free(tree_t *tree);
/// @brief Create a new tree node pointing to the given value.
tree_node_t *tree_node_create(void *value);
/// @brief Insert a node as a child of parent.
void tree_node_insert_child_node(tree_t *tree, tree_node_t *parent,
tree_node_t *node);
/// @brief Insert a (fresh) node as a child of parent.
tree_node_t *tree_node_insert_child(tree_t *tree, tree_node_t *parent,
void *value);
/// @brief Recursive node part of tree_find_parent.
tree_node_t *tree_node_find_parent(tree_node_t *haystack, tree_node_t *needle);
/// @brief Remove a node when we know its parent; update node counts for the
/// tree.
void tree_node_parent_remove(tree_t *tree, tree_node_t *parent,
tree_node_t *node);
/// @brief Remove an entire branch given its root.
void tree_node_remove(tree_t *tree, tree_node_t *node);
/// @brief Remove this node and move its children into its parent's
/// list of children.
void tree_remove(tree_t *tree, tree_node_t *node);
// TODO: doxygen comment.
void tree_break_off(tree_t *tree, tree_node_t *node);
/// @brief Searches the given value inside the tree.
tree_node_t *tree_find(tree_t *tree, void *value, tree_comparator_t comparator);
+25 -25
View File
@@ -1,25 +1,25 @@
/// MentOS, The Mentoring Operating system project
/// @file buddysystem.h
/// @brief Buddy System.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "zone_allocator.h"
/// @brief Allocate a block of page frames in a zone of size 2^{order.
/// @param zone A memory zone.
/// @param order The logarithm of the size of the block.
/// @return The address of the first page descriptor of the block, or NULL.
page_t *bb_alloc_pages(zone_t *zone, unsigned int order);
/// @brief Free a block of page frames in a zone of size 2^{order.
/// @param zone A memory zone.
/// @param page The address of the first page descriptor of the block.
/// @param order The logarithm of the size of the block.
void bb_free_pages(zone_t *zone, page_t *page, unsigned int order);
/// @brief Print the size of free_list of each free_area.
/// @param zone A memory zone.
void buddy_system_dump(zone_t *zone);
/// MentOS, The Mentoring Operating system project
/// @file buddysystem.h
/// @brief Buddy System.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "zone_allocator.h"
/// @brief Allocate a block of page frames in a zone of size 2^{order.
/// @param zone A memory zone.
/// @param order The logarithm of the size of the block.
/// @return The address of the first page descriptor of the block, or NULL.
page_t *bb_alloc_pages(zone_t *zone, unsigned int order);
/// @brief Free a block of page frames in a zone of size 2^{order.
/// @param zone A memory zone.
/// @param page The address of the first page descriptor of the block.
/// @param order The logarithm of the size of the block.
void bb_free_pages(zone_t *zone, page_t *page, unsigned int order);
/// @brief Print the size of free_list of each free_area.
/// @param zone A memory zone.
void buddy_system_dump(zone_t *zone);
+167 -167
View File
@@ -1,167 +1,167 @@
/// MentOS, The Mentoring Operating system project
/// @file gfp.h
/// @brief List of GFP Flags.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Type used for GFP_FLAGS.
typedef unsigned int gfp_t;
// Plain integer GFP bitmasks. Do not use this directly.
#define ___GFP_DMA 0x01u
#define ___GFP_HIGHMEM 0x02u
#define ___GFP_DMA32 0x04u
#define ___GFP_RECLAIMABLE 0x10u
#define ___GFP_HIGH 0x20u
#define ___GFP_IO 0x40u
#define ___GFP_FS 0x80u
#define ___GFP_ZERO 0x100u
#define ___GFP_ATOMIC 0x200u
#define ___GFP_DIRECT_RECLAIM 0x400u
#define ___GFP_KSWAPD_RECLAIM 0x800u
/*
* Physical address zone modifiers (see linux/mmzone.h - low four bits)
*
* Do not put any conditional on these. If necessary modify the definitions
* without the underscores and use them consistently. The definitions here may
* be used in bit comparisons.
*/
#define __GFP_DMA ___GFP_DMA
#define __GFP_HIGHMEM ___GFP_HIGHMEM
#define __GFP_DMA32 ___GFP_DMA32
#define GFP_ZONEMASK (__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32)
/**
* DOC: Watermark modifiers
*
* Watermark modifiers -- controls access to emergency reserves
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* %__GFP_HIGH indicates that the caller is high-priority and that granting
* the request is necessary before the system can make forward progress.
* For example, creating an IO context to clean pages.
*
* %__GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
* high priority. Users are typically interrupt handlers. This may be
* used in conjunction with %__GFP_HIGH
*/
#define __GFP_ATOMIC ___GFP_ATOMIC
#define __GFP_HIGH ___GFP_HIGH
/**
* DOC: Reclaim modifiers
*
* Reclaim modifiers
* ~~~~~~~~~~~~~~~~~
*
* %__GFP_IO can start physical IO.
*
* %__GFP_FS can call down to the low-level FS. Clearing the flag avoids the
* allocator recursing into the filesystem which might already be holding
* locks.
*
* %__GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
* This flag can be cleared to avoid unnecessary delays when a fallback
* option is available.
*
* %__GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
* the low watermark is reached and have it reclaim pages until the high
* watermark is reached. A caller may wish to clear this flag when fallback
* options are available and the reclaim is likely to disrupt the system. The
* canonical example is THP allocation where a fallback is cheap but
* reclaim/compaction may cause indirect stalls.
*
* %__GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
*/
#define __GFP_IO ___GFP_IO
#define __GFP_FS ___GFP_FS
// Caller can reclaim.
#define __GFP_DIRECT_RECLAIM ___GFP_DIRECT_RECLAIM
// Kswapd can wake.
#define __GFP_KSWAPD_RECLAIM ___GFP_KSWAPD_RECLAIM
#define __GFP_RECLAIM (___GFP_DIRECT_RECLAIM | ___GFP_KSWAPD_RECLAIM)
/**
* DOC: Useful GFP flag combinations
*
* Useful GFP flag combinations
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Useful GFP flag combinations that are commonly used. It is recommended
* that subsystems start with one of these combinations and then set/clear
* %__GFP_FOO flags as necessary.
*
* %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
* watermark is applied to allow access to "atomic reserves"
*
* %GFP_KERNEL is typical for kernel-internal allocations. The caller requires
* %ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
*
* %GFP_NOWAIT is for kernel allocations that should not stall for direct
* reclaim, start physical IO or use any filesystem callback.
*
* %GFP_NOIO will use direct reclaim to discard clean pages or slab pages
* that do not require the starting of any physical IO.
* Please try to avoid using this flag directly and instead use
* memalloc_noio_{save,restore} to mark the whole scope which cannot
* perform any IO with a short explanation why. All allocation requests
* will inherit GFP_NOIO implicitly.
*
* %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
* Please try to avoid using this flag directly and instead use
* memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
* recurse into the FS layer with a short explanation why. All allocation
* requests will inherit GFP_NOFS implicitly.
*
* %GFP_USER is for userspace allocations that also need to be directly
* accessibly by the kernel or hardware. It is typically used by hardware
* for buffers that are mapped to userspace (e.g. graphics) that hardware
* still must DMA to. cpuset limits are enforced for these allocations.
*
* %GFP_DMA exists for historical reasons and should be avoided where possible.
* The flags indicates that the caller requires that the lowest zone be
* used (%ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
* it would require careful auditing as some users really require it and
* others use the flag to avoid lowmem reserves in %ZONE_DMA and treat the
* lowest zone as a type of emergency reserve.
*
* %GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
* do not need to be directly accessible by the kernel but that cannot
* move once in use. An example may be a hardware allocation that maps
* data directly into userspace but has no addressing limitations.
*/
#define GFP_ATOMIC (__GFP_HIGH | __GFP_ATOMIC | __GFP_KSWAPD_RECLAIM)
#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
#define GFP_NOIO (__GFP_RECLAIM)
#define GFP_NOFS (__GFP_RECLAIM | __GFP_IO)
#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define GFP_DMA (__GFP_DMA)
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
/// MentOS, The Mentoring Operating system project
/// @file gfp.h
/// @brief List of GFP Flags.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Type used for GFP_FLAGS.
typedef unsigned int gfp_t;
// Plain integer GFP bitmasks. Do not use this directly.
#define ___GFP_DMA 0x01u
#define ___GFP_HIGHMEM 0x02u
#define ___GFP_DMA32 0x04u
#define ___GFP_RECLAIMABLE 0x10u
#define ___GFP_HIGH 0x20u
#define ___GFP_IO 0x40u
#define ___GFP_FS 0x80u
#define ___GFP_ZERO 0x100u
#define ___GFP_ATOMIC 0x200u
#define ___GFP_DIRECT_RECLAIM 0x400u
#define ___GFP_KSWAPD_RECLAIM 0x800u
/*
* Physical address zone modifiers (see linux/mmzone.h - low four bits)
*
* Do not put any conditional on these. If necessary modify the definitions
* without the underscores and use them consistently. The definitions here may
* be used in bit comparisons.
*/
#define __GFP_DMA ___GFP_DMA
#define __GFP_HIGHMEM ___GFP_HIGHMEM
#define __GFP_DMA32 ___GFP_DMA32
#define GFP_ZONEMASK (__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32)
/**
* DOC: Watermark modifiers
*
* Watermark modifiers -- controls access to emergency reserves
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* %__GFP_HIGH indicates that the caller is high-priority and that granting
* the request is necessary before the system can make forward progress.
* For example, creating an IO context to clean pages.
*
* %__GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
* high priority. Users are typically interrupt handlers. This may be
* used in conjunction with %__GFP_HIGH
*/
#define __GFP_ATOMIC ___GFP_ATOMIC
#define __GFP_HIGH ___GFP_HIGH
/**
* DOC: Reclaim modifiers
*
* Reclaim modifiers
* ~~~~~~~~~~~~~~~~~
*
* %__GFP_IO can start physical IO.
*
* %__GFP_FS can call down to the low-level FS. Clearing the flag avoids the
* allocator recursing into the filesystem which might already be holding
* locks.
*
* %__GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
* This flag can be cleared to avoid unnecessary delays when a fallback
* option is available.
*
* %__GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
* the low watermark is reached and have it reclaim pages until the high
* watermark is reached. A caller may wish to clear this flag when fallback
* options are available and the reclaim is likely to disrupt the system. The
* canonical example is THP allocation where a fallback is cheap but
* reclaim/compaction may cause indirect stalls.
*
* %__GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
*/
#define __GFP_IO ___GFP_IO
#define __GFP_FS ___GFP_FS
// Caller can reclaim.
#define __GFP_DIRECT_RECLAIM ___GFP_DIRECT_RECLAIM
// Kswapd can wake.
#define __GFP_KSWAPD_RECLAIM ___GFP_KSWAPD_RECLAIM
#define __GFP_RECLAIM (___GFP_DIRECT_RECLAIM | ___GFP_KSWAPD_RECLAIM)
/**
* DOC: Useful GFP flag combinations
*
* Useful GFP flag combinations
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Useful GFP flag combinations that are commonly used. It is recommended
* that subsystems start with one of these combinations and then set/clear
* %__GFP_FOO flags as necessary.
*
* %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
* watermark is applied to allow access to "atomic reserves"
*
* %GFP_KERNEL is typical for kernel-internal allocations. The caller requires
* %ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
*
* %GFP_NOWAIT is for kernel allocations that should not stall for direct
* reclaim, start physical IO or use any filesystem callback.
*
* %GFP_NOIO will use direct reclaim to discard clean pages or slab pages
* that do not require the starting of any physical IO.
* Please try to avoid using this flag directly and instead use
* memalloc_noio_{save,restore} to mark the whole scope which cannot
* perform any IO with a short explanation why. All allocation requests
* will inherit GFP_NOIO implicitly.
*
* %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
* Please try to avoid using this flag directly and instead use
* memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
* recurse into the FS layer with a short explanation why. All allocation
* requests will inherit GFP_NOFS implicitly.
*
* %GFP_USER is for userspace allocations that also need to be directly
* accessibly by the kernel or hardware. It is typically used by hardware
* for buffers that are mapped to userspace (e.g. graphics) that hardware
* still must DMA to. cpuset limits are enforced for these allocations.
*
* %GFP_DMA exists for historical reasons and should be avoided where possible.
* The flags indicates that the caller requires that the lowest zone be
* used (%ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
* it would require careful auditing as some users really require it and
* others use the flag to avoid lowmem reserves in %ZONE_DMA and treat the
* lowest zone as a type of emergency reserve.
*
* %GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
* do not need to be directly accessible by the kernel but that cannot
* move once in use. An example may be a hardware allocation that maps
* data directly into userspace but has no addressing limitations.
*/
#define GFP_ATOMIC (__GFP_HIGH | __GFP_ATOMIC | __GFP_KSWAPD_RECLAIM)
#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
#define GFP_NOIO (__GFP_RECLAIM)
#define GFP_NOFS (__GFP_RECLAIM | __GFP_IO)
#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define GFP_DMA (__GFP_DMA)
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
+139 -128
View File
@@ -1,128 +1,139 @@
/// MentOS, The Mentoring Operating system project
/// @file kheap.h
/// @brief Interface for kernel heap functions, also provides a placement
/// malloc() for use before the heap is initialised.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "scheduler.h"
//#define KHEAP_START (void*)(LOAD_MEMORY_ADDRESS + 0x00800000) // 0x00800000 = 8M
//#define KHEAP_MAX_ADDRESS (void*)(LOAD_MEMORY_ADDRESS + 0x0FFFFFFF) // 0x10000000 = 256 M
// M = 1024 * 1024 = 1MB
#define KHEAP_INITIAL_SIZE (4 * M)
#define UHEAP_INITIAL_SIZE (1 * M)
/**
* @brief Structure of block_t
* size: | 31 bit | 1 bit |
* | first bits of real size | free/alloc |
* To calculate the real size, set to zero the last bit
* prev: -> block_t
* next: -> block_t
**/
typedef struct block_t {
unsigned int size;
struct block_t *nextfree;
struct block_t *next;
} block_t;
/// @brief Initialize heap.
/// @param initial_size Starting size.
void kheap_init(size_t initial_size);
/// @brief Returns if the kheap is enabled.
bool_t kheap_is_enabled();
void *ksbrk(int increment);
#if 0
/// @brief Kmalloc wrapper.
/// @details When heap is not created, use a placement memory allocator, when
/// heap is created, use malloc(), the dynamic memory allocator.
/// @param size Size of memory to allocate.
/// @param align Return a page-aligned memory block.
/// @param phys Return the physical address of the memory block.
/// @return
uint32_t kmalloc_int(size_t size, bool_t align, uint32_t *phys);
/// @brief Wrapper for kmalloc, get physical address.
/// @param sz Size of memory to allocate.
/// @param phys Pointer to the variable where to place the physical address.
/// @return
void *kmalloc_p(unsigned int sz, unsigned int *phys);
/// @brief Wrapper for aligned kmalloc, get physical address.
/// @param sz Size of memory to allocate.
/// @param phys Pointer to the variable where to place the physical address.
/// @return
void *kmalloc_ap(unsigned int sz, unsigned int *phys);
#endif
/// @brief Dynamically allocates memory of the given size.
/// @param sz Size of memory to allocate.
/// @return
void *kmalloc(unsigned int sz);
/// @brief Wrapper for aligned kmalloc.
/// @param size Size of memory to allocate.
/// @return
void *kmalloc_align(size_t size);
/// @brief Dynamically allocates memory for (size * num) and memset it.
/// @param num Multiplier.
/// @param size Size of memory to allocate.
/// @return
void *kcalloc(unsigned int num, unsigned int size);
/// @brief Wrapper function for realloc.
/// @param ptr
/// @param size
/// @return
void *krealloc(void *ptr, unsigned int size);
/// @brief Wrapper function for free.
/// @param p
void kfree(void *p);
/// @brief Allocates size bytes of uninitialized storage.
//void *malloc(unsigned int size);
// We can't do a user heap brk if we don't enable paging...
void *usbrk(int increment);
/// @brief User malloc
/// @param size The size requested in byte.
/// @return The address of the allocated space.
void *umalloc(unsigned int size);
/// @brief User free
/// @param p Pointer to the space to free.
void ufree(void *p);
/// @brief Allocates size bytes of uninitialized storage with block align.
//void *malloc_align(struct vm_area_struct *heap, unsigned int size);
/// @brief Deallocates previously allocated space.
//void free(void *ptr);
/// @brief Reallocates the given area of memory. It must be still allocated
/// and not yet freed with a call to free or realloc.
/// @param ptr
/// @param size
/// @return
//void *realloc(void *ptr, unsigned int size);
/// @brief Prints the heap visually, for debug.
void kheap_dump();
/// @brief Get the pointer to the kernel heap start.
/// @return The kernel heap start pointer.
uint32_t get_kheap_start();
/// @brief Get the pointer to the kernel heap curr.
/// @return The kernel heap current pointer.
uint32_t get_kheap_curr();
/// MentOS, The Mentoring Operating system project
/// @file kheap.h
/// @brief Interface for kernel heap functions, also provides a placement
/// malloc() for use before the heap is initialised.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "scheduler.h"
//#define KHEAP_START (void*)(LOAD_MEMORY_ADDRESS + 0x00800000) // 0x00800000 = 8M
//#define KHEAP_MAX_ADDRESS (void*)(LOAD_MEMORY_ADDRESS + 0x0FFFFFFF) // 0x10000000 = 256 M
// M = 1024 * 1024 = 1MB
#define KHEAP_INITIAL_SIZE (4 * M)
#define UHEAP_INITIAL_SIZE (1 * M)
/**
* @brief Structure of block_t
* size: | 31 bit | 1 bit |
* | first bits of real size | free/alloc |
* To calculate the real size, set to zero the last bit
* prev: -> block_t
* next: -> block_t
**/
typedef struct block_t {
unsigned int size;
struct block_t *nextfree;
struct block_t *next;
} block_t;
/// @brief Initialize heap.
/// @param initial_size Starting size.
void kheap_init(size_t initial_size);
/// @brief Returns if the kheap is enabled.
bool_t kheap_is_enabled();
void *ksbrk(int increment);
#if 0
/// @brief Kmalloc wrapper.
/// @details When heap is not created, use a placement memory allocator, when
/// heap is created, use malloc(), the dynamic memory allocator.
/// @param size Size of memory to allocate.
/// @param align Return a page-aligned memory block.
/// @param phys Return the physical address of the memory block.
/// @return
uint32_t kmalloc_int(size_t size, bool_t align, uint32_t *phys);
/// @brief Wrapper for kmalloc, get physical address.
/// @param sz Size of memory to allocate.
/// @param phys Pointer to the variable where to place the physical address.
/// @return
void *kmalloc_p(unsigned int sz, unsigned int *phys);
/// @brief Wrapper for aligned kmalloc, get physical address.
/// @param sz Size of memory to allocate.
/// @param phys Pointer to the variable where to place the physical address.
/// @return
void *kmalloc_ap(unsigned int sz, unsigned int *phys);
#endif
/// @brief Dynamically allocates memory of the given size.
/// @param sz Size of memory to allocate.
/// @return
void *kmalloc(unsigned int sz);
/// @brief Wrapper for aligned kmalloc.
/// @param size Size of memory to allocate.
/// @return
void *kmalloc_align(size_t size);
/// @brief Dynamically allocates memory for (size * num) and memset it.
/// @param num Multiplier.
/// @param size Size of memory to allocate.
/// @return
void *kcalloc(unsigned int num, unsigned int size);
/// @brief Wrapper function for realloc.
/// @param ptr
/// @param size
/// @return
void *krealloc(void *ptr, unsigned int size);
/// @brief Allocate a matrix with n rows of a specific size.
/// @param n Number of matrix rows.
/// @param size Size of each matrix row.
/// @return Matrix pointer.
void **kmmalloc(size_t n, size_t size);
/// @brief Wrapper function for free.
/// @param p
void kfree(void *p);
/// @brief Free a matrix of n rows.
/// @param src Matrix to free.
/// @param n Number of matrix rows.
void kmfree(void **src, size_t n);
/// @brief Allocates size bytes of uninitialized storage.
//void *malloc(unsigned int size);
// We can't do a user heap brk if we don't enable paging...
void *usbrk(int increment);
/// @brief User malloc
/// @param size The size requested in byte.
/// @return The address of the allocated space.
void *umalloc(unsigned int size);
/// @brief User free
/// @param p Pointer to the space to free.
void ufree(void *p);
/// @brief Allocates size bytes of uninitialized storage with block align.
//void *malloc_align(struct vm_area_struct *heap, unsigned int size);
/// @brief Deallocates previously allocated space.
//void free(void *ptr);
/// @brief Reallocates the given area of memory. It must be still allocated
/// and not yet freed with a call to free or realloc.
/// @param ptr
/// @param size
/// @return
//void *realloc(void *ptr, unsigned int size);
/// @brief Prints the heap visually, for debug.
void kheap_dump();
/// @brief Get the pointer to the kernel heap start.
/// @return The kernel heap start pointer.
uint32_t get_kheap_start();
/// @brief Get the pointer to the kernel heap curr.
/// @return The kernel heap current pointer.
uint32_t get_kheap_curr();
+106 -106
View File
@@ -1,106 +1,106 @@
/// MentOS, The Mentoring Operating system project
/// @file paging.h
/// @brief Implementation of a memory paging management.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "zone_allocator.h"
#include "kernel.h"
#include "stddef.h"
/// Size of a page.
#define PAGE_SIZE 4096
/// @brief Virtual Memory Area.
/// Process segments.
struct vm_area_struct {
/// Memory descriptor associated.
struct mm_struct *vm_mm;
/// Start address of the segment.
uint32_t vm_start;
/// End address of the segment.
uint32_t vm_end;
/// Next memory area of the list.
struct vm_area_struct *vm_next;
/// Permissions.
pgprot_t vm_page_prot;
/// Flags.
unsigned short vm_flags;
/// rbtree node.
// struct rb_node vm_rb;
};
/// @brief Memory Descriptor.
/// Memory description of user process.
struct mm_struct {
/// List of memory area.
struct vm_area_struct *mmap;
// /// rbtree of memory area.
// struct rb_root mm_rb;
/// Last memory area used.
struct vm_area_struct *mmap_cache;
// ///< Process page directory.
// page_directory_t * pgd;
/// Number of memory area.
int map_count;
/// List of mm_struct.
list_head mmlist;
/// CODE.
uint32_t start_code, end_code;
/// DATA.
uint32_t start_data, end_data;
/// HEAP.
uint32_t start_brk, brk;
/// STACK.
uint32_t start_stack;
/// ARGS.
uint32_t arg_start, arg_end;
/// ENVIRONMENT.
uint32_t env_start, env_end;
/// Number of mapped pages.
unsigned int total_vm;
};
/// @brief Returns if paging is enabled.
bool_t paging_is_enabled();
/// @brief Create a Memory Descriptor.
/// @param stack_size The size of the stack in byte.
/// @return The Memory Descriptor created.
struct mm_struct *create_process_image(size_t stack_size);
/// @brief Create a virtual memory area.
/// @param mm The memory descriptor which will contain the new segment.
/// @param size The size of the segment.
/// @return The virtual address of the starting point of the segment.
uint32_t create_segment(struct mm_struct *mm, size_t size);
/// @brief Free Memory Descriptor with all the memory segment contained.
/// @param mm The Memory Descriptor to free.
void destroy_process_image(struct mm_struct *mm);
/*
* /// @brief Free a virtual memory area.
* /// @param mm The Memory Descriptor that contains the segment.
* /// @param segment The segment to free.
* void destroy_segment(struct mm_struct *mm, struct vm_area_struct *segment);
*/
/// MentOS, The Mentoring Operating system project
/// @file paging.h
/// @brief Implementation of a memory paging management.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "zone_allocator.h"
#include "kernel.h"
#include "stddef.h"
/// Size of a page.
#define PAGE_SIZE 4096
/// @brief Virtual Memory Area.
/// Process segments.
struct vm_area_struct {
/// Memory descriptor associated.
struct mm_struct *vm_mm;
/// Start address of the segment.
uint32_t vm_start;
/// End address of the segment.
uint32_t vm_end;
/// Next memory area of the list.
struct vm_area_struct *vm_next;
/// Permissions.
pgprot_t vm_page_prot;
/// Flags.
unsigned short vm_flags;
/// rbtree node.
// struct rb_node vm_rb;
};
/// @brief Memory Descriptor.
/// Memory description of user process.
struct mm_struct {
/// List of memory area.
struct vm_area_struct *mmap;
// /// rbtree of memory area.
// struct rb_root mm_rb;
/// Last memory area used.
struct vm_area_struct *mmap_cache;
// ///< Process page directory.
// page_directory_t * pgd;
/// Number of memory area.
int map_count;
/// List of mm_struct.
list_head mmlist;
/// CODE.
uint32_t start_code, end_code;
/// DATA.
uint32_t start_data, end_data;
/// HEAP.
uint32_t start_brk, brk;
/// STACK.
uint32_t start_stack;
/// ARGS.
uint32_t arg_start, arg_end;
/// ENVIRONMENT.
uint32_t env_start, env_end;
/// Number of mapped pages.
unsigned int total_vm;
};
/// @brief Returns if paging is enabled.
bool_t paging_is_enabled();
/// @brief Create a Memory Descriptor.
/// @param stack_size The size of the stack in byte.
/// @return The Memory Descriptor created.
struct mm_struct *create_process_image(size_t stack_size);
/// @brief Create a virtual memory area.
/// @param mm The memory descriptor which will contain the new segment.
/// @param size The size of the segment.
/// @return The virtual address of the starting point of the segment.
uint32_t create_segment(struct mm_struct *mm, size_t size);
/// @brief Free Memory Descriptor with all the memory segment contained.
/// @param mm The Memory Descriptor to free.
void destroy_process_image(struct mm_struct *mm);
/*
* /// @brief Free a virtual memory area.
* /// @param mm The Memory Descriptor that contains the segment.
* /// @param segment The segment to free.
* void destroy_segment(struct mm_struct *mm, struct vm_area_struct *segment);
*/
+163 -163
View File
@@ -1,163 +1,163 @@
/// MentOS, The Mentoring Operating system project
/// @file zone_allocator.h
/// @brief Implementation of the Zone Allocator
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "gfp.h"
#include "math.h"
#include "stdint.h"
#include "stdbool.h"
#include "list_head.h"
/// Max order of buddysystem blocks.
#define MAX_ORDER 11
/// @brief Buddy system descriptor: collection of free page blocks.
/// Each block represents 2^k free contiguous page.
typedef struct {
/// free_list collectes the first page descriptors of a blocks of 2^k frames
list_head free_list;
/// nr_free specifies the number of blocks of free pages.
int nr_free;
} free_area_t;
/// @brief Page descriptor. Use as a bitmap to understand
/// the order of the block and if it is free or allocated.
typedef struct {
/// Array of flags encoding also the zone number to which the page frame belongs.
unsigned long flags;
/// Page frames reference counter. -1 free, >= 0 used
int _count;
/// If the page is free, this field is used by the buddy system.
unsigned long private;
/// Contains pointers to the least recently used doubly linked list of pages.
struct list_head lru;
} page_t;
/// @brief Enumeration for zone_t.
enum zone_type {
/*
* ZONE_DMA is used when there are devices that are not able
* to do DMA to all of addressable memory (ZONE_NORMAL). Then we
* carve out the portion of memory that is needed for these devices.
* The range is arch specific.
*
* Some examples
*
* Architecture Limit
* ---------------------------
* parisc, ia64, sparc <4G
* s390 <2G
* arm Various
* alpha Unlimited or 0-16MB.
*
* i386, x86_64 and multiple other arches
* <16M.
*/
// ///< Direct memory access.
// ZONE_DMA,
/*
* Normal addressable memory is in ZONE_NORMAL. DMA operations can be
* performed on pages in ZONE_NORMAL if the DMA devices support
* transfers to all addressable memory.
*/
/// Direct mapping. Used by the kernel.
ZONE_NORMAL,
/*
* A memory area that is only addressable by the kernel through
* mapping portions into its own address space. This is for example
* used by i386 to allow the kernel to address the memory beyond
* 900MB. The kernel will set up special mappings (page
* table entries on i386) for each page that the kernel needs to
* access.
*/
/// Page tables mapping. Used by user processes.
ZONE_HIGHMEM,
__MAX_NR_ZONES
};
/// @brief Data structure to differentiate memory zone.
typedef struct {
/// Number of free pages in the zone.
unsigned long free_pages;
/// BuddySystem structure for the zone.
free_area_t free_area[MAX_ORDER];
/// Pointer to first page descriptor of the zone.
page_t *zone_mem_map;
/// Index of the first page frame of the zone.
uint32_t zone_start_pfn;
/// Zone's name.
char *name;
/// Zone's size in number of pages.
unsigned long size;
} zone_t;
/// @brief Data structure to rapresent a memory node.
/// In UMA Architecture there is only one node called
/// contig_page_data.
typedef struct {
/// Zones of the node.
zone_t node_zones[__MAX_NR_ZONES];
/// Number of zones in the node.
int nr_zones;
/// Array of pages of the node.
page_t *node_mem_map;
/// Physical address of the first page of the node.
unsigned long node_start_paddr;
/// Index on global mem_map for node_mem_map.
unsigned long node_start_mapnr;
/// Node's size in number of pages.
unsigned long node_size;
/// NID.
int node_id;
/// Pointer to the next node.
struct pglist_data *node_next;
} pg_data_t;
extern page_t *mem_map;
extern pg_data_t *contig_page_data;
/// @brief Find the nearest block's order of size greater
/// than the amount of byte.
/// @param amount The amount of byte which we want to calculate order.
/// @return The block's order greater and nearest than amount.
uint32_t find_nearest_order_greater(uint32_t amount);
/// @brief Physical memory manager initialization (page_t, zones)
/// @param mem_size Size of the memory.
bool_t pmmngr_init(uint32_t mem_size);
/// @brief Find the first free page frame, set it allocated
/// and return the memory address of the page frame.
/// @param gfp_mask GFP_FLAGS to decide the zone allocation.
/// @return Memory address of the first free block.
uint32_t __alloc_page(gfp_t gfp_mask);
/// @brief Frees the given page frame address.
/// @param addr The block address.
void free_page(uint32_t addr);
/// @brief Find the first free 2^order amount of page frames,
/// set it allocated and return the memory address of the first
/// page frame allocated.
/// @param gfp_mask GFP_FLAGS to decide the zone allocation.
/// @param order The logarithm of the size of the page frame.
/// @return Memory address of the first free page frame allocated.
uint32_t __alloc_pages(gfp_t gfp_mask, uint32_t order);
/// @brief Frees from the given page frame address up to
/// 2^order amount of page frames.
/// @param addr The page frame address.
/// @param order The logarithm of the size of the block.
void free_pages(uint32_t addr, uint32_t order);
/// @brief Get the pointer of the last byte allocated with pmmngr_init()
/// @return The pointer to the memory.
uint32_t get_memory_start();
/// MentOS, The Mentoring Operating system project
/// @file zone_allocator.h
/// @brief Implementation of the Zone Allocator
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "gfp.h"
#include "math.h"
#include "stdint.h"
#include "stdbool.h"
#include "list_head.h"
/// Max order of buddysystem blocks.
#define MAX_ORDER 11
/// @brief Buddy system descriptor: collection of free page blocks.
/// Each block represents 2^k free contiguous page.
typedef struct {
/// free_list collectes the first page descriptors of a blocks of 2^k frames
list_head free_list;
/// nr_free specifies the number of blocks of free pages.
int nr_free;
} free_area_t;
/// @brief Page descriptor. Use as a bitmap to understand
/// the order of the block and if it is free or allocated.
typedef struct {
/// Array of flags encoding also the zone number to which the page frame belongs.
unsigned long flags;
/// Page frames reference counter. -1 free, >= 0 used
int _count;
/// If the page is free, this field is used by the buddy system.
unsigned long private;
/// Contains pointers to the least recently used doubly linked list of pages.
struct list_head lru;
} page_t;
/// @brief Enumeration for zone_t.
enum zone_type {
/*
* ZONE_DMA is used when there are devices that are not able
* to do DMA to all of addressable memory (ZONE_NORMAL). Then we
* carve out the portion of memory that is needed for these devices.
* The range is arch specific.
*
* Some examples
*
* Architecture Limit
* ---------------------------
* parisc, ia64, sparc <4G
* s390 <2G
* arm Various
* alpha Unlimited or 0-16MB.
*
* i386, x86_64 and multiple other arches
* <16M.
*/
// ///< Direct memory access.
// ZONE_DMA,
/*
* Normal addressable memory is in ZONE_NORMAL. DMA operations can be
* performed on pages in ZONE_NORMAL if the DMA devices support
* transfers to all addressable memory.
*/
/// Direct mapping. Used by the kernel.
ZONE_NORMAL,
/*
* A memory area that is only addressable by the kernel through
* mapping portions into its own address space. This is for example
* used by i386 to allow the kernel to address the memory beyond
* 900MB. The kernel will set up special mappings (page
* table entries on i386) for each page that the kernel needs to
* access.
*/
/// Page tables mapping. Used by user processes.
ZONE_HIGHMEM,
__MAX_NR_ZONES
};
/// @brief Data structure to differentiate memory zone.
typedef struct {
/// Number of free pages in the zone.
unsigned long free_pages;
/// BuddySystem structure for the zone.
free_area_t free_area[MAX_ORDER];
/// Pointer to first page descriptor of the zone.
page_t *zone_mem_map;
/// Index of the first page frame of the zone.
uint32_t zone_start_pfn;
/// Zone's name.
char *name;
/// Zone's size in number of pages.
unsigned long size;
} zone_t;
/// @brief Data structure to rapresent a memory node.
/// In UMA Architecture there is only one node called
/// contig_page_data.
typedef struct {
/// Zones of the node.
zone_t node_zones[__MAX_NR_ZONES];
/// Number of zones in the node.
int nr_zones;
/// Array of pages of the node.
page_t *node_mem_map;
/// Physical address of the first page of the node.
unsigned long node_start_paddr;
/// Index on global mem_map for node_mem_map.
unsigned long node_start_mapnr;
/// Node's size in number of pages.
unsigned long node_size;
/// NID.
int node_id;
/// Pointer to the next node.
struct pglist_data *node_next;
} pg_data_t;
extern page_t *mem_map;
extern pg_data_t *contig_page_data;
/// @brief Find the nearest block's order of size greater
/// than the amount of byte.
/// @param amount The amount of byte which we want to calculate order.
/// @return The block's order greater and nearest than amount.
uint32_t find_nearest_order_greater(uint32_t amount);
/// @brief Physical memory manager initialization (page_t, zones)
/// @param mem_size Size of the memory.
bool_t pmmngr_init(uint32_t mem_size);
/// @brief Find the first free page frame, set it allocated
/// and return the memory address of the page frame.
/// @param gfp_mask GFP_FLAGS to decide the zone allocation.
/// @return Memory address of the first free block.
uint32_t __alloc_page(gfp_t gfp_mask);
/// @brief Frees the given page frame address.
/// @param addr The block address.
void free_page(uint32_t addr);
/// @brief Find the first free 2^order amount of page frames,
/// set it allocated and return the memory address of the first
/// page frame allocated.
/// @param gfp_mask GFP_FLAGS to decide the zone allocation.
/// @param order The logarithm of the size of the page frame.
/// @return Memory address of the first free page frame allocated.
uint32_t __alloc_pages(gfp_t gfp_mask, uint32_t order);
/// @brief Frees from the given page frame address up to
/// 2^order amount of page frames.
/// @param addr The page frame address.
/// @param order The logarithm of the size of the block.
void free_pages(uint32_t addr, uint32_t order);
/// @brief Get the pointer of the last byte allocated with pmmngr_init()
/// @return The pointer to the memory.
uint32_t get_memory_start();
+30 -30
View File
@@ -1,30 +1,30 @@
/// MentOS, The Mentoring Operating system project
/// @file bitops.h
/// @brief Bitmasks functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stdbool.h"
/// @brief Finds the first bit set in the given irq mask.
int find_first_bit(unsigned short int irq_mask);
/// @brief Check if the passed value has the given flag set.
/// @param flags The value to check.
/// @param flag The flag to search.
/// @return True If the value contain the flag, <br>
/// False otherwise.
bool_t has_flag(uint32_t flags, uint32_t flag);
/// @brief Set the passed flag to the value.
/// @param flags The destination value.
/// @param flag The flag to set.
void set_flag(uint32_t *flags, uint32_t flag);
/// @brief Clear the passed flag to the value.
/// @param flags The destination value.
/// @param flag The flag to clear.
void clear_flag(uint32_t *flags, uint32_t flag);
/// MentOS, The Mentoring Operating system project
/// @file bitops.h
/// @brief Bitmasks functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdint.h"
#include "stdbool.h"
/// @brief Finds the first bit set in the given irq mask.
int find_first_bit(unsigned short int irq_mask);
/// @brief Check if the passed value has the given flag set.
/// @param flags The value to check.
/// @param flag The flag to search.
/// @return True If the value contain the flag, <br>
/// False otherwise.
bool_t has_flag(uint32_t flags, uint32_t flag);
/// @brief Set the passed flag to the value.
/// @param flags The destination value.
/// @param flag The flag to set.
void set_flag(uint32_t *flags, uint32_t flag);
/// @brief Clear the passed flag to the value.
/// @param flags The destination value.
/// @param flag The flag to clear.
void clear_flag(uint32_t *flags, uint32_t flag);
+98 -98
View File
@@ -1,98 +1,98 @@
/// MentOS, The Mentoring Operating system project
/// @file clock.h
/// @brief Clock functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Used to store time values.
typedef unsigned int time_t;
/// Used to get information about the current time.
typedef struct tm_t {
/// Seconds [0 to 59]
int tm_sec;
/// Minutes [0 to 59]
int tm_min;
/// Hours [0 to 23]
int tm_hour;
/// Day of the month [1 to 31]
int tm_mday;
/// Month [0 to 11]
int tm_mon;
/// Year [since 1900]
int tm_year;
/// Day of the week [0 to 6]
int tm_wday;
/// Day in the year [0 to 365]
int tm_yday;
/// Is Daylight Saving Time.
int tm_isdst;
} tm_t;
/// Value used to retrieve the seconds.
#define SECOND_RTC 0x00
/// Value used to retrieve the minutes.
#define MINUTE_RTC 0x02
/// Value used to retrieve the hours.
#define HOUR_RTC 0x04
/// Value used to retrieve the day of the week.
#define DAY_W_RTC 0x06
/// Value used to retrieve the day of the month.
#define DAY_M_RTC 0x07
/// Value used to retrieve the month.
#define MONTH_RTC 0x08
/// Value used to retrieve the year.
#define YEAR_RTC 0x09
/// @brief Returns the milliseconds.
time_t get_millisecond();
/// @brief Returns the seconds.
time_t get_second();
/// @brief Returns the hours.
time_t get_hour();
/// @brief Returns the minutes.
time_t get_minute();
/// @brief Returns the day of the month.
time_t get_day_m();
/// @brief returns the month.
time_t get_month();
/// @brief Returns the year.
time_t get_year();
/// @brief Returns the day of the week.
time_t get_day_w();
/// @brief Returns the name of the month.
char *get_month_lng();
/// @brief Returns the name of the day.
char *get_day_lng();
/// @brief Returns the current time.
time_t time(time_t *timer);
// TODO: doxygen comment.
time_t difftime(time_t time1, time_t time2);
// TODO: doxygen comment.
void strhourminutesecond(char *dst);
// TODO: doxygen comment.
void strdaymonthyear(char *dst);
// TODO: doxygen comment.
void strdatehour(char *dst);
/// MentOS, The Mentoring Operating system project
/// @file clock.h
/// @brief Clock functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Used to store time values.
typedef unsigned int time_t;
/// Used to get information about the current time.
typedef struct tm_t {
/// Seconds [0 to 59]
int tm_sec;
/// Minutes [0 to 59]
int tm_min;
/// Hours [0 to 23]
int tm_hour;
/// Day of the month [1 to 31]
int tm_mday;
/// Month [0 to 11]
int tm_mon;
/// Year [since 1900]
int tm_year;
/// Day of the week [0 to 6]
int tm_wday;
/// Day in the year [0 to 365]
int tm_yday;
/// Is Daylight Saving Time.
int tm_isdst;
} tm_t;
/// Value used to retrieve the seconds.
#define SECOND_RTC 0x00
/// Value used to retrieve the minutes.
#define MINUTE_RTC 0x02
/// Value used to retrieve the hours.
#define HOUR_RTC 0x04
/// Value used to retrieve the day of the week.
#define DAY_W_RTC 0x06
/// Value used to retrieve the day of the month.
#define DAY_M_RTC 0x07
/// Value used to retrieve the month.
#define MONTH_RTC 0x08
/// Value used to retrieve the year.
#define YEAR_RTC 0x09
/// @brief Returns the milliseconds.
time_t get_millisecond();
/// @brief Returns the seconds.
time_t get_second();
/// @brief Returns the hours.
time_t get_hour();
/// @brief Returns the minutes.
time_t get_minute();
/// @brief Returns the day of the month.
time_t get_day_m();
/// @brief returns the month.
time_t get_month();
/// @brief Returns the year.
time_t get_year();
/// @brief Returns the day of the week.
time_t get_day_w();
/// @brief Returns the name of the month.
char *get_month_lng();
/// @brief Returns the name of the day.
char *get_day_lng();
/// @brief Returns the current time.
time_t time(time_t *timer);
// TODO: doxygen comment.
time_t difftime(time_t time1, time_t time2);
// TODO: doxygen comment.
void strhourminutesecond(char *dst);
// TODO: doxygen comment.
void strdaymonthyear(char *dst);
// TODO: doxygen comment.
void strdatehour(char *dst);
+67 -67
View File
@@ -1,67 +1,67 @@
/// MentOS, The Mentoring Operating system project
/// @file debug.h
/// @brief Debugging primitives.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "port_io.h"
/// @brief Used to enable the device. Any I/O to the debug module before this
/// command is sent will simply be ignored.
#define DBG_ENABLE 0x8A00
/// @brief Disable the I/O interface to the debugger and the memory
/// monitoring functions.
#define DBG_DISABLE 0x8AFF
/// @brief Selects register 0: Memory monitoring range start address
/// (inclusive).
#define SELECTS_REG_0 0x8A01
/// @brief Selects register 1: Memory monitoring range end address (exclusive).
#define SELECTS_REG_1 0x8A02
/// @brief Enable address range memory monitoring as indicated by register 0
/// and 1 and clears both registers.
#define ENABLE_ADDR_RANGE_MEM_MONITOR 0x8A80
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE2
/// to port 0x8A00 after the device has been enabled will enable instruction
/// tracing.
#define INSTRUCTION_TRACE_ENABLE 0x8AE3
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE2
/// to port 0x8A00 after the device has been enabled will disable instruction
/// tracing.
#define INSTRUCTION_TRACE_DISABLE 0x8AE2
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE5
/// to port 0x8A00 after the device has been enabled will enable register
/// tracing. This currently output the value of all the registers for each
/// instruction traced. Note: instruction tracing must be enabled to view
/// the register tracing.
#define REGISTER_TRACE_ENABLE 0x8AE5
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE4
/// to port 0x8A00 after the device has been enabled will disable register
/// tracing.
#define REGISTER_TRACE_DISABLE 0x8AE4
/// @brief Prints the given string to the debug output.
void _dbg_print(const char *file, const char *fun, int line, const char *msg,
...);
#define __FILENAME__ \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : \
__FILE__)
#define dbg_print(...) _dbg_print(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
/// @brief Prints the given registers to the debug output.
void print_reg(register_t *reg);
/// @brief Prints the given intrframe to the debug output.
void print_intrframe(pt_regs *frame);
/// MentOS, The Mentoring Operating system project
/// @file debug.h
/// @brief Debugging primitives.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "kernel.h"
#include "port_io.h"
/// @brief Used to enable the device. Any I/O to the debug module before this
/// command is sent will simply be ignored.
#define DBG_ENABLE 0x8A00
/// @brief Disable the I/O interface to the debugger and the memory
/// monitoring functions.
#define DBG_DISABLE 0x8AFF
/// @brief Selects register 0: Memory monitoring range start address
/// (inclusive).
#define SELECTS_REG_0 0x8A01
/// @brief Selects register 1: Memory monitoring range end address (exclusive).
#define SELECTS_REG_1 0x8A02
/// @brief Enable address range memory monitoring as indicated by register 0
/// and 1 and clears both registers.
#define ENABLE_ADDR_RANGE_MEM_MONITOR 0x8A80
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE2
/// to port 0x8A00 after the device has been enabled will enable instruction
/// tracing.
#define INSTRUCTION_TRACE_ENABLE 0x8AE3
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE2
/// to port 0x8A00 after the device has been enabled will disable instruction
/// tracing.
#define INSTRUCTION_TRACE_DISABLE 0x8AE2
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE5
/// to port 0x8A00 after the device has been enabled will enable register
/// tracing. This currently output the value of all the registers for each
/// instruction traced. Note: instruction tracing must be enabled to view
/// the register tracing.
#define REGISTER_TRACE_ENABLE 0x8AE5
/// @brief If the debugger is enabled (via --enable-debugger), sending 0x8AE4
/// to port 0x8A00 after the device has been enabled will disable register
/// tracing.
#define REGISTER_TRACE_DISABLE 0x8AE4
/// @brief Prints the given string to the debug output.
void _dbg_print(const char *file, const char *fun, int line, const char *msg,
...);
#define __FILENAME__ \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : \
__FILE__)
#define dbg_print(...) _dbg_print(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
/// @brief Prints the given registers to the debug output.
void print_reg(register_t *reg);
/// @brief Prints the given intrframe to the debug output.
void print_intrframe(pt_regs *frame);
+206 -206
View File
@@ -1,206 +1,206 @@
/// MentOS, The Mentoring Operating system project
/// @file multiboot.h
/// @brief Data structures used for multiboot.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
// Do not inc here in boot.s.
#pragma once
#include "stdint.h"
// The magic field should contain this.
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
// This should be in %eax.
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/// Is there basic lower/upper memory information?
#define MULTIBOOT_FLAG_MEM 0x00000001U
/// is there a boot device set?
#define MULTIBOOT_FLAG_DEVICE 0x00000002U
/// is the command-line defined?
#define MULTIBOOT_FLAG_CMDLINE 0x00000004U
/// are there modules to do something with?
#define MULTIBOOT_FLAG_MODS 0x00000008U
/// is there a symbol table loaded?
#define MULTIBOOT_FLAG_AOUT 0x00000010U
/// is there an ELF section header table?
#define MULTIBOOT_FLAG_ELF 0x00000020U
/// is there a full memory map?
#define MULTIBOOT_FLAG_MMAP 0x00000040U
/// Is there drive info?
#define MULTIBOOT_FLAG_DRIVE_INFO 0x00000080U
/// Is there a config table?
#define MULTIBOOT_FLAG_CONFIG_TABLE 0x00000100U
/// Is there a boot loader name?
#define MULTIBOOT_FLAG_BOOT_LOADER_NAME 0x00000200U
/// Is there a APM table?
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
/// Is there video information?
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
// +-------------------+
// 0 | flags | (required)
// +-------------------+
// 4 | mem_lower | (present if flags[0] is set)
// 8 | mem_upper | (present if flags[0] is set)
// +-------------------+
// 12 | boot_device | (present if flags[1] is set)
// +-------------------+
// 16 | cmdline | (present if flags[2] is set)
// +-------------------+
// 20 | mods_count | (present if flags[3] is set)
// 24 | mods_addr | (present if flags[3] is set)
// +-------------------+
// 28 - 40 | syms | (present if flags[4] or
// | | flags[5] is set)
// +-------------------+
// 44 | mmap_length | (present if flags[6] is set)
// 48 | mmap_addr | (present if flags[6] is set)
// +-------------------+
// 52 | drives_length | (present if flags[7] is set)
// 56 | drives_addr | (present if flags[7] is set)
// +-------------------+
// 60 | config_table | (present if flags[8] is set)
// +-------------------+
// 64 | boot_loader_name | (present if flags[9] is set)
// +-------------------+
// 68 | apm_table | (present if flags[10] is set)
// +-------------------+
// 72 | vbe_control_info | (present if flags[11] is set)
// 76 | vbe_mode_info |
// 80 | vbe_mode |
// 82 | vbe_interface_seg |
// 84 | vbe_interface_off |
// 86 | vbe_interface_len |
// +-------------------+
// 88 | framebuffer_addr | (present if flags[12] is set)
// 96 | framebuffer_pitch |
// 100 | framebuffer_width |
// 104 | framebuffer_height|
// 108 | framebuffer_bpp |
// 109 | framebuffer_type |
// 110-115 | color_info |
// +-------------------+
/// The symbol table for a.out.
typedef struct multiboot_aout_symbol_table {
uint32_t tabsize;
uint32_t strsize;
uint32_t addr;
uint32_t reserved;
} multiboot_aout_symbol_table_t;
/// The section header table for ELF.
typedef struct multiboot_elf_section_header_table {
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
} multiboot_elf_section_header_table_t;
// TODO: doxygen comment.
typedef struct multiboot_module {
// The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive.
uint32_t mod_start;
uint32_t mod_end;
// Module command line.
uint32_t cmdline;
// Padding to take it to 16 bytes (must be zero).
uint32_t pad;
} multiboot_module_t;
typedef struct multiboot_memory_map {
uint32_t size;
uint32_t base_addr_low;
uint32_t base_addr_high;
uint32_t length_low;
uint32_t length_high;
uint32_t type;
} multiboot_memory_map_t;
// TODO: doxygen comment.
typedef struct multiboot_info {
/// Multiboot info version number.
uint32_t flags;
/// Available memory from BIOS.
uint32_t mem_lower;
uint32_t mem_upper;
/// "root" partition.
uint32_t boot_device;
/// Kernel command line.
uint32_t cmdline;
/// Boot-Module list.
uint32_t mods_count;
uint32_t mods_addr;
union {
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
/// Memory Mapping buffer.
uint32_t mmap_length;
uint32_t mmap_addr;
/// Drive Info buffer.
uint32_t drives_length;
uint32_t drives_addr;
/// ROM configuration table.
uint32_t config_table;
/// Boot Loader Name.
uint32_t boot_loader_name;
/// APM table.
uint32_t apm_table;
/// Video.
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint32_t vbe_mode;
uint32_t vbe_interface_seg;
uint32_t vbe_interface_off;
uint32_t vbe_interface_len;
uint32_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint32_t framebuffer_bpp;
uint32_t framebuffer_type;
union {
struct {
uint32_t framebuffer_palette_addr;
uint16_t framebuffer_palette_num_colors;
};
struct {
uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position;
uint8_t framebuffer_green_mask_size;
uint8_t framebuffer_blue_field_position;
uint8_t framebuffer_blue_mask_size;
};
};
} __attribute__((packed)) multiboot_info_t;
// TODO: doxygen comment.
void dump_multiboot(multiboot_info_t *mboot_ptr);
/// MentOS, The Mentoring Operating system project
/// @file multiboot.h
/// @brief Data structures used for multiboot.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
// Do not inc here in boot.s.
#pragma once
#include "stdint.h"
// The magic field should contain this.
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
// This should be in %eax.
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/// Is there basic lower/upper memory information?
#define MULTIBOOT_FLAG_MEM 0x00000001U
/// is there a boot device set?
#define MULTIBOOT_FLAG_DEVICE 0x00000002U
/// is the command-line defined?
#define MULTIBOOT_FLAG_CMDLINE 0x00000004U
/// are there modules to do something with?
#define MULTIBOOT_FLAG_MODS 0x00000008U
/// is there a symbol table loaded?
#define MULTIBOOT_FLAG_AOUT 0x00000010U
/// is there an ELF section header table?
#define MULTIBOOT_FLAG_ELF 0x00000020U
/// is there a full memory map?
#define MULTIBOOT_FLAG_MMAP 0x00000040U
/// Is there drive info?
#define MULTIBOOT_FLAG_DRIVE_INFO 0x00000080U
/// Is there a config table?
#define MULTIBOOT_FLAG_CONFIG_TABLE 0x00000100U
/// Is there a boot loader name?
#define MULTIBOOT_FLAG_BOOT_LOADER_NAME 0x00000200U
/// Is there a APM table?
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
/// Is there video information?
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
// +-------------------+
// 0 | flags | (required)
// +-------------------+
// 4 | mem_lower | (present if flags[0] is set)
// 8 | mem_upper | (present if flags[0] is set)
// +-------------------+
// 12 | boot_device | (present if flags[1] is set)
// +-------------------+
// 16 | cmdline | (present if flags[2] is set)
// +-------------------+
// 20 | mods_count | (present if flags[3] is set)
// 24 | mods_addr | (present if flags[3] is set)
// +-------------------+
// 28 - 40 | syms | (present if flags[4] or
// | | flags[5] is set)
// +-------------------+
// 44 | mmap_length | (present if flags[6] is set)
// 48 | mmap_addr | (present if flags[6] is set)
// +-------------------+
// 52 | drives_length | (present if flags[7] is set)
// 56 | drives_addr | (present if flags[7] is set)
// +-------------------+
// 60 | config_table | (present if flags[8] is set)
// +-------------------+
// 64 | boot_loader_name | (present if flags[9] is set)
// +-------------------+
// 68 | apm_table | (present if flags[10] is set)
// +-------------------+
// 72 | vbe_control_info | (present if flags[11] is set)
// 76 | vbe_mode_info |
// 80 | vbe_mode |
// 82 | vbe_interface_seg |
// 84 | vbe_interface_off |
// 86 | vbe_interface_len |
// +-------------------+
// 88 | framebuffer_addr | (present if flags[12] is set)
// 96 | framebuffer_pitch |
// 100 | framebuffer_width |
// 104 | framebuffer_height|
// 108 | framebuffer_bpp |
// 109 | framebuffer_type |
// 110-115 | color_info |
// +-------------------+
/// The symbol table for a.out.
typedef struct multiboot_aout_symbol_table {
uint32_t tabsize;
uint32_t strsize;
uint32_t addr;
uint32_t reserved;
} multiboot_aout_symbol_table_t;
/// The section header table for ELF.
typedef struct multiboot_elf_section_header_table {
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
} multiboot_elf_section_header_table_t;
// TODO: doxygen comment.
typedef struct multiboot_module {
// The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive.
uint32_t mod_start;
uint32_t mod_end;
// Module command line.
uint32_t cmdline;
// Padding to take it to 16 bytes (must be zero).
uint32_t pad;
} multiboot_module_t;
typedef struct multiboot_memory_map {
uint32_t size;
uint32_t base_addr_low;
uint32_t base_addr_high;
uint32_t length_low;
uint32_t length_high;
uint32_t type;
} multiboot_memory_map_t;
// TODO: doxygen comment.
typedef struct multiboot_info {
/// Multiboot info version number.
uint32_t flags;
/// Available memory from BIOS.
uint32_t mem_lower;
uint32_t mem_upper;
/// "root" partition.
uint32_t boot_device;
/// Kernel command line.
uint32_t cmdline;
/// Boot-Module list.
uint32_t mods_count;
uint32_t mods_addr;
union {
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
/// Memory Mapping buffer.
uint32_t mmap_length;
uint32_t mmap_addr;
/// Drive Info buffer.
uint32_t drives_length;
uint32_t drives_addr;
/// ROM configuration table.
uint32_t config_table;
/// Boot Loader Name.
uint32_t boot_loader_name;
/// APM table.
uint32_t apm_table;
/// Video.
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint32_t vbe_mode;
uint32_t vbe_interface_seg;
uint32_t vbe_interface_off;
uint32_t vbe_interface_len;
uint32_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint32_t framebuffer_bpp;
uint32_t framebuffer_type;
union {
struct {
uint32_t framebuffer_palette_addr;
uint16_t framebuffer_palette_num_colors;
};
struct {
uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position;
uint8_t framebuffer_green_mask_size;
uint8_t framebuffer_blue_field_position;
uint8_t framebuffer_blue_mask_size;
};
};
} __attribute__((packed)) multiboot_info_t;
// TODO: doxygen comment.
void dump_multiboot(multiboot_info_t *mboot_ptr);
+55 -55
View File
@@ -1,55 +1,55 @@
/// MentOS, The Mentoring Operating system project
/// @file prio.h
/// @brief Defines processes priority value.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#define MAX_NICE +19
#define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
// Priority of a process goes from 0..MAX_PRIO-1, valid RT
// priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
// tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
// values are inverted: lower p->prio value means higher priority.
//
// The MAX_USER_RT_PRIO value allows the actual maximum
// RT priority to be separate from the value exported to
// user-space. This allows kernel threads to set their
// priority to a value higher than any user task.
// Note: MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
#define MAX_RT_PRIO 100
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
// Convert user-nice values [ -20 ... 0 ... 19 ]
// to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
// and back.
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio)-DEFAULT_PRIO)
// 'User priority' is the nice value converted to something we
// can work with better when scaling various scheduler parameters,
// it's a [ 0 ... 39 ] range.
#define USER_PRIO(p) ((p)-MAX_RT_PRIO)
#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
static const int prio_to_weight[NICE_WIDTH] = {
/* 100 */ 88761, 71755, 56483, 46273, 36291,
/* 105 */ 29154, 23254, 18705, 14949, 11916,
/* 110 */ 9548, 7620, 6100, 4904, 3906,
/* 115 */ 3121, 2501, 1991, 1586, 1277,
/* 120 */ 1024, 820, 655, 526, 423,
/* 125 */ 335, 272, 215, 172, 137,
/* 130 */ 110, 87, 70, 56, 45,
/* 135 */ 36, 29, 23, 18, 15
};
/// MentOS, The Mentoring Operating system project
/// @file prio.h
/// @brief Defines processes priority value.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#define MAX_NICE +19
#define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
// Priority of a process goes from 0..MAX_PRIO-1, valid RT
// priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
// tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
// values are inverted: lower p->prio value means higher priority.
//
// The MAX_USER_RT_PRIO value allows the actual maximum
// RT priority to be separate from the value exported to
// user-space. This allows kernel threads to set their
// priority to a value higher than any user task.
// Note: MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
#define MAX_RT_PRIO 100
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
// Convert user-nice values [ -20 ... 0 ... 19 ]
// to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
// and back.
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio)-DEFAULT_PRIO)
// 'User priority' is the nice value converted to something we
// can work with better when scaling various scheduler parameters,
// it's a [ 0 ... 39 ] range.
#define USER_PRIO(p) ((p)-MAX_RT_PRIO)
#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
static const int prio_to_weight[NICE_WIDTH] = {
/* 100 */ 88761, 71755, 56483, 46273, 36291,
/* 105 */ 29154, 23254, 18705, 14949, 11916,
/* 110 */ 9548, 7620, 6100, 4904, 3906,
/* 115 */ 3121, 2501, 1991, 1586, 1277,
/* 120 */ 1024, 820, 655, 526, 423,
/* 125 */ 335, 272, 215, 172, 137,
/* 130 */ 110, 87, 70, 56, 45,
/* 135 */ 36, 29, 23, 18, 15
};
+209 -203
View File
@@ -1,203 +1,209 @@
/// MentOS, The Mentoring Operating system project
/// @file process.h
/// @brief Process data structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "tree.h"
#include "clock.h"
#include "types.h"
#include "stdint.h"
#include "stddef.h"
#include "paging.h"
#include "kernel.h"
#include "unistd.h"
#include "list_head.h"
#include "signal_defs.h"
#include "limits.h"
/// The maximum length of a name for a task_struct.
#define TASK_NAME_MAX_LENGTH 100
/// The default dimension of the stack of a process (1 MByte).
#define DEFAULT_STACK_SIZE 0x100000
//==== Task state ==============================================================
// Used in tsk->state
/// The task is running.
#define TASK_RUNNING 0x0000
/// The task is interruptible.
#define TASK_INTERRUPTIBLE 0x0001
/// The task is uninterruptible.
#define TASK_UNINTERRUPTIBLE 0x0002
// Used in tsk->exit_state
/// The task is dead.
#define EXIT_DEAD 0x0010
/// The task is zombie.
#define EXIT_ZOMBIE 0x0020
//==============================================================================
/// @brief Every task_struck has a sched_entity. This structure is used to track
/// the statistics of a process. While the other variables also play a role in
/// CFS decisions'algorithm, vruntime is by far the core variable which needs
/// more attention as to understand the scheduling decision process.
/// @details
/// The nice value is a user-space and priority 'prio' is the process's actual
/// priority that use by Linux kernel. In linux system priorities are 0 to 139
/// in which 0 to 99 for real time and 100 to 139 for users.
/// The nice value range is -20 to +19 where -20 is highest, 0 default and +19
/// is lowest. relation between nice value and priority is : PR = 20 + NI.
typedef struct sched_entity {
/// Static execution priority.
int prio;
/// Start execution time.
time_t start_runtime;
/// Last context switch time.
time_t exec_start;
/// Overall execution time.
time_t sum_exec_runtime;
/// weighted execution time.
time_t vruntime;
} sched_entity;
// x86 thread (x86 and FPU registers).
typedef struct thread_struct {
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t useresp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Instruction Pointer Register.
uint32_t eip;
/// 32-bit flag register.
uint32_t eflags;
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
// ///< Code Segment.
// uint32_t cs;
// ///< Stack Segment.
// uint32_t ss;
/// Determines if the FPU is enabled.
bool_t fpu_enabled;
/// Data structure used to save FPU registers.
savefpu fpu_register;
} thread_struct;
/// @brief this is our task object. Every process in the system has this, and
/// it holds a lot of information. Itll hold mm information, its name,
/// statistics, etc..
typedef struct task_struct {
/// The pid of the process.
pid_t pid;
// -1 unrunnable, 0 runnable, >0 stopped.
/// The current state of the process:
__volatile__ long state;
/// Pointer to process's parent.
struct task_struct *parent;
/// List head for scheduling purposes.
list_head run_list;
/// List of children traced by the process.
list_head children;
/// List of siblings.
list_head sibling;
/// The context of the processors.
thread_struct thread;
/// For scheduling algorithms.
sched_entity se;
/// Exit code of the process. (parameter of _exit() system call).
int exit_code;
/// The name of the task (Added for debug purpose).
char name[TASK_NAME_MAX_LENGTH];
/// Task's segments.
struct mm_struct *mm;
/// Task's specific error number.
int error_no;
/// The current working directory.
char cwd[PATH_MAX];
//==== Future work =========================================================
// - task's attributes:
// struct task_struct __rcu *real_parent;
// int exit_state;
// int exit_signal;
// struct thread_info thread_info;
// List of sibling, namely processes created by parent process
// struct list_head sibling;
// - task's file descriptor:
// struct files_struct *files;
// - task's signal handlers:
// struct signal_struct *signal;
// struct sighand_struct *sighand;
// sigset_t blocked;
// sigset_t real_blocked;
// sigset_t saved_sigmask;
// struct sigpending pending;
//==========================================================================
} task_struct;
// TODO: doxygen comment.
char *get_current_dir_name();
/// @brief Create and spawn the init process.
struct task_struct *create_init_process();
/// MentOS, The Mentoring Operating system project
/// @file process.h
/// @brief Process data structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "list.h"
#include "tree.h"
#include "clock.h"
#include "types.h"
#include "stdint.h"
#include "stddef.h"
#include "paging.h"
#include "kernel.h"
#include "unistd.h"
#include "list_head.h"
#include "signal_defs.h"
#include "limits.h"
/// The maximum length of a name for a task_struct.
#define TASK_NAME_MAX_LENGTH 100
/// The default dimension of the stack of a process (1 MByte).
#define DEFAULT_STACK_SIZE 0x100000
/// The maximum number of resources for a task.
#define TASK_RESOURCE_MAX_AMOUNT 32
//==== Task state ==============================================================
// Used in tsk->state
/// The task is running.
#define TASK_RUNNING 0x0000
/// The task is interruptible.
#define TASK_INTERRUPTIBLE 0x0001
/// The task is uninterruptible.
#define TASK_UNINTERRUPTIBLE 0x0002
// Used in tsk->exit_state
/// The task is dead.
#define EXIT_DEAD 0x0010
/// The task is zombie.
#define EXIT_ZOMBIE 0x0020
//==============================================================================
/// @brief Every task_struck has a sched_entity. This structure is used to track
/// the statistics of a process. While the other variables also play a role in
/// CFS decisions'algorithm, vruntime is by far the core variable which needs
/// more attention as to understand the scheduling decision process.
/// @details
/// The nice value is a user-space and priority 'prio' is the process's actual
/// priority that use by Linux kernel. In linux system priorities are 0 to 139
/// in which 0 to 99 for real time and 100 to 139 for users.
/// The nice value range is -20 to +19 where -20 is highest, 0 default and +19
/// is lowest. relation between nice value and priority is : PR = 20 + NI.
typedef struct sched_entity {
/// Static execution priority.
int prio;
/// Start execution time.
time_t start_runtime;
/// Last context switch time.
time_t exec_start;
/// Overall execution time.
time_t sum_exec_runtime;
/// weighted execution time.
time_t vruntime;
} sched_entity;
// x86 thread (x86 and FPU registers).
typedef struct thread_struct {
/// 32-bit base pointer register.
uint32_t ebp;
/// 32-bit stack pointer register.
uint32_t useresp;
/// 32-bit base register.
uint32_t ebx;
/// 32-bit data register.
uint32_t edx;
/// 32-bit counter.
uint32_t ecx;
/// 32-bit accumulator register.
uint32_t eax;
/// Instruction Pointer Register.
uint32_t eip;
/// 32-bit flag register.
uint32_t eflags;
/// FS and GS have no hardware-assigned uses.
uint32_t gs;
/// FS and GS have no hardware-assigned uses.
uint32_t fs;
/// Extra Segment determined by the programmer.
uint32_t es;
/// Data Segment.
uint32_t ds;
/// 32-bit destination register.
uint32_t edi;
/// 32-bit source register.
uint32_t esi;
// ///< Code Segment.
// uint32_t cs;
// ///< Stack Segment.
// uint32_t ss;
/// Determines if the FPU is enabled.
bool_t fpu_enabled;
/// Data structure used to save FPU registers.
savefpu fpu_register;
} thread_struct;
/// @brief this is our task object. Every process in the system has this, and
/// it holds a lot of information. Itll hold mm information, its name,
/// statistics, etc..
typedef struct task_struct {
/// The pid of the process.
pid_t pid;
// -1 unrunnable, 0 runnable, >0 stopped.
/// The current state of the process:
__volatile__ long state;
/// Pointer to process's parent.
struct task_struct *parent;
/// List head for scheduling purposes.
list_head run_list;
/// List of children traced by the process.
list_head children;
/// List of siblings.
list_head sibling;
/// The context of the processors.
thread_struct thread;
/// For scheduling algorithms.
sched_entity se;
/// Exit code of the process. (parameter of _exit() system call).
int exit_code;
/// The name of the task (Added for debug purpose).
char name[TASK_NAME_MAX_LENGTH];
/// Task's segments.
struct mm_struct *mm;
/// Task's specific error number.
int error_no;
/// The current working directory.
char cwd[PATH_MAX];
/// Array of resource pointers that task need for.
struct resource *resources[TASK_RESOURCE_MAX_AMOUNT];
//==== Future work =========================================================
// - task's attributes:
// struct task_struct __rcu *real_parent;
// int exit_state;
// int exit_signal;
// struct thread_info thread_info;
// List of sibling, namely processes created by parent process
// struct list_head sibling;
// - task's file descriptor:
// struct files_struct *files;
// - task's signal handlers:
// struct signal_struct *signal;
// struct sighand_struct *sighand;
// sigset_t blocked;
// sigset_t real_blocked;
// sigset_t saved_sigmask;
// struct sigpending pending;
//==========================================================================
} task_struct;
// TODO: doxygen comment.
char *get_current_dir_name();
/// @brief Create and spawn the init process.
struct task_struct *create_init_process();
+68 -68
View File
@@ -1,68 +1,68 @@
/// MentOS, The Mentoring Operating system project
/// @file scheduler.h
/// @brief Scheduler structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "clock.h"
#include "kernel.h"
#include "stdint.h"
#include "process.h"
typedef struct {
/// Number of queued processes.
size_t num_active;
/// Queue of processes.
list_head queue;
/// The current running process.
task_struct *curr;
} runqueue_t;
/// @brief Returns a non-decreasing unique process id.
/// @return Process identifier (PID).
uint32_t get_new_pid();
/// @brief Initialize the scheduler.
void kernel_initialize_scheduler();
/// @brief Activate the given process.
/// @param process Process that has to be activated.
void enqueue_task(task_struct *process);
/// @brief Removes the given process from the queue.
/// @param process Process that has to be activated.
void dequeue_task(task_struct *process);
/// @brief Returns the number of active processes.
size_t kernel_get_active_processes();
/// @brief Returns the pointer to the current active process.
task_struct *kernel_get_current_process();
/// @brief Returns a pointer to the process with the given pid.
task_struct *kernel_get_running_process(pid_t pid);
task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec);
/// @brief The RR implementation of the scheduler.
/// @param f The context of the process.
void kernel_schedule(pt_regs *f);
/// @birief Values from pt_regs to task_struct process.
void update_context(pt_regs *f, task_struct *process);
/// @brief Values from task_struct process to pt_regs.
void do_switch(task_struct *process, pt_regs *f);
/// @brief Switch CPU to user mode and start running that given process.
/// @param process The process that has to be executed
void enter_user_jmp(uintptr_t location, uintptr_t stack);
/// @brief Sets the priority value of the given task.
int set_user_nice(task_struct *p, long nice);
/// MentOS, The Mentoring Operating system project
/// @file scheduler.h
/// @brief Scheduler structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "clock.h"
#include "kernel.h"
#include "stdint.h"
#include "process.h"
typedef struct {
/// Number of queued processes.
size_t num_active;
/// Queue of processes.
list_head queue;
/// The current running process.
task_struct *curr;
} runqueue_t;
/// @brief Returns a non-decreasing unique process id.
/// @return Process identifier (PID).
uint32_t get_new_pid();
/// @brief Initialize the scheduler.
void kernel_initialize_scheduler();
/// @brief Activate the given process.
/// @param process Process that has to be activated.
void enqueue_task(task_struct *process);
/// @brief Removes the given process from the queue.
/// @param process Process that has to be activated.
void dequeue_task(task_struct *process);
/// @brief Returns the number of active processes.
size_t kernel_get_active_processes();
/// @brief Returns the pointer to the current active process.
task_struct *kernel_get_current_process();
/// @brief Returns a pointer to the process with the given pid.
task_struct *kernel_get_running_process(pid_t pid);
task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec);
/// @brief The RR implementation of the scheduler.
/// @param f The context of the process.
void kernel_schedule(pt_regs *f);
/// @birief Values from pt_regs to task_struct process.
void update_context(pt_regs *f, task_struct *process);
/// @brief Values from task_struct process to pt_regs.
void do_switch(task_struct *process, pt_regs *f);
/// @brief Switch CPU to user mode and start running that given process.
/// @param process The process that has to be executed
void enter_user_jmp(uintptr_t location, uintptr_t stack);
/// @brief Sets the priority value of the given task.
int set_user_nice(task_struct *p, long nice);
+48 -48
View File
@@ -1,48 +1,48 @@
/// MentOS, The Mentoring Operating system project
/// @file dirent.h
/// @brief Functions used to manage directories.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "limits.h"
/// @brief Contains the entries of a directory.
typedef struct dirent_t {
/// The inode of the entry.
ino_t d_ino;
/// The type of the entry.
int d_type;
/// The nam of the entry.
char d_name[NAME_MAX + 1];
} dirent_t;
/// @brief Contains information concerning a directory.
typedef struct DIR {
/// Filesystem directory handle.
int fd;
/// The currently opened entry.
ino_t cur_entry;
/// Path to the directory.
char path[NAME_MAX + 1];
/// Next directory item.
dirent_t entry;
} DIR;
/// @brief Opens a directory and returns a handler to it.
/// @param path The path of the directory.
/// @return Pointer to the directory. Otherwise, NULL.
DIR *opendir(const char *path);
/// @brief Given a pointer to a directory, it closes it.
int closedir(DIR *dirp);
/// @brief At each call of this function, it returns a pointer to the next
/// element inside the directory.
/// @return A pointer to the next element. If there are no more elments, it
/// returns NULL.
dirent_t *readdir(DIR *dirp);
/// MentOS, The Mentoring Operating system project
/// @file dirent.h
/// @brief Functions used to manage directories.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
#include "limits.h"
/// @brief Contains the entries of a directory.
typedef struct dirent_t {
/// The inode of the entry.
ino_t d_ino;
/// The type of the entry.
int d_type;
/// The nam of the entry.
char d_name[NAME_MAX + 1];
} dirent_t;
/// @brief Contains information concerning a directory.
typedef struct DIR {
/// Filesystem directory handle.
int fd;
/// The currently opened entry.
ino_t cur_entry;
/// Path to the directory.
char path[NAME_MAX + 1];
/// Next directory item.
dirent_t entry;
} DIR;
/// @brief Opens a directory and returns a handler to it.
/// @param path The path of the directory.
/// @return Pointer to the directory. Otherwise, NULL.
DIR *opendir(const char *path);
/// @brief Given a pointer to a directory, it closes it.
int closedir(DIR *dirp);
/// @brief At each call of this function, it returns a pointer to the next
/// element inside the directory.
/// @return A pointer to the next element. If there are no more elments, it
/// returns NULL.
dirent_t *readdir(DIR *dirp);
+383 -383
View File
@@ -1,383 +1,383 @@
/// MentOS, The Mentoring Operating system project
/// @file process.c
/// @brief System call errors definition.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
extern int *__geterrno();
#define errno (*__geterrno())
/// Operation not permitted.
#define EPERM 1
/// No such file or directory.
#define ENOENT 2
/// No such process.
#define ESRCH 3
/// Interrupted system call.
#define EINTR 4
///I/O error.
#define EIO 5
/// No such device or address.
#define ENXIO 6
/// Arg list too long.
#define E2BIG 7
/// Exec format error.
#define ENOEXEC 8
/// Bad file number.
#define EBADF 9
/// No child processes.
#define ECHILD 10
/// Try again.
#define EAGAIN 11
/// Out of memory.
#define ENOMEM 12
/// Permission denied.
#define EACCES 13
/// Bad address.
#define EFAULT 14
/// Block device required.
#define ENOTBLK 15
/// Device or resource busy.
#define EBUSY 16
/// File exists.
#define EEXIST 17
/// Cross-device link.
#define EXDEV 18
/// No such device.
#define ENODEV 19
/// Not a directory.
#define ENOTDIR 20
/// Is a directory.
#define EISDIR 21
/// Invalid argument.
#define EINVAL 22
/// File table overflow.
#define ENFILE 23
/// Too many open files.
#define EMFILE 24
/// Not a typewriter.
#define ENOTTY 25
/// Text file busy.
#define ETXTBSY 26
/// File too large.
#define EFBIG 27
/// No space left on device.
#define ENOSPC 28
/// Illegal seek.
#define ESPIPE 29
/// Read-only file system.
#define EROFS 30
/// Too many links.
#define EMLINK 31
/// Broken pipe.
#define EPIPE 32
/// Math argument out of domain of func.
#define EDOM 33
/// Math result not representable.
#define ERANGE 34
/// Resource deadlock would occur.
#define EDEADLK 35
/// File name too long.
#define ENAMETOOLONG 36
/// No record locks available.
#define ENOLCK 37
/// Function not implemented.
#define ENOSYS 38
/// Directory not empty.
#define ENOTEMPTY 39
/// Too many symbolic links encountered.
#define ELOOP 40
/// Operation would block.
#define EWOULDBLOCK EAGAIN
/// No message of desired type.
#define ENOMSG 42
/// Identifier removed.
#define EIDRM 43
/// Channel number out of range.
#define ECHRNG 44
/// Level 2 not synchronized.
#define EL2NSYNC 45
/// Level 3 halted.
#define EL3HLT 46
/// Level 3 reset.
#define EL3RST 47
/// Link number out of range.
#define ELNRNG 48
/// Protocol driver not attached.
#define EUNATCH 49
/// No CSI structure available.
#define ENOCSI 50
/// Level 2 halted.
#define EL2HLT 51
/// Invalid exchange.
#define EBADE 52
/// Invalid request descriptor.
#define EBADR 53
/// Exchange full.
#define EXFULL 54
/// No anode.
#define ENOANO 55
/// Invalid request code.
#define EBADRQC 56
/// Invalid slot.
#define EBADSLT 57
// TODO: doxygen comment.
#define EDEADLOCK EDEADLK
/// Bad font file format.
#define EBFONT 59
/// Device not a stream.
#define ENOSTR 60
/// No data available.
#define ENODATA 61
/// Timer expired.
#define ETIME 62
/// Out of streams resources.
#define ENOSR 63
/// Machine is not on the network.
#define ENONET 64
/// Package not installed.
#define ENOPKG 65
/// Object is remote.
#define EREMOTE 66
/// Link has been severed.
#define ENOLINK 67
/// Advertise error.
#define EADV 68
/// Srmount error.
#define ESRMNT 69
/// Communication error on send.
#define ECOMM 70
/// Protocol error.
#define EPROTO 71
/// Multihop attempted.
#define EMULTIHOP 72
/// RFS specific error.
#define EDOTDOT 73
/// Not a data message.
#define EBADMSG 74
/// Value too large for defined data type.
#define EOVERFLOW 75
/// Name not unique on network.
#define ENOTUNIQ 76
/// File descriptor in bad state.
#define EBADFD 77
/// Remote address changed.
#define EREMCHG 78
/// Can not access a needed shared library.
#define ELIBACC 79
/// Accessing a corrupted shared library.
#define ELIBBAD 80
/// .lib section in a.out corrupted.
#define ELIBSCN 81
/// Attempting to link in too many shared libraries.
#define ELIBMAX 82
/// Cannot exec a shared library directly.
#define ELIBEXEC 83
/// Illegal byte sequence.
#define EILSEQ 84
/// Interrupted system call should be restarted.
#define ERESTART 85
/// Streams pipe error.
#define ESTRPIPE 86
/// Too many users.
#define EUSERS 87
///Socket operation on non-socket.
#define ENOTSOCK 88
/// Destination address required.
#define EDESTADDRREQ 89
/// Message too long.
#define EMSGSIZE 90
/// Protocol wrong type for socket.
#define EPROTOTYPE 91
/// Protocol not available.
#define ENOPROTOOPT 92
/// Protocol not supported.
#define EPROTONOSUPPORT 93
/// Socket type not supported.
#define ESOCKTNOSUPPORT 94
/// Operation not supported on transport endpoint.
#define EOPNOTSUPP 95
/// Protocol family not supported.
#define EPFNOSUPPORT 96
/// Address family not supported by protocol.
#define EAFNOSUPPORT 97
/// Address already in use.
#define EADDRINUSE 98
/// Cannot assign requested address.
#define EADDRNOTAVAIL 99
/// Network is down.
#define ENETDOWN 100
/// Network is unreachable.
#define ENETUNREACH 101
/// Network dropped connection because of reset.
#define ENETRESET 102
/// Software caused connection abort.
#define ECONNABORTED 103
/// Connection reset by peer.
#define ECONNRESET 104
/// No buffer space available.
#define ENOBUFS 105
/// Transport endpoint is already connected.
#define EISCONN 106
/// Transport endpoint is not connected.
#define ENOTCONN 107
/// Cannot send after transport endpoint shutdown.
#define ESHUTDOWN 108
/// Too many references: cannot splice.
#define ETOOMANYREFS 109
/// Connection timed out.
#define ETIMEDOUT 110
/// Connection refused.
#define ECONNREFUSED 111
/// Host is down.
#define EHOSTDOWN 112
/// No route to host.
#define EHOSTUNREACH 113
///Operation already in progress.
#define EALREADY 114
/// Operation now in progress.
#define EINPROGRESS 115
/// Stale NFS file handle.
#define ESTALE 116
/// Structure needs cleaning.
#define EUCLEAN 117
/// Not a XENIX named type file.
#define ENOTNAM 118
/// No XENIX semaphores available.
#define ENAVAIL 119
/// Is a named type file.
#define EISNAM 120
/// Remote I/O error.
#define EREMOTEIO 121
/// Quota exceeded.
#define EDQUOT 122
/// No medium found.
#define ENOMEDIUM 123
/// Wrong medium type.
#define EMEDIUMTYPE 124
/// MentOS, The Mentoring Operating system project
/// @file process.c
/// @brief System call errors definition.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
extern int *__geterrno();
#define errno (*__geterrno())
/// Operation not permitted.
#define EPERM 1
/// No such file or directory.
#define ENOENT 2
/// No such process.
#define ESRCH 3
/// Interrupted system call.
#define EINTR 4
///I/O error.
#define EIO 5
/// No such device or address.
#define ENXIO 6
/// Arg list too long.
#define E2BIG 7
/// Exec format error.
#define ENOEXEC 8
/// Bad file number.
#define EBADF 9
/// No child processes.
#define ECHILD 10
/// Try again.
#define EAGAIN 11
/// Out of memory.
#define ENOMEM 12
/// Permission denied.
#define EACCES 13
/// Bad address.
#define EFAULT 14
/// Block device required.
#define ENOTBLK 15
/// Device or resource busy.
#define EBUSY 16
/// File exists.
#define EEXIST 17
/// Cross-device link.
#define EXDEV 18
/// No such device.
#define ENODEV 19
/// Not a directory.
#define ENOTDIR 20
/// Is a directory.
#define EISDIR 21
/// Invalid argument.
#define EINVAL 22
/// File table overflow.
#define ENFILE 23
/// Too many open files.
#define EMFILE 24
/// Not a typewriter.
#define ENOTTY 25
/// Text file busy.
#define ETXTBSY 26
/// File too large.
#define EFBIG 27
/// No space left on device.
#define ENOSPC 28
/// Illegal seek.
#define ESPIPE 29
/// Read-only file system.
#define EROFS 30
/// Too many links.
#define EMLINK 31
/// Broken pipe.
#define EPIPE 32
/// Math argument out of domain of func.
#define EDOM 33
/// Math result not representable.
#define ERANGE 34
/// Resource deadlock would occur.
#define EDEADLK 35
/// File name too long.
#define ENAMETOOLONG 36
/// No record locks available.
#define ENOLCK 37
/// Function not implemented.
#define ENOSYS 38
/// Directory not empty.
#define ENOTEMPTY 39
/// Too many symbolic links encountered.
#define ELOOP 40
/// Operation would block.
#define EWOULDBLOCK EAGAIN
/// No message of desired type.
#define ENOMSG 42
/// Identifier removed.
#define EIDRM 43
/// Channel number out of range.
#define ECHRNG 44
/// Level 2 not synchronized.
#define EL2NSYNC 45
/// Level 3 halted.
#define EL3HLT 46
/// Level 3 reset.
#define EL3RST 47
/// Link number out of range.
#define ELNRNG 48
/// Protocol driver not attached.
#define EUNATCH 49
/// No CSI structure available.
#define ENOCSI 50
/// Level 2 halted.
#define EL2HLT 51
/// Invalid exchange.
#define EBADE 52
/// Invalid request descriptor.
#define EBADR 53
/// Exchange full.
#define EXFULL 54
/// No anode.
#define ENOANO 55
/// Invalid request code.
#define EBADRQC 56
/// Invalid slot.
#define EBADSLT 57
// TODO: doxygen comment.
#define EDEADLOCK EDEADLK
/// Bad font file format.
#define EBFONT 59
/// Device not a stream.
#define ENOSTR 60
/// No data available.
#define ENODATA 61
/// Timer expired.
#define ETIME 62
/// Out of streams resources.
#define ENOSR 63
/// Machine is not on the network.
#define ENONET 64
/// Package not installed.
#define ENOPKG 65
/// Object is remote.
#define EREMOTE 66
/// Link has been severed.
#define ENOLINK 67
/// Advertise error.
#define EADV 68
/// Srmount error.
#define ESRMNT 69
/// Communication error on send.
#define ECOMM 70
/// Protocol error.
#define EPROTO 71
/// Multihop attempted.
#define EMULTIHOP 72
/// RFS specific error.
#define EDOTDOT 73
/// Not a data message.
#define EBADMSG 74
/// Value too large for defined data type.
#define EOVERFLOW 75
/// Name not unique on network.
#define ENOTUNIQ 76
/// File descriptor in bad state.
#define EBADFD 77
/// Remote address changed.
#define EREMCHG 78
/// Can not access a needed shared library.
#define ELIBACC 79
/// Accessing a corrupted shared library.
#define ELIBBAD 80
/// .lib section in a.out corrupted.
#define ELIBSCN 81
/// Attempting to link in too many shared libraries.
#define ELIBMAX 82
/// Cannot exec a shared library directly.
#define ELIBEXEC 83
/// Illegal byte sequence.
#define EILSEQ 84
/// Interrupted system call should be restarted.
#define ERESTART 85
/// Streams pipe error.
#define ESTRPIPE 86
/// Too many users.
#define EUSERS 87
///Socket operation on non-socket.
#define ENOTSOCK 88
/// Destination address required.
#define EDESTADDRREQ 89
/// Message too long.
#define EMSGSIZE 90
/// Protocol wrong type for socket.
#define EPROTOTYPE 91
/// Protocol not available.
#define ENOPROTOOPT 92
/// Protocol not supported.
#define EPROTONOSUPPORT 93
/// Socket type not supported.
#define ESOCKTNOSUPPORT 94
/// Operation not supported on transport endpoint.
#define EOPNOTSUPP 95
/// Protocol family not supported.
#define EPFNOSUPPORT 96
/// Address family not supported by protocol.
#define EAFNOSUPPORT 97
/// Address already in use.
#define EADDRINUSE 98
/// Cannot assign requested address.
#define EADDRNOTAVAIL 99
/// Network is down.
#define ENETDOWN 100
/// Network is unreachable.
#define ENETUNREACH 101
/// Network dropped connection because of reset.
#define ENETRESET 102
/// Software caused connection abort.
#define ECONNABORTED 103
/// Connection reset by peer.
#define ECONNRESET 104
/// No buffer space available.
#define ENOBUFS 105
/// Transport endpoint is already connected.
#define EISCONN 106
/// Transport endpoint is not connected.
#define ENOTCONN 107
/// Cannot send after transport endpoint shutdown.
#define ESHUTDOWN 108
/// Too many references: cannot splice.
#define ETOOMANYREFS 109
/// Connection timed out.
#define ETIMEDOUT 110
/// Connection refused.
#define ECONNREFUSED 111
/// Host is down.
#define EHOSTDOWN 112
/// No route to host.
#define EHOSTUNREACH 113
///Operation already in progress.
#define EALREADY 114
/// Operation now in progress.
#define EINPROGRESS 115
/// Stale NFS file handle.
#define ESTALE 116
/// Structure needs cleaning.
#define EUCLEAN 117
/// Not a XENIX named type file.
#define ENOTNAM 118
/// No XENIX semaphores available.
#define ENAVAIL 119
/// Is a named type file.
#define EISNAM 120
/// Remote I/O error.
#define EREMOTEIO 121
/// Quota exceeded.
#define EDQUOT 122
/// No medium found.
#define ENOMEDIUM 123
/// Wrong medium type.
#define EMEDIUMTYPE 124
+53 -53
View File
@@ -1,53 +1,53 @@
/// MentOS, The Mentoring Operating system project
/// @file ipc.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Create key if key does not exist.
#define IPC_CREAT 01000
/// Fail if key exists.
#define IPC_EXCL 02000
/// Return error on wait.
#define IPC_NOWAIT 04000
/// Remove identifier.
#define IPC_RMID 0
/// Set `ipc_perm' options.
#define IPC_SET 1
/// Get `ipc_perm' options.
#define IPC_STAT 2
/// See ipcs.
#define IPC_INFO 3
struct ipc_perm {
/// Creator user id.
uid_t cuid;
/// Creator group id.
gid_t cgid;
/// User id.
uid_t uid;
/// Group id.
gid_t gid;
/// r/w permission.
ushort mode;
/// Sequence # (to generate unique msg/sem/shm id).
ushort seq;
/// User specified msg/sem/shm key.
key_t key;
};
/// MentOS, The Mentoring Operating system project
/// @file ipc.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// Create key if key does not exist.
#define IPC_CREAT 01000
/// Fail if key exists.
#define IPC_EXCL 02000
/// Return error on wait.
#define IPC_NOWAIT 04000
/// Remove identifier.
#define IPC_RMID 0
/// Set `ipc_perm' options.
#define IPC_SET 1
/// Get `ipc_perm' options.
#define IPC_STAT 2
/// See ipcs.
#define IPC_INFO 3
struct ipc_perm {
/// Creator user id.
uid_t cuid;
/// Creator group id.
gid_t cgid;
/// User id.
uid_t uid;
/// Group id.
gid_t gid;
/// r/w permission.
ushort mode;
/// Sequence # (to generate unique msg/sem/shm id).
ushort seq;
/// User specified msg/sem/shm key.
key_t key;
};
+7 -7
View File
@@ -1,7 +1,7 @@
/// MentOS, The Mentoring Operating system project
/// @file module.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// MentOS, The Mentoring Operating system project
/// @file module.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
+43 -43
View File
@@ -1,43 +1,43 @@
/// MentOS, The Mentoring Operating system project
/// @file reboot.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC1 0xfee1dead
#define LINUX_REBOOT_MAGIC2 672274793
#define LINUX_REBOOT_MAGIC2A 85072278
#define LINUX_REBOOT_MAGIC2B 369367448
#define LINUX_REBOOT_MAGIC2C 537993216
// Commands accepted by the _reboot() system call.
/// Restart system using default command and mode.
#define LINUX_REBOOT_CMD_RESTART 0x01234567
/// Stop OS and give system control to ROM monitor, if any.
#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
/// Ctrl-Alt-Del sequence causes RESTART command.
#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
/// Ctrl-Alt-Del sequence sends SIGINT to init task.
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
/// Stop OS and remove all power from system, if possible.
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
/// Restart system using given command string.
#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
/// Suspend system using software suspend if compiled in.
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
/// Restart system using a previously loaded Linux kernel
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
/// MentOS, The Mentoring Operating system project
/// @file reboot.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// Magic values required to use _reboot() system call.
#define LINUX_REBOOT_MAGIC1 0xfee1dead
#define LINUX_REBOOT_MAGIC2 672274793
#define LINUX_REBOOT_MAGIC2A 85072278
#define LINUX_REBOOT_MAGIC2B 369367448
#define LINUX_REBOOT_MAGIC2C 537993216
// Commands accepted by the _reboot() system call.
/// Restart system using default command and mode.
#define LINUX_REBOOT_CMD_RESTART 0x01234567
/// Stop OS and give system control to ROM monitor, if any.
#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
/// Ctrl-Alt-Del sequence causes RESTART command.
#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
/// Ctrl-Alt-Del sequence sends SIGINT to init task.
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
/// Stop OS and remove all power from system, if possible.
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
/// Restart system using given command string.
#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
/// Suspend system using software suspend if compiled in.
#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
/// Restart system using a previously loaded Linux kernel
#define LINUX_REBOOT_CMD_KEXEC 0x45584543
+132 -132
View File
@@ -1,132 +1,132 @@
/// MentOS, The Mentoring Operating system project
/// @file shm.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "ipc.h"
#include "debug.h"
#include "clock.h"
#include "kheap.h"
#include "stddef.h"
#include "paging.h"
#include "syscall.h"
#include "scheduler.h"
//======== Permission flag for shmget ==========================================
// or S_IRUGO from <linux/stat.h>.
#define SHM_R 0400
// or S_IWUGO from <linux/stat.h>.
#define SHM_W 0200
//==============================================================================
//======== Flags for shmat =====================================================
// Attach read-only else read-write.
#define SHM_RDONLY 010000
// Round attach address to SHMLBA.
#define SHM_RND 020000
// Take-over region on attach.
#define SHM_REMAP 040000
// Execution access.
#define SHM_EXEC 0100000
//==============================================================================
//======== Commands for shmctl =================================================
// Lock segment (root only).
#define SHM_LOCK 11
// Unlock segment (root only).
#define SHM_UNLOCK 12
//==============================================================================
// Ipcs ctl commands.
#define SHM_STAT 13
#define SHM_INFO 14
#define SHM_STAT_ANY 15
//======== shm_mode upper byte flags ===========================================
// segment will be destroyed on last detach.
#define SHM_DEST 01000
// Segment will not be swapped.
#define SHM_LOCKED 02000
// Segment is mapped via hugetlb.
#define SHM_HUGETLB 04000
// Don't check for reservations.
#define SHM_NORESERVE 010000
typedef unsigned long shmatt_t;
struct shmid_ds {
// Operation permission struct.
struct ipc_perm shm_perm;
// Size of segment in bytes.
size_t shm_segsz;
// Time of last shmat().
time_t shm_atime;
// Time of last shmdt().
time_t shm_dtime;
// Time of last change by shmctl().
time_t shm_ctime;
// Pid of creator.
pid_t shm_cpid;
// Pid of last shmop.
pid_t shm_lpid;
// Number of current attaches.
shmatt_t shm_nattch;
struct shmid_ds *next;
// Where shm created is memorized, should be a file.
void *shm_location;
};
/// @@brief Syscall Service Routine: Shared memory control operation.
int syscall_shmctl(int *args);
/// @@brief Syscall Service Routine: Get shared memory segment.
int syscall_shmget(int *args);
/// @@brief Syscall Service Routine: Attach shared memory segment.
void *syscall_shmat(int *args);
/// @@brief Syscall Service Routine: Detach shared memory segment.
int syscall_shmdt(int *args);
/// @@brief User Wrapper: Shared memory control operation.
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
/// @@brief User Wrapper: Get shared memory segment.
int shmget(key_t key, size_t size, int flags);
/// @@brief User Wrapper: Attach shared memory segment.
void *shmat(int shmid, void *shmaddr, int flag);
/// @@brief User Wrapper: Detach shared memory segment.
int shmdt(void *shmaddr);
/// @@brief Find shmid_ds on list.
struct shmid_ds *find_shm_fromid(int shmid);
/// @@brief Find shmid_ds on list.
struct shmid_ds *find_shm_fromkey(key_t key);
/// @@brief shmid_ds on list.
struct shmid_ds *find_shm_fromvaddr(void *shmvaddr);
/// MentOS, The Mentoring Operating system project
/// @file shm.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "ipc.h"
#include "debug.h"
#include "clock.h"
#include "kheap.h"
#include "stddef.h"
#include "paging.h"
#include "syscall.h"
#include "scheduler.h"
//======== Permission flag for shmget ==========================================
// or S_IRUGO from <linux/stat.h>.
#define SHM_R 0400
// or S_IWUGO from <linux/stat.h>.
#define SHM_W 0200
//==============================================================================
//======== Flags for shmat =====================================================
// Attach read-only else read-write.
#define SHM_RDONLY 010000
// Round attach address to SHMLBA.
#define SHM_RND 020000
// Take-over region on attach.
#define SHM_REMAP 040000
// Execution access.
#define SHM_EXEC 0100000
//==============================================================================
//======== Commands for shmctl =================================================
// Lock segment (root only).
#define SHM_LOCK 11
// Unlock segment (root only).
#define SHM_UNLOCK 12
//==============================================================================
// Ipcs ctl commands.
#define SHM_STAT 13
#define SHM_INFO 14
#define SHM_STAT_ANY 15
//======== shm_mode upper byte flags ===========================================
// segment will be destroyed on last detach.
#define SHM_DEST 01000
// Segment will not be swapped.
#define SHM_LOCKED 02000
// Segment is mapped via hugetlb.
#define SHM_HUGETLB 04000
// Don't check for reservations.
#define SHM_NORESERVE 010000
typedef unsigned long shmatt_t;
struct shmid_ds {
// Operation permission struct.
struct ipc_perm shm_perm;
// Size of segment in bytes.
size_t shm_segsz;
// Time of last shmat().
time_t shm_atime;
// Time of last shmdt().
time_t shm_dtime;
// Time of last change by shmctl().
time_t shm_ctime;
// Pid of creator.
pid_t shm_cpid;
// Pid of last shmop.
pid_t shm_lpid;
// Number of current attaches.
shmatt_t shm_nattch;
struct shmid_ds *next;
// Where shm created is memorized, should be a file.
void *shm_location;
};
/// @@brief Syscall Service Routine: Shared memory control operation.
int syscall_shmctl(int *args);
/// @@brief Syscall Service Routine: Get shared memory segment.
int syscall_shmget(int *args);
/// @@brief Syscall Service Routine: Attach shared memory segment.
void *syscall_shmat(int *args);
/// @@brief Syscall Service Routine: Detach shared memory segment.
int syscall_shmdt(int *args);
/// @@brief User Wrapper: Shared memory control operation.
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
/// @@brief User Wrapper: Get shared memory segment.
int shmget(key_t key, size_t size, int flags);
/// @@brief User Wrapper: Attach shared memory segment.
void *shmat(int shmid, void *shmaddr, int flag);
/// @@brief User Wrapper: Detach shared memory segment.
int shmdt(void *shmaddr);
/// @@brief Find shmid_ds on list.
struct shmid_ds *find_shm_fromid(int shmid);
/// @@brief Find shmid_ds on list.
struct shmid_ds *find_shm_fromkey(key_t key);
/// @@brief shmid_ds on list.
struct shmid_ds *find_shm_fromvaddr(void *shmvaddr);
+41 -41
View File
@@ -1,41 +1,41 @@
/// MentOS, The Mentoring Operating system project
/// @file stat.h
/// @brief Stat functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "clock.h"
#include "stddef.h"
/// @brief Data structure which contains information about a file.
typedef struct stat_t
{
/// ID of device containing file.
dev_t st_dev;
/// Fle serial number.
ino_t st_ino;
/// Mode of file.
mode_t st_mode;
/// User id del file.
uid_t st_uid;
/// Group id del file.
gid_t st_gid;
/// Dimensione del file.
off_t st_size;
/// Time of last access.
time_t st_atime;
/// Time of last data modification.
time_t st_mtime;
/// Time of last status change.
time_t st_ctime;
} stat_t;
/// @brief Retrieves information about the file at the given location.
/// @param path The file descriptor of the file that is being inquired.
/// @param buf A structure where data about the file will be stored.
/// @return Returns a negative value on failure.
int stat(const char *path, stat_t *buf);
int mkdir(const char *path, mode_t mode);
/// MentOS, The Mentoring Operating system project
/// @file stat.h
/// @brief Stat functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "clock.h"
#include "stddef.h"
/// @brief Data structure which contains information about a file.
typedef struct stat_t
{
/// ID of device containing file.
dev_t st_dev;
/// Fle serial number.
ino_t st_ino;
/// Mode of file.
mode_t st_mode;
/// User id del file.
uid_t st_uid;
/// Group id del file.
gid_t st_gid;
/// Dimensione del file.
off_t st_size;
/// Time of last access.
time_t st_atime;
/// Time of last data modification.
time_t st_mtime;
/// Time of last status change.
time_t st_ctime;
} stat_t;
/// @brief Retrieves information about the file at the given location.
/// @param path The file descriptor of the file that is being inquired.
/// @param buf A structure where data about the file will be stored.
/// @return Returns a negative value on failure.
int stat(const char *path, stat_t *buf);
int mkdir(const char *path, mode_t mode);
+67 -67
View File
@@ -1,67 +1,67 @@
/// MentOS, The Mentoring Operating system project
/// @file types.h
/// @brief Collection of Kernel datatype
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// The type of process id.
typedef signed int pid_t;
/// The type of process user variable.
typedef unsigned int user_t;
/// The type of process status.
typedef unsigned int status_t;
/// Defines the list of flags of a process.
typedef enum eflags_list {
/// Carry flag.
EFLAG_CF = (1 << 0),
/// Parity flag.
EFLAG_PF = (1 << 2),
/// Auxiliary carry flag.
EFLAG_AF = (1 << 4),
/// Zero flag.
EFLAG_ZF = (1 << 6),
/// Sign flag.
EFLAG_SF = (1 << 7),
/// Trap flag.
EFLAG_TF = (1 << 8),
/// Interrupt enable flag.
EFLAG_IF = (1 << 9),
/// Direction flag.
EFLAG_DF = (1 << 10),
/// Overflow flag.
EFLAG_OF = (1 << 11),
/// Nested task flag.
EFLAG_NT = (1 << 14),
/// Resume flag.
EFLAG_RF = (1 << 16),
/// Virtual 8086 mode flag.
EFLAG_VM = (1 << 17),
/// Alignment check flag (486+).
EFLAG_AC = (1 << 18),
/// Virutal interrupt flag.
EFLAG_VIF = (1 << 19),
/// Virtual interrupt pending flag.
EFLAG_VIP = (1 << 20),
/// ID flag.
EFLAG_ID = (1 << 21),
} eflags_list;
/// MentOS, The Mentoring Operating system project
/// @file types.h
/// @brief Collection of Kernel datatype
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// The type of process id.
typedef signed int pid_t;
/// The type of process user variable.
typedef unsigned int user_t;
/// The type of process status.
typedef unsigned int status_t;
/// Defines the list of flags of a process.
typedef enum eflags_list {
/// Carry flag.
EFLAG_CF = (1 << 0),
/// Parity flag.
EFLAG_PF = (1 << 2),
/// Auxiliary carry flag.
EFLAG_AF = (1 << 4),
/// Zero flag.
EFLAG_ZF = (1 << 6),
/// Sign flag.
EFLAG_SF = (1 << 7),
/// Trap flag.
EFLAG_TF = (1 << 8),
/// Interrupt enable flag.
EFLAG_IF = (1 << 9),
/// Direction flag.
EFLAG_DF = (1 << 10),
/// Overflow flag.
EFLAG_OF = (1 << 11),
/// Nested task flag.
EFLAG_NT = (1 << 14),
/// Resume flag.
EFLAG_RF = (1 << 16),
/// Virtual 8086 mode flag.
EFLAG_VM = (1 << 17),
/// Alignment check flag (486+).
EFLAG_AC = (1 << 18),
/// Virutal interrupt flag.
EFLAG_VIF = (1 << 19),
/// Virtual interrupt pending flag.
EFLAG_VIP = (1 << 20),
/// ID flag.
EFLAG_ID = (1 << 21),
} eflags_list;
+95 -95
View File
@@ -1,95 +1,95 @@
/// MentOS, The Mentoring Operating system project
/// @file unistd.h
/// @brief Functions used to manage files.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "types.h"
#include "stddef.h"
//======== Standard file descriptors ===========================================
/// Standard input.
#define STDIN_FILENO -3
/// Standard output.
#define STDOUT_FILENO -2
/// Standard error output.
#define STDERR_FILENO -1
//==============================================================================
/// Maximum number of opened file.
#define MAX_OPEN_FD 4
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t write(int fd, void *buf, size_t nbytes);
/// @brief Opens the file specified by pathname.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer for
/// use in subsequent system calls.
int open(const char *pathname, int flags, mode_t mode);
/// @brief Close a file descriptor.
/// @param fd The file descriptor.
/// @return The result of the operation.
int close(int fd);
/// @brief Removes the given directory.
/// @param path The path to the directory to remove.
/// @return
int rmdir(const char *path);
/// @brief Wrapper for exit system call.
extern void exit(int status);
/// @brief Return the process identifier of the calling process.
/// @return pid_t process identifier.
extern pid_t getpid();
/// @brief Clone the calling process, but without copying the whole address space.
/// The calling process is suspended until the new process exits or is
/// replaced by a call to `execve'. Return -1 for errors, 0 to the new
/// process, and the process ID of the new process to the old process.
/// @return
extern pid_t vfork();
/// @brief Replaces the current process image with a new process image.
/// @param path The path to the binary file to execute.
/// @param argv The list of arguments.
/// @param envp
/// @return
extern int execve(const char *path, char *const argv[], char *const envp[]);
/// @brief Adds inc to the nice value for the calling thread.
/// @param inc The value to add to the nice.
/// @return On success, the new nice value is returned. On error, -1 is
/// returned, and errno is set appropriately.
int nice(int inc);
/// @brief Reboot system call.
/// @param cmd
/// @param arg
/// @return
int reboot(int magic1, int magic2, unsigned int cmd, void *arg);
void getcwd(char *path, size_t size);
void chdir(char const *path);
/// MentOS, The Mentoring Operating system project
/// @file unistd.h
/// @brief Functions used to manage files.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "types.h"
#include "stddef.h"
//======== Standard file descriptors ===========================================
/// Standard input.
#define STDIN_FILENO -3
/// Standard output.
#define STDOUT_FILENO -2
/// Standard error output.
#define STDERR_FILENO -1
//==============================================================================
/// Maximum number of opened file.
#define MAX_OPEN_FD 4
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t write(int fd, void *buf, size_t nbytes);
/// @brief Opens the file specified by pathname.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer for
/// use in subsequent system calls.
int open(const char *pathname, int flags, mode_t mode);
/// @brief Close a file descriptor.
/// @param fd The file descriptor.
/// @return The result of the operation.
int close(int fd);
/// @brief Removes the given directory.
/// @param path The path to the directory to remove.
/// @return
int rmdir(const char *path);
/// @brief Wrapper for exit system call.
extern void exit(int status);
/// @brief Return the process identifier of the calling process.
/// @return pid_t process identifier.
extern pid_t getpid();
/// @brief Clone the calling process, but without copying the whole address space.
/// The calling process is suspended until the new process exits or is
/// replaced by a call to `execve'. Return -1 for errors, 0 to the new
/// process, and the process ID of the new process to the old process.
/// @return
extern pid_t vfork();
/// @brief Replaces the current process image with a new process image.
/// @param path The path to the binary file to execute.
/// @param argv The list of arguments.
/// @param envp
/// @return
extern int execve(const char *path, char *const argv[], char *const envp[]);
/// @brief Adds inc to the nice value for the calling thread.
/// @param inc The value to add to the nice.
/// @return On success, the new nice value is returned. On error, -1 is
/// returned, and errno is set appropriately.
int nice(int inc);
/// @brief Reboot system call.
/// @param cmd
/// @param arg
/// @return
int reboot(int magic1, int magic2, unsigned int cmd, void *arg);
void getcwd(char *path, size_t size);
void chdir(char const *path);
+28 -28
View File
@@ -1,28 +1,28 @@
/// MentOS, The Mentoring Operating system project
/// @file utsname.h
/// @brief Functions used to provide information about the machine & OS.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Maximum length of the string used by utsname.
#define SYS_LEN 257
/// @brief Holds information concerning the machine and the os.
typedef struct utsname_t {
/// The name of the system.
char sysname[SYS_LEN];
/// The name of the node.
char nodename[SYS_LEN];
/// The version of the OS.
char version[SYS_LEN];
/// The name of the machine.
char machine[SYS_LEN];
} utsname_t;
/// @brief Sets the values of os_infos.
int uname(utsname_t *os_infos);
/// MentOS, The Mentoring Operating system project
/// @file utsname.h
/// @brief Functions used to provide information about the machine & OS.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// Maximum length of the string used by utsname.
#define SYS_LEN 257
/// @brief Holds information concerning the machine and the os.
typedef struct utsname_t {
/// The name of the system.
char sysname[SYS_LEN];
/// The name of the node.
char nodename[SYS_LEN];
/// The version of the OS.
char version[SYS_LEN];
/// The name of the machine.
char machine[SYS_LEN];
} utsname_t;
/// @brief Sets the values of os_infos.
int uname(utsname_t *os_infos);
+60 -60
View File
@@ -1,60 +1,60 @@
/// MentOS, The Mentoring Operating system project
/// @file wait.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "types.h"
/// @brief Return immediately if no child is there to be waited for.
#define WNOHANG 0x00000001
/// @brief Return for children that are stopped, and whose status has not
/// been reported.
#define WUNTRACED 0x00000002
/// @brief returns true if the child process exited because of a signal that
/// was not caught.
#define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
/// @brief returns true if the child process that caused the return is
/// currently stopped; this is only possible if the call was done using
/// WUNTRACED().
#define WIFSTOPPED(status) (((status)&0xff) == 0x7f)
/// @brief evaluates to the least significant eight bits of the return code
/// of the child that terminated, which may have been set as the argument
/// to a call to exit() or as the argument for a return statement in the
/// main program. This macro can only be evaluated if WIFEXITED()
/// returned nonzero.
#define WEXITSTATUS(status) (((status)&0xff00) >> 8)
/// @brief returns the number of the signal that caused the child process to
/// terminate. This macro can only be evaluated if WIFSIGNALED() returned
/// nonzero.
#define WTERMSIG(status) ((status)&0x7f)
/// @brief Is nonzero if the child exited normally.
#define WIFEXITED(status) (WTERMSIG(status) == 0)
/// @brief returns the number of the signal that caused the child to stop.
/// This macro can only be evaluated if WIFSTOPPED() returned nonzero.
#define WSTOPSIG(status) (WEXITSTATUS(status))
extern pid_t wait(int *status);
/// @brief Suspends the execution of the calling thread until a child
/// specified by pid argument has changed state.
/// @details
/// By default, waitpid() waits only for terminated children, but this
/// behavior is modifiable via the options argument, as described below.
/// The value of pid can be:
/// - 1 meaning wait for any child process.
/// 0 meaning wait for any child process whose process group ID is
/// equal to that of the calling process.
/// > 0 meaning wait for the child whose process ID is equal to the
/// value of pid.
/// @return On error, -1 is returned.
extern pid_t waitpid(pid_t pid, int *status, int options);
/// MentOS, The Mentoring Operating system project
/// @file wait.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "types.h"
/// @brief Return immediately if no child is there to be waited for.
#define WNOHANG 0x00000001
/// @brief Return for children that are stopped, and whose status has not
/// been reported.
#define WUNTRACED 0x00000002
/// @brief returns true if the child process exited because of a signal that
/// was not caught.
#define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
/// @brief returns true if the child process that caused the return is
/// currently stopped; this is only possible if the call was done using
/// WUNTRACED().
#define WIFSTOPPED(status) (((status)&0xff) == 0x7f)
/// @brief evaluates to the least significant eight bits of the return code
/// of the child that terminated, which may have been set as the argument
/// to a call to exit() or as the argument for a return statement in the
/// main program. This macro can only be evaluated if WIFEXITED()
/// returned nonzero.
#define WEXITSTATUS(status) (((status)&0xff00) >> 8)
/// @brief returns the number of the signal that caused the child process to
/// terminate. This macro can only be evaluated if WIFSIGNALED() returned
/// nonzero.
#define WTERMSIG(status) ((status)&0x7f)
/// @brief Is nonzero if the child exited normally.
#define WIFEXITED(status) (WTERMSIG(status) == 0)
/// @brief returns the number of the signal that caused the child to stop.
/// This macro can only be evaluated if WIFSTOPPED() returned nonzero.
#define WSTOPSIG(status) (WEXITSTATUS(status))
extern pid_t wait(int *status);
/// @brief Suspends the execution of the calling thread until a child
/// specified by pid argument has changed state.
/// @details
/// By default, waitpid() waits only for terminated children, but this
/// behavior is modifiable via the options argument, as described below.
/// The value of pid can be:
/// - 1 meaning wait for any child process.
/// 0 meaning wait for any child process whose process group ID is
/// equal to that of the calling process.
/// > 0 meaning wait for the child whose process ID is equal to the
/// value of pid.
/// @return On error, -1 is returned.
extern pid_t waitpid(pid_t pid, int *status, int options);
+12 -12
View File
@@ -1,12 +1,12 @@
/// MentOS, The Mentoring Operating system project
/// @file panic.h
/// @brief Functions used to manage kernel panic.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Prints the given message and then safely stop the execution of
/// the kernel.
/// @param msg The message that has to be shown.
void kernel_panic(const char *msg);
/// MentOS, The Mentoring Operating system project
/// @file panic.h
/// @brief Functions used to manage kernel panic.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Prints the given message and then safely stop the execution of
/// the kernel.
/// @param msg The message that has to be shown.
void kernel_panic(const char *msg);
+10 -10
View File
@@ -1,10 +1,10 @@
/// MentOS, The Mentoring Operating system project
/// @file printk.c
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Write formatted output to stdout.
void printk(const char *, ...);
/// MentOS, The Mentoring Operating system project
/// @file printk.c
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
/// @brief Write formatted output to stdout.
void printk(const char *, ...);
+121 -121
View File
@@ -1,121 +1,121 @@
/// MentOS, The Mentoring Operating system project
/// @file signal_defs.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
// Signal names (from the Unix specification on signals)
/// Hangup.
#define SIGHUP 1
/// Interupt.
#define SIGINT 2
/// Quit.
#define SIGQUIT 3
/// Illegal instruction.
#define SIGILL 4
/// A breakpoint or trace instruction has been reached.
#define SIGTRAP 5
/// Another process has requested that you abort.
#define SIGABRT 6
/// Emulation trap XXX.
#define SIGEMT 7
/// Floating-point arithmetic exception.
#define SIGFPE 8
/// You have been stabbed repeated with a large knife.
#define SIGKILL 9
/// Bus error (device error).
#define SIGBUS 10
/// Segmentation fault.
#define SIGSEGV 11
/// Bad system call.
#define SIGSYS 12
/// Attempted to read or write from a broken pipe.
#define SIGPIPE 13
/// This is your wakeup call.
#define SIGALRM 14
/// You have been Schwarzenegger'd.
#define SIGTERM 15
/// User Defined Signal #1.
#define SIGUSR1 16
/// User Defined Signal #2.
#define SIGUSR2 17
/// Child status report.
#define SIGCHLD 18
/// We need moar powah!.
#define SIGPWR 19
/// Your containing terminal has changed size.
#define SIGWINCH 20
/// An URGENT! event (On a socket).
#define SIGURG 21
/// XXX OBSOLETE; socket i/o possible.
#define SIGPOLL 22
/// Stopped (signal).
#define SIGSTOP 23
/// ^Z (suspend).
#define SIGTSTP 24
/// Unsuspended (please, continue).
#define SIGCONT 25
/// TTY input has stopped.
#define SIGTTIN 26
/// TTY output has stopped.
#define SIGTTOUT 27
/// Virtual timer has expired.
#define SIGVTALRM 28
/// Profiling timer expired.
#define SIGPROF 29
/// CPU time limit exceeded.
#define SIGXCPU 30
/// File size limit exceeded.
#define SIGXFSZ 31
/// Herp.
#define SIGWAITING 32
/// Die in a fire.
#define SIGDIAF 33
/// The sending process does not like you.
#define SIGHATE 34
/// Window server event.
#define SIGWINEVENT 35
/// Everybody loves cats.
#define SIGCAT 36
#define SIGTTOU 37
#define NUMSIGNALS 38
#define NSIG NUMSIGNALS
/// MentOS, The Mentoring Operating system project
/// @file signal_defs.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
// Signal names (from the Unix specification on signals)
/// Hangup.
#define SIGHUP 1
/// Interupt.
#define SIGINT 2
/// Quit.
#define SIGQUIT 3
/// Illegal instruction.
#define SIGILL 4
/// A breakpoint or trace instruction has been reached.
#define SIGTRAP 5
/// Another process has requested that you abort.
#define SIGABRT 6
/// Emulation trap XXX.
#define SIGEMT 7
/// Floating-point arithmetic exception.
#define SIGFPE 8
/// You have been stabbed repeated with a large knife.
#define SIGKILL 9
/// Bus error (device error).
#define SIGBUS 10
/// Segmentation fault.
#define SIGSEGV 11
/// Bad system call.
#define SIGSYS 12
/// Attempted to read or write from a broken pipe.
#define SIGPIPE 13
/// This is your wakeup call.
#define SIGALRM 14
/// You have been Schwarzenegger'd.
#define SIGTERM 15
/// User Defined Signal #1.
#define SIGUSR1 16
/// User Defined Signal #2.
#define SIGUSR2 17
/// Child status report.
#define SIGCHLD 18
/// We need moar powah!.
#define SIGPWR 19
/// Your containing terminal has changed size.
#define SIGWINCH 20
/// An URGENT! event (On a socket).
#define SIGURG 21
/// XXX OBSOLETE; socket i/o possible.
#define SIGPOLL 22
/// Stopped (signal).
#define SIGSTOP 23
/// ^Z (suspend).
#define SIGTSTP 24
/// Unsuspended (please, continue).
#define SIGCONT 25
/// TTY input has stopped.
#define SIGTTIN 26
/// TTY output has stopped.
#define SIGTTOUT 27
/// Virtual timer has expired.
#define SIGVTALRM 28
/// Profiling timer expired.
#define SIGPROF 29
/// CPU time limit exceeded.
#define SIGXCPU 30
/// File size limit exceeded.
#define SIGXFSZ 31
/// Herp.
#define SIGWAITING 32
/// Die in a fire.
#define SIGDIAF 33
/// The sending process does not like you.
#define SIGHATE 34
/// Window server event.
#define SIGWINEVENT 35
/// Everybody loves cats.
#define SIGCAT 36
#define SIGTTOU 37
#define NUMSIGNALS 38
#define NSIG NUMSIGNALS
+83 -83
View File
@@ -1,84 +1,84 @@
/// MentOS, The Mentoring Operating system project
/// @file syscall.h
/// @brief System Call handler definition.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "syscall_types.h"
#include "kernel.h"
#include "dirent.h"
#include "types.h"
#include "stat.h"
/// @brief Initialize the system calls.
void syscall_init();
/// @brief Handler for the system calls.
void syscall_handler(pt_regs *r);
/// The exit() function causes normal process termination.
void sys_exit(int exit_code);
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t sys_read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t sys_write(int fd, void *buf, size_t nbytes);
/// @brief Given a pathname for a file, open() returns a file
/// descriptor, a small, nonnegative integer for use in
/// subsequent system calls.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer
/// for use in subsequent system calls.
int sys_open(const char *pathname, int flags, mode_t mode);
/// @brief
/// @param fd
/// @return
int sys_close(int fd);
/// @brief Suspends execution of the calling thread until a child specified
/// by pid argument has changed state.
pid_t sys_waitpid(pid_t pid, int *status, int options);
/// @brief Replaces the current process image with a new process image.
int sys_execve(pt_regs *r);
void sys_chdir(char const *path);
/// Returns the process ID (PID) of the calling process.
pid_t sys_getpid();
/// @brief Adds the increment to the priority value of the task.
int sys_nice(int increment);
/// Returns the parent process ID (PPID) of the calling process.
pid_t sys_getppid();
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
void sys_getcwd(char *path, size_t size);
/// @brief Create a child process.
pid_t sys_vfork(pt_regs *r);
int sys_stat(const char *path, stat_t *buf);
int sys_mkdir(const char *path, mode_t mode);
/// MentOS, The Mentoring Operating system project
/// @file syscall.h
/// @brief System Call handler definition.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "syscall_types.h"
#include "kernel.h"
#include "dirent.h"
#include "types.h"
#include "stat.h"
/// @brief Initialize the system calls.
void syscall_init();
/// @brief Handler for the system calls.
void syscall_handler(pt_regs *r);
/// The exit() function causes normal process termination.
void sys_exit(int exit_code);
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t sys_read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t sys_write(int fd, void *buf, size_t nbytes);
/// @brief Given a pathname for a file, open() returns a file
/// descriptor, a small, nonnegative integer for use in
/// subsequent system calls.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer
/// for use in subsequent system calls.
int sys_open(const char *pathname, int flags, mode_t mode);
/// @brief
/// @param fd
/// @return
int sys_close(int fd);
/// @brief Suspends execution of the calling thread until a child specified
/// by pid argument has changed state.
pid_t sys_waitpid(pid_t pid, int *status, int options);
/// @brief Replaces the current process image with a new process image.
int sys_execve(pt_regs *r);
void sys_chdir(char const *path);
/// Returns the process ID (PID) of the calling process.
pid_t sys_getpid();
/// @brief Adds the increment to the priority value of the task.
int sys_nice(int increment);
/// Returns the parent process ID (PPID) of the calling process.
pid_t sys_getppid();
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
void sys_getcwd(char *path, size_t size);
/// @brief Create a child process.
pid_t sys_vfork(pt_regs *r);
int sys_stat(const char *path, stat_t *buf);
int sys_mkdir(const char *path, mode_t mode);
dirent_t *sys_readdir(DIR *dirp);
+232 -220
View File
@@ -1,220 +1,232 @@
/// MentOS, The Mentoring Operating system project
/// @file syscall_number.h
/// @brief System Call numbers.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// Return result in eax ("=a").
// System call number in eax ("a").
#define DEFN_SYSCALL0(__res, num) \
__asm__ __volatile__("INT $0x80" : "=a"(__res) : "a"(num))
// Return result in eax ("=a").
// System call number in eax ("a").
// p1 in ebx ("+b").
#define DEFN_SYSCALL1(__res, num, p1) \
__asm__ __volatile__("INT $0x80" : "=a"(__res), "+b"(p1) : "a"(num))
#define DEFN_SYSCALL2(__res, num, p1, p2) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2) \
: "a"(num));
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \
: "a"(num))
#define DEFN_SYSCALL4(__res, num, p1, p2, p3, p4) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), "+S"(p4) \
: "a"(num))
#define DEFN_SYSCALL5(__res, num, p1, p2, p3, p4, p5) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), \
"+S"(p4), "+D"(p5) \
: "a"(num))
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_oldumount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_access 33
#define __NR_nice 34
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount 52
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_setpgid 57
#define __NR_olduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_newstat 106
#define __NR_newlstat 107
#define __NR_newfstat 108
#define __NR_uname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86old 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_newuname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR_llseek 140
#define __NR_getdents 141
#define __NR_select 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR_sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_vm86 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread 180
#define __NR_pwrite 181
#define __NR_chown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_vfork 188
#define __NR_free 189 // TODO: remove me!
#define SYSCALL_NUMBER 190
/// MentOS, The Mentoring Operating system project
/// @file syscall_number.h
/// @brief System Call numbers.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// Return result in eax ("=a").
// System call number in eax ("a").
#define DEFN_SYSCALL0(__res, num) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res) \
: "a"(num))
// Return result in eax ("=a").
// System call number in eax ("a").
// p1 in ebx ("+b").
#define DEFN_SYSCALL1(__res, num, p1) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1) \
: "a"(num))
#define DEFN_SYSCALL2(__res, num, p1, p2) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2) \
: "a"(num));
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \
: "a"(num))
#define DEFN_SYSCALL4(__res, num, p1, p2, p3, p4) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), "+S"(p4) \
: "a"(num))
#define DEFN_SYSCALL5(__res, num, p1, p2, p3, p4, p5) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), \
"+S"(p4), "+D"(p5) \
: "a"(num))
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_oldumount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_access 33
#define __NR_nice 34
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount 52
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_setpgid 57
#define __NR_olduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_newstat 106
#define __NR_newlstat 107
#define __NR_newfstat 108
#define __NR_uname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86old 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_newuname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR_llseek 140
#define __NR_getdents 141
#define __NR_select 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR_sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_vm86 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread 180
#define __NR_pwrite 181
#define __NR_chown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_vfork 188
#define __NR_free 189 // TODO: remove me!
/*
#define __NR_sem_... 190
#define __NR_sem_... 191
#define __NR_sem_... 192
#define __NR_sem_... 193
#define __NR_sem_... 194
*/
#define SYSCALL_NUMBER 195
+96 -93
View File
@@ -1,93 +1,96 @@
/// MentOS, The Mentoring Operating system project
/// @file commands.h
/// @brief Prototypes of functions for the Shell.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "shell.h"
/// @brief Prints the logo.
void cmd_logo(int argc, char **argv);
/// @brief Returns the list of commands.
void cmd_help(int argc, char **argv);
/// @brief Echos the given message.
void cmd_echo(int argc, char **argv);
/// @brief Power off the machine.
void cmd_poweroff(int argc, char **argv);
/// @brief Call the uname function.
void cmd_uname(int argc, char **argv);
/// @brief Prints the credits.
void cmd_credits(int argc, char **argv);
/// @brief Sleeps the thread of the shell for a given period of time.
void cmd_sleep(int argc, char **argv);
/// @brief Shows the output of the cpuid function.
void cmd_cpuid(int argc, char **argv);
/// @brief Lists the directory.
void cmd_ls(int argc, char **argv);
/// @brief Move to another directory.
void cmd_cd(int argc, char **argv);
/// @brief Creates a new directory.
void cmd_mkdir(int argc, char **argv);
/// @brief Removes a file.
void cmd_rm(int argc, char **argv);
/// @brief Removes a directory.
void cmd_rmdir(int argc, char **argv);
/// @brief Show the current user name.
void cmd_whoami(int argc, char **argv);
/// @brief Allows to test some functionalities of the kernel.
void cmd_tester(int argc, char **argv);
/// @brief Print current working directory.
void cmd_pwd(int argc, char **argv);
/// @brief Read content of a file.
void cmd_more(int argc, char **argv);
/// @brief Create a new file.
void cmd_touch(int argc, char **argv);
/// @brief Create a new file.
void cmd_newfile(int argc, char **argv);
/// @brief Show task list.
void cmd_ps(int argc, char **argv);
/// @brief Show date and time.
void cmd_date(int argc, char **argv);
/// @brief Clears the screen.
void cmd_clear(int argc, char **argv);
/// @brief Shows the PID of the shell.
void cmd_showpid(int argc, char **argv);
/// @brief Prints the history.
void cmd_show_history(int argc, char **argv);
/// @brief Loads the drivers.
void cmd_drv_load(int argc, char **argv);
/// @brief Show IPC state.
void cmd_ipcs(int argc, char **argv);
/// @brief Remove IPC resorce from id.
void cmd_ipcrm(int argc, char **argv);
/// @brief Change the nice value.
void cmd_nice(int argc, char **argv);
/// MentOS, The Mentoring Operating system project
/// @file commands.h
/// @brief Prototypes of functions for the Shell.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "shell.h"
/// @brief Prints the logo.
void cmd_logo(int argc, char **argv);
/// @brief Returns the list of commands.
void cmd_help(int argc, char **argv);
/// @brief Echos the given message.
void cmd_echo(int argc, char **argv);
/// @brief Power off the machine.
void cmd_poweroff(int argc, char **argv);
/// @brief Call the uname function.
void cmd_uname(int argc, char **argv);
/// @brief Prints the credits.
void cmd_credits(int argc, char **argv);
/// @brief Sleeps the thread of the shell for a given period of time.
void cmd_sleep(int argc, char **argv);
/// @brief Shows the output of the cpuid function.
void cmd_cpuid(int argc, char **argv);
/// @brief Lists the directory.
void cmd_ls(int argc, char **argv);
/// @brief Move to another directory.
void cmd_cd(int argc, char **argv);
/// @brief Creates a new directory.
void cmd_mkdir(int argc, char **argv);
/// @brief Removes a file.
void cmd_rm(int argc, char **argv);
/// @brief Removes a directory.
void cmd_rmdir(int argc, char **argv);
/// @brief Show the current user name.
void cmd_whoami(int argc, char **argv);
/// @brief Allows to test some functionalities of the kernel.
void cmd_tester(int argc, char **argv);
/// @brief Print current working directory.
void cmd_pwd(int argc, char **argv);
/// @brief Read content of a file.
void cmd_more(int argc, char **argv);
/// @brief Create a new file.
void cmd_touch(int argc, char **argv);
/// @brief Create a new file.
void cmd_newfile(int argc, char **argv);
/// @brief Show task list.
void cmd_ps(int argc, char **argv);
/// @brief Show date and time.
void cmd_date(int argc, char **argv);
/// @brief Clears the screen.
void cmd_clear(int argc, char **argv);
/// @brief Shows the PID of the shell.
void cmd_showpid(int argc, char **argv);
/// @brief Prints the history.
void cmd_show_history(int argc, char **argv);
/// @brief Loads the drivers.
void cmd_drv_load(int argc, char **argv);
/// @brief Show IPC state.
void cmd_ipcs(int argc, char **argv);
/// @brief Remove IPC resorce from id.
void cmd_ipcrm(int argc, char **argv);
/// @brief Change the nice value.
void cmd_nice(int argc, char **argv);
/// @brief Test deadlock behavior with tasks and shared resources.
void cmd_deadlock(int argc, char **argv);
+10 -10
View File
@@ -1,10 +1,10 @@
/// MentOS, The Mentoring Operating system project
/// @file init.h
/// @brief Scheduler structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// TODO: doxygen comment.
int main_init();
/// MentOS, The Mentoring Operating system project
/// @file init.h
/// @brief Scheduler structures and functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// TODO: doxygen comment.
int main_init();

Some files were not shown because too many files have changed in this diff Show More