Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cbc8e8a61 | |||
| 13441daa37 |
+68
-22
@@ -61,6 +61,54 @@ else()
|
|||||||
set(CMAKE_LINKER ld)
|
set(CMAKE_LINKER ld)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Enable the assembly language.
|
||||||
|
enable_language(ASM)
|
||||||
|
# Find the NASM compiler.
|
||||||
|
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
||||||
|
# Mark the variable ASM_COMPILER as advanced.
|
||||||
|
mark_as_advanced(ASM_COMPILER)
|
||||||
|
# Check that we have found the compiler.
|
||||||
|
if(NOT ASM_COMPILER)
|
||||||
|
message(FATAL_ERROR "ASM compiler not found!")
|
||||||
|
endif(NOT ASM_COMPILER)
|
||||||
|
|
||||||
|
# Set the assembly compiler flags.
|
||||||
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32")
|
||||||
|
# Warning flags.
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
||||||
|
# Disable some specific warnings.
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
|
||||||
|
# Set the compiler options.
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
||||||
|
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} -fno-pic")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffreestanding")
|
||||||
|
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||||
|
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||||
|
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# COMPILATION
|
# COMPILATION
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -135,8 +183,8 @@ set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -drive file=${CMAKE_BINARY_DIR}/rootfs.img,
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
qemu
|
qemu
|
||||||
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
||||||
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -kernel ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin
|
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -kernel ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS kernel_bootloader.bin
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -147,17 +195,17 @@ add_custom_target(
|
|||||||
# executables.
|
# executables.
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
gdbinit
|
gdbinit
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit ${CMAKE_BINARY_DIR}/gdb.run
|
BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
# Create the generic gdb configuration.
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND echo "add-symbol-file ${CMAKE_BINARY_DIR}/mentos/kernel.bin" > ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND echo "add-symbol-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/tests/test_* >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND ls -1 ${CMAKE_BINARY_DIR}/programs/tests/test_* | sed 's/^/add-symbol-file /' >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/prog_* >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND ls -1 ${CMAKE_BINARY_DIR}/programs/prog_* | sed 's/^/add-symbol-file /' >> ${CMAKE_BINARY_DIR}/.gdbinit
|
|
||||||
COMMAND echo "break boot.c: boot_main" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND echo "break boot.c: boot_main" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND echo "break kernel.c: kmain" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND echo "break kernel.c: kmain" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
# Create the GDB connection file.
|
# Create the GDB connection file.
|
||||||
COMMAND echo "target remote localhost:1234" > ${CMAKE_BINARY_DIR}/gdb.run
|
COMMAND echo "target remote localhost:1234" > ${CMAKE_BINARY_DIR}/gdb.run
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
|
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel.bin
|
||||||
DEPENDS all_programs
|
DEPENDS all_programs
|
||||||
DEPENDS all_tests
|
DEPENDS all_tests
|
||||||
DEPENDS libc
|
DEPENDS libc
|
||||||
@@ -169,17 +217,15 @@ add_custom_target(
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
qemu-gdb
|
qemu-gdb
|
||||||
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
||||||
COMMAND echo ""
|
COMMAND echo "\n\n"
|
||||||
COMMAND echo "Now, QEMU has loaded the kernel, and it is waiting that you"
|
COMMAND echo "Now, QEMU has loaded the kernel, and it is waiting that you\n"
|
||||||
COMMAND echo "remotely connect to it. To start debugging, open a new shell"
|
COMMAND echo "remotely connect to it. To start debugging, open a new shell\n"
|
||||||
COMMAND echo "in THIS same folder, and just type:"
|
COMMAND echo "in THIS same folder, and just type :\n"
|
||||||
COMMAND echo " gdb --quiet --command=gdb.run"
|
COMMAND printf " cgdb -q -iex %q" "add-auto-load-safe-path ."
|
||||||
COMMAND echo "or if you want to use cgdb, type:"
|
COMMAND echo "\n\n"
|
||||||
COMMAND echo " cgdb --quiet --command=gdb.run"
|
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -s -S -kernel ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
COMMAND echo ""
|
DEPENDS kernel_bootloader.bin
|
||||||
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -s -S -kernel ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin
|
DEPENDS .gdbinit
|
||||||
DEPENDS kernel-bootloader.bin
|
|
||||||
DEPENDS gdbinit
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -190,9 +236,9 @@ add_custom_target(
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
cdrom.iso
|
cdrom.iso
|
||||||
COMMAND cp -rf ${CMAKE_SOURCE_DIR}/iso .
|
COMMAND cp -rf ${CMAKE_SOURCE_DIR}/iso .
|
||||||
COMMAND cp ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin ${CMAKE_BINARY_DIR}/iso/boot
|
COMMAND cp ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin ${CMAKE_BINARY_DIR}/iso/boot
|
||||||
COMMAND grub-mkrescue -o ${CMAKE_BINARY_DIR}/cdrom.iso ${CMAKE_BINARY_DIR}/iso
|
COMMAND grub-mkrescue -o ${CMAKE_BINARY_DIR}/cdrom.iso ${CMAKE_BINARY_DIR}/iso
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS kernel_bootloader.bin
|
||||||
)
|
)
|
||||||
|
|
||||||
# This third target runs the emualtor, but this time, the kernel binary file is
|
# This third target runs the emualtor, but this time, the kernel binary file is
|
||||||
|
|||||||
+67
-145
@@ -1,148 +1,70 @@
|
|||||||
# =============================================================================
|
# Add the libc library.
|
||||||
# Author: Enrico Fraccaroli
|
add_library(libc
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/stdio.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/ctype.c
|
||||||
# Set the minimum required version of cmake.
|
${PROJECT_SOURCE_DIR}/libc/src/string.c
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
${PROJECT_SOURCE_DIR}/libc/src/stdlib.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/math.c
|
||||||
# Initialize the project.
|
${PROJECT_SOURCE_DIR}/libc/src/fcvt.c
|
||||||
project(libc C ASM)
|
${PROJECT_SOURCE_DIR}/libc/src/time.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/strerror.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/termios.c
|
||||||
# ASSEMBLY
|
${PROJECT_SOURCE_DIR}/libc/src/libgen.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/vsprintf.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/vscanf.c
|
||||||
# Enable the assembly language.
|
${PROJECT_SOURCE_DIR}/libc/src/pwd.c
|
||||||
enable_language(ASM)
|
${PROJECT_SOURCE_DIR}/libc/src/grp.c
|
||||||
# Find the NASM compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/sched.c
|
||||||
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
${PROJECT_SOURCE_DIR}/libc/src/readline.c
|
||||||
# Mark the variable ASM_COMPILER as advanced.
|
${PROJECT_SOURCE_DIR}/libc/src/setenv.c
|
||||||
mark_as_advanced(ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/assert.c
|
||||||
# Check that we have found the compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/abort.c
|
||||||
if(NOT ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/io/mm_io.c
|
||||||
message(FATAL_ERROR "ASM compiler not found!")
|
${PROJECT_SOURCE_DIR}/libc/src/io/debug.c
|
||||||
endif(NOT ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/sys/ipc.c
|
||||||
# Set the asm compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/sys/unistd.c
|
||||||
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
|
${PROJECT_SOURCE_DIR}/libc/src/sys/errno.c
|
||||||
# Set the assembly compiler flags.
|
${PROJECT_SOURCE_DIR}/libc/src/sys/utsname.c
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
${PROJECT_SOURCE_DIR}/libc/src/sys/mman.c
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O0 -F dwarf -o <OBJECT> <SOURCE>")
|
${PROJECT_SOURCE_DIR}/libc/src/sys/ioctl.c
|
||||||
else()
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/creat.c
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O3 -o <OBJECT> <SOURCE>")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getppid.c
|
||||||
endif()
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpid.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/exit.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setsid.c
|
||||||
# C WARNINGs
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getsid.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setpgid.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpgid.c
|
||||||
# Warning flags.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setuid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getuid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/fork.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/read.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/write.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/exec.c
|
||||||
# Disable some specific warnings.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/nice.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/open.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/reboot.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/waitpid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/chdir.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getcwd.c
|
||||||
# Set the compiler options.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/close.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/stat.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/rmdir.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/mkdir.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/unlink.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getdents.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/lseek.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/kill.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/signal.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/interval.c
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/symlink.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/readlink.c
|
||||||
endif()
|
${PROJECT_SOURCE_DIR}/libc/src/libc_start.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/crt0.s
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Add the library.
|
|
||||||
add_library(
|
|
||||||
${PROJECT_NAME}
|
|
||||||
|
|
||||||
${PROJECT_SOURCE_DIR}/src/stdio.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/ctype.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/string.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/stdlib.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/math.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/fcvt.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/time.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/strerror.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/termios.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/libgen.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/vsprintf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/vscanf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/pwd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/grp.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sched.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/readline.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/setenv.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/assert.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/abort.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/io/mm_io.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/io/debug.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/ipc.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/unistd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/errno.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/utsname.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/mman.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/ioctl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/creat.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getppid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getpid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/exit.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setsid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getsid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setpgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getpgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setuid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getuid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/fork.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/read.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/write.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/exec.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/nice.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/open.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/reboot.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/waitpid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/chdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getcwd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/close.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/stat.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/rmdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/mkdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/unlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getdents.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/lseek.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/kill.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/signal.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/interval.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/symlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/readlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/libc_start.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/crt0.S
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC inc)
|
target_include_directories(libc PRIVATE ${PROJECT_SOURCE_DIR}/libc/inc)
|
||||||
|
|
||||||
# Remove the 'lib' prefix.
|
# Remove the 'lib' prefix.
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
set_target_properties(libc PROPERTIES PREFIX "")
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
.extern main
|
||||||
|
.extern __libc_start_main
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
_start: # _start is the entry point known to the linker
|
||||||
|
mov $0, %ebp # Set ebp to 0 as x86 programs require
|
||||||
|
push $main
|
||||||
|
call __libc_start_main # Call the libc initialization function.
|
||||||
|
mov %eax, %ebx # Move `main` return value to ebx.
|
||||||
|
mov $1, %eax # Call the `exit` function by using `int 80` (i.e., a system call)
|
||||||
|
int $0x80
|
||||||
+116
-171
@@ -1,19 +1,9 @@
|
|||||||
# =============================================================================
|
|
||||||
# Author: Enrico Fraccaroli
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Set the minimum required version of cmake.
|
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
|
||||||
|
|
||||||
# Initialize the project.
|
|
||||||
project(kernel C ASM)
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Set the main file names.
|
# Set the main file names.
|
||||||
set(KERNEL_NAME kernel)
|
set(KERNEL_NAME kernel)
|
||||||
set(BOOTLOADER_NAME kernel_bootloader)
|
set(BOOTLOADER_NAME kernel_bootloader)
|
||||||
set(BUDDY_SYSTEM_NAME kernel_memory)
|
set(BUDDY_SYSTEM_NAME kernel_memory)
|
||||||
set(BUDDY_SYSTEM_FILE ${PROJECT_SOURCE_DIR}/src/mem/libbuddysystem.a)
|
set(BUDDY_SYSTEM_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/mem/libbuddysystem.a)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
@@ -28,164 +18,103 @@ option(ENABLE_ALLOC_TRACE "Enables memory allocation tracing." OFF)
|
|||||||
# Enables scheduling feedback on terminal.
|
# Enables scheduling feedback on terminal.
|
||||||
option(ENABLE_SCHEDULER_FEEDBACK "Enables scheduling feedback on terminal." OFF)
|
option(ENABLE_SCHEDULER_FEEDBACK "Enables scheduling feedback on terminal." OFF)
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# ASSEMBLY
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Find the NASM compiler.
|
|
||||||
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
|
||||||
# Mark the variable ASM_COMPILER as advanced.
|
|
||||||
mark_as_advanced(ASM_COMPILER)
|
|
||||||
# Check that we have found the compiler.
|
|
||||||
if(NOT ASM_COMPILER)
|
|
||||||
message(FATAL_ERROR "ASM compiler not found!")
|
|
||||||
endif(NOT ASM_COMPILER)
|
|
||||||
# Set the asm compiler.
|
|
||||||
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
|
|
||||||
# Set the assembly compiler flags.
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O0 -F dwarf -o <OBJECT> <SOURCE>")
|
|
||||||
else()
|
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O3 -o <OBJECT> <SOURCE>")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
|
||||||
|
|
||||||
# Set the compiler options.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
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} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# SOURCES
|
# SOURCES
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# Define the list of files.
|
# Define the list of files.
|
||||||
set(KERNEL_SOURCES
|
set(KERNEL_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/src/kernel.c
|
${PROJECT_SOURCE_DIR}/mentos/src/kernel.c
|
||||||
${PROJECT_SOURCE_DIR}/src/multiboot.c
|
${PROJECT_SOURCE_DIR}/mentos/src/multiboot.c
|
||||||
${PROJECT_SOURCE_DIR}/src/devices/pci.c
|
${PROJECT_SOURCE_DIR}/mentos/src/devices/pci.c
|
||||||
${PROJECT_SOURCE_DIR}/src/devices/fpu.c
|
${PROJECT_SOURCE_DIR}/mentos/src/devices/fpu.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/ata.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ata.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/rtc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/rtc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/fdc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/fdc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/mouse.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/mouse.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/ps2.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ps2.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keyboard.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keyboard.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keymap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keymap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/vfs.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/vfs.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/read_write.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/read_write.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/open.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/open.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/stat.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/stat.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/readdir.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/readdir.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/procfs.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/procfs.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/ioctl.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/ioctl.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/namei.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/namei.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/ext2.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/ext2.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/timer.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/timer.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/cpuid.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/cpuid.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/pic8259.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/pic8259.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/debug.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/debug.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/mm_io.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/mm_io.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/video.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/video.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/stdio.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/stdio.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_video.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_video.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_running.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_running.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_feedback.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_feedback.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_system.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_system.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_ipc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_ipc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/vga/vga.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/vga/vga.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/ipc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/ipc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/msg.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/msg.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/sem.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/sem.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/shm.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/shm.c
|
||||||
${PROJECT_SOURCE_DIR}/src/kernel/sys.c
|
${PROJECT_SOURCE_DIR}/mentos/src/kernel/sys.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/assert.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/assert.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/ctype.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/ctype.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/mutex.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/mutex.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/string.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/string.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/vsprintf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/vsprintf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/vscanf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/vscanf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/time.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/time.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/libgen.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/libgen.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/strerror.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/strerror.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/math.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/math.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/fcvt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/fcvt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/spinlock.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/spinlock.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/stdlib.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/stdlib.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/rbtree.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/rbtree.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/ndtree.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/ndtree.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/hashmap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/hashmap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/list.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/list.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/kheap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/kheap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/paging.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/paging.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/slab.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/slab.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/vmem_map.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/vmem_map.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/zone_allocator.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/zone_allocator.c
|
||||||
${PROJECT_SOURCE_DIR}/src/elf/elf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/elf/elf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.s
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler_algorithm.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler_algorithm.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler_feedback.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler_feedback.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/process.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/process.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/wait.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/wait.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/user.S
|
${PROJECT_SOURCE_DIR}/mentos/src/process/user.s
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/utsname.c
|
${PROJECT_SOURCE_DIR}/mentos/src/sys/utsname.c
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/module.c
|
${PROJECT_SOURCE_DIR}/mentos/src/sys/module.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/errno.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/errno.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/panic.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/panic.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/printk.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/printk.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/signal.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/signal.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/syscall.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/syscall.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Add kernel library.
|
# Add kernel library.
|
||||||
if(USE_BUDDY_SYSTEM)
|
if(USE_BUDDY_SYSTEM)
|
||||||
# Add the library with `buddysystem.c`.
|
# Add the library with `buddysystem.c`.
|
||||||
add_library(${KERNEL_NAME} ${KERNEL_SOURCES} src/mem/buddysystem.c)
|
add_library(${KERNEL_NAME} ${KERNEL_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src/mem/buddysystem.c)
|
||||||
else(USE_BUDDY_SYSTEM)
|
else(USE_BUDDY_SYSTEM)
|
||||||
# Add the library without `buddysystem.c`.
|
# Add the library without `buddysystem.c`.
|
||||||
add_library(${KERNEL_NAME} ${KERNEL_SOURCES})
|
add_library(${KERNEL_NAME} ${KERNEL_SOURCES})
|
||||||
@@ -203,6 +132,17 @@ target_compile_definitions(
|
|||||||
${KERNEL_NAME} PUBLIC
|
${KERNEL_NAME} PUBLIC
|
||||||
__KERNEL__
|
__KERNEL__
|
||||||
)
|
)
|
||||||
|
# Link the kernel.
|
||||||
|
add_custom_target(
|
||||||
|
${KERNEL_NAME}.bin
|
||||||
|
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output ${KERNEL_NAME}.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds -Map ${KERNEL_NAME}.map -u kmain
|
||||||
|
$<TARGET_FILE_NAME:${KERNEL_NAME}> ${BUDDY_SYSTEM_FILE}
|
||||||
|
COMMAND objcopy -I binary -O elf32-i386 -B i386 ${KERNEL_NAME}.bin ${KERNEL_NAME}.bin.o
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds
|
||||||
|
DEPENDS ${KERNEL_NAME}
|
||||||
|
BYPRODUCTS ${KERNEL_NAME}.bin ${KERNEL_NAME}.bin.o
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Enables cache tracing.
|
# Enables cache tracing.
|
||||||
@@ -280,8 +220,8 @@ endif()
|
|||||||
# Add bootloader library.
|
# Add bootloader library.
|
||||||
add_library(
|
add_library(
|
||||||
${BOOTLOADER_NAME}
|
${BOOTLOADER_NAME}
|
||||||
src/boot.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/boot.c
|
||||||
src/boot.S
|
${CMAKE_CURRENT_SOURCE_DIR}/src/boot.s
|
||||||
)
|
)
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
@@ -294,16 +234,21 @@ target_compile_definitions(
|
|||||||
${BOOTLOADER_NAME} PUBLIC
|
${BOOTLOADER_NAME} PUBLIC
|
||||||
__KERNEL__
|
__KERNEL__
|
||||||
)
|
)
|
||||||
|
add_dependencies(
|
||||||
# =============================================================================
|
${BOOTLOADER_NAME}
|
||||||
# Build the kernel.
|
${KERNEL_NAME}
|
||||||
add_custom_target(
|
)
|
||||||
kernel-bootloader.bin ALL
|
target_link_libraries(
|
||||||
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output kernel.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds -Map kernel.map -u kmain
|
${BOOTLOADER_NAME} PUBLIC
|
||||||
$<TARGET_FILE_NAME:${KERNEL_NAME}> ${BUDDY_SYSTEM_FILE}
|
${KERNEL_NAME}
|
||||||
COMMAND objcopy -I binary -O elf32-i386 -B i386 kernel.bin kernel.bin.o
|
)
|
||||||
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output kernel-bootloader.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds -Map kernel-bootloader.map
|
# Link the bootloader.
|
||||||
kernel.bin.o $<TARGET_FILE_NAME:${BOOTLOADER_NAME}>
|
add_custom_target(
|
||||||
DEPENDS ${KERNEL_NAME}
|
${BOOTLOADER_NAME}.bin
|
||||||
DEPENDS ${BOOTLOADER_NAME}
|
COMMAND ${CMAKE_LINKER} -melf_i386 -static --output ${BOOTLOADER_NAME}.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds -Map ${BOOTLOADER_NAME}.map ${KERNEL_NAME}.bin.o $<TARGET_FILE_NAME:${BOOTLOADER_NAME}>
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds
|
||||||
|
DEPENDS ${BOOTLOADER_NAME}
|
||||||
|
DEPENDS ${KERNEL_NAME}.bin
|
||||||
|
BYPRODUCTS ${BOOTLOADER_NAME}.bin
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|||||||
+5
-13
@@ -9,45 +9,37 @@ MEMORY {
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x00100000;
|
. = 0x00100000;
|
||||||
_bootloader_start = .;
|
|
||||||
|
_bootloader_start = .;
|
||||||
|
|
||||||
.multiboot . : AT(ADDR(.multiboot))
|
.multiboot . : AT(ADDR(.multiboot))
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_multiboot_header_start = .;
|
|
||||||
*(.multiboot_header)
|
*(.multiboot_header)
|
||||||
_multiboot_header_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Put the .text section. */
|
/* Put the .text section. */
|
||||||
.text . : AT(ADDR(.text))
|
.text . : AT(ADDR(.text))
|
||||||
{
|
{
|
||||||
_text_start = .;
|
|
||||||
*(.text)
|
*(.text)
|
||||||
_text_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-only data. */
|
/* Read-only data. */
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||||
{
|
{
|
||||||
_rodata_start = .;
|
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
_rodata_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-write data (initialized) */
|
/* Read-write data (initialized) */
|
||||||
.data ALIGN(4K) : AT(ADDR(.data))
|
.data ALIGN(4K) : AT(ADDR(.data))
|
||||||
{
|
{
|
||||||
_data_start = .;
|
|
||||||
*(.data)
|
*(.data)
|
||||||
_data_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-write data (uninitialized) and stack */
|
/* Read-write data (uninitialized) and stack */
|
||||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||||
{
|
{
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
_bss_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
||||||
|
|||||||
@@ -15,33 +15,25 @@ SECTIONS
|
|||||||
/* Put the .text section. */
|
/* Put the .text section. */
|
||||||
.text . : AT(ADDR(.text))
|
.text . : AT(ADDR(.text))
|
||||||
{
|
{
|
||||||
_text_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.text)
|
EXCLUDE_FILE(*boot.*.o) *(.text)
|
||||||
_text_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-only data. */
|
/* Read-only data. */
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||||
{
|
{
|
||||||
_rodata_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.rodata)
|
EXCLUDE_FILE(*boot.*.o) *(.rodata)
|
||||||
_rodata_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-write data (initialized) */
|
/* Read-write data (initialized) */
|
||||||
.data ALIGN(4K) : AT(ADDR(.data))
|
.data ALIGN(4K) : AT(ADDR(.data))
|
||||||
{
|
{
|
||||||
_data_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.data)
|
EXCLUDE_FILE(*boot.*.o) *(.data)
|
||||||
_data_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-write data (uninitialized) and stack */
|
/* Read-write data (uninitialized) and stack */
|
||||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||||
{
|
{
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
_bss_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file boot.asm
|
|
||||||
; @brief Kernel start location, multiboot header
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
bits 32 ; All instructions should be 32-bit.
|
|
||||||
extern boot_main ; 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)
|
|
||||||
; 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
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
global boot_entry
|
|
||||||
boot_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 boot_main() function inside boot.c
|
|
||||||
call boot_main
|
|
||||||
; Set interrupt flag [IF = 1]; 0xFA
|
|
||||||
; Clear interrupts and hang if we return from boot_main
|
|
||||||
cli
|
|
||||||
hang:
|
|
||||||
hlt
|
|
||||||
jmp hang
|
|
||||||
|
|
||||||
global boot_kernel
|
|
||||||
boot_kernel:
|
|
||||||
mov edx, [esp + 4] ; stack_pointer
|
|
||||||
mov ebx, [esp + 8] ; entry
|
|
||||||
mov eax, [esp + 12] ; boot info
|
|
||||||
mov esp, edx ; set stack pointer
|
|
||||||
push eax ; push the boot info
|
|
||||||
call ebx ; call the kernel main
|
|
||||||
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (bss)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .bss
|
|
||||||
align 16
|
|
||||||
|
|
||||||
global stack_bottom
|
|
||||||
stack_bottom:
|
|
||||||
resb KERNEL_STACK_SIZE
|
|
||||||
|
|
||||||
global stack_top
|
|
||||||
stack_top:
|
|
||||||
; the top of the stack is the bottom because the stack counts down
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file boot.asm
|
||||||
|
# @brief Kernel start location, multiboot header
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
# All instructions should be 32-bit.
|
||||||
|
.extern boot_main # The start point of our C code
|
||||||
|
|
||||||
|
# The magic field should contain this.
|
||||||
|
.equ MULTIBOOT_HEADER_MAGIC, 0x1BADB002
|
||||||
|
# This should be in %eax.
|
||||||
|
.equ MULTIBOOT_BOOTLOADER_MAGIC, 0x2BADB002
|
||||||
|
|
||||||
|
# = Specify what GRUB should PROVIDE =========================================
|
||||||
|
# Align the kernel and kernel modules on i386 page (4KB) boundaries.
|
||||||
|
.equ MULTIBOOT_PAGE_ALIGN, 0x00000001
|
||||||
|
# Provide the kernel with memory information.
|
||||||
|
.equ MULTIBOOT_MEMORY_INFO, 0x00000002
|
||||||
|
# Must pass video information to OS.
|
||||||
|
.equ MULTIBOOT_VIDEO_MODE, 0x00000004
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# This is the flag combination that we prepare for Grub
|
||||||
|
# to read at kernel load time.
|
||||||
|
.equ MULTIBOOT_HEADER_FLAGS, (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
|
||||||
|
# Grub reads this value to make sure it loads a kernel
|
||||||
|
# and not just garbage.
|
||||||
|
.equ MULTIBOOT_CHECKSUM, -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||||
|
|
||||||
|
.equ LOAD_MEMORY_ADDRESS, 0x00000000
|
||||||
|
# reserve (1024*1024) for the stack on a doubleword boundary
|
||||||
|
.equ KERNEL_STACK_SIZE, 0x100000
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.pushsection .note.name, "a", @note
|
||||||
|
.align 4
|
||||||
|
.long 2f - 1f /* namesz */
|
||||||
|
.long 4f - 3f /* descsz */
|
||||||
|
.long 18 /* type */
|
||||||
|
1:.asciz "MentOS" /* name */
|
||||||
|
2:.align 4
|
||||||
|
3:.long boot_entry /* desc */
|
||||||
|
4:.align 4
|
||||||
|
.popsection
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (multiboot_header)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.globl multiboot_header
|
||||||
|
.align 4
|
||||||
|
# This is the GRUB Multiboot header.
|
||||||
|
multiboot_header:
|
||||||
|
# magic
|
||||||
|
.long MULTIBOOT_HEADER_MAGIC
|
||||||
|
# flags
|
||||||
|
.long MULTIBOOT_HEADER_FLAGS
|
||||||
|
# checksum
|
||||||
|
.long MULTIBOOT_CHECKSUM
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (data)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# section .data nobits
|
||||||
|
# align 4096
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
.global boot_entry
|
||||||
|
boot_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 $stack_top, %esp
|
||||||
|
# pass the initial ESP
|
||||||
|
push %esp
|
||||||
|
# pass Multiboot info structure
|
||||||
|
push %ebx
|
||||||
|
# pass Multiboot magic number
|
||||||
|
push %eax
|
||||||
|
# Call the boot_main() function inside boot.c
|
||||||
|
call boot_main
|
||||||
|
# Set interrupt flag [IF = 1]; 0xFA
|
||||||
|
# Clear interrupts and hang if we return from boot_main
|
||||||
|
cli
|
||||||
|
hang:
|
||||||
|
hlt
|
||||||
|
jmp hang
|
||||||
|
|
||||||
|
.global boot_kernel
|
||||||
|
boot_kernel:
|
||||||
|
mov 4(%esp),%edx # stack_pointer
|
||||||
|
mov 8(%esp),%ebx # entry
|
||||||
|
mov 12(%esp),%eax # boot info
|
||||||
|
mov %edx,%esp # set stack pointer
|
||||||
|
push %eax # push the boot info
|
||||||
|
call *%ebx # call the kernel main
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (bss)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.global stack_bottom
|
||||||
|
.global stack_top
|
||||||
|
.bss
|
||||||
|
.align 16
|
||||||
|
stack_bottom:
|
||||||
|
.skip KERNEL_STACK_SIZE
|
||||||
|
stack_top:
|
||||||
|
# the top of the stack is the bottom because the stack counts down
|
||||||
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file exception.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
extern isr_handler
|
|
||||||
|
|
||||||
; Macro used to define a ISR which does not push an error code.
|
|
||||||
%macro ISR_NOERR 1
|
|
||||||
global INT_%1
|
|
||||||
INT_%1:
|
|
||||||
cli
|
|
||||||
; A normal ISR stub that pops a dummy error code to keep a
|
|
||||||
; uniform stack frame
|
|
||||||
push 0
|
|
||||||
push %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; Macro used to define a ISR which pushes an error code.
|
|
||||||
%macro ISR_ERR 1
|
|
||||||
global INT_%1
|
|
||||||
INT_%1:
|
|
||||||
cli
|
|
||||||
push %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; Standard X86 interrupt service routines
|
|
||||||
ISR_NOERR 0
|
|
||||||
ISR_NOERR 1
|
|
||||||
ISR_NOERR 2
|
|
||||||
ISR_NOERR 3
|
|
||||||
ISR_NOERR 4
|
|
||||||
ISR_NOERR 5
|
|
||||||
ISR_NOERR 6
|
|
||||||
ISR_NOERR 7
|
|
||||||
ISR_ERR 8
|
|
||||||
ISR_NOERR 9
|
|
||||||
ISR_ERR 10
|
|
||||||
ISR_ERR 11
|
|
||||||
ISR_ERR 12
|
|
||||||
ISR_ERR 13
|
|
||||||
ISR_ERR 14
|
|
||||||
ISR_NOERR 15
|
|
||||||
ISR_NOERR 16
|
|
||||||
ISR_NOERR 17
|
|
||||||
ISR_NOERR 18
|
|
||||||
ISR_NOERR 19
|
|
||||||
ISR_NOERR 20
|
|
||||||
ISR_NOERR 21
|
|
||||||
ISR_NOERR 22
|
|
||||||
ISR_NOERR 23
|
|
||||||
ISR_NOERR 24
|
|
||||||
ISR_NOERR 25
|
|
||||||
ISR_NOERR 26
|
|
||||||
ISR_NOERR 27
|
|
||||||
ISR_NOERR 28
|
|
||||||
ISR_NOERR 29
|
|
||||||
ISR_NOERR 30
|
|
||||||
ISR_NOERR 31
|
|
||||||
|
|
||||||
ISR_NOERR 80
|
|
||||||
|
|
||||||
isr_common:
|
|
||||||
; Save all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi)
|
|
||||||
pusha
|
|
||||||
|
|
||||||
; Save segment registers
|
|
||||||
push ds
|
|
||||||
push es
|
|
||||||
push fs
|
|
||||||
push gs
|
|
||||||
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
; CLD - Azzera la flag di Direzione
|
|
||||||
; Questa istruzione forza semplicemente a zero la flag di Direzione.
|
|
||||||
; Quando la flag di direzione vale 0 tutte le istruzioni per la
|
|
||||||
; manipolazione delle stringhe agiscono in avanti, cioè dagli indirizzi più
|
|
||||||
; bassi a quelli più alti.
|
|
||||||
; L'istruzione agisce dunque sui puntatori SI e DI producendo su essi un
|
|
||||||
; autoincremento proporzionale alla dimensione degli operandi trattati.
|
|
||||||
; Le sue caratteristiche sono riassunte nella seguente tabella (leggi le
|
|
||||||
; istruzioni Legenda della Tabella):
|
|
||||||
cld
|
|
||||||
|
|
||||||
; Call the interrupt handler.
|
|
||||||
push esp
|
|
||||||
call isr_handler
|
|
||||||
add esp, 0x4
|
|
||||||
|
|
||||||
; Restore segment registers.
|
|
||||||
pop gs
|
|
||||||
pop fs
|
|
||||||
pop es
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
; Restore all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi).
|
|
||||||
popa
|
|
||||||
|
|
||||||
; Cleanup error code and IRQ #
|
|
||||||
add esp, 0x8
|
|
||||||
|
|
||||||
|
|
||||||
iret ; pops 5 things at once:
|
|
||||||
; CS, EIP, EFLAGS, SS, and ESP
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file exception.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.extern isr_handler
|
||||||
|
|
||||||
|
# Macro used to define a ISR which does not push an error code.
|
||||||
|
.macro ISR_NOERR ARG1
|
||||||
|
.globl INT_&ARG1
|
||||||
|
INT_&ARG1:
|
||||||
|
cli
|
||||||
|
# A normal ISR stub that pops a dummy error code to keep a
|
||||||
|
# uniform stack frame
|
||||||
|
push $0
|
||||||
|
push &ARG1
|
||||||
|
jmp isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# Macro used to define a ISR which pushes an error code.
|
||||||
|
.macro ISR_ERR ARG1
|
||||||
|
.globl INT_&ARG1
|
||||||
|
INT_&ARG1:
|
||||||
|
cli
|
||||||
|
push &ARG1
|
||||||
|
jmp isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
# Standard X86 interrupt service routines
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_NOERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_NOERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_NOERR 29
|
||||||
|
ISR_NOERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
ISR_NOERR 80
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
# Save all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi)
|
||||||
|
pusha
|
||||||
|
|
||||||
|
# Save segment registers
|
||||||
|
push %ds
|
||||||
|
push %es
|
||||||
|
push %fs
|
||||||
|
push %gs
|
||||||
|
|
||||||
|
mov $0x10,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
# CLD - Azzera la flag di Direzione
|
||||||
|
# Questa istruzione forza semplicemente a zero la flag di Direzione.
|
||||||
|
# Quando la flag di direzione vale 0 tutte le istruzioni per la
|
||||||
|
# manipolazione delle stringhe agiscono in avanti, cioè dagli indirizzi più
|
||||||
|
# bassi a quelli più alti.
|
||||||
|
# L'istruzione agisce dunque sui puntatori SI e DI producendo su essi un
|
||||||
|
# autoincremento proporzionale alla dimensione degli operandi trattati.
|
||||||
|
# Le sue caratteristiche sono riassunte nella seguente tabella (leggi le
|
||||||
|
# istruzioni Legenda della Tabella):
|
||||||
|
cld
|
||||||
|
|
||||||
|
# Call the interrupt handler.
|
||||||
|
push %esp
|
||||||
|
call isr_handler
|
||||||
|
add $0x4,%esp
|
||||||
|
|
||||||
|
# Restore segment registers.
|
||||||
|
pop %gs
|
||||||
|
pop %fs
|
||||||
|
pop %es
|
||||||
|
pop %ds
|
||||||
|
|
||||||
|
# Restore all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi).
|
||||||
|
popa
|
||||||
|
|
||||||
|
# Cleanup error code and IRQ #
|
||||||
|
add $0x8,%esp
|
||||||
|
|
||||||
|
|
||||||
|
iret # pops 5 things at once:
|
||||||
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file gdt.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global gdt_flush ; Allows the C code to call gdt_flush().
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
gdt_flush:
|
|
||||||
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
|
|
||||||
lgdt [eax] ; Load the new GDT pointer
|
|
||||||
|
|
||||||
; The data segments selectors (registers), can be easily modified using
|
|
||||||
; simple mov instruction, but the cs can't be used with mov, so you use:
|
|
||||||
jmp 0x08:flush
|
|
||||||
; to load the segment configurations into the the code segment selector.
|
|
||||||
|
|
||||||
flush:
|
|
||||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
|
||||||
mov ds, ax ; Load all data segment selectors
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file gdt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global gdt_flush # Allows the C code to call gdt_flush().
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
gdt_flush:
|
||||||
|
mov 4(%esp),%eax # Get the pointer to the GDT, passed as a parameter.
|
||||||
|
lgdt (%eax)
|
||||||
|
|
||||||
|
# The data segments selectors (registers), can be easily modified using
|
||||||
|
# simple mov instruction, but the cs can't be used with mov, so you use:
|
||||||
|
mov $0x10,%ax # 0x10 is the offset in the GDT to our data segment
|
||||||
|
mov %ax,%ds # Load all data segment selectors
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
mov %ax,%ss
|
||||||
|
|
||||||
|
# to load the segment configurations into the the code segment selector.
|
||||||
|
ret
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file idt.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global idt_flush ; Allows the C code to call idt_flush().
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
idt_flush:
|
|
||||||
mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter.
|
|
||||||
lidt [eax] ; Load the IDT pointer.
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file idt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global idt_flush # Allows the C code to call idt_flush().
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
idt_flush:
|
||||||
|
mov 4(%esp),%eax # Get the pointer to the IDT, passed as a parameter.
|
||||||
|
lidt (%eax)
|
||||||
|
ret
|
||||||
@@ -1,28 +1,26 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
# MentOS, The Mentoring Operating system project
|
||||||
; @file interrupt.asm
|
# @file interrupt.asm
|
||||||
; @brief
|
# @brief
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
; See LICENSE.md for details.
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
extern irq_handler
|
.extern irq_handler
|
||||||
|
|
||||||
%macro IRQ 2
|
.macro IRQ ARG1, ARG2
|
||||||
global IRQ_%1
|
.globl IRQ_&ARG1
|
||||||
IRQ_%1:
|
IRQ_&ARG1:
|
||||||
cli ; disable interrupt line
|
cli # disable interrupt line
|
||||||
; A normal ISR stub that pops a dummy error code to keep a
|
push $0
|
||||||
; uniform stack frame
|
push &ARG2
|
||||||
push 0
|
|
||||||
push %2 ; irq number
|
|
||||||
jmp irq_common
|
jmp irq_common
|
||||||
%endmacro
|
.endm
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
; SECTION (text)
|
# SECTION (text)
|
||||||
; -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
section .text
|
.text
|
||||||
|
|
||||||
; 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
# 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
||||||
IRQ 0, 32
|
IRQ 0, 32
|
||||||
IRQ 1, 33
|
IRQ 1, 33
|
||||||
IRQ 2, 34
|
IRQ 2, 34
|
||||||
@@ -40,52 +38,52 @@ IRQ 13, 45
|
|||||||
IRQ 14, 46
|
IRQ 14, 46
|
||||||
IRQ 15, 47
|
IRQ 15, 47
|
||||||
|
|
||||||
irq_common:
|
irq_common:
|
||||||
;==== Save CPU registers ===================================================
|
# ==== Save CPU registers ===================================================
|
||||||
; when an irq occurs, the following registers are already pushed on stack:
|
# when an irq occurs, the following registers are already pushed on stack:
|
||||||
; eip, cs, eflags, useresp, ss
|
# eip, cs, eflags, useresp, ss
|
||||||
|
|
||||||
; Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
# Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
; Save segment registers
|
# Save segment registers
|
||||||
push ds
|
push %ds
|
||||||
push es
|
push %es
|
||||||
push fs
|
push %fs
|
||||||
push gs
|
push %gs
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== ensure we are using kernel data segment ==============================
|
# ==== ensure we are using kernel data segment ==============================
|
||||||
mov ax, 0x10
|
mov $0x10,%ax
|
||||||
mov ds, ax
|
mov %ax,%ds
|
||||||
mov es, ax
|
mov %ax,%es
|
||||||
mov fs, ax
|
mov %ax,%fs
|
||||||
mov gs, ax
|
mov %ax,%gs
|
||||||
cld
|
cld
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== Call the interrupt handler ===========================================
|
# ==== Call the interrupt handler ===========================================
|
||||||
; The argument passed is a pointer to an Interrupt_State struct,
|
# The argument passed is a pointer to an Interrupt_State struct,
|
||||||
; which describes the stack layout for all interrupts.
|
# which describes the stack layout for all interrupts.
|
||||||
push esp
|
push %esp
|
||||||
call irq_handler
|
call irq_handler
|
||||||
add esp, $4 ; remove esp from stack
|
add $0x04, %esp # remove esp from stack
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== Restore registers ====================================================
|
# ==== Restore registers ====================================================
|
||||||
; restore segment registers
|
# restore segment registers
|
||||||
pop gs
|
pop %gs
|
||||||
pop fs
|
pop %fs
|
||||||
pop es
|
pop %es
|
||||||
pop ds
|
pop %ds
|
||||||
|
|
||||||
; restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
# restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
popa
|
popa
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
; Cleanup error code and IRQ #
|
# Cleanup error code and IRQ #
|
||||||
add esp, $8
|
add $0x08, %esp
|
||||||
|
|
||||||
; return to process
|
# return to process
|
||||||
iret ; pops 5 things at once:
|
iret # pops 5 things at once:
|
||||||
; CS, EIP, EFLAGS, SS, and ESP
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file interrupt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.extern irq_handler
|
||||||
|
|
||||||
|
.macro IRQ ARG1, ARG2
|
||||||
|
.globl IRQ_&ARG1
|
||||||
|
IRQ_&ARG1:
|
||||||
|
cli # disable interrupt line
|
||||||
|
push $0
|
||||||
|
push &ARG2
|
||||||
|
jmp irq_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
# 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
||||||
|
IRQ 0, 32
|
||||||
|
IRQ 1, 33
|
||||||
|
IRQ 2, 34
|
||||||
|
IRQ 3, 35
|
||||||
|
IRQ 4, 36
|
||||||
|
IRQ 5, 37
|
||||||
|
IRQ 6, 38
|
||||||
|
IRQ 7, 39
|
||||||
|
IRQ 8, 40
|
||||||
|
IRQ 9, 41
|
||||||
|
IRQ 10, 42
|
||||||
|
IRQ 11, 43
|
||||||
|
IRQ 12, 44
|
||||||
|
IRQ 13, 45
|
||||||
|
IRQ 14, 46
|
||||||
|
IRQ 15, 47
|
||||||
|
|
||||||
|
irq_common:
|
||||||
|
# ==== Save CPU registers ===================================================
|
||||||
|
# when an irq occurs, the following registers are already pushed on stack:
|
||||||
|
# eip, cs, eflags, useresp, ss
|
||||||
|
|
||||||
|
# Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
|
pusha
|
||||||
|
|
||||||
|
# Save segment registers
|
||||||
|
push %ds
|
||||||
|
push %es
|
||||||
|
push %fs
|
||||||
|
push %gs
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== ensure we are using kernel data segment ==============================
|
||||||
|
mov $0x10,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
cld
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== Call the interrupt handler ===========================================
|
||||||
|
# The argument passed is a pointer to an Interrupt_State struct,
|
||||||
|
# which describes the stack layout for all interrupts.
|
||||||
|
push %esp
|
||||||
|
call irq_handler
|
||||||
|
add $0x04, %esp # remove esp from stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== Restore registers ====================================================
|
||||||
|
# restore segment registers
|
||||||
|
pop %gs
|
||||||
|
pop %fs
|
||||||
|
pop %es
|
||||||
|
pop %ds
|
||||||
|
|
||||||
|
# restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
|
popa
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Cleanup error code and IRQ #
|
||||||
|
add $0x08, %esp
|
||||||
|
|
||||||
|
# return to process
|
||||||
|
iret # pops 5 things at once:
|
||||||
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file tss.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global tss_flush
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
tss_flush:
|
|
||||||
mov ax, 0x28
|
|
||||||
ltr ax
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file tss.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global tss_flush
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
tss_flush:
|
||||||
|
mov $0x28,%ax
|
||||||
|
ltr %ax
|
||||||
|
ret
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
// Setup the logging for this file (do this before any other include).
|
// Setup the logging for this file (do this before any other include).
|
||||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||||
#define __DEBUG_HEADER__ "[ELF ]" ///< Change header.
|
#define __DEBUG_HEADER__ "[ELF ]" ///< Change header.
|
||||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG ///< Set log level.
|
||||||
#include "io/debug.h" // Include debugging functions.
|
#include "io/debug.h" // Include debugging functions.
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|||||||
+23
-45
@@ -43,28 +43,6 @@ char *module_start[MAX_MODULES];
|
|||||||
/// Describe end address of grub multiboot modules.
|
/// Describe end address of grub multiboot modules.
|
||||||
char *module_end[MAX_MODULES];
|
char *module_end[MAX_MODULES];
|
||||||
|
|
||||||
// Everything is defined in kernel.ld.
|
|
||||||
|
|
||||||
/// Points at the multiheader grub info, starting address.
|
|
||||||
extern uint32_t _multiboot_header_start;
|
|
||||||
/// Points at the multiheader grub info, ending address.
|
|
||||||
extern uint32_t _multiboot_header_end;
|
|
||||||
/// Points at the kernel code, starting address.
|
|
||||||
extern uint32_t _text_start;
|
|
||||||
/// Points at the kernel code, ending address.
|
|
||||||
extern uint32_t _text_end;
|
|
||||||
/// Points at the read-only kernel data, starting address.
|
|
||||||
extern uint32_t _rodata_start;
|
|
||||||
/// Points at the read-only kernel data, ending address.
|
|
||||||
extern uint32_t _rodata_end;
|
|
||||||
/// Points at the read-write kernel data initialized, starting address.
|
|
||||||
extern uint32_t _data_start;
|
|
||||||
/// Points at the read-write kernel data initialized, ending address.
|
|
||||||
extern uint32_t _data_end;
|
|
||||||
/// Points at the read-write kernel data uninitialized an kernel stack, starting address.
|
|
||||||
extern uint32_t _bss_start;
|
|
||||||
/// Points at the read-write kernel data uninitialized an kernel stack, ending address.
|
|
||||||
extern uint32_t _bss_end;
|
|
||||||
/// Points at the top of the kernel stack.
|
/// Points at the top of the kernel stack.
|
||||||
extern uint32_t stack_top;
|
extern uint32_t stack_top;
|
||||||
/// Points at the bottom of the kernel stack.
|
/// Points at the bottom of the kernel stack.
|
||||||
@@ -107,8 +85,8 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
boot_info = *boot_informations;
|
boot_info = *boot_informations;
|
||||||
// Am I booted by a Multiboot-compliant boot loader?
|
// Am I booted by a Multiboot-compliant boot loader?
|
||||||
if (boot_info.magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
if (boot_info.magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
printf("Invalid magic number: 0x%x\n", boot_info.magic);
|
pr_emerg("Invalid magic number: 0x%x\n", boot_info.magic);
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
// Set the initial esp.
|
// Set the initial esp.
|
||||||
initial_esp = boot_info.stack_base;
|
initial_esp = boot_info.stack_base;
|
||||||
@@ -131,7 +109,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize modules...");
|
printf("Initialize modules...");
|
||||||
if (!init_modules(boot_info.multiboot_header)) {
|
if (!init_modules(boot_info.multiboot_header)) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -140,7 +118,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize physical memory manager...");
|
printf("Initialize physical memory manager...");
|
||||||
if (!pmmngr_init(&boot_info)) {
|
if (!pmmngr_init(&boot_info)) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -216,7 +194,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize ATA devices...");
|
printf("Initialize ATA devices...");
|
||||||
if (ata_initialize()) {
|
if (ata_initialize()) {
|
||||||
pr_emerg("Failed to initialize ATA devices!\n");
|
pr_emerg("Failed to initialize ATA devices!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -225,7 +203,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize EXT2 filesystem...");
|
printf("Initialize EXT2 filesystem...");
|
||||||
if (ext2_initialize()) {
|
if (ext2_initialize()) {
|
||||||
pr_emerg("Failed to initialize EXT2 filesystem!\n");
|
pr_emerg("Failed to initialize EXT2 filesystem!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -234,7 +212,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Mount EXT2 filesystem...");
|
printf("Mount EXT2 filesystem...");
|
||||||
if (do_mount("ext2", "/", "/dev/hda")) {
|
if (do_mount("ext2", "/", "/dev/hda")) {
|
||||||
pr_emerg("Failed to mount EXT2 filesystem...\n");
|
pr_emerg("Failed to mount EXT2 filesystem...\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -244,7 +222,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procfs_module_init()) {
|
if (procfs_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to register `procfs`!\n");
|
pr_emerg("Failed to register `procfs`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -253,7 +231,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf(" Mounting 'procfs'...");
|
printf(" Mounting 'procfs'...");
|
||||||
if (do_mount("procfs", "/proc", NULL)) {
|
if (do_mount("procfs", "/proc", NULL)) {
|
||||||
pr_emerg("Failed to mount procfs at `/proc`!\n");
|
pr_emerg("Failed to mount procfs at `/proc`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -263,7 +241,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procv_module_init()) {
|
if (procv_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize `/proc/video`!\n");
|
pr_emerg("Failed to initialize `/proc/video`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -273,7 +251,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procs_module_init()) {
|
if (procs_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize proc system entries!\n");
|
pr_emerg("Failed to initialize proc system entries!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -283,7 +261,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procipc_module_init()) {
|
if (procipc_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC information system!\n");
|
pr_emerg("Failed to initialize the IPC information system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -293,7 +271,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (sem_init()) {
|
if (sem_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/SEM system!\n");
|
pr_emerg("Failed to initialize the IPC/SEM system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -303,7 +281,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (msq_init()) {
|
if (msq_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/MSQ system!\n");
|
pr_emerg("Failed to initialize the IPC/MSQ system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -313,7 +291,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (shm_init()) {
|
if (shm_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/SHM system!\n");
|
pr_emerg("Failed to initialize the IPC/SHM system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -328,7 +306,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (ps2_initialize()) {
|
if (ps2_initialize()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize proc system entries!\n");
|
pr_emerg("Failed to initialize proc system entries!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -365,7 +343,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Init process management...");
|
printf("Init process management...");
|
||||||
if (!init_tasking()) {
|
if (!init_tasking()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -375,7 +353,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize scheduler feedback system...");
|
printf("Initialize scheduler feedback system...");
|
||||||
if (!scheduler_feedback_init()) {
|
if (!scheduler_feedback_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
#endif
|
#endif
|
||||||
@@ -385,7 +363,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize scheduler feedback system (2)...");
|
printf("Initialize scheduler feedback system (2)...");
|
||||||
if (procfb_module_init()) {
|
if (procfb_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -395,7 +373,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
task_struct *init_p = process_create_init("/bin/init");
|
task_struct *init_p = process_create_init("/bin/init");
|
||||||
if (!init_p) {
|
if (!init_p) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -404,7 +382,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize floating point unit...");
|
printf("Initialize floating point unit...");
|
||||||
if (!fpu_install()) {
|
if (!fpu_install()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -413,7 +391,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize signals...");
|
printf("Initialize signals...");
|
||||||
if (!signals_init()) {
|
if (!signals_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -432,5 +410,5 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
for (;;) {}
|
for (;;) {}
|
||||||
// We should not be here.
|
// We should not be here.
|
||||||
pr_emerg("Dear developer, we have to talk...\n");
|
pr_emerg("Dear developer, we have to talk...\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
// Setup the logging for this file (do this before any other include).
|
// Setup the logging for this file (do this before any other include).
|
||||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||||
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
||||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG ///< Set log level.
|
||||||
#include "io/debug.h" // Include debugging functions.
|
#include "io/debug.h" // Include debugging functions.
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "elf/elf.h"
|
#include "elf/elf.h"
|
||||||
@@ -91,11 +91,15 @@ static int __reset_process(task_struct *task)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_debug("Switching to task page directory.\n");
|
||||||
|
|
||||||
// Save the current page directory.
|
// Save the current page directory.
|
||||||
page_directory_t *crtdir = paging_get_current_directory();
|
page_directory_t *crtdir = paging_get_current_directory();
|
||||||
// FIXME: Now to clear the stack a pgdir switch is made, it should be a kernel mmapping.
|
// FIXME: Now to clear the stack a pgdir switch is made, it should be a kernel mmapping.
|
||||||
paging_switch_directory_va(task->mm->pgd);
|
paging_switch_directory_va(task->mm->pgd);
|
||||||
|
|
||||||
|
pr_debug("Clean stack (%p).\n", task->mm->start_stack);
|
||||||
|
|
||||||
// Clean stack space.
|
// Clean stack space.
|
||||||
memset((char *)task->mm->start_stack, 0, DEFAULT_STACK_SIZE);
|
memset((char *)task->mm->start_stack, 0, DEFAULT_STACK_SIZE);
|
||||||
// Set the base address of the stack.
|
// Set the base address of the stack.
|
||||||
@@ -105,6 +109,8 @@ static int __reset_process(task_struct *task)
|
|||||||
// Enable the interrupts.
|
// Enable the interrupts.
|
||||||
task->thread.regs.eflags = task->thread.regs.eflags | EFLAG_IF;
|
task->thread.regs.eflags = task->thread.regs.eflags | EFLAG_IF;
|
||||||
|
|
||||||
|
pr_debug("Switching to previous page directory.\n");
|
||||||
|
|
||||||
// Restore previous pgdir
|
// Restore previous pgdir
|
||||||
paging_switch_directory(crtdir);
|
paging_switch_directory(crtdir);
|
||||||
|
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file user.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
; Enter userspace (ring3) (from Ring 0, namely Kernel)
|
|
||||||
; Usage: enter_userspace(uintptr_t location, uintptr_t stack);
|
|
||||||
; On stack
|
|
||||||
; | stack | [ebp + 0x0C] ARG1
|
|
||||||
; | location | [ebp + 0x08] ARG0
|
|
||||||
; | return address | [ebp + 0x04]
|
|
||||||
; | EBP | [ebp + 0x00]
|
|
||||||
; | SS |
|
|
||||||
; | ESP |
|
|
||||||
; | EFLAGS |
|
|
||||||
; | CS |
|
|
||||||
; | EIP |
|
|
||||||
|
|
||||||
; We can use the following macros to access the arguments ONLY AFTER 0x23 is
|
|
||||||
; pushed onto the stack, in fact, the first argument is after 0x08 because
|
|
||||||
; we just pushed first `ebp` and then `0x23`.
|
|
||||||
%define ARG0 [ebp + 0x08] ; Argument 0
|
|
||||||
%define ARG1 [ebp + 0x0C] ; Argument 1
|
|
||||||
%define ARG2 [ebp + 0x10] ; Argument 2
|
|
||||||
%define ARG3 [ebp + 0x14] ; Argument 3
|
|
||||||
%define ARG4 [ebp + 0x18] ; Argument 4
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
global enter_userspace ; Allows the C code to call enter_userspace(...).
|
|
||||||
|
|
||||||
enter_userspace:
|
|
||||||
|
|
||||||
push ebp ; Save current ebp
|
|
||||||
mov ebp, esp ; open a new stack frame
|
|
||||||
|
|
||||||
;==== Segment selector =====================================================
|
|
||||||
mov ax, 0x23
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
; we don't need to worry about SS. it's handled by iret
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; We have to prepare the following stack before executing iret
|
|
||||||
; SS --> Segment selector
|
|
||||||
; ESP --> Stack address
|
|
||||||
; EFLAGS --> CPU state flgas
|
|
||||||
; CS --> Code segment
|
|
||||||
; EIP --> Entry point
|
|
||||||
;
|
|
||||||
|
|
||||||
;==== User data segmenet with bottom 2 bits set for ring3 ?=================
|
|
||||||
push 0x23 ; push SS on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (ESP) Stack address ==================================================
|
|
||||||
mov eax, ARG1 ; get uintptr_t stack
|
|
||||||
push eax ; push process's stack address on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (EFLAGS) =============================================================
|
|
||||||
pushf ; push EFLAGS into Kernel's stack
|
|
||||||
pop eax ; pop EFLAGS into eax
|
|
||||||
or eax, 0x200 ; enable interrupt
|
|
||||||
push eax ; push new EFLAGS on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (CS) Code Segment ====================================================
|
|
||||||
push 0x1b ;
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (EIP) Entry point ====================================================
|
|
||||||
mov eax, ARG0 ; get uintptr_t location
|
|
||||||
push eax ; push uintptr_t location on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
iret ; interrupt return
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
; WE SHOULD NOT STILL BE HERE! :(p
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file user.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
# Enter userspace (ring3) (from Ring 0, namely Kernel)
|
||||||
|
# Usage: enter_userspace(uintptr_t location, uintptr_t stack);
|
||||||
|
# On stack
|
||||||
|
# | stack | [ebp + 0x0C] ARG1
|
||||||
|
# | location | [ebp + 0x08] ARG0
|
||||||
|
# | return address | [ebp + 0x04]
|
||||||
|
# | EBP | [ebp + 0x00]
|
||||||
|
# | SS |
|
||||||
|
# | ESP |
|
||||||
|
# | EFLAGS |
|
||||||
|
# | CS |
|
||||||
|
# | EIP |
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
.global enter_userspace # Allows the C code to call enter_userspace(...).
|
||||||
|
|
||||||
|
enter_userspace:
|
||||||
|
|
||||||
|
push %ebp # Save current ebp
|
||||||
|
mov %esp,%ebp # open a new stack frame
|
||||||
|
|
||||||
|
# ==== Segment selector =====================================================
|
||||||
|
mov $0x23,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
# we don't need to worry about SS. it's handled by iret
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# We have to prepare the following stack before executing iret
|
||||||
|
# SS --> Segment selector
|
||||||
|
# ESP --> Stack address
|
||||||
|
# EFLAGS --> CPU state flgas
|
||||||
|
# CS --> Code segment
|
||||||
|
# EIP --> Entry point
|
||||||
|
#
|
||||||
|
|
||||||
|
# ==== User data segmenet with bottom 2 bits set for ring3 ?=================
|
||||||
|
push $0x23 # push SS on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (ESP) Stack address ==================================================
|
||||||
|
mov 0x0C(%ebp),%eax # get uintptr_t stack
|
||||||
|
push %eax # push process's stack address on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (EFLAGS) =============================================================
|
||||||
|
pushf # push EFLAGS into Kernel's stack
|
||||||
|
pop %eax # pop EFLAGS into eax
|
||||||
|
or $0x200,%eax # enable interrupt
|
||||||
|
push %eax # push new EFLAGS on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (CS) Code Segment ====================================================
|
||||||
|
push $0x1b #
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (EIP) Entry point ====================================================
|
||||||
|
mov 0x08(%ebp),%eax # get uintptr_t location
|
||||||
|
push %eax # push uintptr_t location on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
iret # interrupt return
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
# WE SHOULD NOT STILL BE HERE! :(p
|
||||||
+62
-56
@@ -1,57 +1,3 @@
|
|||||||
# =============================================================================
|
|
||||||
# Author: Enrico Fraccaroli
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Set the minimum required version of cmake.
|
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
|
||||||
|
|
||||||
# Initialize the project.
|
|
||||||
project(programs C)
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# We need to specify the name of the entry function.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -u_start")
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
|
|
||||||
|
|
||||||
# Set the compiler options.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
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} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# BUILD
|
# BUILD
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -88,11 +34,44 @@ set(PROGRAMS
|
|||||||
)
|
)
|
||||||
# Set the directory where the compiled binaries will be placed.
|
# Set the directory where the compiled binaries will be placed.
|
||||||
set(MENTOS_BIN_DIR ${CMAKE_SOURCE_DIR}/files/bin)
|
set(MENTOS_BIN_DIR ${CMAKE_SOURCE_DIR}/files/bin)
|
||||||
|
# Create the directory.
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${MENTOS_BIN_DIR})
|
||||||
|
# Add the executables (manually).
|
||||||
|
set(PROGRAMS
|
||||||
|
init.c
|
||||||
|
cpuid.c
|
||||||
|
clear.c
|
||||||
|
date.c
|
||||||
|
ls.c
|
||||||
|
logo.c
|
||||||
|
nice.c
|
||||||
|
poweroff.c
|
||||||
|
rm.c
|
||||||
|
shell.c
|
||||||
|
uname.c
|
||||||
|
cat.c
|
||||||
|
echo.c
|
||||||
|
login.c
|
||||||
|
mkdir.c
|
||||||
|
pwd.c
|
||||||
|
rmdir.c
|
||||||
|
showpid.c
|
||||||
|
touch.c
|
||||||
|
env.c
|
||||||
|
ps.c
|
||||||
|
kill.c
|
||||||
|
ipcrm.c
|
||||||
|
ipcs.c
|
||||||
|
sleep.c
|
||||||
|
man.c
|
||||||
|
edit.c
|
||||||
|
uptime.c
|
||||||
|
)
|
||||||
|
|
||||||
foreach(FILE_NAME ${PROGRAMS})
|
foreach(FILE_NAME ${PROGRAMS})
|
||||||
# Prepare the program name.
|
# Prepare the program name.
|
||||||
string(REPLACE ".c" "" EXECUTABLE_NAME ${FILE_NAME})
|
string(REPLACE ".c" "" EXECUTABLE_NAME ${FILE_NAME})
|
||||||
|
|
||||||
# Set the name of the target.
|
# Set the name of the target.
|
||||||
set(TARGET_NAME prog_${EXECUTABLE_NAME})
|
set(TARGET_NAME prog_${EXECUTABLE_NAME})
|
||||||
|
|
||||||
@@ -108,11 +87,28 @@ foreach(FILE_NAME ${PROGRAMS})
|
|||||||
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
||||||
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# EXECUTABLE
|
||||||
|
# =========================================================================
|
||||||
|
set(TARGET_NAME prog_${EXECUTABLE_NAME})
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# TEXT ADDRESS
|
||||||
|
# =========================================================================
|
||||||
|
# Randomize .text section address so when debugging symbols don't clash.
|
||||||
|
# The allowed range is from 256MB to 2.75GB
|
||||||
|
# Minimum allowed address: 0x10000000
|
||||||
|
# Max allowed address: 0xB0000000
|
||||||
|
string(MD5 RAND_HASH ${FILE_NAME})
|
||||||
|
string(SUBSTRING ${RAND_HASH} 1 3 TEXADDR_INFIX)
|
||||||
|
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
||||||
|
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# EXECUTABLE
|
# EXECUTABLE
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# Create the target.
|
# Create the target.
|
||||||
add_executable(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/programs/${FILE_NAME})
|
add_executable(${TARGET_NAME} ${FILE_NAME})
|
||||||
# Add the dependency to libc.
|
# Add the dependency to libc.
|
||||||
add_dependencies(${TARGET_NAME} libc)
|
add_dependencies(${TARGET_NAME} libc)
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
@@ -128,6 +124,16 @@ foreach(FILE_NAME ${PROGRAMS})
|
|||||||
# Set the output name.
|
# Set the output name.
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
||||||
|
|
||||||
|
target_link_libraries(${TARGET_NAME} libc)
|
||||||
|
# We need to specify the name of the entry function.
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE -u_start)
|
||||||
|
# Add the linking properties.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,-Ttext=${TEXT_ADDR},-e_start,-melf_i386")
|
||||||
|
# Set the output directory.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MENTOS_BIN_DIR}")
|
||||||
|
# Set the output name.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
||||||
|
|
||||||
# Append the program name to the list of all the executables.
|
# Append the program name to the list of all the executables.
|
||||||
list(APPEND ALL_EXECUTABLES ${TARGET_NAME})
|
list(APPEND ALL_EXECUTABLES ${TARGET_NAME})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -1,95 +1,40 @@
|
|||||||
# =============================================================================
|
|
||||||
# Author: Enrico Fraccaroli
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Set the minimum required version of cmake.
|
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
|
||||||
|
|
||||||
# Initialize the project.
|
|
||||||
project(tests C)
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# We need to specify the name of the entry function.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -u_start")
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
|
|
||||||
|
|
||||||
# Set the compiler options.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
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} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# BUILD
|
# BUILD
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Add your file in this list.
|
|
||||||
set(TESTS
|
|
||||||
t_gid.c
|
|
||||||
t_alarm.c
|
|
||||||
t_periodic3.c
|
|
||||||
t_setenv.c
|
|
||||||
t_itimer.c
|
|
||||||
t_fork.c
|
|
||||||
t_semget.c
|
|
||||||
t_exec.c
|
|
||||||
t_sleep.c
|
|
||||||
t_periodic2.c
|
|
||||||
t_sigfpe.c
|
|
||||||
t_sigmask.c
|
|
||||||
t_getenv.c
|
|
||||||
t_sigusr.c
|
|
||||||
t_exec_callee.c
|
|
||||||
t_shmget.c
|
|
||||||
t_stopcont.c
|
|
||||||
t_semop.c
|
|
||||||
t_sigaction.c
|
|
||||||
t_schedfb.c
|
|
||||||
t_siginfo.c
|
|
||||||
t_groups.c
|
|
||||||
t_semflg.c
|
|
||||||
t_abort.c
|
|
||||||
t_msgget.c
|
|
||||||
t_periodic1.c
|
|
||||||
t_kill.c
|
|
||||||
t_shm_write.c
|
|
||||||
t_mem.c
|
|
||||||
t_shm_read.c
|
|
||||||
)
|
|
||||||
# Set the directory where the compiled binaries will be placed.
|
# Set the directory where the compiled binaries will be placed.
|
||||||
set(MENTOS_TESTS_DIR ${CMAKE_SOURCE_DIR}/files/bin/tests)
|
set(MENTOS_TESTS_DIR ${CMAKE_SOURCE_DIR}/files/bin/tests)
|
||||||
|
# Create the directory.
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${MENTOS_TESTS_DIR})
|
||||||
|
|
||||||
|
# Add the executables (manually).
|
||||||
|
set(TESTS
|
||||||
|
t_mem.c
|
||||||
|
t_fork.c
|
||||||
|
# Real-time programs
|
||||||
|
t_periodic1.c
|
||||||
|
t_periodic2.c
|
||||||
|
t_periodic3.c
|
||||||
|
# Exec
|
||||||
|
t_exec.c
|
||||||
|
t_exec_callee.c
|
||||||
|
# Test environmental variables.
|
||||||
|
t_setenv.c
|
||||||
|
t_getenv.c
|
||||||
|
# Test: signals.
|
||||||
|
t_stopcont.c
|
||||||
|
t_sigusr.c
|
||||||
|
t_abort.c
|
||||||
|
t_sigfpe.c
|
||||||
|
t_siginfo.c
|
||||||
|
t_sleep.c
|
||||||
|
t_sigaction.c
|
||||||
|
t_sigmask.c
|
||||||
|
t_groups.c
|
||||||
|
t_alarm.c
|
||||||
|
t_kill.c
|
||||||
|
t_itimer.c
|
||||||
|
t_gid.c
|
||||||
|
)
|
||||||
|
|
||||||
foreach(FILE_NAME ${TESTS})
|
foreach(FILE_NAME ${TESTS})
|
||||||
# Prepare the program name.
|
# Prepare the program name.
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ void sig_handler(int sig)
|
|||||||
{
|
{
|
||||||
printf("handler(%d) : Starting handler.\n", sig);
|
printf("handler(%d) : Starting handler.\n", sig);
|
||||||
if (sig == SIGABRT) {
|
if (sig == SIGABRT) {
|
||||||
|
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
counter += 1;
|
counter += 1;
|
||||||
|
|
||||||
@@ -38,8 +37,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGABRT, &action, NULL) == -1) {
|
if (sigaction(SIGABRT, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGABRT, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGABRT, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,12 +39,11 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = alarm_handler;
|
action.sa_handler = alarm_handler;
|
||||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
alarm(5);
|
alarm(5);
|
||||||
while(1) { }
|
while (1) {}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ int main(int argc, char *argv[])
|
|||||||
int status;
|
int status;
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
__print_usage(argc, argv);
|
__print_usage(argc, argv);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
||||||
printf("Failed to set env: `ENV_VAR`\n");
|
printf("Failed to set env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *file = "echo";
|
char *file = "echo";
|
||||||
@@ -54,11 +54,11 @@ int main(int argc, char *argv[])
|
|||||||
execvpe(file, exec_argv, exec_envp);
|
execvpe(file, exec_argv, exec_envp);
|
||||||
} else {
|
} else {
|
||||||
__print_usage(argc, argv);
|
__print_usage(argc, argv);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Exec failed.\n");
|
printf("Exec failed.\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
wait(&status);
|
wait(&status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ int main(int argc, char *argv[])
|
|||||||
char *ENV_VAR = getenv("ENV_VAR");
|
char *ENV_VAR = getenv("ENV_VAR");
|
||||||
if (ENV_VAR == NULL) {
|
if (ENV_VAR == NULL) {
|
||||||
printf("Failed to get env: `ENV_VAR`\n");
|
printf("Failed to get env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("ENV_VAR = %s\n", ENV_VAR);
|
printf("ENV_VAR = %s\n", ENV_VAR);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int N;
|
int N;
|
||||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ int main(int argc, char *argv[])
|
|||||||
char *ENV_VAR = getenv("ENV_VAR");
|
char *ENV_VAR = getenv("ENV_VAR");
|
||||||
if (ENV_VAR == NULL) {
|
if (ENV_VAR == NULL) {
|
||||||
printf("Failed to get env: `ENV_VAR`\n");
|
printf("Failed to get env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("ENV_VAR = %s\n", ENV_VAR);
|
printf("ENV_VAR = %s\n", ENV_VAR);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ int main(int argc, char **argv)
|
|||||||
group_t *root_group = getgrgid(0);
|
group_t *root_group = getgrgid(0);
|
||||||
if (strcmp(root_group->gr_name, "root") != 0) {
|
if (strcmp(root_group->gr_name, "root") != 0) {
|
||||||
printf("Error in getgrgid function.");
|
printf("Error in getgrgid function.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
root_group = getgrnam("root");
|
root_group = getgrnam("root");
|
||||||
if (root_group->gr_gid != 0) {
|
if (root_group->gr_gid != 0) {
|
||||||
printf("Error in getgrnam function.");
|
printf("Error in getgrnam function.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ int main(int argc, char **argv)
|
|||||||
printf("%d) pid_child: %d, gid_child: %d, ppid_child: %d, sid_child: %d\n",
|
printf("%d) pid_child: %d, gid_child: %d, ppid_child: %d, sid_child: %d\n",
|
||||||
i, pid_child, gid_child, ppid_child, sid_child);
|
i, pid_child, gid_child, ppid_child, sid_child);
|
||||||
sleep(5);
|
sleep(5);
|
||||||
exit(0);
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//int status;
|
//int status;
|
||||||
//while (wait(&status) > 0)
|
//while (wait(&status) > 0)
|
||||||
// ;
|
// ;
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = alarm_handler;
|
action.sa_handler = alarm_handler;
|
||||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
itimerval interval = { 0 };
|
itimerval interval = { 0 };
|
||||||
@@ -57,5 +57,5 @@ int main(int argc, char *argv[])
|
|||||||
setitimer(ITIMER_REAL, &interval, NULL);
|
setitimer(ITIMER_REAL, &interval, NULL);
|
||||||
|
|
||||||
while(1) { }
|
while(1) { }
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = child_sigusr1_handler;
|
action.sa_handler = child_sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
child_process();
|
child_process();
|
||||||
} else {
|
} else {
|
||||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
|||||||
int status;
|
int status;
|
||||||
wait(&status);
|
wait(&status);
|
||||||
printf("main : end (%d)\n", status);
|
printf("main : end (%d)\n", status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
printf("%s: You must provide 2 dimensions.\n", argv[0]);
|
printf("%s: You must provide 2 dimensions.\n", argv[0]);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int rows = strtol(argv[1], &ptr, 10);
|
int rows = strtol(argv[1], &ptr, 10);
|
||||||
@@ -48,5 +48,5 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
sleep(5);
|
sleep(5);
|
||||||
pr_warning("Exiting!\n");
|
pr_warning("Exiting!\n");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
|
|||||||
key = ftok("/home/user/test7.txt", 5);
|
key = ftok("/home/user/test7.txt", 5);
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
perror("Failed to generate key using ftok");
|
perror("Failed to generate key using ftok");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Generated key using ftok (key = %d)\n", key);
|
printf("Generated key using ftok (key = %d)\n", key);
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
|
|||||||
msqid = msgget(key, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
msqid = msgget(key, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (msqid < 0) {
|
if (msqid < 0) {
|
||||||
perror("Failed to create message queue");
|
perror("Failed to create message queue");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Created message queue (id : %d)\n", msqid);
|
printf("Created message queue (id : %d)\n", msqid);
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
// Send the message.
|
// Send the message.
|
||||||
__send_message(msqid, 1, &message, "General Kenobi...");
|
__send_message(msqid, 1, &message, "General Kenobi...");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
// Receive the message.
|
// Receive the message.
|
||||||
__receive_message(msqid, 1, &message);
|
__receive_message(msqid, 1, &message);
|
||||||
@@ -106,5 +106,5 @@ int main(int argc, char *argv[])
|
|||||||
perror("Failed to remove message queue.");
|
perror("Failed to remove message queue.");
|
||||||
}
|
}
|
||||||
printf("Correctly removed message queue.\n");
|
printf("Correctly removed message queue.\n");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -42,5 +43,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -14,9 +15,9 @@ int main(int argc, char *argv[])
|
|||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if ((cpid = fork()) == 0) {
|
if ((cpid = fork()) == 0) {
|
||||||
execl("/bin/tests/t_alarm", "t_alarm", NULL);
|
execl("/bin/tests/t_alarm", "t_alarm", NULL);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (wait(NULL) != -1) continue;
|
while (wait(NULL) != -1) continue;
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ int main(int argc, char *argv[])
|
|||||||
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (semid < 0) {
|
if (semid < 0) {
|
||||||
perror("Failed to create semaphore set");
|
perror("Failed to create semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Created semaphore set (semid : %d)\n", semid);
|
printf("[father] Created semaphore set (semid : %d)\n", semid);
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, SETVAL, &arg);
|
ret = semctl(semid, 0, SETVAL, &arg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to set value of semaphore");
|
perror("Failed to set value of semaphore");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
|
|||||||
// Increment semaphore value.
|
// Increment semaphore value.
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform first child operation");
|
perror("Failed to perform first child operation");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
printf("[child] Exit, now.\n", semid, ret);
|
printf("[child] Exit, now.\n", semid, ret);
|
||||||
@@ -87,14 +87,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[child] Correctly removed semaphore set.\n");
|
printf("[child] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Perform the operations.
|
// Perform the operations.
|
||||||
if (semop(semid, op, 2) < 0) {
|
if (semop(semid, op, 2) < 0) {
|
||||||
perror("Failed to perform operation");
|
perror("Failed to perform operation");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Performed semaphore operations (id : %d)\n", semid);
|
printf("[father] Performed semaphore operations (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -115,5 +115,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[father] Correctly removed semaphore set.\n");
|
printf("[father] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -26,7 +26,7 @@ int main(int argc, char *argv[])
|
|||||||
key = ftok("/home/user/test7.txt", 5);
|
key = ftok("/home/user/test7.txt", 5);
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
perror("Failed to generate key using ftok.");
|
perror("Failed to generate key using ftok.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Generated key using ftok (key = %d)\n", key);
|
printf("Generated key using ftok (key = %d)\n", key);
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
|
|||||||
semid = semget(key, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
semid = semget(key, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (semid < 0) {
|
if (semid < 0) {
|
||||||
perror("Failed to create semaphore set.");
|
perror("Failed to create semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Created semaphore set (id : %d)\n", semid);
|
printf("[father] Created semaphore set (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, SETVAL, &arg);
|
ret = semctl(semid, 0, SETVAL, &arg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to set value of semaphore.");
|
perror("Failed to set value of semaphore.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform first child operation.");
|
perror("Failed to perform first child operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform second child operation.");
|
perror("Failed to perform second child operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -95,14 +95,14 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
printf("[child] Exit, now.\n", semid, ret);
|
printf("[child] Exit, now.\n", semid, ret);
|
||||||
|
|
||||||
// Exit with the child process.
|
// Exit with the child process.
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
|
|||||||
// Perform the operations.
|
// Perform the operations.
|
||||||
if (semop(semid, op_father, 3) < 0) {
|
if (semop(semid, op_father, 3) < 0) {
|
||||||
perror("Failed to perform father operation.");
|
perror("Failed to perform father operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(2);
|
sleep(2);
|
||||||
@@ -132,7 +132,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
@@ -143,5 +143,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[father] Correctly removed semaphore set.\n");
|
printf("[father] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (semctl(semid, 0, SETALL, &arg) == -1) {
|
if (semctl(semid, 0, SETALL, &arg) == -1) {
|
||||||
perror("Failed to set semaphores");
|
perror("Failed to set semaphores");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fork()) {
|
if (!fork()) {
|
||||||
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
|
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
|
||||||
perror("Failed to remove IPC");
|
perror("Failed to remove IPC");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
||||||
printf("Failed to set env: `PWD`\n");
|
printf("Failed to set env: `PWD`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
@@ -24,5 +24,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
wait(&status);
|
wait(&status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = sigusr1_handler;
|
action.sa_handler = sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("main : Calling handler (%d).\n", SIGUSR1);
|
printf("main : Calling handler (%d).\n", SIGUSR1);
|
||||||
@@ -41,8 +41,9 @@ int main(int argc, char *argv[])
|
|||||||
int ret = kill(getpid(), SIGUSR1);
|
int ret = kill(getpid(), SIGUSR1);
|
||||||
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
||||||
printf("main : value : %d\n", values);
|
printf("main : value : %d\n", values);
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
printf("values[%d] : `%d`\n", i, values[i]);
|
printf("values[%d] : `%d`\n", i, values[i]);
|
||||||
|
}
|
||||||
free(values);
|
free(values);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Diving by zero (unrecoverable)...\n");
|
printf("Diving by zero (unrecoverable)...\n");
|
||||||
@@ -57,4 +57,5 @@ int main(int argc, char *argv[])
|
|||||||
d /= e;
|
d /= e;
|
||||||
e -= 1;
|
e -= 1;
|
||||||
printf("d: %d, e: %d\n", d, e);
|
printf("d: %d, e: %d\n", d, e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Diving by zero (unrecoverable)...\n");
|
printf("Diving by zero (unrecoverable)...\n");
|
||||||
@@ -48,4 +48,5 @@ int main(int argc, char *argv[])
|
|||||||
e -= 1;
|
e -= 1;
|
||||||
}
|
}
|
||||||
printf("d: %d, e: %d\n", d, e);
|
printf("d: %d, e: %d\n", d, e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = sigusr1_handler;
|
action.sa_handler = sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%d, %s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%d, %s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("main : Blocking signal (%d).\n", SIGUSR1);
|
printf("main : Blocking signal (%d).\n", SIGUSR1);
|
||||||
@@ -45,5 +45,5 @@ int main(int argc, char *argv[])
|
|||||||
ret = kill(getpid(), SIGUSR1);
|
ret = kill(getpid(), SIGUSR1);
|
||||||
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sigaction(SIGUSR2, &action, NULL) == -1) {
|
if (sigaction(SIGUSR2, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR2, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR2, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
kill(getpid(), SIGUSR1);
|
kill(getpid(), SIGUSR1);
|
||||||
@@ -51,5 +51,6 @@ int main(int argc, char *argv[])
|
|||||||
kill(getpid(), SIGUSR2);
|
kill(getpid(), SIGUSR2);
|
||||||
|
|
||||||
while(1) { };
|
while(1) { };
|
||||||
return 0;
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ int main(int argc, char *argv[])
|
|||||||
sleep(4);
|
sleep(4);
|
||||||
printf("COMPLETED.\n");
|
printf("COMPLETED.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = wait_for_child;
|
action.sa_handler = wait_for_child;
|
||||||
if (sigaction(SIGCHLD, &action, NULL) == -1) {
|
if (sigaction(SIGCHLD, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler. %d\n", SIGCHLD);
|
printf("Failed to set signal handler. %d\n", SIGCHLD);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
@@ -55,5 +55,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user