28 Commits

Author SHA1 Message Date
Mirco De Marchi fb8f820383 Merge branch 'master' into feature/Feature-DeadlockExercise 2021-04-12 02:14:41 +02:00
Mirco De Marchi a8201fcdde Fix MacOS installation instructions 2021-04-12 02:13:23 +02:00
Mirco De Marchi eecb9dcc71 Update README.md with deadlock prevention enablement info 2021-03-26 19:01:34 +01:00
Mirco De Marchi feee0b80db Clean code 2021-03-26 18:28:19 +01:00
Mirco De Marchi a5bc390cf0 Rename available, max, alloc and need deadlock structures 2021-03-26 16:00:39 +01:00
Mirco De Marchi eafaca084f Replace tabs with spaces 2021-03-26 14:53:02 +01:00
Mirco De Marchi f957e05615 Integrate OS compatibility in this brench 2021-03-26 14:48:07 +01:00
Enrico Fraccaroli 05c3f2c033 Add skeleton code for deadlock prevention. 2021-03-23 13:32:46 +01:00
Enrico Fraccaroli 1236941a9c Merge pull request #4 from mentos-team/compatibility
Compatibility
2021-01-26 10:02:28 +01:00
Mirco De Marchi de33947249 Update README.md with prerequisistes install commands and some fix 2021-01-19 21:24:53 +01:00
Mirco De Marchi 05397f24c9 Add compatibility for GCC 10
Insert additional -fcommon C flag to obtain the same behavior of previous versions of GCC compilers, because
now, by default GCC 10 compiler has the -fno-common flag
that give error when omitting extern when declaring
a global variable in a header file.

TODO: for the next MentOS release check the "extern"
keyword in global variable in header files.
2021-01-19 19:17:59 +01:00
Mirco De Marchi 0d8fa6c9cd Remove SDL in qemu command for ubuntu 19 and 20
Add compatibility for ubuntu lsb versions that haven't sdl support
2021-01-19 17:02:56 +01:00
Mirco De Marchi b47110b402 Improve compatibility for Ubuntu 18.04
Disable ASM_NASM language and take only ASM language with third_party nasm tool to avoid errors.
2021-01-19 15:43:53 +01:00
Mirco De Marchi f99b9f739c Add MacOS compatibility with cross-compiler toolchain 2021-01-19 10:42:42 +01:00
Enrico Fraccaroli 6fd063984a Add new defines to vfs types 2019-05-16 17:22:47 +02:00
Enrico Fraccaroli bc2623ce99 Clean up stdlib 2019-05-16 17:22:21 +02:00
Enrico Fraccaroli c16a750251 Use standard limits for VFS file and path length 2019-05-16 17:13:35 +02:00
Enrico Fraccaroli c673fb9351 Improve multiboot code 2019-05-16 17:03:37 +02:00
Enrico Fraccaroli 25ffb602ea Improve multiboot info 2019-05-16 16:19:26 +02:00
Enrico Fraccaroli 552e2a073f Update limit values 2019-05-16 13:59:07 +02:00
Enrico Fraccaroli c0e5808656 Standardize most system calls 2019-05-10 17:18:34 +02:00
Enrico Fraccaroli 9368b0d6eb Canonicalize sys_open and sys_close, add close System Call 2019-05-10 12:26:30 +02:00
Enrico Fraccaroli 3bfa61d189 Re-format the code 2019-05-10 12:07:35 +02:00
Enrico Fraccaroli d9fd3b1646 Clean math code 2019-05-10 12:04:50 +02:00
Enrico Fraccaroli 14d64d25d3 Remove getchar old code 2019-05-10 12:01:10 +02:00
Enrico Fraccaroli dbeed54f2b Just return 0 when passing NULL string to atoi 2019-05-10 12:00:03 +02:00
Enrico Fraccaroli 07bd4d7901 Improve atoi function, safeguard gets function from out-of-bound errors 2019-05-10 11:59:18 +02:00
Enrico Fraccaroli 614d3dfd62 Standardize assert 2019-05-10 11:28:47 +02:00
236 changed files with 25954 additions and 24412 deletions
+36 -2
View File
@@ -1,5 +1,40 @@
# ------------------------------------------------------------------------------
# Initialize the project.
project(MentOs)
cmake_minimum_required(VERSION 2.8.4) cmake_minimum_required(VERSION 2.8.4)
message(STATUS "Crosscompiling: ${CMAKE_CROSSCOMPILING}")
# ------------------------------------------------------------------------------
# Add operating system specific option.
message(STATUS "System name: ${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "Kernel version: ${CMAKE_SYSTEM_VERSION}")
if ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE)
# Apple MacOSx
elseif ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32)
# Windows
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
else()
# Generic Unix System
find_program(LSB_RELEASE_EXEC lsb_release)
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release
OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "LSB version: ${LSB_RELEASE_VERSION_SHORT}")
if (${LSB_RELEASE_VERSION_SHORT} MATCHES "^18")
# Ubuntu 18
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^19")
# Ubuntu 19
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^20")
# Ubuntu 20
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
else()
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
endif()
endif()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Add the debugging option. # Add the debugging option.
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
@@ -28,7 +63,7 @@ add_custom_target(
COMMAND echo "---------------------------------------------" COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initfs'..." COMMAND echo "Initializing 'initfs'..."
COMMAND echo "---------------------------------------------" COMMAND echo "---------------------------------------------"
COMMAND initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev COMMAND ./initscp/initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
COMMAND echo "---------------------------------------------" COMMAND echo "---------------------------------------------"
COMMAND echo "Done!" COMMAND echo "Done!"
COMMAND echo "---------------------------------------------" COMMAND echo "---------------------------------------------"
@@ -49,7 +84,6 @@ elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
endif () endif ()
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std) SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it) SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE}) SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin) SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
SET(EMULATOR_FS -initrd initfs) SET(EMULATOR_FS -initrd initfs)
+94 -6
View File
@@ -36,6 +36,9 @@ Main Developers:
Prerequisites Prerequisites
----------------- -----------------
MentOS is compatible with the main Unix distribution operating systems. It has been tested with *Ubuntu* and *MacOS*, but specifically tested on *Ubuntu 18.04*.
For compiling the main system: For compiling the main system:
* nasm * nasm
@@ -47,17 +50,44 @@ For compiling the main system:
To run and try: To run and try:
* qemu-system-x86 * qemu-system-i386
For debugging: For debugging:
* ccmake * ccmake
* gdb or cgdb * cgdb
* xterm * xterm
For MacOS, you have additional dependencies:
* i386-elf-binutils (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
* i386-elf-gcc (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
Prerequisites installation commands
-----------------
For Ubuntu:
```
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y build-essential git cmake qemu-system-i386
sudo apt-get install -y cgdb xterm #<- for debug only
```
For MacOS:
You need to install additionally the i386-elf cross-compiler. The simplest installation method is through Homebrew package manager. Install [Homebrew](https://brew.sh/index_it) if you don't already have and exec the following commands:
```
brew update && brew upgrade
brew tap nativeos/i386-elf-toolchain
brew install i386-elf-binutils i386-elf-gcc git cmake qemu nasm
brew install cgdb xterm #<- for debug only
```
Compiling MentOS Compiling MentOS
----------------- -----------------
Compile and boot MentOS with qemu: Compile and boot MentOS with qemu in Unix systems:
``` ```
cd <clone_directory> cd <clone_directory>
@@ -70,6 +100,12 @@ make qemu
If you want to access to the shell, use one of the usernames listed in files/passwd. If you want to access to the shell, use one of the usernames listed in files/passwd.
**For MacOS**, the steps are the same but instead of `cmake ..`, you have to put an additional argument in order to use the i386-elf cross-compiler:
```
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
```
Change the scheduling algorithm Change the scheduling algorithm
----------------- -----------------
@@ -80,6 +116,23 @@ MentOS provides three different scheduling algorithms:
* Completely Fair Scheduling * Completely Fair Scheduling
If you want to change the scheduling algorithm: If you want to change the scheduling algorithm:
```
cd build
# Round Robin scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_RR ..
# Priority scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_PRIORITY ..
# Completely Fair Scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_CFS ..
make
make qemu
```
Otherwise you can use `ccmake`:
``` ```
cd build cd build
cmake .. cmake ..
@@ -107,13 +160,23 @@ make
make qemu make qemu
``` ```
Enable to Buddy System Enable Buddy System
----------------- -----------------
MentOS provides a Buddy System to manage the allocation and deallocation of MentOS provides a Buddy System to manage the allocation and deallocation of
page frames in the physical memory. page frames in physical memory.
If you want to enable MentOS's Buddy System:
```
cd build
cmake -DENABLE_BUDDY_SYSTEM=ON ..
make
make qemu
```
Otherwise you can use `ccmake`:
If you want to enable the MentOS's Buddy System:
``` ```
cd build cd build
cmake .. cmake ..
@@ -150,6 +213,31 @@ make
make qemu make qemu
``` ```
Enable Deadlock Prevention
-----------------
MentOS implements the Banker's Algorithm to perform deadlock prevention for
user-space tasks.
If you want to enable deadlock prevention in MentOS:
```
cd build
cmake -DENABLE_DEADLOCK_PREVENTION=ON ..
make
make qemu
```
Otherwise you can use `ccmake` as shown previously for Buddy System enablement.
You can control the behavior of the deadlock algorithm with a shell command
line that allows you to run two mis-synchronized processes on two shared
resources, bringing the operating system into a possible deadlock state.
Of course the deadlock state is not always reached, because the tasks scheduling
is nondeterministic. The shell command line is `deadlock [-i <iter>]` where the
optional parameter `-i <iter>` specify the number of iterations of created tasks
over the shared resources, by default it will perform only 1 iteration.
Use Debugger Use Debugger
----------------- -----------------
If you want to use GDB to debug MentOS: If you want to use GDB to debug MentOS:
+180 -181
View File
@@ -1,181 +1,180 @@
| EAX | Name | Source | EBX | ECX | EDX | ESX | EDI | | S | EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------| |:--|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
| 1 | sys_exit | kernel/exit.c | int | - | - | - | - | | 1 | 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
| 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - | | | 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - | | 1 | 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
| 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - | | 1 | 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
| 5 | sys_open | fs/open.c | const char * | int | int | - | - | | 1 | 5 | sys_open | fs/open.c | const char * | int | int | - | - |
| 6 | sys_close | fs/open.c | unsigned int | - | - | - | - | | 1 | 6 | sys_close | fs/open.c | int | - | - | - | - |
| 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - | | 1 | 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
| 8 | sys_creat | fs/open.c | const char * | int | - | - | - | | | 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
| 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - | | | 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
| 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - | | | 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
| 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - | | 1 | 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 12 | sys_chdir | fs/open.c | const char * | - | - | - | - | | 1 | 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
| 13 | sys_time | kernel/time.c | int * | - | - | - | - | | | 13 | sys_time | kernel/time.c | int * | - | - | - | - |
| 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - | | | 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
| 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - | | | 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
| 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - | | | 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - | | 1 | 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - | | | 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
| 20 | sys_getpid | kernel/sched.c | - | - | - | - | - | | 1 | 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
| 21 | sys_mount | fs/super.c | char * | char * | char * | - | - | | | 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
| 22 | sys_oldumount | fs/super.c | char * | - | - | - | - | | | 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
| 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - | | | 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
| 24 | sys_getuid | kernel/sched.c | - | - | - | - | - | | | 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
| 25 | sys_stime | kernel/time.c | int * | - | - | - | - | | | 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
| 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - | | | 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
| 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - | | | 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
| 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - | | | 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
| 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - | | | 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
| 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - | | | 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
| 33 | sys_access | fs/open.c | const char * | int | - | - | - | | | 33 | sys_access | fs/open.c | const char * | int | - | - | - |
| 34 | sys_nice | kernel/sched.c | int | - | - | - | - | | 1 | 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
| 36 | sys_sync | fs/buffer.c | - | - | - | - | - | | | 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
| 37 | sys_kill | kernel/signal.c | int | int | - | - | - | | | 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
| 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - | | | 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
| 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - | | 1 | 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
| 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - | | | 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
| 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - | | | 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
| 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - | | | 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
| 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - | | | 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
| 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - | | | 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
| 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - | | | 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
| 47 | sys_getgid | kernel/sched.c | - | - | - | - | - | | | 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
| 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - | | | 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
| 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - | | | 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
| 50 | sys_getegid | kernel/sched.c | - | - | - | - | - | | | 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
| 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - | | | 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
| 52 | sys_umount | fs/super.c | char * | int | - | - | - | | | 52 | sys_umount | fs/super.c | char * | int | - | - | - |
| 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - | | | 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
| 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - | | | 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - |
| 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - | | | 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - |
| 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - | | | 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
| 60 | sys_umask | kernel/sys.c | int | - | - | - | - | | | 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
| 61 | sys_chroot | fs/open.c | const char * | - | - | - | - | | | 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
| 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - | | | 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
| 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - | | | 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
| 64 | sys_getppid | kernel/sched.c | - | - | - | - | - | | 1 | 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
| 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - | | | 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - |
| 66 | sys_setsid | kernel/sys.c | - | - | - | - | - | | | 66 | sys_setsid | kernel/sys.c | - | - | - | - | - |
| 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - | | | 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
| 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - | | | 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
| 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - | | | 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
| 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - | | | 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
| 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - | | | 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
| 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - | | | 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
| 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - | | | 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
| 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - | | | 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
| 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - | | | 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - | | | 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
| 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - | | | 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - |
| 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - | | | 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - | | | 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
| 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - | | | 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - | | | 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
| | 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
| 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - | | | 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - | | | 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
| 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - | | | 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
| 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - | | | 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
| 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - | | 1 | 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
| 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - | | 1 | 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - | | | 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
| 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - | | | 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
| 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - | | | 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
| 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - | | | 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
| 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - | | | 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
| 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - | | | 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
| 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - | | | 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
| 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - | | | 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
| 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - | | | 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - |
| 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - | | | 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - |
| 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - | | | 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - |
| 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - | | | 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
| 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - | | | 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
| 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - | | | 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
| 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - | | | 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
| 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - | | | 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - |
| 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - | | | 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - |
| 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - | | | 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - |
| 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - | | | 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
| 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - | | | 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
| 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - | | | 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
| 111 | sys_vhangup | fs/open.c | - | - | - | - | - | | | 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
| 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - | | | 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - |
| 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - | | | 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - |
| 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - | | | 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
| 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - | | | 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
| 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - | | | 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
| 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * | | | 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
| 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - | | | 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - | | | 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - | | | 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
| 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - | | | 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
| 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - | | | 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
| 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - | | | 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
| 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - | | | 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - |
| 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - | | | 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - |
| 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - | | | 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
| 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - | | | 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
| 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - | | | 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
| 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - | | | 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
| 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - | | | 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
| 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - | | | 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
| 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - | | | 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
| 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - | | | 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
| 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - | | | 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
| 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - | | | 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
| 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - | | | 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - |
| 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - | | | 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - |
| 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - | | | 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int |
| 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int | | | 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - | | | 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * |
| 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * | | | 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - |
| 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - | | | 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - |
| 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - | | | 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - | | | 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - | | | 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
| 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - | | | 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
| 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - | | | 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
| 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - | | | 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - | | | 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - | | | 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
| 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - | | | 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
| 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - | | | 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
| 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - | | | 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
| 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - | | | 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - |
| 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - | | | 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
| 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - | | | 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
| 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - | | | 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - |
| 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - | | | 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - |
| 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - | | | 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - |
| 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - | | | 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
| 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - | | | 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - |
| 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - | | | 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - |
| 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - | | | 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
| 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - | | | 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - |
| 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - | | | 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * |
| 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * | | | 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
| 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - | | | 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
| 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - | | | 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - |
| 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - | | | 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - |
| 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - | | | 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long |
| 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long | | | 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - | | | 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - |
| 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - | | | 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - |
| 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - | | | 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - |
| 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - | | | 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - |
| 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - | | | 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - |
| 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - | | | 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - |
| 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - | | | 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - |
| 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - | | | 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - |
| 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - | | | 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - | | 1 | 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
| 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - | | | 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - |
| 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - | | | 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - |
| 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - | | | 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - |
| 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - | | | 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - |
| 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - | | 1 | 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - | | | | | | | | | | |
| | | | | | | | |
+6 -4
View File
@@ -6,6 +6,12 @@ project(initfscp C ASM)
# Set the project name. # Set the project name.
set(PROJECT_NAME initfscp) set(PROJECT_NAME initfscp)
if (CMAKE_CROSSCOMPILING)
set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_EXE_LINKER_FLAGS "")
endif (CMAKE_CROSSCOMPILING)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Set the compiler options (original). # Set the compiler options (original).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
@@ -13,10 +19,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
# ------------------------------------------------------------------------------
# Add the includes.
include_directories(inc)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Add the source files. # Add the source files.
set(SOURCE_FILES src/initfscp.c) set(SOURCE_FILES src/initfscp.c)
-42
View File
@@ -1,42 +0,0 @@
/// @file initfscp.h
/// @brief
#pragma once
#define MAX_FILENAME_LENGTH 64
#define MAX_FILES 32
#define INITFSCP_VER "0.3.0"
#define FS_FILE 0x01 ///< Identifies a file.
#define FS_DIRECTORY 0x02 ///< Identifies a directory.
#define FS_CHARDEVICE 0x04 ///< Identifies a character devies.
#define FS_BLOCKDEVICE 0x08 ///< Identifies a block devies.
#define FS_PIPE 0x10 ///< Identifies a pipe.
#define FS_SYMLINK 0x20 ///< Identifies a symbolic link.
#define FS_MOUNTPOINT 0x40 ///< Identifies a mount-point.
#define RESET "\033[00m"
#define BLACK "\033[30m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The name of the file.
char fileName[MAX_FILENAME_LENGTH];
/// The type of the file.
short int file_type;
/// The uid of the owner.
int uid;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} initrd_file_t;
+52 -7
View File
@@ -4,16 +4,60 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <initfscp.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <libgen.h> #include <libgen.h>
#include <dirent.h> #include <dirent.h>
#include <assert.h> #include <assert.h>
#define INITFSCP_VER "0.3.0"
#define INITFSCP_NAME_MAX 255
#define INITFSCP_MAX_FILES 32
#define RESET "\033[00m"
#define BLACK "\033[30m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
/// Identifies a file.
#define FS_FILE 0x01
/// Identifies a directory.
#define FS_DIRECTORY 0x02
/// Identifies a character devies.
#define FS_CHARDEVICE 0x04
/// Identifies a block devies.
#define FS_BLOCKDEVICE 0x08
/// Identifies a pipe.
#define FS_PIPE 0x10
/// Identifies a symbolic link.
#define FS_SYMLINK 0x20
/// Identifies a mount-point.
#define FS_MOUNTPOINT 0x40
/// @brief Information concerning a file.
typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF.
int magic;
/// The name of the file.
char fileName[INITFSCP_NAME_MAX];
/// The type of the file.
short int file_type;
/// The uid of the owner.
int uid;
/// Offset of the starting address.
unsigned int offset;
/// Dimension of the file.
unsigned int length;
} initrd_file_t;
static FILE *target_fs = NULL; static FILE *target_fs = NULL;
static initrd_file_t headers[MAX_FILES]; static initrd_file_t headers[INITFSCP_MAX_FILES];
static char mount_points[MAX_FILES][MAX_FILENAME_LENGTH]; static char mount_points[INITFSCP_MAX_FILES][INITFSCP_NAME_MAX];
static int mountpoint_idx = 0; static int mountpoint_idx = 0;
static int header_idx = 0; static int header_idx = 0;
static int header_offset = 0; static int header_offset = 0;
@@ -91,9 +135,9 @@ static bool open_target_fs(int argc, char *argv[])
static bool init_headers() static bool init_headers()
{ {
printf("%-64s", "Initializing headers structures..."); printf("%-64s", "Initializing headers structures...");
for (size_t i = 0; i < MAX_FILES; i++) { for (size_t i = 0; i < INITFSCP_MAX_FILES; i++) {
headers[i].magic = 0xBF; headers[i].magic = 0xBF;
memset(headers[i].fileName, 0, MAX_FILENAME_LENGTH); memset(headers[i].fileName, 0, INITFSCP_NAME_MAX);
headers[i].file_type = 0; headers[i].file_type = 0;
headers[i].uid = 0; headers[i].uid = 0;
headers[i].offset = 0; headers[i].offset = 0;
@@ -218,7 +262,7 @@ static bool create_file_headers(char *mountpoint, char *directory)
static bool write_file_system(char *mountpoint) static bool write_file_system(char *mountpoint)
{ {
printf("Copying data to filesystem...\n"); printf("Copying data to filesystem...\n");
for (int i = 0; i < MAX_FILES; i++) { for (int i = 0; i < INITFSCP_MAX_FILES; i++) {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
char absolute_path[256]; char absolute_path[256];
memset(absolute_path, 0, 256); memset(absolute_path, 0, 256);
@@ -288,7 +332,8 @@ int main(int argc, char *argv[])
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Create file headers. // Create file headers.
header_offset = sizeof(struct initrd_file_t) * MAX_FILES + sizeof(int); header_offset =
sizeof(struct initrd_file_t) * INITFSCP_MAX_FILES + sizeof(int);
printf("Creating headers...\n"); printf("Creating headers...\n");
for (uint32_t i = 1; i < argc; ++i) { for (uint32_t i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) { if (is_option_source(argv[i]) && ((i + 1) < argc)) {
+51 -12
View File
@@ -1,10 +1,17 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Initialize the project. # Initialize the project.
project(MentOs C ASM) project(MentOs C ASM)
set(PROJECT_NAME MentOs)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Set the project name. # Add operating system specific option.
set(PROJECT_NAME MentOs) if((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE) # Apple MacOSx
set(CMAKE_ASM_COMPILER nasm)
elseif ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32) # Windows
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
else () # Generic Unix System
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
endif ()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Find doxygen # Find doxygen
@@ -63,6 +70,16 @@ else (ENABLE_BUDDY_SYSTEM)
message(STATUS "Buddy system disabled.") message(STATUS "Buddy system disabled.")
endif (ENABLE_BUDDY_SYSTEM) endif (ENABLE_BUDDY_SYSTEM)
# ------------------------------------------------------------------------------
# Add the option to enable deadlock prevention.
option(ENABLE_DEADLOCK_PREVENTION "Enables the buddy system" OFF)
if (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Enabling deadlock prevention.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_DEADLOCK_PREVENTION")
else (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Deadlock prevention disabled.")
endif (ENABLE_DEADLOCK_PREVENTION)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Set the compiler options (original). # Set the compiler options (original).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
@@ -128,6 +145,10 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
endif()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
if (CMAKE_BUILD_TYPE MATCHES "Release") if (CMAKE_BUILD_TYPE MATCHES "Release")
@@ -137,13 +158,11 @@ endif (CMAKE_BUILD_TYPE MATCHES "Release")
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Set the assembly flags. # Set the assembly flags.
enable_language(ASM) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf") set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> <SOURCE> -o <OBJECT>")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Add the includes. # Add the includes.
@@ -162,6 +181,8 @@ include_directories(
inc/mem inc/mem
inc/misc inc/misc
inc/sys inc/sys
inc/experimental
inc/experimental/math
inc/system inc/system
inc/process inc/process
inc/elf inc/elf
@@ -188,10 +209,18 @@ set(SOURCE_FILES
src/drivers/keyboard/keyboard.c src/drivers/keyboard/keyboard.c
src/drivers/keyboard/keymap.c src/drivers/keyboard/keymap.c
src/experimental/smart_sem_kernel.c
src/experimental/smart_sem_user.c
src/experimental/resource.c
src/experimental/math/arr_math.c
src/fs/fcntl.c src/fs/fcntl.c
src/fs/initrd.c src/fs/initrd.c
src/fs/vfs.c src/fs/vfs.c
src/fs/read_write.c src/fs/read_write.c
src/fs/open.c
src/fs/stat.c
src/fs/readdir.c
src/sys/module.c src/sys/module.c
src/sys/unistd.c src/sys/unistd.c
@@ -204,6 +233,7 @@ set(SOURCE_FILES
src/kernel/sys.c src/kernel/sys.c
src/libc/assert.c
src/libc/ctype.c src/libc/ctype.c
src/libc/stdio.c src/libc/stdio.c
src/libc/string.c src/libc/string.c
@@ -236,6 +266,9 @@ set(SOURCE_FILES
src/libc/unistd/waitpid.c src/libc/unistd/waitpid.c
src/libc/unistd/chdir.c src/libc/unistd/chdir.c
src/libc/unistd/getcwd.c src/libc/unistd/getcwd.c
src/libc/unistd/close.c
src/libc/unistd/stat.c
src/libc/unistd/mkdir.c
src/mem/kheap.c src/mem/kheap.c
src/mem/paging.c src/mem/paging.c
@@ -245,9 +278,7 @@ set(SOURCE_FILES
src/misc/clock.c src/misc/clock.c
src/misc/debug.c src/misc/debug.c
src/sys/dirent.c src/sys/dirent.c
src/sys/stat.c
src/sys/utsname.c src/sys/utsname.c
#src/sys/shm.c
src/elf/elf.c src/elf/elf.c
src/descriptor_tables/gdt.c src/descriptor_tables/gdt.c
@@ -297,6 +328,7 @@ set(SOURCE_FILES
src/ui/command/cmd_ipcs.c src/ui/command/cmd_ipcs.c
src/ui/command/cmd_ipcrm.c src/ui/command/cmd_ipcrm.c
src/ui/command/cmd_nice.c src/ui/command/cmd_nice.c
src/ui/command/cmd_deadlock.c
src/ui/init/init.c src/ui/init/init.c
@@ -310,6 +342,13 @@ if (ENABLE_BUDDY_SYSTEM MATCHES "ON")
src/mem/buddysystem.c) src/mem/buddysystem.c)
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON") endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
if (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
set(SOURCE_FILES
${SOURCE_FILES}
src/experimental/deadlock_prevention.c
src/experimental/deadlock_simulation.c)
endif (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Add the executable. # Add the executable.
add_library(${PROJECT_NAME} ${SOURCE_FILES}) add_library(${PROJECT_NAME} ${SOURCE_FILES})
@@ -319,7 +358,7 @@ add_library(${PROJECT_NAME} ${SOURCE_FILES})
add_custom_command( add_custom_command(
TARGET MentOs TARGET MentOs
POST_BUILD POST_BUILD
COMMAND $(LD) COMMAND ${CMAKE_LINKER}
-melf_i386 -melf_i386
-static -static
--oformat elf32-i386 --oformat elf32-i386
+22 -14
View File
@@ -7,20 +7,26 @@
[BITS 32] ; All instructions should be 32-bit. [BITS 32] ; All instructions should be 32-bit.
[EXTERN kmain] ; The start point of our C code [EXTERN kmain] ; The start point of our C code
; Grub is informed with this flag to load ; The magic field should contain this.
; the kernel and kernel modules on a page boundary. MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MBOOT_PAGE_ALIGN equ 1<<0 ; This should be in %eax.
; Grub is informed with this flag to provide the kernel MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
; with memory information.
MBOOT_MEM_INFO equ 1<<1 ; = Specify what GRUB should PROVIDE =========================================
; This is the multiboot magic value. ; Align the kernel and kernel modules on i386 page (4KB) boundaries.
MBOOT_HEADER_MAGIC equ 0x1BADB002 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 ; This is the flag combination that we prepare for Grub
; to read at kernel load time. ; to read at kernel load time.
MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO MULTIBOOT_HEADER_FLAGS equ (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE)
; Grub reads this value to make sure it loads a kernel ; Grub reads this value to make sure it loads a kernel
; and not just garbage. ; and not just garbage.
MBOOT_CHECKSUM equ - (MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS) MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
LOAD_MEMORY_ADDRESS equ 0x00000000 LOAD_MEMORY_ADDRESS equ 0x00000000
; reserve (1024*1024) for the stack on a doubleword boundary ; reserve (1024*1024) for the stack on a doubleword boundary
@@ -33,9 +39,12 @@ section .multiboot_header
align 4 align 4
; This is the GRUB Multiboot header. ; This is the GRUB Multiboot header.
multiboot_header: multiboot_header:
dd MBOOT_HEADER_MAGIC ; magic
dd MBOOT_HEADER_FLAGS dd MULTIBOOT_HEADER_MAGIC
dd MBOOT_CHECKSUM ; flags
dd MULTIBOOT_HEADER_FLAGS
; checksum
dd MULTIBOOT_CHECKSUM
; ----------------------------------------------------------------------------- ; -----------------------------------------------------------------------------
; SECTION (data) ; SECTION (data)
@@ -61,7 +70,6 @@ kernel_entry:
mov esp, stack_top mov esp, stack_top
; pass the initial ESP ; pass the initial ESP
push esp push esp
;mov ebp, esp
; pass Multiboot info structure ; pass Multiboot info structure
push ebx push ebx
; pass Multiboot magic number ; pass Multiboot magic number
+21 -25
View File
@@ -14,19 +14,19 @@
#define IDT_SIZE 256 #define IDT_SIZE 256
/// When an exception occurs whose entry is a Task Gate, a task switch results. /// When an exception occurs whose entry is a Task Gate, a task switch results.
#define TASK_GATE 0x5 #define TASK_GATE 0x5
/// Used to specify an interrupt service routine (16-bit). /// Used to specify an interrupt service routine (16-bit).
#define INT16_GATE 0x6 #define INT16_GATE 0x6
/// @brief Similar to an Interrupt gate (16-bit). /// @brief Similar to an Interrupt gate (16-bit).
#define TRAP16_GATE 0x7 #define TRAP16_GATE 0x7
/// Used to specify an interrupt service routine (32-bit). /// Used to specify an interrupt service routine (32-bit).
#define INT32_GATE 0xE #define INT32_GATE 0xE
/// @brief Similar to an Interrupt gate (32-bit). /// @brief Similar to an Interrupt gate (32-bit).
#define TRAP32_GATE 0xF #define TRAP32_GATE 0xF
/* /*
* Trap and Interrupt gates are similar, and their descriptors are * Trap and Interrupt gates are similar, and their descriptors are
@@ -36,25 +36,23 @@
*/ */
/// @brief This structure describes one interrupt gate. /// @brief This structure describes one interrupt gate.
typedef struct idt_descriptor_t typedef struct idt_descriptor_t {
{ unsigned short offset_low;
unsigned short offset_low; unsigned short seg_selector;
unsigned short seg_selector; // This will ALWAYS be set to 0.
// This will ALWAYS be set to 0. unsigned char null_par;
unsigned char null_par; // |P|DPL|01110|.
// |P|DPL|01110|. // P present, DPL required Ring (2bits).
// P present, DPL required Ring (2bits). unsigned char options;
unsigned char options; unsigned short offset_high;
unsigned short offset_high;
} __attribute__((packed)) idt_descriptor_t; } __attribute__((packed)) idt_descriptor_t;
/// @brief A pointer structure used for informing the CPU about our IDT. /// @brief A pointer structure used for informing the CPU about our IDT.
typedef struct idt_pointer_t typedef struct idt_pointer_t {
{ /// The size of the IDT (entry number).
/// The size of the IDT (entry number). unsigned short int limit;
unsigned short int limit; /// The start address of the IDT.
/// The start address of the IDT. unsigned int base;
unsigned int base;
} __attribute__((packed)) idt_pointer_t; } __attribute__((packed)) idt_pointer_t;
/// @brief Initialise the interrupt descriptor table. /// @brief Initialise the interrupt descriptor table.
@@ -65,10 +63,8 @@ void init_idt();
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione /// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER) /// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
/// @param seg_sel Il selettore del segmento della GDT. /// @param seg_sel Il selettore del segmento della GDT.
void idt_set_gate(uint8_t index, void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
interrupt_handler_t handler, uint8_t seg_sel);
uint16_t options,
uint8_t seg_sel);
//==== List of exceptions generated internally by the CPU ====================== //==== List of exceptions generated internally by the CPU ======================
extern void INT_0(); extern void INT_0();
+5 -5
View File
@@ -155,7 +155,7 @@
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
typedef void (*pci_func_t)(uint32_t device, uint16_t vendor_id, typedef void (*pci_func_t)(uint32_t device, uint16_t vendor_id,
uint16_t device_id, void *extra); uint16_t device_id, void *extra);
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
@@ -183,8 +183,8 @@ static inline int pci_extract_func(uint32_t device)
static inline uint32_t pci_get_addr(uint32_t device, int field) static inline uint32_t pci_get_addr(uint32_t device, int field)
{ {
return 0x80000000 | (pci_extract_bus(device) << 16) | return 0x80000000 | (pci_extract_bus(device) << 16) |
(pci_extract_slot(device) << 11) | (pci_extract_slot(device) << 11) | (pci_extract_func(device) << 8) |
(pci_extract_func(device) << 8) | ((field)&0xFC); ((field)&0xFC);
} }
// TODO: doxygen comment. // TODO: doxygen comment.
@@ -212,7 +212,7 @@ const char *pci_vendor_lookup(unsigned short vendor_id);
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
const char *pci_device_lookup(unsigned short vendor_id, const char *pci_device_lookup(unsigned short vendor_id,
unsigned short device_id); unsigned short device_id);
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra); void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra);
@@ -220,7 +220,7 @@ void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra);
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func, void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
void *extra); void *extra);
// TODO: doxygen comment. // TODO: doxygen comment.
/// @brief /// @brief
@@ -0,0 +1,38 @@
/**
* @author Mirco De Marchi
* @date 2/02/2021
* @brief Header file for deadlock prevention algorithms.
* @copyright (c) University of Verona
*/
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdbool.h"
#include "string.h"
/// @brief Resource allocation request status enumeration.
typedef enum {
SAFE, ///< State safe.
WAIT, ///< State waiting.
WAIT_UNSAFE, ///< State waiting for unsafe detection.
ERROR, ///< State error.
} deadlock_status_t;
/// @brief Request of resources perfomed by a task.
/// @param req_vec Array pointer of resource request for each task in the
/// system.
/// @param task_i Index of task that perform the request to use as array index.
/// @param arr_available Array of resources instances currently available.
/// @param mat_alloc Matrix of current resources instances allocation of
/// each task.
/// @param mat_need Matrix of current resources instances need of each
/// task. need[i][j] = max[i][j] - alloc[i][j]
/// @param n Number of tasks currently in the system.
/// @param m Number of resource types in the system (length of req_vec).
/// @return Status of the request (see status_t enum).
deadlock_status_t request(uint32_t *req_vec, size_t task_i,
uint32_t *arr_available, uint32_t ** mat_alloc, uint32_t **mat_need,
size_t n, size_t m);
@@ -0,0 +1,11 @@
/**
* @author Mirco De Marchi
* @date 2/02/2021
* @brief Header file for deadlock deterministic simulation.
* @copyright (c) University of Verona
*/
#pragma once
/// @brief Deadlock deterministic simulation start function.
void deadlock_simulation();
+150
View File
@@ -0,0 +1,150 @@
/// MentOS, The Mentoring Operating system project
/// @file arr_math.h
/// @brief Array arithmetic operations source file-
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdint.h"
#include "stdbool.h"
/// @brief Initialize all memory cells of destination array with a value.
/// @param dst Pointer of destination array.
/// @param value Value to use for array inizialization.
/// @param length Length of destination array.
/// @return The pointer of the destination array.
uint32_t *all(uint32_t *dst, uint32_t value, size_t length);
/// @brief Element wise array subtraction.
/// @param left Pointer of left operator and destination array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return The pointer of the destination array.
/// E.g. [4, 5, 6] - [1, 2, 3] = [3, 3, 3]
uint32_t *arr_sub(uint32_t *left, const uint32_t *right, size_t length);
/// @brief Element wise array addition.
/// @param left Pointer of left operator and destination array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return The pointer of the destination array.
/// E.g. [4, 5, 6] + [1, 2, 3] = [5, 7, 9]
uint32_t *arr_add(uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is greater than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array greater than the
/// respective right one, otherwise false.
/// E.g. [1, 1, 6] g_any [1, 2, 3] = true
/// [1, 1, 3] g_any [1, 2, 3] = false
bool_t arr_g_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is greater or equal than
/// another array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array greater or equal than
/// the respective right one, otherwise false.
/// E.g. [1, 1, 6] ge_any [1, 2, 3] = true
/// [0, 1, 3] ge_any [1, 2, 3] = true
/// [0, 1, 2] ge_any [1, 2, 3] = false
bool_t arr_ge_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is less than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array less than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] l_any [1, 1, 6] = true
/// [1, 2, 3] l_any [0, 1, 3] = false
bool_t arr_l_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is less or equal than
/// another array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array less or equal than
/// the respective right one, otherwise false.
/// E.g. [1, 2, 3] le_any [1, 1, 6] = true
/// [1, 2, 3] le_any [0, 1, 3] = true
/// [1, 2, 3] le_any [0, 1, 2] = false
bool_t arr_le_any(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is greater than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are greater than the
/// respective right one, otherwise false.
/// E.g. [2, 3, 4] g_all [1, 2, 3] = true
/// [2, 3, 3] g_all [1, 2, 3] = false
bool_t arr_g(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is greater or equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are greater or equal than the
/// respective right one, otherwise false.
/// E.g. [2, 3, 4] ge_all [1, 2, 3] = true
/// [2, 3, 3] ge_all [1, 2, 3] = true
/// [2, 3, 3] ge_all [1, 2, 4] = false
bool_t arr_ge(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is less than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are less than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] l_all [2, 3, 4] = true
/// [1, 2, 3] l_all [2, 3, 3] = false
bool_t arr_l(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is less or equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are less or equal than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] le_all [2, 3, 4] = true
/// [1, 2, 3] le_all [2, 3, 3] = true
/// [1, 2, 4] le_all [2, 3, 3] = false
bool_t arr_le(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if each element of an array is equal than another array in
/// relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if all elements of the left array are equal than the respective
/// right one, otherwise false.
/// E.g. [1, 2, 3] e_all [1, 2, 3] = true
/// [1, 2, 3] e_all [1, 2, 1] = false
bool_t arr_e(const uint32_t *left, const uint32_t *right, size_t length);
/// @brief Check if at least one element of an array is not equal than another
/// array in relation to the respective index.
/// @param left Pointer of left operator array.
/// @param right Pointer of right operator array.
/// @param length Length of arrays.
/// @return True if there is an element of the left array not equal than the
/// respective right one, otherwise false.
/// E.g. [1, 2, 3] e_all [1, 2, 1] = true
/// [1, 2, 3] e_all [1, 2, 3] = false
bool_t arr_ne(const uint32_t *left, const uint32_t *right, size_t length);
+101
View File
@@ -0,0 +1,101 @@
/// MentOS, The Mentoring Operating system project
/// @file resource.h
/// @brief Resource definition header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "process.h"
#include "stdint.h"
#include "types.h"
#include "list_head.h"
/// @brief Resource descriptor.
typedef struct resource {
/// Resource index. The resources indexes has to be continuous: 0, 1, ... M.
size_t rid;
/// List head for tasks that share this resource.
list_head resources_list;
/// Number of instances of this resource. For now, always 1.
size_t n_instances;
/// The category of the resource (added for debug purpose).
const char *category;
/// If the resource has been assigned, it points to the task assigned,
/// otherwise NULL.
task_struct *assigned_task;
/// Number of instances assigned to assigned task.
size_t assigned_instances;
} resource_t;
/// @brief Structure that maintains information about resources currently
/// allocated in the system.
typedef struct resource_list {
/// Number of queued resources.
size_t num_active;
/// Head of resources.
list_head head;
} resource_list_t;
/// @brief Resource creation.
/// @param category Resource category string, used to group resources.
/// @return The pointer to the resource created.
resource_t *resource_create(const char *category);
/// @brief Resource initialization.
/// @param r Pointer to a resource created.
void resource_init(resource_t *r);
/// @brief Resource destruction.
/// @param r Pointer to a resource created.
void resource_destroy(resource_t *r);
/// @brief Assign the ownership of a resource to the current calling task.
/// @param r Pointer to a resource created.
void resource_assign(resource_t *r);
/// @brief Remove the ownership of a resource from the current calling task.
/// @param r Pointer to a resource created.
void resource_deassign(resource_t *r);
/// @brief Initialize deadlock prevention structures.
/// @param available Array of resources instances currently available;
/// @param max Matrix of the maximum resources instances that each
/// task may require;
/// @param alloc Matrix of current resources instances allocation of
/// each task.
/// @param need Matrix of current resources instances need of each task.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
void init_deadlock_structures(uint32_t *available, uint32_t **max,
uint32_t **alloc, uint32_t **need,
task_struct *idx_map_task_struct[]);
/// @brief Reset to zero deadlock prevention structures.
/// @param available Array of resources instances currently available;
/// @param max Matrix of the maximum resources instances that each
/// task may require;
/// @param alloc Matrix of current resources instances allocation of
/// each task.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// There is no need to reset the need matrix because it has to be calculated
/// starting from max matrix, which is clean.
void reset_deadlock_structures(uint32_t *available, uint32_t **max,
uint32_t **alloc, task_struct *idx_map_task_struct[]);
/// @brief Get the number of total resources allocated in the system.
/// @return The number of resources.
size_t kernel_get_active_resources();
/// @brief Return the index of the current task contained in the array of index
/// and processes mapping.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// @return The index that maps with the current task in the
/// idx_map_task_struct array, or -1 if not found the mapping task.
int32_t get_current_task_idx_from(task_struct *idx_map_task_struct[]);
@@ -0,0 +1,37 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_kernel.h
/// @brief Smart semaphore semaphore kernel-side implementation header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
/// N.B. Header to use only in kernel space.
#pragma once
#include "stdatomic.h"
/// @brief Smart semaphore creation.
/// @return The semaphore id or -1 if creation failed.
int sys_sem_create();
/// @brief Destruction of a created smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if destroy failed, otherwise 0.
int sys_sem_destroy(int id);
/// @brief Initialization of a created smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if initialization failed, otherwise 0.
int sys_sem_init(int id);
/// @brief Tries a safety acquisition of a smart semaphore identified by
/// an ID and, if available, takes the ownership.
/// @param id Smart semaphore ID.
/// @return Return -1 if creation failed, return 0 if semaphore busy or
/// the acquisition is unsafe, otherwise return 1 if semaphore has been
/// acquired.
int sys_sem_try_acquire(int id);
/// @brief Release the ownership of a smart semaphore.
/// @param id Smart semaphore ID.
/// @return Return -1 if release failed, otherwise 0.
int sys_sem_release(int id);
+35
View File
@@ -0,0 +1,35 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_user.h
/// @brief Semaphore user-side implementation header code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
/// N.B. Header to use only in user space.
#pragma once
/// @brief Semaphore creation.
/// @return The semaphore id or -1 if creation failed.
/// Set the errno code if failed.
int sem_create();
/// @brief Destruction of a created semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if destroy failed, otherwise 0.
int sem_destroy(int id);
/// @brief Initialization of a created semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if initialization failed, otherwise 0.
int sem_init(int id);
/// @brief Acquire the semaphore ownership if available, otherwise waits that
/// becomes available.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if creation failed, otherwise 0 if
/// semaphore has been successfully acquired.
int sem_acquire(int id);
/// @brief Release the ownership of a Semaphore.
/// @param id Semaphore ID.
/// @return Return -1 and set errno if release failed, otherwise 0.
int sem_release(int id);
-16
View File
@@ -10,31 +10,15 @@
/// Open for reading only. /// Open for reading only.
#define O_RDONLY 0x00 #define O_RDONLY 0x00
/// Open for writing only. /// Open for writing only.
#define O_WRONLY 0x01 #define O_WRONLY 0x01
/// Open for reading and writing. /// Open for reading and writing.
#define O_RDWR 0x02 #define O_RDWR 0x02
/// If the file exists, this flag has no effect. Otherwise, the file is created. /// If the file exists, this flag has no effect. Otherwise, the file is created.
#define O_CREAT 0x40 #define O_CREAT 0x40
/// The file offset will be set to the end of the file prior to each write. /// The file offset will be set to the end of the file prior to each write.
#define O_APPEND 0x400 #define O_APPEND 0x400
/// @brief Given a pathname for a file, open() returns a file
/// descriptor, a small, nonnegative integer for use in
/// subsequent system calls.
/// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer
/// for use in subsequent system calls.
int sys_open(const char *pathname, int flags, mode_t mode);
/// @brief Deletes the file whose name is specified in filename. /// @brief Deletes the file whose name is specified in filename.
/// @param pathname A path to a file. /// @param pathname A path to a file.
/// @return On success, zero is returned. On error, -1 is returned, /// @return On success, zero is returned. On error, -1 is returned,
+1 -1
View File
@@ -29,7 +29,7 @@ typedef struct initrd_file_t {
/// Number used as delimiter, it must be set to 0xBF. /// Number used as delimiter, it must be set to 0xBF.
int magic; int magic;
/// The name of the file. /// The name of the file.
char fileName[MAX_FILENAME_LENGTH]; char fileName[NAME_MAX];
/// The type of the file. /// The type of the file.
short int file_type; short int file_type;
/// The uid of the owner. /// The uid of the owner.
-23
View File
@@ -1,23 +0,0 @@
/// MentOS, The Mentoring Operating system project
/// @file read_write.c
/// @brief Read and write functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
#include "stddef.h"
/// @brief Read data from a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer.
/// @param nbytes The number of bytes to read.
/// @return The number of read characters.
ssize_t sys_read(int fd, void *buf, size_t nbytes);
/// @brief Write data into a file descriptor.
/// @param fd The file descriptor.
/// @param buf The buffer collecting data to written.
/// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t sys_write(int fd, void *buf, size_t nbytes);
+13 -14
View File
@@ -10,26 +10,25 @@
#include "kernel.h" #include "kernel.h"
#include "dirent.h" #include "dirent.h"
#define PATH_SEPARATOR '/'
#define PATH_SEPARATOR_STRING "/"
#define PATH_UP ".."
#define PATH_DOT "."
/// Identifies a file. /// Identifies a file.
#define FS_FILE 0x01 #define FS_FILE 0x01U
/// Identifies a directory. /// Identifies a directory.
#define FS_DIRECTORY 0x02 #define FS_DIRECTORY 0x02U
/// Identifies a character devies. /// Identifies a character devies.
#define FS_CHARDEVICE 0x04 #define FS_CHARDEVICE 0x04U
/// Identifies a block devies. /// Identifies a block devies.
#define FS_BLOCKDEVICE 0x08 #define FS_BLOCKDEVICE 0x08U
/// Identifies a pipe. /// Identifies a pipe.
#define FS_PIPE 0x10 #define FS_PIPE 0x10U
/// Identifies a symbolic link. /// Identifies a symbolic link.
#define FS_SYMLINK 0x20 #define FS_SYMLINK 0x20U
/// Identifies a mount-point. /// Identifies a mount-point.
#define FS_MOUNTPOINT 0x40 #define FS_MOUNTPOINT 0x40U
/// Function used to open a directory. /// Function used to open a directory.
typedef DIR *(*opendir_callback)(const char *); typedef DIR *(*opendir_callback)(const char *);
@@ -103,7 +102,7 @@ typedef struct mountpoint_t {
/// The id of the mountpoint. /// The id of the mountpoint.
int32_t mp_id; int32_t mp_id;
/// Name of the mountpoint. /// Name of the mountpoint.
char mountpoint[MAX_FILENAME_LENGTH]; char mountpoint[NAME_MAX];
/// Maschera dei permessi. /// Maschera dei permessi.
unsigned int pmask; unsigned int pmask;
/// User ID. /// User ID.
-9
View File
@@ -12,18 +12,9 @@
#include "stdbool.h" #include "stdbool.h"
#include "multiboot.h" #include "multiboot.h"
/// The maximum length of a file name.
#define MAX_FILENAME_LENGTH 64
/// The maximum length of a path.
#define MAX_PATH_LENGTH 256
/// The maximum number of modules. /// The maximum number of modules.
#define MAX_MODULES 10 #define MAX_MODULES 10
/// This should be in %eax.
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/// Our kernel now loads at 0xC0000000, so what low memory address such as /// Our kernel now loads at 0xC0000000, so what low memory address such as
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800 /// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
#define LOAD_MEMORY_ADDRESS 0x00000000 #define LOAD_MEMORY_ADDRESS 0x00000000
-15
View File
@@ -1,15 +0,0 @@
/// MentOS, The Mentoring Operating system project
/// @file sys.h
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// TODO: doxygen comment.
/// @brief
/// @param magic1
/// @param magic2
/// @param cmd
/// @param arg
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
+2 -12
View File
@@ -15,18 +15,8 @@
/// @param file The file where the assertion is located. /// @param file The file where the assertion is located.
/// @param line The line inside the file. /// @param line The line inside the file.
/// @param function The function where the assertion is. /// @param function The function where the assertion is.
static void __assert_fail(const char *assertion, const char *file, void __assert_fail(const char *assertion, const char *file, unsigned int line,
unsigned int line, const char *function) const char *function);
{
char message[1024];
sprintf(message,
"FILE: %s\n"
"LINE: %d\n"
"FUNC: %s\n\n"
"Assertion `%s` failed.\n",
file, line, (function ? function : "NO_FUN"), assertion);
kernel_panic(message);
}
/// @brief Assert function. /// @brief Assert function.
#define assert(expression) \ #define assert(expression) \
+17 -11
View File
@@ -7,35 +7,41 @@
#pragma once #pragma once
/// Number of bits in a `char'. /// Number of bits in a `char'.
#define CHAR_BIT 8 #define CHAR_BIT 8
/// Minimum value a `signed char' can hold. /// Minimum value a `signed char' can hold.
#define SCHAR_MIN (-128) #define SCHAR_MIN (-128)
/// Maximum value a `signed char' can hold. /// Maximum value a `signed char' can hold.
#define SCHAR_MAX 127 #define SCHAR_MAX 127
/// Maximum value a `char' can hold. (Minimum is 0.) /// Maximum value a `char' can hold. (Minimum is 0.)
#define CHAR_MAX 255 #define CHAR_MAX 255
/// Minimum value a `signed short int' can hold. /// Minimum value a `signed short int' can hold.
#define SHRT_MIN (-32768) #define SHRT_MIN (-32768)
/// Maximum value a `signed short int' can hold. /// Maximum value a `signed short int' can hold.
#define SHRT_MAX 32767 #define SHRT_MAX 32767
/// Minimum value a `signed int' can hold. /// Minimum value a `signed int' can hold.
#define INT_MIN (-INT_MAX - 1) #define INT_MIN (-INT_MAX - 1)
/// Maximum values a `signed int' can hold. /// Maximum values a `signed int' can hold.
#define INT_MAX 2147483647 #define INT_MAX 2147483647
/// Maximum value an `unsigned int' can hold. (Minimum is 0.) /// Maximum value an `unsigned int' can hold. (Minimum is 0.)
#define UINT_MAX 4294967295U #define UINT_MAX 4294967295U
/// Minimum value a `signed long int' can hold. /// Minimum value a `signed long int' can hold.
#define LONG_MAX 2147483647L #define LONG_MAX 2147483647L
/// Maximum value a `signed long int' can hold. /// Maximum value a `signed long int' can hold.
#define LONG_MIN (-LONG_MAX - 1L) #define LONG_MIN (-LONG_MAX - 1L)
/// Maximum number of characters in a file name.
#define NAME_MAX 255
/// Maximum number of characters in a path name.
#define PATH_MAX 4096
+61 -65
View File
@@ -9,125 +9,121 @@
#include "stddef.h" #include "stddef.h"
/// @brief Structure used to implement the list_head data structure. /// @brief Structure used to implement the list_head data structure.
typedef struct list_head typedef struct list_head {
{ /// @brief The previous element.
/// @brief The previous element. struct list_head *prev;
struct list_head * prev; /// @brief The subsequent element.
/// @brief The subsequent element. struct list_head *next;
struct list_head * next;
} list_head; } list_head;
/// @brief Get the struct for this entry. /// @brief Get the struct for this entry.
/// @param ptr The &struct list_head pointer. /// @param ptr The &struct list_head pointer.
/// @param type The type of the struct this is embedded in. /// @param type The type of the struct this is embedded in.
/// @param member The name of the list_head within the struct. /// @param member The name of the list_head within the struct.
#define list_entry(ptr, type, member) \ #define list_entry(ptr, type, member) \
((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member))) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/// @brief Iterates over a list. /// @brief Iterates over a list.
/// @param pos The &struct list_head to use as a loop cursor. /// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list. /// @param head The head for your list.
#define list_for_each(pos, head) \ #define list_for_each(pos, head) \
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next) for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
/// @brief Iterates over a list backwards. /// @brief Iterates over a list backwards.
/// @param pos The &struct list_head to use as a loop cursor. /// @param pos The &struct list_head to use as a loop cursor.
/// @param head The head for your list. /// @param head The head for your list.
#define list_for_each_prev(pos, head) \ #define list_for_each_prev(pos, head) \
for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev) for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
/// @brief Iterates over a list safe against removal of list entry. /// @brief Iterates over a list safe against removal of list entry.
/// @param pos The &struct list_head to use as a loop cursor. /// @param pos The &struct list_head to use as a loop cursor.
/// @param store Another &struct list_head to use as temporary storage. /// @param store Another &struct list_head to use as temporary storage.
/// @param head The head for your list. /// @param head The head for your list.
#define list_for_each_safe(pos, store, head) \ #define list_for_each_safe(pos, store, head) \
for ((pos) = (head)->next, (store) = (pos)->next; (pos) != (head); \ for ((pos) = (head)->next, (store) = (pos)->next; (pos) != (head); \
(pos) = (store), (store) = (pos)->next) (pos) = (store), (store) = (pos)->next)
/// @brief Initializes the list_head. /// @brief Initializes the list_head.
/// @param head The head for your list. /// @param head The head for your list.
#define list_head_init(head) \ #define list_head_init(head) (head)->next = (head)->prev = (head)
(head)->next = (head)->prev = (head)
/// @brief Insert element l2 after l1. /// @brief Insert element l2 after l1.
static inline void list_head_insert_after(list_head * l1, list_head * l2) static inline void list_head_insert_after(list_head *l1, list_head *l2)
{ {
// [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb] // [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb]
list_head * l1_next = l1->next; list_head *l1_next = l1->next;
// [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb] // [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb]
l1->next = l2; l1->next = l2;
// [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb] // [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb]
l2->prev = l1; l2->prev = l1;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb] // [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb]
l2->next = l1_next; l2->next = l1_next;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb] // [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb]
l1_next->prev = l2; l1_next->prev = l2;
} }
/// @brief Insert element l2 before l1. /// @brief Insert element l2 before l1.
static inline void list_head_insert_before(list_head * l1, list_head * l2) static inline void list_head_insert_before(list_head *l1, list_head *l2)
{ {
// [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb] // [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb]
list_head * l1_prev = l1->prev; list_head *l1_prev = l1->prev;
// [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb] // [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb]
l1_prev->next = l2; l1_prev->next = l2;
// [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb] // [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb]
l2->prev = l1_prev; l2->prev = l1_prev;
// [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb] // [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb]
l2->next = l1; l2->next = l1;
// [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb] // [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb]
l1->prev = l2; l1->prev = l2;
} }
/// @brief Remove l from the list. /// @brief Remove l from the list.
/// @param l The element to remove. /// @param l The element to remove.
static inline void list_head_del(list_head * l) static inline void list_head_del(list_head *l)
{ {
// [La]->l La<-[l]->Lb l<-[Lb] // [La]->l La<-[l]->Lb l<-[Lb]
// [La]->Lb La<-[l]->Lb l<-[Lb] // [La]->Lb La<-[l]->Lb l<-[Lb]
l->prev->next = l->next; l->prev->next = l->next;
// [La]->Lb La<-[l]->Lb La<-[Lb] // [La]->Lb La<-[l]->Lb La<-[Lb]
l->next->prev = l->prev; l->next->prev = l->prev;
// [La]->Lb l<-[l]->l La<-[Lb] // [La]->Lb l<-[l]->l La<-[Lb]
l->next = l->prev = l; l->next = l->prev = l;
} }
/// @brief Tests whether the given list is empty. /// @brief Tests whether the given list is empty.
/// @param head The list to check. /// @param head The list to check.
/// @return 1 if empty, 0 otherwise. /// @return 1 if empty, 0 otherwise.
static inline int list_head_empty(list_head const * head) static inline int list_head_empty(list_head const *head)
{ {
return head->next == head; return head->next == head;
} }
/// Insert a new entry between two known consecutive entries. /// Insert a new entry between two known consecutive entries.
static inline void __list_add(list_head * new, static inline void __list_add(list_head *new, list_head *prev, list_head *next)
list_head * prev,
list_head * next)
{ {
// [prev]-> <-[new]-> <-[next] // [prev]-> <-[new]-> <-[next]
// [prev]-> <-[new]-> new<-[next] // [prev]-> <-[new]-> new<-[next]
next->prev = new; next->prev = new;
// [prev]-> <-[new]->next new<-[next] // [prev]-> <-[new]->next new<-[next]
new->next = next; new->next = next;
// [prev]-> prev<-[new]->next new<-[next] // [prev]-> prev<-[new]->next new<-[next]
new->prev = prev; new->prev = prev;
// [prev]->new prev<-[new]->next new<-[next] // [prev]->new prev<-[new]->next new<-[next]
prev->next = new; prev->next = new;
} }
/// @brief Insert element l2 before l1. /// @brief Insert element l2 before l1.
static inline void list_head_add(list_head * new, list_head * head) static inline void list_head_add(list_head *new, list_head *head)
{ {
__list_add(new, head, head->next); __list_add(new, head, head->next);
} }
/// @brief Insert element l2 before l1. /// @brief Insert element l2 before l1.
static inline void list_head_add_tail(list_head * new, list_head * head) static inline void list_head_add_tail(list_head *new, list_head *head)
{ {
__list_add(new, head->prev, head); __list_add(new, head->prev, head);
} }
+13 -15
View File
@@ -10,24 +10,22 @@
#include "stdbool.h" #include "stdbool.h"
/// @brief A node of the queue. /// @brief A node of the queue.
typedef struct queue_node_t typedef struct queue_node_t {
{ /// The wrapped data.
/// The wrapped data. void *data;
void *data; /// The next node of the queue.
/// The next node of the queue. struct queue_node_t *next;
struct queue_node_t *next;
} queue_node_t; } queue_node_t;
/// @brief The queue. /// @brief The queue.
typedef struct queue_t typedef struct queue_t {
{ /// The front of the queue.
/// The front of the queue. queue_node_t *front;
queue_node_t *front; /// The back of the queue.
/// The back of the queue. queue_node_t *back;
queue_node_t *back; /// The size of the data contained inside the queue.
/// The size of the data contained inside the queue. size_t data_size;
size_t data_size; } * queue_t;
} *queue_t;
/// @brief Creates a queue. /// @brief Creates a queue.
/// @param data_size The size of the stored elements. /// @param data_size The size of the stored elements.
+1 -1
View File
@@ -17,7 +17,7 @@ typedef char *va_list;
/// @brief Amount of space required in an argument list (ie. the stack) for an /// @brief Amount of space required in an argument list (ie. the stack) for an
/// argument of type t. /// argument of type t.
#define va_size(t) \ #define va_size(t) \
(((sizeof(t) + sizeof(va_item) - 1) / sizeof(va_item)) * sizeof(va_item)) (((sizeof(t) + sizeof(va_item) - 1) / sizeof(va_item)) * sizeof(va_item))
/// @brief The start of a variadic list. /// @brief The start of a variadic list.
#define va_start(ap, last_arg) (ap = ((va_list)(&last_arg) + va_size(last_arg))) #define va_start(ap, last_arg) (ap = ((va_list)(&last_arg) + va_size(last_arg)))
+1 -1
View File
@@ -9,7 +9,7 @@
#ifndef NULL #ifndef NULL
/// @brief Define NULL. /// @brief Define NULL.
#define NULL ((void*)0) #define NULL ((void *)0)
#endif #endif
+2
View File
@@ -11,6 +11,8 @@
/// @brief The maximum number of digits of an integer. /// @brief The maximum number of digits of an integer.
#define MAX_DIGITS_IN_INTEGER 11 #define MAX_DIGITS_IN_INTEGER 11
/// @brief The size of 'gets' buffer.
#define GETS_BUFFERSIZE 255
#ifndef EOF #ifndef EOF
/// @brief Define the End-Of-File. /// @brief Define the End-Of-File.
+14 -17
View File
@@ -11,29 +11,26 @@
/// @brief Malloc based on the number of elements. /// @brief Malloc based on the number of elements.
void *calloc(size_t element_number, size_t element_size); void *calloc(size_t element_number, size_t element_size);
/// @brief Allows to set the seed of the random value generator.
void srand(int x);
void *malloc(unsigned int size); void *malloc(unsigned int size);
void free(void * p); void free(void * p);
/// @brief Allocate a matrix with n rows of a specific size.
/// @param n Number of matrix rows.
/// @param size Size of each matrix row.
/// @return Matrix pointer.
void **mmalloc(size_t n, size_t size);
#ifndef MS_RAND /// @brief Free a matrix of n rows.
/// @param src Matrix to free.
/// @param n Number of matrix rows.
void mfree(void **src, size_t n);
/// @brief The maximum value of the random. /// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31) - 1) #define RAND_MAX ((1U << 31U) - 1U)
/// @brief Allows to set the seed of the random value generator.
void srand(int x);
/// @brief Generates a random value. /// @brief Generates a random value.
int rand(); int rand();
// MS rand
#else
#define RAND_MAX_32 ((1U << 31) - 1)
#define RAND_MAX ((1U << 15) - 1)
int rand();
#endif
+11
View File
@@ -84,10 +84,21 @@ void *kcalloc(unsigned int num, unsigned int size);
/// @return /// @return
void *krealloc(void *ptr, unsigned int size); void *krealloc(void *ptr, unsigned int size);
/// @brief Allocate a matrix with n rows of a specific size.
/// @param n Number of matrix rows.
/// @param size Size of each matrix row.
/// @return Matrix pointer.
void **kmmalloc(size_t n, size_t size);
/// @brief Wrapper function for free. /// @brief Wrapper function for free.
/// @param p /// @param p
void kfree(void *p); void kfree(void *p);
/// @brief Free a matrix of n rows.
/// @param src Matrix to free.
/// @param n Number of matrix rows.
void kmfree(void **src, size_t n);
/// @brief Allocates size bytes of uninitialized storage. /// @brief Allocates size bytes of uninitialized storage.
//void *malloc(unsigned int size); //void *malloc(unsigned int size);
+118 -135
View File
@@ -10,43 +10,46 @@
#include "stdint.h" #include "stdint.h"
#define MULTIBOOT_FLAG_MEM 0x001 // The magic field should contain this.
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
// This should be in %eax.
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
#define MULTIBOOT_FLAG_DEVICE 0x002 /// Is there basic lower/upper memory information?
#define MULTIBOOT_FLAG_MEM 0x00000001U
#define MULTIBOOT_FLAG_CMDLINE 0x004 /// is there a boot device set?
#define MULTIBOOT_FLAG_DEVICE 0x00000002U
#define MULTIBOOT_FLAG_MODS 0x008 /// is the command-line defined?
#define MULTIBOOT_FLAG_CMDLINE 0x00000004U
#define MULTIBOOT_FLAG_AOUT 0x010 /// are there modules to do something with?
#define MULTIBOOT_FLAG_MODS 0x00000008U
#define MULTIBOOT_FLAG_ELF 0x020 /// is there a symbol table loaded?
#define MULTIBOOT_FLAG_AOUT 0x00000010U
#define MULTIBOOT_FLAG_MMAP 0x040 /// is there an ELF section header table?
#define MULTIBOOT_FLAG_ELF 0x00000020U
#define MULTIBOOT_FLAG_CONFIG 0x080 /// is there a full memory map?
#define MULTIBOOT_FLAG_MMAP 0x00000040U
#define MULTIBOOT_FLAG_LOADER 0x100 /// Is there drive info?
#define MULTIBOOT_FLAG_DRIVE_INFO 0x00000080U
#define MULTIBOOT_FLAG_APM 0x200 /// Is there a config table?
#define MULTIBOOT_FLAG_CONFIG_TABLE 0x00000100U
#define MULTIBOOT_FLAG_VBE 0x400 /// Is there a boot loader name?
#define MULTIBOOT_FLAG_BOOT_LOADER_NAME 0x00000200U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 /// Is there a APM table?
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 /// Is there video information?
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
#define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_BADRAM 5
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
// +-------------------+ // +-------------------+
// 0 | flags | (required) // 0 | flags | (required)
@@ -93,131 +96,111 @@
// +-------------------+ // +-------------------+
/// The symbol table for a.out. /// The symbol table for a.out.
typedef struct multiboot_aout_symbol_table typedef struct multiboot_aout_symbol_table {
{ uint32_t tabsize;
uint32_t tabsize; uint32_t strsize;
uint32_t strsize; uint32_t addr;
uint32_t addr; uint32_t reserved;
uint32_t reserved;
} multiboot_aout_symbol_table_t; } multiboot_aout_symbol_table_t;
/// The section header table for ELF. /// The section header table for ELF.
typedef struct multiboot_elf_section_header_table typedef struct multiboot_elf_section_header_table {
{ uint32_t num;
uint32_t num; uint32_t size;
uint32_t size; uint32_t addr;
uint32_t addr; uint32_t shndx;
uint32_t shndx;
} multiboot_elf_section_header_table_t; } multiboot_elf_section_header_table_t;
// TODO: doxygen comment. // TODO: doxygen comment.
typedef struct multiboot_mod_list typedef struct multiboot_module {
{ // The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive.
// The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive. uint32_t mod_start;
uint32_t mod_start; uint32_t mod_end;
uint32_t mod_end; // Module command line.
// Module command line. uint32_t cmdline;
uint32_t cmdline; // Padding to take it to 16 bytes (must be zero).
// Padding to take it to 16 bytes (must be zero). uint32_t pad;
uint32_t pad;
} multiboot_module_t; } multiboot_module_t;
// TODO: doxygen comment. typedef struct multiboot_memory_map {
typedef struct multiboot_mmap_entry uint32_t size;
{ uint32_t base_addr_low;
uint32_t size; uint32_t base_addr_high;
uint64_t addr; uint32_t length_low;
uint64_t len; uint32_t length_high;
uint32_t type; uint32_t type;
} __attribute__((packed)) multiboot_memory_map_t; } multiboot_memory_map_t;
// TODO: doxygen comment. // TODO: doxygen comment.
typedef struct multiboot_info typedef struct multiboot_info {
{ /// Multiboot info version number.
/// Multiboot info version number. uint32_t flags;
uint32_t flags;
/// Available memory from BIOS. /// Available memory from BIOS.
uint32_t mem_lower; uint32_t mem_lower;
uint32_t mem_upper; uint32_t mem_upper;
/// "root" partition. /// "root" partition.
uint32_t boot_device; uint32_t boot_device;
/// Kernel command line. /// Kernel command line.
uint32_t cmdline; uint32_t cmdline;
/// Boot-Module list. /// Boot-Module list.
uint32_t mods_count; uint32_t mods_count;
uint32_t mods_addr; uint32_t mods_addr;
union union {
{ multiboot_aout_symbol_table_t aout_sym;
multiboot_aout_symbol_table_t aout_sym; multiboot_elf_section_header_table_t elf_sec;
multiboot_elf_section_header_table_t elf_sec; } u;
} u;
/// Memory Mapping buffer. /// Memory Mapping buffer.
uint32_t mmap_length; uint32_t mmap_length;
uint32_t mmap_addr; uint32_t mmap_addr;
/// Drive Info buffer. /// Drive Info buffer.
uint32_t drives_length; uint32_t drives_length;
uint32_t drives_addr; uint32_t drives_addr;
/// ROM configuration table. /// ROM configuration table.
uint32_t config_table; uint32_t config_table;
/// Boot Loader Name. /// Boot Loader Name.
uint32_t boot_loader_name; uint32_t boot_loader_name;
/// APM table. /// APM table.
uint32_t apm_table; uint32_t apm_table;
/// Video. /// Video.
uint32_t vbe_control_info; uint32_t vbe_control_info;
uint32_t vbe_mode_info; uint32_t vbe_mode_info;
uint32_t vbe_mode; uint32_t vbe_mode;
uint32_t vbe_interface_seg; uint32_t vbe_interface_seg;
uint32_t vbe_interface_off; uint32_t vbe_interface_off;
uint32_t vbe_interface_len; uint32_t vbe_interface_len;
uint32_t framebuffer_addr; uint32_t framebuffer_addr;
uint32_t framebuffer_pitch; uint32_t framebuffer_pitch;
uint32_t framebuffer_width; uint32_t framebuffer_width;
uint32_t framebuffer_height; uint32_t framebuffer_height;
uint32_t framebuffer_bpp; uint32_t framebuffer_bpp;
uint32_t framebuffer_type; uint32_t framebuffer_type;
union union {
{ struct {
struct uint32_t framebuffer_palette_addr;
{ uint16_t framebuffer_palette_num_colors;
uint32_t framebuffer_palette_addr; };
uint16_t framebuffer_palette_num_colors; struct {
}; uint8_t framebuffer_red_field_position;
struct uint8_t framebuffer_red_mask_size;
{ uint8_t framebuffer_green_field_position;
uint8_t framebuffer_red_field_position; uint8_t framebuffer_green_mask_size;
uint8_t framebuffer_red_mask_size; uint8_t framebuffer_blue_field_position;
uint8_t framebuffer_green_field_position; uint8_t framebuffer_blue_mask_size;
uint8_t framebuffer_green_mask_size; };
uint8_t framebuffer_blue_field_position; };
uint8_t framebuffer_blue_mask_size;
};
};
} __attribute__((packed)) multiboot_info_t; } __attribute__((packed)) multiboot_info_t;
// Be careful that the offset 0 is base_addr_low but no size.
/// @brief The memory map.
typedef struct memory_map
{
uint32_t size;
uint32_t base_addr_low;
uint32_t base_addr_high;
uint32_t length_low;
uint32_t length_high;
uint32_t type;
} memory_map_t;
// TODO: doxygen comment. // TODO: doxygen comment.
void dump_multiboot(multiboot_info_t *mboot_ptr); void dump_multiboot(multiboot_info_t *mboot_ptr);
+14 -14
View File
@@ -4,11 +4,11 @@
/// @copyright (c) 2019 This file is distributed under the MIT License. /// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details. /// See LICENSE.md for details.
#define MAX_NICE +19 #define MAX_NICE +19
#define MIN_NICE -20 #define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1) #define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
// Priority of a process goes from 0..MAX_PRIO-1, valid RT // Priority of a process goes from 0..MAX_PRIO-1, valid RT
// priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH // priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
@@ -23,7 +23,7 @@
#define MAX_RT_PRIO 100 #define MAX_RT_PRIO 100
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH) #define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2) #define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
@@ -32,24 +32,24 @@
// and back. // and back.
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO) #define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio) - DEFAULT_PRIO) #define PRIO_TO_NICE(prio) ((prio)-DEFAULT_PRIO)
// 'User priority' is the nice value converted to something we // 'User priority' is the nice value converted to something we
// can work with better when scaling various scheduler parameters, // can work with better when scaling various scheduler parameters,
// it's a [ 0 ... 39 ] range. // it's a [ 0 ... 39 ] range.
#define USER_PRIO(p) ((p)-MAX_RT_PRIO) #define USER_PRIO(p) ((p)-MAX_RT_PRIO)
#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio) #define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO)) #define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
static const int prio_to_weight[NICE_WIDTH] = { static const int prio_to_weight[NICE_WIDTH] = {
/* 100 */ 88761, 71755, 56483, 46273, 36291, /* 100 */ 88761, 71755, 56483, 46273, 36291,
/* 105 */ 29154, 23254, 18705, 14949, 11916, /* 105 */ 29154, 23254, 18705, 14949, 11916,
/* 110 */ 9548, 7620, 6100, 4904, 3906, /* 110 */ 9548, 7620, 6100, 4904, 3906,
/* 115 */ 3121, 2501, 1991, 1586, 1277, /* 115 */ 3121, 2501, 1991, 1586, 1277,
/* 120 */ 1024, 820, 655, 526, 423, /* 120 */ 1024, 820, 655, 526, 423,
/* 125 */ 335, 272, 215, 172, 137, /* 125 */ 335, 272, 215, 172, 137,
/* 130 */ 110, 87, 70, 56, 45, /* 130 */ 110, 87, 70, 56, 45,
/* 135 */ 36, 29, 23, 18, 15 /* 135 */ 36, 29, 23, 18, 15
}; };
+8 -13
View File
@@ -17,6 +17,7 @@
#include "unistd.h" #include "unistd.h"
#include "list_head.h" #include "list_head.h"
#include "signal_defs.h" #include "signal_defs.h"
#include "limits.h"
/// The maximum length of a name for a task_struct. /// The maximum length of a name for a task_struct.
#define TASK_NAME_MAX_LENGTH 100 #define TASK_NAME_MAX_LENGTH 100
@@ -24,6 +25,9 @@
/// The default dimension of the stack of a process (1 MByte). /// The default dimension of the stack of a process (1 MByte).
#define DEFAULT_STACK_SIZE 0x100000 #define DEFAULT_STACK_SIZE 0x100000
/// The maximum number of resources for a task.
#define TASK_RESOURCE_MAX_AMOUNT 32
//==== Task state ============================================================== //==== Task state ==============================================================
// Used in tsk->state // Used in tsk->state
/// The task is running. /// The task is running.
@@ -170,7 +174,10 @@ typedef struct task_struct {
int error_no; int error_no;
/// The current working directory. /// The current working directory.
char cwd[MAX_PATH_LENGTH]; char cwd[PATH_MAX];
/// Array of resource pointers that task need for.
struct resource *resources[TASK_RESOURCE_MAX_AMOUNT];
//==== Future work ========================================================= //==== Future work =========================================================
// - task's attributes: // - task's attributes:
@@ -195,20 +202,8 @@ typedef struct task_struct {
} task_struct; } task_struct;
/// @brief Create a child process.
pid_t sys_vfork(pt_regs *r);
// TODO: doxygen comment. // TODO: doxygen comment.
char *get_current_dir_name(); char *get_current_dir_name();
// TODO: doxygen comment.
void sys_getcwd(char *path, size_t size);
// TODO: doxygen comment.s
void sys_chdir(char const *path);
/// @brief Replaces the current process image with a new process image.
int sys_execve(pt_regs *r);
/// @brief Create and spawn the init process. /// @brief Create and spawn the init process.
struct task_struct *create_init_process(); struct task_struct *create_init_process();
-14
View File
@@ -62,21 +62,7 @@ void do_switch(task_struct *process, pt_regs *f);
/// @param process The process that has to be executed /// @param process The process that has to be executed
void enter_user_jmp(uintptr_t location, uintptr_t stack); void enter_user_jmp(uintptr_t location, uintptr_t stack);
/// Returns the process ID (PID) of the calling process.
pid_t sys_getpid();
/// Returns the parent process ID (PPID) of the calling process.
pid_t sys_getppid();
/// @brief Sets the priority value of the given task. /// @brief Sets the priority value of the given task.
int set_user_nice(task_struct *p, long nice); int set_user_nice(task_struct *p, long nice);
/// @brief Adds the increment to the priority value of the task.
int sys_nice(int increment);
/// @brief Suspends execution of the calling thread until a child specified
/// by pid argument has changed state.
pid_t sys_waitpid(pid_t pid, int *status, int options);
/// The exit() function causes normal process termination.
void sys_exit(int exit_code);
+17 -24
View File
@@ -7,37 +7,30 @@
#pragma once #pragma once
#include "stddef.h" #include "stddef.h"
#include "limits.h"
/// The maximum length for a name.
#define NAME_MAX 30
/// @brief Contains the entries of a directory. /// @brief Contains the entries of a directory.
typedef struct dirent_t typedef struct dirent_t {
{ /// The inode of the entry.
/// The inode of the entry. ino_t d_ino;
ino_t d_ino;
/// The type of the entry. /// The type of the entry.
int d_type; int d_type;
/// The nam of the entry. /// The nam of the entry.
char d_name[NAME_MAX + 1]; char d_name[NAME_MAX + 1];
} dirent_t; } dirent_t;
/// @brief Contains information concerning a directory. /// @brief Contains information concerning a directory.
typedef struct DIR typedef struct DIR {
{ /// Filesystem directory handle.
/// Filesystem directory handle. int fd;
int handle; /// The currently opened entry.
ino_t cur_entry;
/// The currently opened entry. /// Path to the directory.
ino_t cur_entry; char path[NAME_MAX + 1];
/// Next directory item.
/// Path to the directory. dirent_t entry;
char path[NAME_MAX + 1];
/// Next directory item.
dirent_t entry;
} DIR; } DIR;
/// @brief Opens a directory and returns a handler to it. /// @brief Opens a directory and returns a handler to it.
-1
View File
@@ -38,5 +38,4 @@ typedef struct stat_t
/// @return Returns a negative value on failure. /// @return Returns a negative value on failure.
int stat(const char *path, stat_t *buf); int stat(const char *path, stat_t *buf);
// TODO: doxygen comment.
int mkdir(const char *path, mode_t mode); int mkdir(const char *path, mode_t mode);
+4 -4
View File
@@ -47,10 +47,10 @@ ssize_t write(int fd, void *buf, size_t nbytes);
/// use in subsequent system calls. /// use in subsequent system calls.
int open(const char *pathname, int flags, mode_t mode); int open(const char *pathname, int flags, mode_t mode);
/// @brief Close a file descriptor. /// @brief Close a file descriptor.
/// @param fildes The file descriptor. /// @param fd The file descriptor.
/// @return The result of the operation. /// @return The result of the operation.
int close(int fildes); int close(int fd);
/// @brief Removes the given directory. /// @brief Removes the given directory.
/// @param path The path to the directory to remove. /// @param path The path to the directory to remove.
+9 -10
View File
@@ -10,19 +10,18 @@
#define SYS_LEN 257 #define SYS_LEN 257
/// @brief Holds information concerning the machine and the os. /// @brief Holds information concerning the machine and the os.
typedef struct utsname_t typedef struct utsname_t {
{ /// The name of the system.
/// The name of the system. char sysname[SYS_LEN];
char sysname[SYS_LEN];
/// The name of the node. /// The name of the node.
char nodename[SYS_LEN]; char nodename[SYS_LEN];
/// The version of the OS. /// The version of the OS.
char version[SYS_LEN]; char version[SYS_LEN];
/// The name of the machine. /// The name of the machine.
char machine[SYS_LEN]; char machine[SYS_LEN];
} utsname_t; } utsname_t;
/// @brief Sets the values of os_infos. /// @brief Sets the values of os_infos.
+38 -38
View File
@@ -7,115 +7,115 @@
// Signal names (from the Unix specification on signals) // Signal names (from the Unix specification on signals)
/// Hangup. /// Hangup.
#define SIGHUP 1 #define SIGHUP 1
/// Interupt. /// Interupt.
#define SIGINT 2 #define SIGINT 2
/// Quit. /// Quit.
#define SIGQUIT 3 #define SIGQUIT 3
/// Illegal instruction. /// Illegal instruction.
#define SIGILL 4 #define SIGILL 4
/// A breakpoint or trace instruction has been reached. /// A breakpoint or trace instruction has been reached.
#define SIGTRAP 5 #define SIGTRAP 5
/// Another process has requested that you abort. /// Another process has requested that you abort.
#define SIGABRT 6 #define SIGABRT 6
/// Emulation trap XXX. /// Emulation trap XXX.
#define SIGEMT 7 #define SIGEMT 7
/// Floating-point arithmetic exception. /// Floating-point arithmetic exception.
#define SIGFPE 8 #define SIGFPE 8
/// You have been stabbed repeated with a large knife. /// You have been stabbed repeated with a large knife.
#define SIGKILL 9 #define SIGKILL 9
/// Bus error (device error). /// Bus error (device error).
#define SIGBUS 10 #define SIGBUS 10
/// Segmentation fault. /// Segmentation fault.
#define SIGSEGV 11 #define SIGSEGV 11
/// Bad system call. /// Bad system call.
#define SIGSYS 12 #define SIGSYS 12
/// Attempted to read or write from a broken pipe. /// Attempted to read or write from a broken pipe.
#define SIGPIPE 13 #define SIGPIPE 13
/// This is your wakeup call. /// This is your wakeup call.
#define SIGALRM 14 #define SIGALRM 14
/// You have been Schwarzenegger'd. /// You have been Schwarzenegger'd.
#define SIGTERM 15 #define SIGTERM 15
/// User Defined Signal #1. /// User Defined Signal #1.
#define SIGUSR1 16 #define SIGUSR1 16
/// User Defined Signal #2. /// User Defined Signal #2.
#define SIGUSR2 17 #define SIGUSR2 17
/// Child status report. /// Child status report.
#define SIGCHLD 18 #define SIGCHLD 18
/// We need moar powah!. /// We need moar powah!.
#define SIGPWR 19 #define SIGPWR 19
/// Your containing terminal has changed size. /// Your containing terminal has changed size.
#define SIGWINCH 20 #define SIGWINCH 20
/// An URGENT! event (On a socket). /// An URGENT! event (On a socket).
#define SIGURG 21 #define SIGURG 21
/// XXX OBSOLETE; socket i/o possible. /// XXX OBSOLETE; socket i/o possible.
#define SIGPOLL 22 #define SIGPOLL 22
/// Stopped (signal). /// Stopped (signal).
#define SIGSTOP 23 #define SIGSTOP 23
/// ^Z (suspend). /// ^Z (suspend).
#define SIGTSTP 24 #define SIGTSTP 24
/// Unsuspended (please, continue). /// Unsuspended (please, continue).
#define SIGCONT 25 #define SIGCONT 25
/// TTY input has stopped. /// TTY input has stopped.
#define SIGTTIN 26 #define SIGTTIN 26
/// TTY output has stopped. /// TTY output has stopped.
#define SIGTTOUT 27 #define SIGTTOUT 27
/// Virtual timer has expired. /// Virtual timer has expired.
#define SIGVTALRM 28 #define SIGVTALRM 28
/// Profiling timer expired. /// Profiling timer expired.
#define SIGPROF 29 #define SIGPROF 29
/// CPU time limit exceeded. /// CPU time limit exceeded.
#define SIGXCPU 30 #define SIGXCPU 30
/// File size limit exceeded. /// File size limit exceeded.
#define SIGXFSZ 31 #define SIGXFSZ 31
/// Herp. /// Herp.
#define SIGWAITING 32 #define SIGWAITING 32
/// Die in a fire. /// Die in a fire.
#define SIGDIAF 33 #define SIGDIAF 33
/// The sending process does not like you. /// The sending process does not like you.
#define SIGHATE 34 #define SIGHATE 34
/// Window server event. /// Window server event.
#define SIGWINEVENT 35 #define SIGWINEVENT 35
/// Everybody loves cats. /// Everybody loves cats.
#define SIGCAT 36 #define SIGCAT 36
#define SIGTTOU 37 #define SIGTTOU 37
#define NUMSIGNALS 38 #define NUMSIGNALS 38
#define NSIG NUMSIGNALS #define NSIG NUMSIGNALS
+52 -381
View File
@@ -6,7 +6,11 @@
#pragma once #pragma once
#include "syscall_types.h"
#include "kernel.h" #include "kernel.h"
#include "dirent.h"
#include "types.h"
#include "stat.h"
/// @brief Initialize the system calls. /// @brief Initialize the system calls.
void syscall_init(); void syscall_init();
@@ -14,400 +18,67 @@ void syscall_init();
/// @brief Handler for the system calls. /// @brief Handler for the system calls.
void syscall_handler(pt_regs *r); void syscall_handler(pt_regs *r);
// Return result in eax ("=a"). /// The exit() function causes normal process termination.
// System call number in eax ("a"). void sys_exit(int exit_code);
#define DEFN_SYSCALL0(__res, num) \
__asm__ __volatile__("INT $0x80" : "=a"(__res) : "a"(num))
// Return result in eax ("=a"). /// @brief Read data from a file descriptor.
// System call number in eax ("a"). /// @param fd The file descriptor.
// p1 in ebx ("+b"). /// @param buf The buffer.
#define DEFN_SYSCALL1(__res, num, p1) \ /// @param nbytes The number of bytes to read.
__asm__ __volatile__("INT $0x80" : "=a"(__res), "+b"(p1) : "a"(num)) /// @return The number of read characters.
ssize_t sys_read(int fd, void *buf, size_t nbytes);
#define DEFN_SYSCALL2(__res, num, p1, p2) \ /// @brief Write data into a file descriptor.
__asm__ __volatile__("INT $0x80" \ /// @param fd The file descriptor.
: "=a"(__res), "+b"(p1), "+c"(p2) \ /// @param buf The buffer collecting data to written.
: "a"(num)); /// @param nbytes The number of bytes to write.
/// @return The number of written bytes.
ssize_t sys_write(int fd, void *buf, size_t nbytes);
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \ /// @brief Given a pathname for a file, open() returns a file
__asm__ __volatile__("INT $0x80" \ /// descriptor, a small, nonnegative integer for use in
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \ /// subsequent system calls.
: "a"(num)) /// @param pathname A pathname for a file.
/// @param flags Used to set the file status flags and file access modes
/// of the open file description.
/// @param mode Specifies the file mode bits be applied when a new file
/// is created.
/// @return Returns a file descriptor, a small, nonnegative integer
/// for use in subsequent system calls.
int sys_open(const char *pathname, int flags, mode_t mode);
#define DEFN_SYSCALL4(__res, num, p1, p2, p3, p4) \ /// @brief
__asm__ __volatile__("INT $0x80" \ /// @param fd
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), "+S"(p4) \ /// @return
: "a"(num)) int sys_close(int fd);
#define DEFN_SYSCALL5(fn, num, P1, P2, P3, P4, P5) \ /// @brief Suspends execution of the calling thread until a child specified
int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \ /// by pid argument has changed state.
{ \ pid_t sys_waitpid(pid_t pid, int *status, int options);
int __res; \
__asm__ __volatile__("push eax\n movl %2,%%ebx; INT 0x80; pop %%ebx" \
: "=a"(__res) \
: "0"(num), "r"((int)(p1)), "c"((int)(p2)), \
"d"((int)(p3)), "S"((int)(p4)), \
"D"((int)(p5))); \
return __res; \
}
#define __NR_exit 1 /// @brief Replaces the current process image with a new process image.
int sys_execve(pt_regs *r);
#define __NR_fork 2 void sys_chdir(char const *path);
#define __NR_read 3 /// Returns the process ID (PID) of the calling process.
pid_t sys_getpid();
#define __NR_write 4 /// @brief Adds the increment to the priority value of the task.
int sys_nice(int increment);
#define __NR_open 5 /// Returns the parent process ID (PPID) of the calling process.
pid_t sys_getppid();
#define __NR_close 6 int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
#define __NR_waitpid 7 void sys_getcwd(char *path, size_t size);
#define __NR_creat 8 /// @brief Create a child process.
pid_t sys_vfork(pt_regs *r);
#define __NR_link 9 int sys_stat(const char *path, stat_t *buf);
#define __NR_unlink 10 int sys_mkdir(const char *path, mode_t mode);
#define __NR_execve 11 dirent_t *sys_readdir(DIR *dirp);
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_oldumount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_access 33
#define __NR_nice 34
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount 52
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_setpgid 57
#define __NR_olduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_newstat 106
#define __NR_newlstat 107
#define __NR_newfstat 108
#define __NR_uname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86old 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_newuname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR_llseek 140
#define __NR_getdents 141
#define __NR_select 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR_sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_vm86 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread 180
#define __NR_pwrite 181
#define __NR_chown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_vfork 188
#define __NR_free 189 // TODO: remove me!
#define SYSCALL_NUMBER 190
//-----------------------------------------------------------------------------
+232
View File
@@ -0,0 +1,232 @@
/// MentOS, The Mentoring Operating system project
/// @file syscall_number.h
/// @brief System Call numbers.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#pragma once
// Return result in eax ("=a").
// System call number in eax ("a").
#define DEFN_SYSCALL0(__res, num) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res) \
: "a"(num))
// Return result in eax ("=a").
// System call number in eax ("a").
// p1 in ebx ("+b").
#define DEFN_SYSCALL1(__res, num, p1) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1) \
: "a"(num))
#define DEFN_SYSCALL2(__res, num, p1, p2) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2) \
: "a"(num));
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \
: "a"(num))
#define DEFN_SYSCALL4(__res, num, p1, p2, p3, p4) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), "+S"(p4) \
: "a"(num))
#define DEFN_SYSCALL5(__res, num, p1, p2, p3, p4, p5) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), \
"+S"(p4), "+D"(p5) \
: "a"(num))
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_oldumount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_access 33
#define __NR_nice 34
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount 52
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_setpgid 57
#define __NR_olduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_newstat 106
#define __NR_newlstat 107
#define __NR_newfstat 108
#define __NR_uname 109
#define __NR_iopl 110
#define __NR_vhangup 111
#define __NR_idle 112
#define __NR_vm86old 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_newuname 122
#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR_llseek 140
#define __NR_getdents 141
#define __NR_select 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR_sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_vm86 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread 180
#define __NR_pwrite 181
#define __NR_chown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_vfork 188
#define __NR_free 189 // TODO: remove me!
/*
#define __NR_sem_... 190
#define __NR_sem_... 191
#define __NR_sem_... 192
#define __NR_sem_... 193
#define __NR_sem_... 194
*/
#define SYSCALL_NUMBER 195
+3
View File
@@ -91,3 +91,6 @@ void cmd_ipcrm(int argc, char **argv);
/// @brief Change the nice value. /// @brief Change the nice value.
void cmd_nice(int argc, char **argv); void cmd_nice(int argc, char **argv);
/// @brief Test deadlock behavior with tasks and shared resources.
void cmd_deadlock(int argc, char **argv);
+2 -1
View File
@@ -8,6 +8,7 @@
#include "stdint.h" #include "stdint.h"
#include "kernel.h" #include "kernel.h"
#include "limits.h"
/// Maximum length of credentials. /// Maximum length of credentials.
#define CREDENTIALS_LENGTH 50 #define CREDENTIALS_LENGTH 50
@@ -55,7 +56,7 @@ typedef struct userenv_t
char username[CREDENTIALS_LENGTH]; char username[CREDENTIALS_LENGTH];
/// The current path. /// The current path.
char cur_path[MAX_PATH_LENGTH]; char cur_path[PATH_MAX];
/// The user identifier. /// The user identifier.
unsigned int uid; unsigned int uid;
+1 -1
View File
@@ -114,7 +114,7 @@ void init_idt()
} }
void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options, void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
uint8_t seg_sel) uint8_t seg_sel)
{ {
uint32_t base_prt = (uint32_t)handler; uint32_t base_prt = (uint32_t)handler;
+53 -67
View File
@@ -44,17 +44,17 @@ uint32_t pci_read_field(uint32_t device, int field, int size)
uint32_t pci_find_type(uint32_t device) uint32_t pci_find_type(uint32_t device)
{ {
return pci_read_field(device, PCI_CLASS, 1) << 16 | return pci_read_field(device, PCI_CLASS, 1) << 16 |
pci_read_field(device, PCI_SUBCLASS, 1) << 8 | pci_read_field(device, PCI_SUBCLASS, 1) << 8 |
pci_read_field(device, PCI_PROG_IF, 1); pci_read_field(device, PCI_PROG_IF, 1);
} }
struct { struct {
uint16_t id; uint16_t id;
const char *name; const char *name;
} _pci_vendors[] = { } _pci_vendors[] = {
{ 0x1022, "AMD" }, { 0x106b, "Apple, Inc." }, { 0x1022, "AMD" }, { 0x106b, "Apple, Inc." },
{ 0x1234, "Bochs/QEMU" }, { 0x1274, "Ensoniq" }, { 0x1234, "Bochs/QEMU" }, { 0x1274, "Ensoniq" },
{ 0x15ad, "VMWare" }, { 0x8086, "Intel Corporation" }, { 0x15ad, "VMWare" }, { 0x8086, "Intel Corporation" },
{ 0x80EE, "VirtualBox" }, { 0x80EE, "VirtualBox" },
}; };
@@ -97,18 +97,16 @@ struct {
{ 0x010100, "ISA Compatibility mode-only controller" }, { 0x010100, "ISA Compatibility mode-only controller" },
{ 0x010105, "PCI native mode-only controller" }, { 0x010105, "PCI native mode-only controller" },
{ 0x01010a, "ISA Compatibility mode controller, supports both channels " { 0x01010a, "ISA Compatibility mode controller, supports both channels "
"switched to PCI native mode" }, "switched to PCI native mode" },
{ 0x01010f, { 0x01010f, "PCI native mode controller, supports both channels switched "
"PCI native mode controller, supports both channels switched " "to ISA compatibility mode" },
"to ISA compatibility mode" },
{ 0x010180, { 0x010180,
"ISA Compatibility mode-only controller, supports bus mastering" }, "ISA Compatibility mode-only controller, supports bus mastering" },
{ 0x010185, "PCI native mode-only controller, supports bus mastering" }, { 0x010185, "PCI native mode-only controller, supports bus mastering" },
{ 0x01018a, "ISA Compatibility mode controller, supports both channels " { 0x01018a, "ISA Compatibility mode controller, supports both channels "
"switched to PCI native mode, supports bus mastering" }, "switched to PCI native mode, supports bus mastering" },
{ 0x01018f, { 0x01018f, "PCI native mode controller, supports both channels switched "
"PCI native mode controller, supports both channels switched " "\to ISA compatibility mode, supports bus mastering" },
"\to ISA compatibility mode, supports bus mastering" },
{ 0x010200, "Floppy disk controller" }, { 0x010200, "Floppy disk controller" },
{ 0x010300, "IPI bus controller" }, { 0x010300, "IPI bus controller" },
@@ -154,10 +152,8 @@ struct {
{ 0x060600, "NuBus bridge" }, { 0x060600, "NuBus bridge" },
{ 0x060700, "CardBus bridge" }, { 0x060700, "CardBus bridge" },
// { 0x0608xx , "RACEway bridge" }, // { 0x0608xx , "RACEway bridge" },
{ 0x060940, { 0x060940, "PCI-to-PCI bridge, Semi-transparent, primary facing Host" },
"PCI-to-PCI bridge, Semi-transparent, primary facing Host" }, { 0x060980, "PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
{ 0x060980,
"PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
{ 0x060A00, "InfiniBand-to-PCI host bridge" }, { 0x060A00, "InfiniBand-to-PCI host bridge" },
{ 0x068000, "Bridge device" }, { 0x068000, "Bridge device" },
@@ -273,8 +269,7 @@ struct {
const char *pci_vendor_lookup(unsigned short vendor_id) const char *pci_vendor_lookup(unsigned short vendor_id)
{ {
for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]); for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]); ++i) {
++i) {
if (_pci_vendors[i].id == vendor_id) { if (_pci_vendors[i].id == vendor_id) {
return _pci_vendors[i].name; return _pci_vendors[i].name;
} }
@@ -284,12 +279,11 @@ const char *pci_vendor_lookup(unsigned short vendor_id)
} }
const char *pci_device_lookup(unsigned short vendor_id, const char *pci_device_lookup(unsigned short vendor_id,
unsigned short device_id) unsigned short device_id)
{ {
for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]); for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]); ++i) {
++i) {
if (_pci_devices[i].ven_id == vendor_id && if (_pci_devices[i].ven_id == vendor_id &&
_pci_devices[i].dev_id == device_id) { _pci_devices[i].dev_id == device_id) {
return _pci_devices[i].name; return _pci_devices[i].name;
} }
} }
@@ -299,8 +293,7 @@ const char *pci_device_lookup(unsigned short vendor_id,
const char *pci_class_lookup(uint32_t class_code) const char *pci_class_lookup(uint32_t class_code)
{ {
for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]); for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]); ++i) {
++i) {
if (_pci_classes[i].id == class_code) { if (_pci_classes[i].id == class_code) {
return _pci_classes[i].name; return _pci_classes[i].name;
} }
@@ -317,7 +310,7 @@ void pci_scan_hit(pci_func_t f, uint32_t dev, void *extra)
} }
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func, void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
void *extra) void *extra)
{ {
uint32_t dev = pci_box_device(bus, slot, func); uint32_t dev = pci_box_device(bus, slot, func);
@@ -325,8 +318,7 @@ void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
pci_scan_hit(f, dev, extra); pci_scan_hit(f, dev, extra);
} }
if (pci_find_type(dev) == PCI_TYPE_BRIDGE) { if (pci_find_type(dev) == PCI_TYPE_BRIDGE) {
pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1), pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1), extra);
extra);
} }
} }
@@ -378,7 +370,7 @@ void pci_scan(pci_func_t f, int type, void *extra)
} }
static void find_isa_bridge(uint32_t device, uint16_t vendorid, static void find_isa_bridge(uint32_t device, uint16_t vendorid,
uint16_t deviceid, void *extra) uint16_t deviceid, void *extra)
{ {
if (vendorid == 0x8086 && (deviceid == 0x7000 || deviceid == 0x7110)) { if (vendorid == 0x8086 && (deviceid == 0x7000 || deviceid == 0x7110)) {
*((uint32_t *)extra) = device; *((uint32_t *)extra) = device;
@@ -423,11 +415,10 @@ int pci_get_interrupt(uint32_t device)
uint32_t int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1); uint32_t int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1);
dbg_print( dbg_print("Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?"
"Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?" "int_line=%d\n",
"int_line=%d\n", pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq],
pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq], int_line);
int_line);
if (pci_remaps[pirq] == 0x80) { if (pci_remaps[pirq] == 0x80) {
dbg_print("Not mapped, remapping?\n"); dbg_print("Not mapped, remapping?\n");
@@ -442,7 +433,7 @@ int pci_get_interrupt(uint32_t device)
} }
static void scan_count(uint32_t device, uint16_t vendorid, uint16_t deviceid, static void scan_count(uint32_t device, uint16_t vendorid, uint16_t deviceid,
void *extra) void *extra)
{ {
(void)device; (void)device;
(void)vendorid; (void)vendorid;
@@ -452,61 +443,56 @@ static void scan_count(uint32_t device, uint16_t vendorid, uint16_t deviceid,
} }
static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid, static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
void *extra) void *extra)
{ {
(void)extra; (void)extra;
dbg_print("%2x:%2x.%d\n", pci_extract_bus(device), dbg_print("%2x:%2x.%d\n", pci_extract_bus(device), pci_extract_slot(device),
pci_extract_slot(device), pci_extract_func(device), deviceid); pci_extract_func(device), deviceid);
dbg_print(" Vendor : [0x%06x] %s\n", vendorid, dbg_print(" Vendor : [0x%06x] %s\n", vendorid,
pci_vendor_lookup(vendorid)); pci_vendor_lookup(vendorid));
dbg_print(" Device : [0x%06x] %s\n", deviceid, dbg_print(" Device : [0x%06x] %s\n", deviceid,
pci_device_lookup(vendorid, deviceid)); pci_device_lookup(vendorid, deviceid));
dbg_print(" Type : [0x%06x] %s\n", pci_find_type(device), dbg_print(" Type : [0x%06x] %s\n", pci_find_type(device),
pci_class_lookup(pci_find_type(device))); pci_class_lookup(pci_find_type(device)));
dbg_print(" Status : 0x%4x\n", dbg_print(" Status : 0x%4x\n",
pci_read_field(device, PCI_STATUS, 2)); pci_read_field(device, PCI_STATUS, 2));
dbg_print(" Command : 0x%4x\n", dbg_print(" Command : 0x%4x\n",
pci_read_field(device, PCI_COMMAND, 2)); pci_read_field(device, PCI_COMMAND, 2));
dbg_print(" Revision : %2d\n", dbg_print(" Revision : %2d\n",
pci_read_field(device, PCI_REVISION_ID, 1)); pci_read_field(device, PCI_REVISION_ID, 1));
dbg_print(" Cache Line Size : %2d\n", dbg_print(" Cache Line Size : %2d\n",
pci_read_field(device, PCI_CACHE_LINE_SIZE, 1)); pci_read_field(device, PCI_CACHE_LINE_SIZE, 1));
dbg_print(" Latency Timer : %2d\n", dbg_print(" Latency Timer : %2d\n",
pci_read_field(device, PCI_LATENCY_TIMER, 1)); pci_read_field(device, PCI_LATENCY_TIMER, 1));
dbg_print(" Header Type : %2d\n", dbg_print(" Header Type : %2d\n",
pci_read_field(device, PCI_HEADER_TYPE, 1)); pci_read_field(device, PCI_HEADER_TYPE, 1));
dbg_print(" BIST : %2d\n", dbg_print(" BIST : %2d\n", pci_read_field(device, PCI_BIST, 1));
pci_read_field(device, PCI_BIST, 1)); dbg_print(" BAR0 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_0, 4));
dbg_print(" BAR0 : 0x%08x", dbg_print(" BAR1 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_1, 4));
pci_read_field(device, PCI_BASE_ADDRESS_0, 4));
dbg_print(" BAR1 : 0x%08x",
pci_read_field(device, PCI_BASE_ADDRESS_1, 4));
dbg_print(" BAR2 : 0x%08x\n", dbg_print(" BAR2 : 0x%08x\n",
pci_read_field(device, PCI_BASE_ADDRESS_2, 4)); pci_read_field(device, PCI_BASE_ADDRESS_2, 4));
dbg_print(" BAR3 : 0x%08x", dbg_print(" BAR3 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_3, 4));
pci_read_field(device, PCI_BASE_ADDRESS_3, 4)); dbg_print(" BAR4 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_4, 4));
dbg_print(" BAR4 : 0x%08x",
pci_read_field(device, PCI_BASE_ADDRESS_4, 4));
dbg_print(" BAR6 : 0x%08x\n", dbg_print(" BAR6 : 0x%08x\n",
pci_read_field(device, PCI_BASE_ADDRESS_5, 4)); pci_read_field(device, PCI_BASE_ADDRESS_5, 4));
dbg_print(" Cardbus CIS : 0x%08x\n", dbg_print(" Cardbus CIS : 0x%08x\n",
pci_read_field(device, PCI_CARDBUS_CIS, 4)); pci_read_field(device, PCI_CARDBUS_CIS, 4));
dbg_print(" Subsystem V. ID : 0x%08x\n", dbg_print(" Subsystem V. ID : 0x%08x\n",
pci_read_field(device, PCI_SUBSYSTEM_VENDOR_ID, 2)); pci_read_field(device, PCI_SUBSYSTEM_VENDOR_ID, 2));
dbg_print(" Subsystem ID : 0x%08x\n", dbg_print(" Subsystem ID : 0x%08x\n",
pci_read_field(device, PCI_SUBSYSTEM_ID, 2)); pci_read_field(device, PCI_SUBSYSTEM_ID, 2));
dbg_print(" ROM Base Address: 0x%08x\n", dbg_print(" ROM Base Address: 0x%08x\n",
pci_read_field(device, PCI_ROM_ADDRESS, 4)); pci_read_field(device, PCI_ROM_ADDRESS, 4));
dbg_print(" PCI Cp. LinkList: 0x%08x\n", dbg_print(" PCI Cp. LinkList: 0x%08x\n",
pci_read_field(device, PCI_CAPABILITY_LIST, 1)); pci_read_field(device, PCI_CAPABILITY_LIST, 1));
dbg_print(" Max Latency : 0x%08x\n", dbg_print(" Max Latency : 0x%08x\n",
pci_read_field(device, PCI_MAX_LAT, 1)); pci_read_field(device, PCI_MAX_LAT, 1));
dbg_print(" Min Grant : 0x%08x\n", dbg_print(" Min Grant : 0x%08x\n",
pci_read_field(device, PCI_MIN_GNT, 1)); pci_read_field(device, PCI_MIN_GNT, 1));
dbg_print(" Interrupt Pin : %2d\n", dbg_print(" Interrupt Pin : %2d\n",
pci_read_field(device, PCI_INTERRUPT_PIN, 1)); pci_read_field(device, PCI_INTERRUPT_PIN, 1));
dbg_print(" Interrupt Line : %2d\n", dbg_print(" Interrupt Line : %2d\n",
pci_read_field(device, PCI_INTERRUPT_LINE, 1)); pci_read_field(device, PCI_INTERRUPT_LINE, 1));
dbg_print(" Interrupt Number: %2d\n", pci_get_interrupt(device)); dbg_print(" Interrupt Number: %2d\n", pci_get_interrupt(device));
dbg_print("\n"); dbg_print("\n");
} }
@@ -0,0 +1,107 @@
/// MentOS, The Mentoring Operating system project
/// @file deadlock_prevention.c
/// @brief Deadlock prevention algorithms source code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
///
/// Complete request() and state_safe() functions, according to what you learnt
/// in deadlock lectures.
///
/// In order to complete the functions I prepared for you a library to manage
/// easily arrays. The library is arr_math.h and you can find the documentation
/// in include/util/arr_math.h header file.
///
/// In addition you will find the same data structures that you have seen in
/// class:
/// - available: number of resources instances currently available;
/// - max: matrix of the maximum number of resources instances that each task
/// may require;
/// - alloc: matrix of current resources instances allocation of each task.
/// - need: matrix of current resources instances needs of each task.
/// Assume that these data structure are already filled with the
/// information described, in other words, you need to use these data structures
/// in read-only.
///
/// Suggestion!
/// From arr_math.h you may need only: arr_g_any(), arr_add(), arr_sub(),
/// all() and arr_ne();
#include "deadlock_prevention.h"
#include "arr_math.h"
#include "kheap.h"
/// @brief Check if the current system resource allocation maintains the system
/// in a safe state.
/// @param arr_available Array of resources instances currently available.
/// @param mat_alloc Matrix of current resources instances allocation of
/// each task.
/// @param mat_need Matrix of current resources instances need of each
/// task.
/// @param n Number of tasks currently in the system.
/// @param m Number of resource types in the system (length of req_vec).
static bool_t state_safe(uint32_t *arr_available, uint32_t **mat_alloc,
uint32_t **mat_need, size_t n, size_t m)
{
// Allocate work as a copy of available.
uint32_t *work = memcpy(kmalloc(sizeof(uint32_t) * m), arr_available,
sizeof(uint32_t) * m);
// Allocate finish initialized with all false (zeros).
uint32_t *finish = all(kmalloc(sizeof(uint32_t) * n), 0UL, n);
uint32_t *all_true = all(kmalloc(sizeof(uint32_t) * n), 1UL, n);
int i;
// Loop while finish is not equal an array all true (ones).
while (/* ... */)
{
// Find a task that can satisfy all the resources it needs.
for (i = 0; i < n && (/* ... */ || /* ... */); i++);
if (i == n)
{
// Free memory.
kfree(work);
kfree(finish);
kfree(all_true);
return false;
}
else
{
// Assume to make available the resources that the task found needs.
/* ... */
}
}
// Free memory.
kfree(work);
kfree(finish);
kfree(all_true);
return true;
}
deadlock_status_t request(uint32_t *req_vec, size_t task_i,
uint32_t *arr_available, uint32_t ** mat_alloc, uint32_t **mat_need,
size_t n, size_t m)
{
if (/* ... */)
{
return ERROR;
}
if (/* ... */)
{
return WAIT;
}
// Try to allocate resources.
/* ... */
// Check safe state
if (/* ... */)
{
// Restore previous allocation.
/* ... */
return WAIT_UNSAFE;
}
return SAFE;
}
@@ -0,0 +1,327 @@
/**
* @author Mirco De Marchi
* @date 2/02/2021
* @brief Source file for deadlock deterministic simulation.
* @copyright (c) University of Verona
*/
#include "deadlock_simulation.h"
#include "deadlock_prevention.h"
#include "resource.h"
#include "debug.h"
#include "arr_math.h"
#include "kheap.h"
#define SIM_N 2 ///< Task amount on simulation.
#define SIM_M 2 ///< Resource type amount on simulation.
/// @brief Simulation operations types.
typedef enum {
FREE,
LOCK,
} op_t;
/// @brief Structure type for a task resource request.
typedef struct request {
pid_t req_task; ///< Process id.
op_t op; ///< Operation type.
uint32_t req_vec[SIM_M]; ///< Resource request vector.
} req_t;
/// @brief Print available resources.
static void simulation_stats_available();
/// @brief Print resource request array.
/// @param req_vec Pointer to the resource request array.
/// @param length Length of resource request array.
static void simulation_stats_request(uint32_t *req_vec, size_t length);
/// @brief Print stats of resources over tasks matrix.
/// @param header_str String name related with the matrix to print.
/// @param m Matrix to print stats.
/// @param r Row number of the matrix.
/// @param c Col number of the matrix.
static void simulation_stats_matrix(const char * header_str, uint32_t **m,
size_t r, size_t c);
/// @brief Print system stats.
static void simulation_stats();
/// @brief Simulate a semaphore try lock.
static deadlock_status_t simulation_try_lock(uint32_t *req_vec, size_t task_i,
size_t n, size_t m);
/// @brief Simulate a semaphore lock.
static void simulation_lock(uint32_t *req_vec, pid_t pid);
/// @brief Simulate a semaphore free.
static void simulation_free(uint32_t *req_vec, pid_t pid);
/// @brief Simulation initialization.
static void simulation_init();
/// @brief Simulation core.
static void simulation_start();
/// @brief Simulation end.
static void simulation_close();
/// @brief Initial number of instances of resource type R_j currently available.
uint32_t initial_available[SIM_M] = {1, 1};
/// @brief Initial matrix of maximum resource request that each task require.
uint32_t initial_max[SIM_N][SIM_M] = {{1, 1}, {1, 1}};
/// @brief Initial matrix of current resource allocation of each task.
uint32_t initial_alloc[SIM_N][SIM_M] = {{0, 0}, {0, 0}};
/// Array of resources instances currently available;
uint32_t * arr_available;
/// Matrix of the maximum resources instances that each task may require;
uint32_t ** mat_max;
/// Matrix of current resources instances allocation of each task.
uint32_t ** mat_alloc;
/// Matrix of current resources instances need of each task.
uint32_t ** mat_need;
/// @brief Simulation requests.
req_t req_vec_test[] = {
{.req_task=0, .op=LOCK, .req_vec={1, 0}},
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
{.req_task=0, .op=LOCK, .req_vec={0, 1}},
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
{.req_task=0, .op=LOCK, .req_vec={0, 1}},
{.req_task=0, .op=FREE, .req_vec={0, 1}},
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
{.req_task=0, .op=FREE, .req_vec={1, 0}},
{.req_task=1, .op=LOCK, .req_vec={1, 0}},
{.req_task=1, .op=FREE, .req_vec={1, 0}},
{.req_task=1, .op=FREE, .req_vec={0, 1}},
{.req_task=1, .op=FREE, .req_vec={0, 1}},
};
static void simulation_stats_available()
{
dbg_print(" { ");
for (size_t j = 0; j < SIM_M-1; j++)
dbg_print("R_%i: %u, ", j, arr_available[j]);
dbg_print("R_%d: %u }", SIM_M-1, arr_available[SIM_M-1]);
}
static void simulation_stats_request(uint32_t *req_vec, size_t length)
{
dbg_print(" { ");
for (size_t j = 0; j < length-1; j++)
dbg_print("R_%i: %u, ", j, req_vec[j]);
dbg_print("R_%i: %u }", length-1, req_vec[length-1]);
}
static void simulation_stats_matrix(const char * header_str, uint32_t **m,
size_t r, size_t c)
{
const int col_size = 7;
const size_t tot_col = c + 1;
size_t j = 0;
dbg_print(" ");
for (j = 0; j < (tot_col * col_size) - 1; j++) dbg_print("-");
dbg_print("\n");
dbg_print("|");
const size_t table_space = (tot_col * col_size) - strlen(header_str) - 1;
for (j = 0; j < table_space / 2; j++) dbg_print(" ");
dbg_print("%s", header_str);
for (; j < table_space; j++) dbg_print(" ");
dbg_print("|\n");
dbg_print("| Task |");
for (j = 0; j < c; j++) dbg_print(" R_%-2i |", j);
dbg_print("\n");
for (size_t i = 0; i < r; i++)
{
dbg_print("| %4i |", i);
for (j = 0; j < c; j++)
dbg_print(" %4u |", m[i][j]);
dbg_print("\n");
}
dbg_print(" ");
for (j = 0; j < (tot_col * col_size) - 1; j++) dbg_print("-");
dbg_print("\n");
}
static void simulation_stats()
{
dbg_print("Tasks N: %i\n", SIM_N);
dbg_print("Resources M: %i\n", SIM_M);
dbg_print("AVAILABLE:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("MAX", mat_max, SIM_N, SIM_M);
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
simulation_stats_matrix("NEED", mat_need, SIM_N, SIM_M);
}
static deadlock_status_t simulation_try_lock(uint32_t *req_vec, size_t task_i,
size_t n, size_t m)
{
#if ENABLE_DEADLOCK_PREVENTION
return request(req_vec, task_i, arr_available, mat_alloc, mat_need, n, m);
#else
return ERROR;
#endif
}
static void simulation_lock(uint32_t *req_vec, pid_t pid)
{
if (!(arr_available && mat_max && mat_alloc && mat_need))
{
dbg_print("Some task-resource matrices NULL\n");
return;
}
switch (simulation_try_lock(req_vec, pid, SIM_N, SIM_M)) {
case SAFE:
dbg_print("LOCK (task: %d; req_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(") SAFE: enjoy your resource\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
break;
case WAIT:
dbg_print("LOCK (task %d; req_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(") WAIT: resource busy\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
break;
case WAIT_UNSAFE:
dbg_print("LOCK (task %d; rec_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(") WAIT UNSAFE: deadlock detected\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
break;
case ERROR:
dbg_print("LOCK (task %d; rec_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(") ERROR: max matrix overflow\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
break;
default:
return;
}
}
static void simulation_free(uint32_t *req_vec, pid_t pid)
{
if (arr_l_any(mat_alloc[pid], req_vec, SIM_M))
{
dbg_print("FREE (task %d; rec_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(") ERROR: try to free a resource not own\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
return;
}
arr_add(arr_available, req_vec, SIM_M);
arr_sub(mat_alloc[pid], req_vec, SIM_M);
// Check what happen if you uncomment the following line.
// arr_add(mat_need[pid], req_vec, SIM_M);
dbg_print("FREE (task %d; rec_vec:", pid);
simulation_stats_request(req_vec, SIM_M);
dbg_print(")\n");
dbg_print("available:");
simulation_stats_available();
dbg_print("\n");
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
}
static void simulation_init()
{
arr_available = (uint32_t *) kmalloc(SIM_M * sizeof(uint32_t));
mat_max = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
mat_alloc = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
mat_need = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
memcpy(arr_available, initial_available, SIM_M * sizeof(uint32_t));
for (size_t i = 0; i < SIM_N; i++)
{
memcpy(mat_max[i], initial_max[i], SIM_M * sizeof(uint32_t));
memcpy(mat_alloc[i], initial_alloc[i], SIM_M * sizeof(uint32_t));
}
// Calculate mat_need[i][j] = mat_max[i][j] - mat_alloc[i][j].
for (size_t i = 0; i < SIM_N; i++)
{
memcpy(mat_need[i], mat_max[i], SIM_M * sizeof(uint32_t));
arr_sub(mat_need[i], mat_alloc[i], SIM_M);
}
}
static void simulation_start()
{
dbg_print("Deadlock Prevention: simulation start\n");
for (size_t test = 0; test < sizeof(req_vec_test) / sizeof(req_t); test++)
{
uint32_t *req_vec = req_vec_test[test].req_vec;
pid_t task_pid = req_vec_test[test].req_task;
switch (req_vec_test[test].op)
{
case FREE:
{
simulation_free(req_vec, task_pid);
break;
}
case LOCK:
{
simulation_lock(req_vec, task_pid);
break;
}
default:
{
dbg_print("Request vector operation type not recognized\n");
break;
}
}
}
}
static void simulation_close()
{
kfree(arr_available);
kmfree((void **) mat_max, SIM_N);
kmfree((void **) mat_alloc, SIM_N);
kmfree((void **) mat_need, SIM_N);
mat_max = NULL;
mat_alloc = NULL;
mat_need = NULL;
}
void deadlock_simulation(int argc, char **argv)
{
#if ENABLE_DEADLOCK_PREVENTION
dbg_print("Deadlock Prevention: enabled\n");
simulation_init();
simulation_stats();
simulation_start();
simulation_close();
#else
dbg_print("Deadlock Prevention: disabled\n");
#endif
}
+106
View File
@@ -0,0 +1,106 @@
/// MentOS, The Mentoring Operating system project
/// @file arr_math.c
/// @brief Array arithmetic operations source file-
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "arr_math.h"
uint32_t *all(uint32_t *dst, uint32_t value, size_t length)
{
for (size_t i = 0; i < length; i++) {
*(dst + i) = value;
}
return dst;
}
uint32_t *arr_sub(uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
*(left + i) -= *(right + i);
}
return left;
}
uint32_t *arr_add(uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
*(left + i) += *(right + i);
}
return left;
}
bool_t arr_g_any(const uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (*(left + i) > *(right + i)) {
return true;
}
}
return false;
}
bool_t arr_ge_any(const uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (*(left + i) >= *(right + i)) {
return true;
}
}
return false;
}
bool_t arr_l_any(const uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (*(left + i) < *(right + i)) {
return true;
}
}
return false;
}
bool_t arr_le_any(const uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (*(left + i) <= *(right + i)) {
return true;
}
}
return false;
}
bool_t arr_g(const uint32_t *left, const uint32_t *right, size_t length)
{
return !arr_le_any(left, right, length);
}
bool_t arr_ge(const uint32_t *left, const uint32_t *right, size_t length)
{
return !arr_l_any(left, right, length);
}
bool_t arr_l(const uint32_t *left, const uint32_t *right, size_t length)
{
return !arr_ge_any(left, right, length);
}
bool_t arr_le(const uint32_t *left, const uint32_t *right, size_t length)
{
return !arr_g_any(left, right, length);
}
bool_t arr_e(const uint32_t *left, const uint32_t *right, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (*(left + i) != *(right + i)) {
return false;
}
}
return true;
}
bool_t arr_ne(const uint32_t *left, const uint32_t *right, size_t length)
{
return !arr_e(left, right, length);
}
+269
View File
@@ -0,0 +1,269 @@
/// MentOS, The Mentoring Operating system project
/// @file resource.c
/// @brief Resource definition source code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "resource.h"
#include "kheap.h"
#include "string.h"
#include "arr_math.h"
/// The list of processes.
extern runqueue_t runqueue;
/// The list of resources.
resource_list_t r_list;
/// @brief Remove the resource reference dependency from each task in running
/// state.
/// @param r Resource pointer.
static void clean_resource_reference(resource_t *r)
{
if (!r) return;
// Loop on running tasks.
list_head *it;
list_for_each (it, &runqueue.queue) {
task_struct *entry = list_entry(it, task_struct, run_list);
if (entry != NULL) {
// Loop on resources that tasks depend on.
for (size_t r_i = 0; r_i < TASK_RESOURCE_MAX_AMOUNT; r_i++) {
// Clean the resource reference in the task resources list.
if (entry->resources[r_i] == r) {
entry->resources[r_i] = NULL;
}
}
}
}
}
/// @brief Generate the idx_map_task_struct array, that maps an index with a
/// related process.
/// @param idx_map_task_struct Pointer of the array already allocated to fill.
/// @return The same pointer passed as parameter.
static task_struct **compute_index_map_task_struct(
task_struct *idx_map_task_struct[])
{
// Loop on running tasks.
list_head *task_it;
size_t t_i = 0;
list_for_each (task_it, &runqueue.queue) {
task_struct *task = list_entry(task_it, task_struct, run_list);
if (task != NULL) {
// Map a task with an index.
idx_map_task_struct[t_i] = task;
t_i++;
}
}
return idx_map_task_struct;
}
/// @brief Generate the available array, that contains the resources instances
/// currently available.
/// @param arr_available Pointer of the array already allocated to fill.
/// @return The same pointer passed as parameter.
static uint32_t *fill_available(uint32_t *arr_available)
{
// Loop on resources created.
list_head *resource_it;
list_for_each (resource_it, &r_list.head) {
resource_t *resource = list_entry(resource_it, resource_t,
resources_list);
arr_available[resource->rid] =
resource->n_instances - resource->assigned_instances;
}
return arr_available;
}
/// @brief Generate the max matrix, that contains the maximum number of
/// resources instances that each task may require.
/// @param mat_max Pointer of the matrix already allocated to fill.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// @return The same pointer passed as first parameter.
static uint32_t **fill_max(uint32_t **mat_max, task_struct *idx_map_task_struct[])
{
// Loop on all tasks.
size_t n = kernel_get_active_processes();
size_t m = kernel_get_active_resources();
for (size_t t_i = 0; t_i < n; t_i++) {
task_struct *task = idx_map_task_struct[t_i];
if (task != NULL) {
// Find resources needed by the task.
for (size_t r_i = 0; r_i < m; r_i++) {
if (task->resources[r_i] != NULL) {
mat_max[t_i][r_i] = task->resources[r_i]->n_instances;
}
}
}
}
return mat_max;
}
/// @brief Generate the alloc matrix, that contains the current resources
/// instances allocated for each task.
/// @param mat_alloc Pointer of the matrix already allocated to fill.
/// @param idx_map_task_struct Pointer to the array of index and tasks mapping.
/// @return The same pointer passed as first parameter.
static uint32_t **fill_alloc(uint32_t **mat_alloc,
task_struct *idx_map_task_struct[])
{
size_t n = kernel_get_active_processes();
// Loop on resources created.
list_head *resource_it;
list_for_each (resource_it, &r_list.head) {
resource_t *resource = list_entry(resource_it, resource_t,
resources_list);
// Find the task with this resource assigned and take the instances num.
for (size_t t_i = 0; t_i < n; t_i++) {
if (idx_map_task_struct[t_i] == resource->assigned_task) {
mat_alloc[t_i][resource->rid] = resource->assigned_instances;
}
}
}
return mat_alloc;
}
/// @brief Generate the need matrix, that contains the current resources
/// instances need of each task.
/// @param mat_need Pointer of the matrix already allocated to fill.
/// @param mat_max Pointer to the max matrix.
/// @param mat_alloc Pointer to the alloc matrix.
/// @return The same pointer passed as first parameter.
static uint32_t **fill_need(uint32_t **mat_need, uint32_t **mat_max,
uint32_t **mat_alloc)
{
// Calculate need[i][j] = max[i][j] - alloc[i][j].
size_t n = kernel_get_active_processes();
size_t m = kernel_get_active_resources();
for (size_t i = 0; i < n; i++) {
memcpy(mat_need[i], mat_max[i], m * sizeof(uint32_t));
arr_sub(mat_need[i], mat_alloc[i], m);
}
return mat_need;
}
resource_t *resource_create(const char *category)
{
// Check if current task can allocate a new resource.
task_struct *current_task = kernel_get_current_process();
size_t i = 0;
while(current_task->resources[i] != NULL) {
i++;
if (i >= TASK_RESOURCE_MAX_AMOUNT) {
return NULL;
}
}
// Allocate new resource and initialize it.
resource_t *new = kmalloc(sizeof(resource_t));
memset(new, 0, sizeof(resource_t));
new->rid = r_list.num_active++;
new->category = category;
// Current task is one of the tasks that need for this resource allocation.
current_task->resources[i] = new;
// The number of resource instances: for now always 1.
new->n_instances = 1;
// Initialize the list_head.
list_head_init(&new->resources_list);
list_head_add_tail(&new->resources_list, &r_list.head);
return new;
}
void resource_init(resource_t *r)
{
if (!r) return;
r->assigned_task = NULL;
r->assigned_instances = 0;
}
void resource_destroy(resource_t *r)
{
if (!r) return;
// Remove pointer of this resource from running processes.
clean_resource_reference(r);
// Remove this resource from resources list.
list_head_del(&r->resources_list);
kfree(r);
r_list.num_active--;
// Normalize resource ids.
list_head *resource_it;
size_t rid = 0;
list_for_each (resource_it, &r_list.head) {
resource_t *resource = list_entry(resource_it, resource_t,
resources_list);
if (resource != NULL) {
resource->rid = rid;
}
}
}
void resource_assign(resource_t *r)
{
if (!r) return;
// Assign resource to current task.
r->assigned_task = kernel_get_current_process();
// Number of instances assigned, for now always 1.
r->assigned_instances = 1;
}
void resource_deassign(resource_t *r)
{
if (!r) return;
r->assigned_task = NULL;
r->assigned_instances = 0;
}
void init_deadlock_structures(uint32_t *arr_available, uint32_t **mat_max,
uint32_t **mat_alloc, uint32_t **mat_need,
task_struct *idx_map_task_struct[])
{
reset_deadlock_structures(arr_available, mat_max, mat_alloc, idx_map_task_struct);
compute_index_map_task_struct(idx_map_task_struct);
fill_alloc(mat_alloc, idx_map_task_struct);
fill_max(mat_max, idx_map_task_struct);
fill_available(arr_available);
fill_need(mat_need, mat_max, mat_alloc);
}
void reset_deadlock_structures(uint32_t *arr_available, uint32_t **mat_max,
uint32_t **mat_alloc, task_struct *idx_map_task_struct[])
{
size_t n = kernel_get_active_processes();
size_t m = kernel_get_active_resources();
// Clean idx_map_task_struct and rows of max and alloc.
for (size_t t_i = 0; t_i < n; t_i++) {
idx_map_task_struct[t_i] = NULL;
memset(mat_alloc[t_i], 0, m * sizeof(uint32_t));
memset(mat_max[t_i], 0, m * sizeof(uint32_t));
}
// Clean row of resources.
memset(arr_available, 0, m * sizeof(uint32_t));
}
size_t kernel_get_active_resources()
{
return r_list.num_active;
}
int32_t get_current_task_idx_from(task_struct *idx_map_task_struct[])
{
size_t n = kernel_get_active_processes();
int32_t ret = -1;
for (size_t t_i = 0; t_i < n; t_i++) {
if (idx_map_task_struct[t_i] == kernel_get_current_process()) {
ret = t_i;
break;
}
}
return ret;
}
+185
View File
@@ -0,0 +1,185 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_kernel.c
/// @brief Smart semaphore kernel-side implementation source code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "smart_sem_kernel.h"
#include "errno.h"
#include "resource.h"
#include "kheap.h"
#include "deadlock_prevention.h"
#include "panic.h"
#include "debug.h"
/// Max number of semaphore that the operating system can manage.
#define SEM_MAX 356
/// Max value of a semaphore. WIP
#define SEM_VALUE_MAX 32
/// @brief Smart semaphore descriptor.
typedef struct {
/// Semaphore value. The initialization value is 0.
volatile atomic_t value;
/// Semaphore mutex value. The initialization value is 0.
volatile atomic_t mutex;
/// Set to true if this semaphore instance is used, otherwise is false.
bool_t used;
/// Reference to the resource related with the semaphore used. If semaphore
/// is not used, this pointer is NULL.
resource_t *sem_resource;
} smart_sem_t;
/// Global array of all smart semaphores that can be allocated.
smart_sem_t semaphores[SEM_MAX] = { 0 };
/// @brief Check if the semaphore is available and if it can be safety taken. If
/// the acquisition is safe, it set the semaphore value.
/// Safety check is done only if ENABLE_DEADLOCK_PREVENTION is true.
/// @param id Smart semaphore id.
/// @return True if semaphore can be safely acquired, otherwise if the
/// semaphore acquisition is unsafe or not available, return false.
static bool_t sys_sem_try(int id)
{
#if ENABLE_DEADLOCK_PREVENTION
// Init deadlock prevention structures.
size_t n = kernel_get_active_processes();
size_t m = kernel_get_active_resources();
uint32_t *arr_available = (uint32_t *) kmalloc(m * sizeof(uint32_t));
uint32_t **mat_max = (uint32_t **) kmmalloc(n, m * sizeof(uint32_t));
uint32_t **mat_alloc = (uint32_t **) kmmalloc(n, m * sizeof(uint32_t));
uint32_t **mat_need = (uint32_t **) kmmalloc(n, m * sizeof(uint32_t));
task_struct **idx_map_task_struct = (task_struct **) kmalloc(
n * sizeof(task_struct *));
if (arr_available && mat_max && mat_alloc && mat_need
&& idx_map_task_struct) {
init_deadlock_structures(arr_available, mat_max, mat_alloc, mat_need,
idx_map_task_struct);
} else {
kernel_panic("not able to perform allocation for deadlock prevention");
}
// Init request vector.
uint32_t *req_vec = (uint32_t *) kmalloc(m * sizeof(uint32_t));
if (req_vec) {
memset(req_vec, 0, m * sizeof(uint32_t));
req_vec[semaphores[id].sem_resource->rid] = 1;
} else {
kernel_panic("not able to perform allocation for deadlock prevention");
}
// Find current task correct index.
int32_t current_task_idx = get_current_task_idx_from(idx_map_task_struct);
if (current_task_idx < 0) {
kernel_panic("did't find current task in idx_map_task_struct array");
}
// Perform request.
bool_t ret = false;
switch (request(req_vec, current_task_idx, arr_available, mat_alloc,
mat_need, n, m)) {
case WAIT:
case WAIT_UNSAFE:
break;
case SAFE:
if (atomic_set_and_test(&semaphores[id].value, 1) == 0) {
ret = true;
} else {
kernel_panic("allocation request return bad safe status");
}
break;
case ERROR:
default:
kernel_panic("deadlock prevention error");
}
kfree(arr_available);
kmfree((void **) mat_max, n);
kmfree((void **) mat_alloc, n);
kmfree((void **) mat_need, n);
kfree(idx_map_task_struct);
kfree(req_vec);
return ret;
#else
dbg_print("sys_sem_try(%d)\n", id);
return atomic_set_and_test(&semaphores[id].value, 1) == 0;
#endif
}
int sys_sem_create()
{
int id = -1;
for (unsigned i = 0; i < SEM_MAX; ++i) {
if (!semaphores[i].used) {
semaphores[i].sem_resource = resource_create("sem");
if (!semaphores[i].sem_resource) {
return -1;
}
semaphores[i].used = true;
id = (int)i;
break;
}
}
dbg_print("sys_sem_create() -> %d\n", id);
return id;
}
int sys_sem_destroy(int id)
{
dbg_print("sys_sem_destroy(%d)\n", id);
if ((id < 0) || (id > SEM_MAX)) {
return -1;
}
semaphores[id].used = false;
resource_destroy(semaphores[id].sem_resource);
return 0;
}
int sys_sem_init(int id)
{
dbg_print("sys_sem_init(%d)\n", id);
if ((id < 0) || (id > SEM_MAX)) {
return -1;
}
if (!semaphores[id].used) {
return -1;
}
atomic_set(&semaphores[id].value, 0);
resource_init(semaphores[id].sem_resource);
return 0;
}
int sys_sem_try_acquire(int id)
{
dbg_print("sys_sem_try_acquire(%d)\n", id);
if ((id < 0) || (id > SEM_MAX)) {
return -1;
}
if (!semaphores[id].used) {
return -1;
}
if (sys_sem_try(id)) {
resource_assign(semaphores[id].sem_resource);
return 1;
}
return 0;
}
int sys_sem_release(int id)
{
dbg_print("sys_sem_release(%d)\n", id);
if ((id < 0) || (id > SEM_MAX)) {
return -1;
}
if (!semaphores[id].used) {
return -1;
}
atomic_set(&semaphores[id].value, 0);
resource_deassign(semaphores[id].sem_resource);
return 0;
}
+69
View File
@@ -0,0 +1,69 @@
/// MentOS, The Mentoring Operating system project
/// @file smart_sem_user.c
/// @brief Semaphore user-side implementation source code.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "smart_sem_user.h"
#include "syscall.h"
#include "syscall_types.h"
#include "errno.h"
#include "debug.h"
int sem_create()
{
int retval = 0;
/* ... */
dbg_print("sem_create() -> %d\n", retval);
return retval;
}
int sem_destroy(int id)
{
int retval = 0;
dbg_print("sem_destroy(%d)\n", id);
/* ... */
return retval;
}
int sem_init(int id)
{
int retval = 0;
dbg_print("sem_init(%d)\n", id);
/* ... */
return retval;
}
int sem_acquire(int id)
{
int retval;
dbg_print("sem_acquire(%d)\n", id);
do {
/* ... */
} while (retval != 1);
return retval;
}
int sem_release(int id)
{
int retval = 0;
dbg_print("sem_release(%d)\n", id);
/* ... */
return retval;
}
+15 -97
View File
@@ -4,109 +4,27 @@
/// @copyright (c) 2019 This file is distributed under the MIT License. /// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details. /// See LICENSE.md for details.
#include "vfs.h"
#include "debug.h"
#include "kheap.h"
#include "shell.h"
#include "errno.h"
#include "fcntl.h" #include "fcntl.h"
#include "string.h" #include "string.h"
#include "kernel.h" #include "vfs.h"
#include "limits.h"
int sys_open(const char *pathname, int flags, mode_t mode)
{
// Allocate a variable for the path.
char absolute_path[MAX_PATH_LENGTH];
// Copy the path to the working variable.
strcpy(absolute_path, pathname);
// If the first character is not the '/' then get the absolute path.
if (absolute_path[0] != '/')
{
if (!get_absolute_path(absolute_path))
{
dbg_print("Cannot get the absolute path.\n");
return -1;
}
}
// Search for an unused fd.
for (current_fd = 0; current_fd < MAX_OPEN_FD; ++current_fd)
{
if (fd_list[current_fd].mountpoint_id == -1)
{
break;
}
}
// Check if there is not fd available.
if (current_fd == MAX_OPEN_FD)
{
//errno = EMFILE;
return -1;
}
// Get the mountpoint.
mountpoint_t *mp = get_mountpoint(absolute_path);
if (mp == NULL)
{
//errno = ENODEV;
return -1;
}
// Check if the function is implemented.
if (mp->operations.open_f == NULL)
{
//errno = ENOSYS;
// Reset the file descriptor.
close(current_fd);
return -1;
}
int32_t fs_spec_id = mp->operations.open_f(absolute_path, flags, mode);
if (fs_spec_id == -1)
{
// Reset the file descriptor.
close(current_fd);
return -1;
}
// Set the file descriptor id.
fd_list[current_fd].fs_spec_id = fs_spec_id;
// Set the mount point id.
fd_list[current_fd].mountpoint_id = mp->mp_id;
// Reset the offset.
fd_list[current_fd].offset = 0;
// Set the flags.
fd_list[current_fd].flags_mask = flags;
// Return the file descriptor and increment it.
return (current_fd++);
}
int remove(const char *pathname) int remove(const char *pathname)
{ {
char absolute_path[MAX_PATH_LENGTH]; char absolute_path[PATH_MAX];
strcpy(absolute_path, pathname); strcpy(absolute_path, pathname);
if (pathname[0] != '/') if (pathname[0] != '/') {
{ get_absolute_path(absolute_path);
get_absolute_path(absolute_path); }
}
int32_t mp_id = get_mountpoint_id(absolute_path); int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0) if (mp_id < 0) {
{ return -1;
return -1; }
}
if (mountpoint_list[mp_id].operations.remove_f == NULL) if (mountpoint_list[mp_id].operations.remove_f == NULL) {
{ return -1;
return -1; }
}
return mountpoint_list[mp_id].operations.remove_f(absolute_path); return mountpoint_list[mp_id].operations.remove_f(absolute_path);
} }
+3 -3
View File
@@ -84,7 +84,7 @@ DIR *initfs_opendir(const char *path)
} }
DIR *pdir = kmalloc(sizeof(DIR)); DIR *pdir = kmalloc(sizeof(DIR));
pdir->handle = -1; pdir->fd = -1;
pdir->cur_entry = 0; pdir->cur_entry = 0;
strcpy(pdir->path, path); strcpy(pdir->path, path);
@@ -217,7 +217,7 @@ int initrd_rmdir(const char *path)
} }
// Remove the directory. // Remove the directory.
direntry->magic = 0; direntry->magic = 0;
memset(direntry->fileName, 0, MAX_FILENAME_LENGTH); memset(direntry->fileName, 0, NAME_MAX);
direntry->file_type = 0; direntry->file_type = 0;
direntry->uid = 0; direntry->uid = 0;
direntry->offset = 0; direntry->offset = 0;
@@ -320,7 +320,7 @@ int initfs_remove(const char *path)
// Remove the directory. // Remove the directory.
file->magic = 0; file->magic = 0;
memset(file->fileName, 0, MAX_FILENAME_LENGTH); memset(file->fileName, 0, NAME_MAX);
file->file_type = 0; file->file_type = 0;
file->uid = 0; file->uid = 0;
file->offset = 0; file->offset = 0;
+98
View File
@@ -0,0 +1,98 @@
/// MentOS, The Mentoring Operating system project
/// @file open.c
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "syscall.h"
#include "string.h"
#include "limits.h"
#include "debug.h"
#include "stdio.h"
#include "vfs.h"
int sys_open(const char *pathname, int flags, mode_t mode)
{
// Allocate a variable for the path.
char absolute_path[PATH_MAX];
// Copy the path to the working variable.
strcpy(absolute_path, pathname);
// If the first character is not the '/' then get the absolute path.
if (absolute_path[0] != '/') {
if (!get_absolute_path(absolute_path)) {
dbg_print("Cannot get the absolute path.\n");
return -1;
}
}
// Search for an unused fd.
for (current_fd = 0; current_fd < MAX_OPEN_FD; ++current_fd) {
if (fd_list[current_fd].mountpoint_id == -1) {
break;
}
}
// Check if there is not fd available.
if (current_fd == MAX_OPEN_FD) {
//errno = EMFILE;
return -1;
}
// Get the mountpoint.
mountpoint_t *mp = get_mountpoint(absolute_path);
if (mp == NULL) {
//errno = ENODEV;
return -1;
}
// Check if the function is implemented.
if (mp->operations.open_f == NULL) {
//errno = ENOSYS;
// Reset the file descriptor.
sys_close(current_fd);
return -1;
}
int32_t fs_spec_id = mp->operations.open_f(absolute_path, flags, mode);
if (fs_spec_id == -1) {
// Reset the file descriptor.
sys_close(current_fd);
return -1;
}
// Set the file descriptor id.
fd_list[current_fd].fs_spec_id = fs_spec_id;
// Set the mount point id.
fd_list[current_fd].mountpoint_id = mp->mp_id;
// Reset the offset.
fd_list[current_fd].offset = 0;
// Set the flags.
fd_list[current_fd].flags_mask = flags;
// Return the file descriptor and increment it.
return (current_fd++);
}
int sys_close(int fd)
{
if (fd < 0) {
return -1;
}
if (fd_list[fd].fs_spec_id >= -1) {
int mp_id = fd_list[fd].mountpoint_id;
if (mountpoint_list[mp_id].operations.close_f != NULL) {
int fs_fd = fd_list[fd].fs_spec_id;
mountpoint_list[mp_id].operations.close_f(fs_fd);
}
fd_list[fd].fs_spec_id = -1;
fd_list[fd].mountpoint_id = -1;
} else {
return -1;
}
return 0;
}
-1
View File
@@ -5,7 +5,6 @@
/// See LICENSE.md for details. /// See LICENSE.md for details.
#include <misc/debug.h> #include <misc/debug.h>
#include "read_write.h"
#include "vfs.h" #include "vfs.h"
#include "stdio.h" #include "stdio.h"
#include "fcntl.h" #include "fcntl.h"
+28
View File
@@ -0,0 +1,28 @@
/// MentOS, The Mentoring Operating system project
/// @file readdir.c
/// @brief Function for accessing directory entries.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "dirent.h"
#include "syscall.h"
#include "stdio.h"
#include "vfs.h"
dirent_t *sys_readdir(DIR *dirp)
{
if (dirp == NULL) {
printf("readdir: cannot read directory :"
"Directory pointer is not valid\n");
return NULL;
}
if (mountpoint_list[dirp->fd].dir_op.readdir_f == NULL) {
printf("readdir: cannot read directory '%s':"
"No readdir function\n",
dirp->path);
return NULL;
}
return mountpoint_list[dirp->fd].dir_op.readdir_f(dirp);
}
@@ -9,8 +9,9 @@
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
#include "initrd.h" #include "initrd.h"
#include "limits.h"
int stat(const char *path, stat_t *buf) int sys_stat(const char *path, stat_t *buf)
{ {
// Reset the structure. // Reset the structure.
buf->st_dev = 0; buf->st_dev = 0;
@@ -23,7 +24,7 @@ int stat(const char *path, stat_t *buf)
buf->st_mtime = 0; buf->st_mtime = 0;
buf->st_ctime = 0; buf->st_ctime = 0;
char absolute_path[MAX_PATH_LENGTH]; char absolute_path[PATH_MAX];
strcpy(absolute_path, path); strcpy(absolute_path, path);
if (path[0] != '/') if (path[0] != '/')
@@ -51,9 +52,9 @@ int stat(const char *path, stat_t *buf)
return 0; return 0;
} }
int mkdir(const char *path, mode_t mode) int sys_mkdir(const char *path, mode_t mode)
{ {
char absolute_path[MAX_PATH_LENGTH]; char absolute_path[PATH_MAX];
strcpy(absolute_path, path); strcpy(absolute_path, path);
int result = -1; int result = -1;
+5 -4
View File
@@ -12,6 +12,7 @@
#include "shell.h" #include "shell.h"
#include "string.h" #include "string.h"
#include "initrd.h" #include "initrd.h"
#include "limits.h"
int current_fd; int current_fd;
char *module_start[MAX_MODULES]; char *module_start[MAX_MODULES];
@@ -106,7 +107,7 @@ mountpoint_t *get_mountpoint_from_id(int32_t mp_id)
int get_relative_path(uint32_t mp_id, char *path) int get_relative_path(uint32_t mp_id, char *path)
{ {
char relative_path[MAX_PATH_LENGTH]; char relative_path[PATH_MAX];
// Get the size of the path. // Get the size of the path.
size_t path_size = strlen(path); size_t path_size = strlen(path);
@@ -133,9 +134,9 @@ int get_relative_path(uint32_t mp_id, char *path)
int get_absolute_path(char *path) int get_absolute_path(char *path)
{ {
if (path[0] != '/') { if (path[0] != '/') {
char abspath[MAX_PATH_LENGTH]; char abspath[PATH_MAX];
memset(abspath, '\0', MAX_PATH_LENGTH); memset(abspath, '\0', PATH_MAX);
getcwd(abspath, MAX_PATH_LENGTH); getcwd(abspath, PATH_MAX);
int abs_size = strlen(abspath); int abs_size = strlen(abspath);
if (abspath[abs_size - 1] == '/') { if (abspath[abs_size - 1] == '/') {
strncat(abspath, path, strlen(path)); strncat(abspath, path, strlen(path));
+117 -130
View File
@@ -9,164 +9,152 @@
void get_cpuid(cpuinfo_t *cpuinfo) void get_cpuid(cpuinfo_t *cpuinfo)
{ {
register_t ereg; register_t ereg;
ereg.eax = ereg.ebx = ereg.ecx = ereg.edx = 0; ereg.eax = ereg.ebx = ereg.ecx = ereg.edx = 0;
cpuid_write_vendor(cpuinfo, &ereg); cpuid_write_vendor(cpuinfo, &ereg);
ereg.eax = 1; ereg.eax = 1;
ereg.ebx = ereg.ecx = ereg.edx = 0; ereg.ebx = ereg.ecx = ereg.edx = 0;
cpuid_write_proctype(cpuinfo, &ereg); cpuid_write_proctype(cpuinfo, &ereg);
} }
void call_cpuid(register_t *registers) void call_cpuid(register_t *registers)
{ {
__asm__ ("cpuid\n\t" : __asm__("cpuid\n\t"
"=a" (registers->eax), : "=a"(registers->eax), "=b"(registers->ebx), "=c"(registers->ecx),
"=b" (registers->ebx), "=d"(registers->edx)
"=c" (registers->ecx), : "a"(registers->eax));
"=d" (registers->edx) :
"a" (registers->eax));
} }
void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers) void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers)
{ {
call_cpuid(registers); call_cpuid(registers);
cpuinfo->cpu_vendor[0] = (char) ((registers->ebx & 0x000000FF)); cpuinfo->cpu_vendor[0] = (char)((registers->ebx & 0x000000FF));
cpuinfo->cpu_vendor[1] = (char) ((registers->ebx & 0x0000FF00) >> 8); cpuinfo->cpu_vendor[1] = (char)((registers->ebx & 0x0000FF00) >> 8);
cpuinfo->cpu_vendor[2] = (char) ((registers->ebx & 0x00FF0000) >> 16); cpuinfo->cpu_vendor[2] = (char)((registers->ebx & 0x00FF0000) >> 16);
cpuinfo->cpu_vendor[3] = (char) ((registers->ebx & 0xFF000000) >> 24); cpuinfo->cpu_vendor[3] = (char)((registers->ebx & 0xFF000000) >> 24);
cpuinfo->cpu_vendor[4] = (char) ((registers->edx & 0x000000FF)); cpuinfo->cpu_vendor[4] = (char)((registers->edx & 0x000000FF));
cpuinfo->cpu_vendor[5] = (char) ((registers->edx & 0x0000FF00) >> 8); cpuinfo->cpu_vendor[5] = (char)((registers->edx & 0x0000FF00) >> 8);
cpuinfo->cpu_vendor[6] = (char) ((registers->edx & 0x00FF0000) >> 16); cpuinfo->cpu_vendor[6] = (char)((registers->edx & 0x00FF0000) >> 16);
cpuinfo->cpu_vendor[7] = (char) ((registers->edx & 0xFF000000) >> 24); cpuinfo->cpu_vendor[7] = (char)((registers->edx & 0xFF000000) >> 24);
cpuinfo->cpu_vendor[8] = (char) ((registers->ecx & 0x000000FF)); cpuinfo->cpu_vendor[8] = (char)((registers->ecx & 0x000000FF));
cpuinfo->cpu_vendor[9] = (char) ((registers->ecx & 0x0000FF00) >> 8); cpuinfo->cpu_vendor[9] = (char)((registers->ecx & 0x0000FF00) >> 8);
cpuinfo->cpu_vendor[10] = (char) ((registers->ecx & 0x00FF0000) >> 16); cpuinfo->cpu_vendor[10] = (char)((registers->ecx & 0x00FF0000) >> 16);
cpuinfo->cpu_vendor[11] = (char) ((registers->ecx & 0xFF000000) >> 24); cpuinfo->cpu_vendor[11] = (char)((registers->ecx & 0xFF000000) >> 24);
cpuinfo->cpu_vendor[12] = '\0'; cpuinfo->cpu_vendor[12] = '\0';
} }
void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers) void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
{ {
call_cpuid(registers); call_cpuid(registers);
uint32_t type = cpuid_get_byte(registers->eax, 0xB, 0x3); uint32_t type = cpuid_get_byte(registers->eax, 0xB, 0x3);
switch (type) switch (type) {
{ case 0:
case 0: cpuinfo->cpu_type = "Original OEM Processor";
cpuinfo->cpu_type = "Original OEM Processor"; break;
break; case 1:
case 1: cpuinfo->cpu_type = "Intel Overdrive Processor";
cpuinfo->cpu_type = "Intel Overdrive Processor"; break;
break; case 2:
case 2: cpuinfo->cpu_type = "Dual processor";
cpuinfo->cpu_type = "Dual processor"; break;
break; case 3:
case 3: cpuinfo->cpu_type = "(Intel reserved bit)";
cpuinfo->cpu_type = "(Intel reserved bit)"; break;
break; }
}
uint32_t familyID = cpuid_get_byte(registers->eax, 0x7, 0xE); uint32_t familyID = cpuid_get_byte(registers->eax, 0x7, 0xE);
cpuinfo->cpu_family = familyID; cpuinfo->cpu_family = familyID;
if (familyID == 0x0F) if (familyID == 0x0F) {
{ cpuinfo->cpu_family += cpuid_get_byte(registers->eax, 0x13, 0xFF);
cpuinfo->cpu_family += cpuid_get_byte(registers->eax, 0x13, 0xFF); }
}
uint32_t model = cpuid_get_byte(registers->eax, 0x3, 0xE); uint32_t model = cpuid_get_byte(registers->eax, 0x3, 0xE);
cpuinfo->cpu_model = model; cpuinfo->cpu_model = model;
if (familyID == 0x06 || familyID == 0x0F) if (familyID == 0x06 || familyID == 0x0F) {
{ uint32_t ext_model = cpuid_get_byte(registers->eax, 0xF, 0xE);
uint32_t ext_model = cpuid_get_byte(registers->eax, 0xF, 0xE); cpuinfo->cpu_model += (ext_model << 4);
cpuinfo->cpu_model += (ext_model << 4); }
} cpuinfo->apic_id = cpuid_get_byte(registers->ebx, 0x17, 0xFF);
cpuinfo->apic_id = cpuid_get_byte(registers->ebx, 0x17, 0xFF);
cpuid_feature_ecx(cpuinfo, registers->ecx); cpuid_feature_ecx(cpuinfo, registers->ecx);
cpuid_feature_edx(cpuinfo, registers->edx); cpuid_feature_edx(cpuinfo, registers->edx);
/* Get brand string to identify the processor */ /* Get brand string to identify the processor */
if (familyID >= 0x0F && model >= 0x03) if (familyID >= 0x0F && model >= 0x03) {
{ cpuinfo->brand_string = cpuid_brand_string(registers);
cpuinfo->brand_string = cpuid_brand_string(registers); } else {
} cpuinfo->brand_string = cpuid_brand_index(registers);
else }
{
cpuinfo->brand_string = cpuid_brand_index(registers);
}
} }
void cpuid_feature_ecx(cpuinfo_t *cpuinfo, uint32_t ecx) void cpuid_feature_ecx(cpuinfo_t *cpuinfo, uint32_t ecx)
{ {
uint32_t temp = ecx; uint32_t temp = ecx;
uint32_t i; uint32_t i;
for (i = 0; i < ECX_FLAGS_SIZE; ++i) for (i = 0; i < ECX_FLAGS_SIZE; ++i) {
{ temp = cpuid_get_byte(temp, i, 1);
temp = cpuid_get_byte(temp, i, 1); cpuinfo->cpuid_ecx_flags[i] = temp;
cpuinfo->cpuid_ecx_flags[i] = temp; temp = ecx;
temp = ecx; }
}
} }
void cpuid_feature_edx(cpuinfo_t *cpuinfo, uint32_t edx) void cpuid_feature_edx(cpuinfo_t *cpuinfo, uint32_t edx)
{ {
uint32_t temp = edx; uint32_t temp = edx;
uint32_t i; uint32_t i;
for (i = 0; i < EDX_FLAGS_SIZE; ++i) for (i = 0; i < EDX_FLAGS_SIZE; ++i) {
{ temp = cpuid_get_byte(temp, i, 1);
temp = cpuid_get_byte(temp, i, 1); cpuinfo->cpuid_edx_flags[i] = temp;
cpuinfo->cpuid_edx_flags[i] = temp; temp = edx;
temp = edx; }
}
} }
inline uint32_t cpuid_get_byte(const uint32_t reg, inline uint32_t cpuid_get_byte(const uint32_t reg, const uint32_t position,
const uint32_t position, const uint32_t value)
const uint32_t value)
{ {
return ((reg >> position) & value); return ((reg >> position) & value);
} }
char *cpuid_brand_index(register_t *r) char *cpuid_brand_index(register_t *r)
{ {
char *indexes[21] = {"Reserved", char *indexes[21] = { "Reserved",
"Intel Celeron", "Intel Celeron",
"Intel Pentium III", "Intel Pentium III",
"Intel Pentium III Xeon", "Intel Pentium III Xeon",
"Mobile Intel Pentium III", "Mobile Intel Pentium III",
"Mobile Intel Celeron", "Mobile Intel Celeron",
"Intel Pentium 4", "Intel Pentium 4",
"Intel Pentium 4", "Intel Pentium 4",
"Intel Celeron", "Intel Celeron",
"Intel Xeon MP", "Intel Xeon MP",
"Intel Xeon MP", "Intel Xeon MP",
"Mobile Intel Pentium 4", "Mobile Intel Pentium 4",
"Mobile Intel Celeron", "Mobile Intel Celeron",
"Mobile Genuine Intel", "Mobile Genuine Intel",
"Intel Celeron M", "Intel Celeron M",
"Mobile Intel Celeron", "Mobile Intel Celeron",
"Intel Celeron", "Intel Celeron",
"Mobile Genuine Intel", "Mobile Genuine Intel",
"Intel Pentium M", "Intel Pentium M",
"Mobile Intel Celeron", "Mobile Intel Celeron",
NULL}; NULL };
int bx = (r->ebx & 0xFF); int bx = (r->ebx & 0xFF);
if (bx > 0x17) if (bx > 0x17) {
{ bx = 0;
bx = 0; }
}
return indexes[bx]; return indexes[bx];
} }
/// ///
@@ -174,21 +162,20 @@ char *cpuid_brand_index(register_t *r)
/// @return /// @return
char *cpuid_brand_string(register_t *r) char *cpuid_brand_string(register_t *r)
{ {
char *temp = ""; char *temp = "";
for (r->eax = 0x80000002; r->eax <= 0x80000004; (r->eax)++) for (r->eax = 0x80000002; r->eax <= 0x80000004; (r->eax)++) {
{ r->ebx = r->ecx = r->edx = 0;
r->ebx = r->ecx = r->edx = 0; call_cpuid(r);
call_cpuid(r); temp =
temp = strncat(temp, (const char *) r->eax, strncat(temp, (const char *)r->eax, strlen((const char *)r->eax));
strlen((const char *) r->eax)); temp =
temp = strncat(temp, (const char *) r->ebx, strncat(temp, (const char *)r->ebx, strlen((const char *)r->ebx));
strlen((const char *) r->ebx)); temp =
temp = strncat(temp, (const char *) r->ecx, strncat(temp, (const char *)r->ecx, strlen((const char *)r->ecx));
strlen((const char *) r->ecx)); temp =
temp = strncat(temp, (const char *) r->edx, strncat(temp, (const char *)r->edx, strlen((const char *)r->edx));
strlen((const char *) r->edx)); }
}
return temp; return temp;
} }
+18 -15
View File
@@ -8,49 +8,52 @@
inline uint8_t inportb(uint16_t port) inline uint8_t inportb(uint16_t port)
{ {
unsigned char data = 0; unsigned char data = 0;
__asm__ __volatile__("inb %%dx, %%al" : "=a" (data) : "d" (port)); __asm__ __volatile__("inb %%dx, %%al" : "=a"(data) : "d"(port));
return data; return data;
} }
inline uint16_t inports(uint16_t port) inline uint16_t inports(uint16_t port)
{ {
uint16_t rv; uint16_t rv;
__asm__ __volatile__("inw %1, %0" : "=a" (rv) : "dN" (port)); __asm__ __volatile__("inw %1, %0" : "=a"(rv) : "dN"(port));
return rv; return rv;
} }
void inportsm(uint16_t port, uint8_t * data, unsigned long size) void inportsm(uint16_t port, uint8_t *data, unsigned long size)
{ {
__asm__ __volatile__("rep insw" : "+D" (data), "+c" (size) : "d" (port) : "memory"); __asm__ __volatile__("rep insw"
: "+D"(data), "+c"(size)
: "d"(port)
: "memory");
} }
inline uint32_t inportl(uint16_t port) inline uint32_t inportl(uint16_t port)
{ {
uint32_t rv; uint32_t rv;
__asm__ __volatile__("inl %%dx, %%eax" : "=a" (rv) : "dN" (port)); __asm__ __volatile__("inl %%dx, %%eax" : "=a"(rv) : "dN"(port));
return rv; return rv;
} }
inline void outportb(uint16_t port, uint8_t data) inline void outportb(uint16_t port, uint8_t data)
{ {
__asm__ __volatile__("outb %%al, %%dx"::"a" (data), "d" (port)); __asm__ __volatile__("outb %%al, %%dx" ::"a"(data), "d"(port));
} }
inline void outports(uint16_t port, uint16_t data) inline void outports(uint16_t port, uint16_t data)
{ {
__asm__ __volatile__("outw %1, %0" : : "dN" (port), "a" (data)); __asm__ __volatile__("outw %1, %0" : : "dN"(port), "a"(data));
} }
void outportsm(uint16_t port, uint8_t *data, uint16_t size) void outportsm(uint16_t port, uint8_t *data, uint16_t size)
{ {
asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port)); asm volatile("rep outsw" : "+S"(data), "+c"(size) : "d"(port));
} }
inline void outportl(uint16_t port, uint32_t data) inline void outportl(uint16_t port, uint32_t data)
{ {
__asm__ __volatile__("outl %%eax, %%dx" : : "dN" (port), "a" (data)); __asm__ __volatile__("outl %%eax, %%dx" : : "dN"(port), "a"(data));
} }
+44 -50
View File
@@ -4,7 +4,6 @@
/// @copyright (c) 2019 This file is distributed under the MIT License. /// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details. /// See LICENSE.md for details.
#include "sys.h"
#include "stdio.h" #include "stdio.h"
#include "errno.h" #include "errno.h"
#include "mutex.h" #include "mutex.h"
@@ -13,66 +12,61 @@
static void machine_power_off() static void machine_power_off()
{ {
while (true) while (true) {
{ cpu_relax();
cpu_relax(); }
}
} }
/// @brief Shutdown everything and perform a clean system power_off. /// @brief Shutdown everything and perform a clean system power_off.
static void kernel_power_off() static void kernel_power_off()
{ {
// kernel_shutdown_prepare(SYSTEM_POWER_OFF); // kernel_shutdown_prepare(SYSTEM_POWER_OFF);
// if (pm_power_off_prepare) // if (pm_power_off_prepare)
// { // {
// pm_power_off_prepare(); // pm_power_off_prepare();
// } // }
// migrate_to_reboot_cpu(); // migrate_to_reboot_cpu();
// syscore_shutdown(); // syscore_shutdown();
printf("Power down\n"); printf("Power down\n");
// kmsg_dump(KMSG_DUMP_POWEROFF); // kmsg_dump(KMSG_DUMP_POWEROFF);
machine_power_off(); machine_power_off();
} }
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg) int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg)
{ {
static mutex_t reboot_mutex; static mutex_t reboot_mutex;
// For safety, we require "magic" arguments. // For safety, we require "magic" arguments.
if (magic1 != LINUX_REBOOT_MAGIC1 || if (magic1 != LINUX_REBOOT_MAGIC1 ||
(magic2 != LINUX_REBOOT_MAGIC2 && (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2A && magic2 != LINUX_REBOOT_MAGIC2B && magic2 != LINUX_REBOOT_MAGIC2C)) {
magic2 != LINUX_REBOOT_MAGIC2B && return -EINVAL;
magic2 != LINUX_REBOOT_MAGIC2C)) }
{
return -EINVAL;
}
mutex_lock(&reboot_mutex, 0); mutex_lock(&reboot_mutex, 0);
switch (cmd) switch (cmd) {
{ case LINUX_REBOOT_CMD_RESTART:
case LINUX_REBOOT_CMD_RESTART: break;
break; case LINUX_REBOOT_CMD_CAD_ON:
case LINUX_REBOOT_CMD_CAD_ON: break;
break; case LINUX_REBOOT_CMD_CAD_OFF:
case LINUX_REBOOT_CMD_CAD_OFF: break;
break; case LINUX_REBOOT_CMD_HALT:
case LINUX_REBOOT_CMD_HALT: break;
break; case LINUX_REBOOT_CMD_POWER_OFF:
case LINUX_REBOOT_CMD_POWER_OFF: kernel_power_off();
kernel_power_off(); break;
break; case LINUX_REBOOT_CMD_RESTART2:
case LINUX_REBOOT_CMD_RESTART2: break;
break; case LINUX_REBOOT_CMD_KEXEC:
case LINUX_REBOOT_CMD_KEXEC: break;
break; case LINUX_REBOOT_CMD_SW_SUSPEND:
case LINUX_REBOOT_CMD_SW_SUSPEND: break;
break; default:
default: return -EINVAL;
return -EINVAL; }
} mutex_unlock(&reboot_mutex);
mutex_unlock(&reboot_mutex);
return 0; return 0;
} }
+10 -15
View File
@@ -8,20 +8,15 @@
#include "stdio.h" #include "stdio.h"
#include "panic.h" #include "panic.h"
void __assert_fail(const char *assertion, void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *file, const char *function)
unsigned int line,
const char *function)
{ {
char message[1024]; char message[1024];
sprintf(message, sprintf(message,
"FILE: %s\n" "FILE: %s\n"
"LINE: %d\n" "LINE: %d\n"
"FUNC: %s\n\n" "FUNC: %s\n\n"
"Assertion `%s` failed.\n", "Assertion `%s` failed.\n",
file, file, line, (function ? function : "NO_FUN"), assertion);
line, kernel_panic(message);
(function ? function : "NO_FUN"),
assertion);
kernel_panic(message);
} }
+157 -184
View File
@@ -8,287 +8,260 @@
#include "string.h" #include "string.h"
#include "stdlib.h" #include "stdlib.h"
struct hashmap_entry_t struct hashmap_entry_t {
{ char *key;
char *key; void *value;
void *value; struct hashmap_entry_t *next;
struct hashmap_entry_t *next;
}; };
struct hashmap_t struct hashmap_t {
{ hashmap_hash_t hash_func;
hashmap_hash_t hash_func; hashmap_comp_t hash_comp;
hashmap_comp_t hash_comp; hashmap_dupe_t hash_key_dup;
hashmap_dupe_t hash_key_dup; hashmap_free_t hash_key_free;
hashmap_free_t hash_key_free; hashmap_free_t hash_val_free;
hashmap_free_t hash_val_free; size_t size;
size_t size; hashmap_entry_t **entries;
hashmap_entry_t **entries;
}; };
size_t hashmap_string_hash(void *_key) size_t hashmap_string_hash(void *_key)
{ {
size_t hash = 0; size_t hash = 0;
char *key = (char *) _key; char *key = (char *)_key;
int c; int c;
/* // This is the so-called "sdbm" hash. It comes from a piece of public
* This is the so-called "sdbm" hash. It comes from a piece of public // domain code from a clone of ndbm.
* domain code from a clone of ndbm. while ((c = *key++)) {
*/ hash = c + (hash << 6) + (hash << 16) - hash;
while ((c = *key++)) }
{ return hash;
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
} }
bool_t hashmap_string_comp(void *a, void *b) bool_t hashmap_string_comp(void *a, void *b)
{ {
return !strcmp(a, b); return !strcmp(a, b);
} }
void *hashmap_string_dupe(void *key) void *hashmap_string_dupe(void *key)
{ {
return strdup(key); return strdup(key);
} }
static size_t hashmap_int_hash(void *key) static size_t hashmap_int_hash(void *key)
{ {
return (size_t) key; return (size_t)key;
} }
static bool_t hashmap_int_comp(void *a, void *b) static bool_t hashmap_int_comp(void *a, void *b)
{ {
return (int) a == (int) b; return (int)a == (int)b;
} }
static void *hashmap_int_dupe(void *key) static void *hashmap_int_dupe(void *key)
{ {
return key; return key;
} }
static void hashmap_int_free(void *ptr) static void hashmap_int_free(void *ptr)
{ {
(void) ptr; (void)ptr;
} }
hashmap_t *hashmap_create(size_t size) hashmap_t *hashmap_create(size_t size)
{ {
hashmap_t *map = malloc(sizeof(hashmap_t)); hashmap_t *map = malloc(sizeof(hashmap_t));
map->hash_func = &hashmap_string_hash; map->hash_func = &hashmap_string_hash;
map->hash_comp = &hashmap_string_comp; map->hash_comp = &hashmap_string_comp;
map->hash_key_dup = &hashmap_string_dupe; map->hash_key_dup = &hashmap_string_dupe;
map->hash_key_free = &free; map->hash_key_free = &free;
map->hash_val_free = &free; map->hash_val_free = &free;
map->size = size; map->size = size;
map->entries = malloc(sizeof(hashmap_entry_t *) * size); map->entries = malloc(sizeof(hashmap_entry_t *) * size);
memset(map->entries, 0, sizeof(hashmap_entry_t *) * size); memset(map->entries, 0, sizeof(hashmap_entry_t *) * size);
return map; return map;
} }
hashmap_t *hashmap_create_int(size_t size) hashmap_t *hashmap_create_int(size_t size)
{ {
hashmap_t *map = malloc(sizeof(hashmap_t)); hashmap_t *map = malloc(sizeof(hashmap_t));
map->hash_func = &hashmap_int_hash; map->hash_func = &hashmap_int_hash;
map->hash_comp = &hashmap_int_comp; map->hash_comp = &hashmap_int_comp;
map->hash_key_dup = &hashmap_int_dupe; map->hash_key_dup = &hashmap_int_dupe;
map->hash_key_free = &hashmap_int_free; map->hash_key_free = &hashmap_int_free;
map->hash_val_free = &free; map->hash_val_free = &free;
map->size = size; map->size = size;
map->entries = malloc(sizeof(hashmap_entry_t *) * size); map->entries = malloc(sizeof(hashmap_entry_t *) * size);
memset(map->entries, 0, sizeof(hashmap_entry_t *) * size); memset(map->entries, 0, sizeof(hashmap_entry_t *) * size);
return map; return map;
} }
void hashmap_free(hashmap_t *map) void hashmap_free(hashmap_t *map)
{ {
for (size_t i = 0; i < map->size; ++i) for (size_t i = 0; i < map->size; ++i) {
{ hashmap_entry_t *x = map->entries[i], *p;
hashmap_entry_t *x = map->entries[i], * p; while (x) {
while (x) p = x;
{ x = x->next;
p = x; map->hash_key_free(p->key);
x = x->next; map->hash_val_free(p);
map->hash_key_free(p->key); }
map->hash_val_free(p); }
}
}
free(map->entries); free(map->entries);
} }
void *hashmap_set(hashmap_t *map, void *key, void *value) void *hashmap_set(hashmap_t *map, void *key, void *value)
{ {
size_t hash = map->hash_func(key) % map->size; size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t *x = map->entries[hash]; hashmap_entry_t *x = map->entries[hash];
if (x == NULL) if (x == NULL) {
{ hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t));
hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t)); e->key = map->hash_key_dup(key);
e->key = map->hash_key_dup(key); e->value = value;
e->value = value; e->next = NULL;
e->next = NULL; map->entries[hash] = e;
map->entries[hash] = e;
return NULL; return NULL;
} }
hashmap_entry_t *p = NULL; hashmap_entry_t *p = NULL;
do do {
{ if (map->hash_comp(x->key, key)) {
if (map->hash_comp(x->key, key)) void *out = x->value;
{ x->value = value;
void *out = x->value;
x->value = value;
return out; return out;
} }
p = x; p = x;
x = x->next; x = x->next;
} while (x); } while (x);
hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t)); hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t));
e->key = map->hash_key_dup(key); e->key = map->hash_key_dup(key);
e->value = value; e->value = value;
e->next = NULL; e->next = NULL;
p->next = e; p->next = e;
return NULL; return NULL;
} }
void *hashmap_get(hashmap_t *map, void *key) void *hashmap_get(hashmap_t *map, void *key)
{ {
size_t hash = map->hash_func(key) % map->size; size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t *x = map->entries[hash]; hashmap_entry_t *x = map->entries[hash];
if (x == NULL) if (x == NULL) {
{ return NULL;
return NULL; }
} do {
do if (map->hash_comp(x->key, key)) {
{ return x->value;
if (map->hash_comp(x->key, key)) }
{ x = x->next;
return x->value; } while (x);
}
x = x->next;
} while (x);
return NULL; return NULL;
} }
void *hashmap_remove(hashmap_t *map, void *key) void *hashmap_remove(hashmap_t *map, void *key)
{ {
size_t hash = map->hash_func(key) % map->size; size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t *x = map->entries[hash]; hashmap_entry_t *x = map->entries[hash];
if (x == NULL) if (x == NULL) {
{ return NULL;
return NULL; }
} if (map->hash_comp(x->key, key)) {
if (map->hash_comp(x->key, key)) void *out = x->value;
{ map->entries[hash] = x->next;
void *out = x->value; map->hash_key_free(x->key);
map->entries[hash] = x->next; map->hash_val_free(x);
map->hash_key_free(x->key);
map->hash_val_free(x);
return out; return out;
} }
hashmap_entry_t * p = x; hashmap_entry_t *p = x;
x = x->next; x = x->next;
do do {
{ if (map->hash_comp(x->key, key)) {
if (map->hash_comp(x->key, key)) void *out = x->value;
{ p->next = x->next;
void *out = x->value; map->hash_key_free(x->key);
p->next = x->next; map->hash_val_free(x);
map->hash_key_free(x->key);
map->hash_val_free(x);
return out; return out;
} }
p = x; p = x;
x = x->next; x = x->next;
} while (x); } while (x);
return NULL; return NULL;
} }
bool_t hashmap_is_empty(hashmap_t *map) bool_t hashmap_is_empty(hashmap_t *map)
{ {
for (size_t i = 0; i < map->size; ++i) for (size_t i = 0; i < map->size; ++i) {
{ if (map->entries[i]) {
if (map->entries[i]) return false;
{ }
return false; }
}
}
return true; return true;
} }
bool_t hashmap_has(hashmap_t *map, void *key) bool_t hashmap_has(hashmap_t *map, void *key)
{ {
size_t hash = map->hash_func(key) % map->size; size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t * x = map->entries[hash]; hashmap_entry_t *x = map->entries[hash];
if (x == NULL) if (x == NULL) {
{ return false;
return false; }
} do {
do if (map->hash_comp(x->key, key)) {
{ return true;
if (map->hash_comp(x->key, key)) }
{ x = x->next;
return true; } while (x);
}
x = x->next;
} while (x);
return false; return false;
} }
list_t *hashmap_keys(hashmap_t *map) list_t *hashmap_keys(hashmap_t *map)
{ {
list_t *l = list_create(); list_t *l = list_create();
for (size_t i = 0; i < map->size; ++i) for (size_t i = 0; i < map->size; ++i) {
{ hashmap_entry_t *x = map->entries[i];
hashmap_entry_t * x = map->entries[i]; while (x) {
while (x) list_insert_back(l, x->key);
{ x = x->next;
list_insert_back(l, x->key); }
x = x->next; }
}
}
return l; return l;
} }
list_t *hashmap_values(hashmap_t *map) list_t *hashmap_values(hashmap_t *map)
{ {
list_t *l = list_create(); list_t *l = list_create();
for (size_t i = 0; i < map->size; ++i) for (size_t i = 0; i < map->size; ++i) {
{ hashmap_entry_t *x = map->entries[i];
hashmap_entry_t *x = map->entries[i];
while (x) while (x) {
{ list_insert_back(l, x->value);
list_insert_back(l, x->value); x = x->next;
x = x->next; }
} }
}
return l; return l;
} }
+41 -47
View File
@@ -7,74 +7,68 @@
#include "libgen.h" #include "libgen.h"
#include "string.h" #include "string.h"
#include "initrd.h" #include "initrd.h"
#include "limits.h"
int parse_path(char *out, char **cur, char sep, size_t max) int parse_path(char *out, char **cur, char sep, size_t max)
{ {
if (**cur == '\0') if (**cur == '\0') {
{ return 0;
return 0; }
}
*out++ = **cur; *out++ = **cur;
++*cur; ++*cur;
--max; --max;
while ((max > 0) && (**cur != '\0') && (**cur != sep)) while ((max > 0) && (**cur != '\0') && (**cur != sep)) {
{ *out++ = **cur;
*out++ = **cur; ++*cur;
++*cur; --max;
--max; }
}
*out = '\0'; *out = '\0';
return 1; return 1;
} }
char *dirname(const char *path) char *dirname(const char *path)
{ {
static char s[MAX_PATH_LENGTH]; static char s[PATH_MAX];
static char dot[2] = "."; static char dot[2] = ".";
// Check the input path. // Check the input path.
if (path == NULL) return dot; if (path == NULL)
return dot;
// Copy the path to the support string. // Copy the path to the support string.
strcpy(s, path); strcpy(s, path);
// Get the last occurrence of '/'. // Get the last occurrence of '/'.
char *last_slash = strrchr(s, '/'); char *last_slash = strrchr(s, '/');
if (last_slash == s) if (last_slash == s) {
{ // If the slash is acutally the first character of the string, move the
// If the slash is acutally the first character of the string, move the // pointer to the last slash after it.
// pointer to the last slash after it. ++last_slash;
++last_slash; } else if ((last_slash != NULL) && (last_slash[1] == '\0')) {
} // If the slash is the last character, we need to search before it.
else if ((last_slash != NULL) && (last_slash[1] == '\0')) last_slash = memchr(s, '/', last_slash - s);
{ }
// If the slash is the last character, we need to search before it.
last_slash = memchr(s, '/', last_slash - s);
}
if (last_slash != NULL) if (last_slash != NULL) {
{ // If we have found it, close the string.
// If we have found it, close the string. last_slash[0] = '\0';
last_slash[0] = '\0'; } else {
} // Otherwise, return '.'.
else return dot;
{ }
// Otherwise, return '.'.
return dot;
}
return s; return s;
} }
char *basename(const char *path) char *basename(const char *path)
{ {
char *p = strrchr(path, '/'); char *p = strrchr(path, '/');
return p ? p + 1 : (char *) path; return p ? p + 1 : (char *)path;
} }
+14 -65
View File
@@ -10,58 +10,23 @@
double round(double x) double round(double x)
{ {
double out; double out;
__asm__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x)); __asm__ __volatile__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x));
return out; return out;
} }
double floor(double x) double floor(double x)
{ {
if (x > -1.0 && x < 1.0) { if (x > -1.0 && x < 1.0) {
if (x >= 0) { if (x >= 0)
return 0.0; return 0.0;
} else { return -1.0;
return -1.0;
}
}
int x_i = (int)x;
if (x < 0) {
return (double)(x_i - 1);
} else {
return (double)x_i;
} }
int i = (int)x;
if (x < 0)
return (double)(i - 1);
return (double)i;
} }
#if 0
double pow(double base, double ex)
{
// Power of 0.
if (ex == 0)
{
return 1;
}
// Negative exponenet.
else if (ex < 0)
{
return 1 / pow(base, -ex);
}
// Even exponenet.
else if ((int) ex % 2 == 0)
{
float half_pow = pow(base, ex / 2);
return half_pow * half_pow;
}
// Integer exponenet.
else
{
return base * pow(base, ex - 1);
}
}
#else
double pow(double x, double y) double pow(double x, double y)
{ {
double out; double out;
@@ -85,20 +50,13 @@ double pow(double x, double y)
return out; return out;
} }
#endif
long find_nearest_pow_greater(double base, double value) long find_nearest_pow_greater(double base, double value)
{ {
if (base <= 1) { if (base <= 1)
return -1; return -1;
}
long pow_value = 0; long pow_value = 0;
while (pow(base, pow_value) < value)
while (pow(base, pow_value) < value) {
pow_value++; pow_value++;
}
return pow_value; return pow_value;
} }
@@ -110,16 +68,14 @@ double exp(double x)
double fabs(double x) double fabs(double x)
{ {
double out; double out;
__asm__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x)); __asm__ __volatile__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x));
return out; return out;
} }
double sqrt(double x) double sqrt(double x)
{ {
double out; double out;
__asm__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x)); __asm__ __volatile__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x));
return out; return out;
} }
@@ -130,8 +86,7 @@ int isinf(double x)
double f; double f;
} ieee754; } ieee754;
ieee754.f = x; ieee754.f = x;
return ((unsigned)(ieee754.u >> 32U) & 0x7fffffffU) == 0x7ff00000U &&
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
((unsigned)ieee754.u == 0); ((unsigned)ieee754.u == 0);
} }
@@ -142,7 +97,6 @@ int isnan(double x)
double f; double f;
} ieee754; } ieee754;
ieee754.f = x; ieee754.f = x;
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
((unsigned)ieee754.u != 0) > ((unsigned)ieee754.u != 0) >
0x7ff00000; 0x7ff00000;
@@ -156,18 +110,15 @@ double log10(double x)
double ln(double x) double ln(double x)
{ {
double out; double out;
__asm__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x)); __asm__ __volatile__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x));
return out; return out;
} }
double logx(double x, double y) double logx(double x, double y)
{ {
// Base may not equal 1 or be negative. // Base may not equal 1 or be negative.
if (y == 1.f || y < 0.f || ln(y) == 0.f) { if (y == 1.f || y < 0.f || ln(y) == 0.f)
return 0.f; return 0.f;
}
return ln(x) / ln(y); return ln(x) / ln(y);
} }
@@ -176,7 +127,6 @@ double logx(double x, double y)
double modf(double x, double *intpart) double modf(double x, double *intpart)
{ {
register double absvalue; register double absvalue;
if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) { if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) {
// It must be an integer. // It must be an integer.
(*intpart) = x; (*intpart) = x;
@@ -195,7 +145,6 @@ double modf(double x, double *intpart)
(*intpart) = -(*intpart); (*intpart) = -(*intpart);
} }
} }
// Signed fractional part. // Signed fractional part.
return (x - (*intpart)); return (x - (*intpart));
} }
+50 -57
View File
@@ -11,87 +11,80 @@
int8_t standard_lessthan_predicate(array_type_t a, array_type_t b) int8_t standard_lessthan_predicate(array_type_t a, array_type_t b)
{ {
return (a < b); return (a < b);
} }
ordered_array_t create_ordered_array(uint32_t max_size, ordered_array_t create_ordered_array(uint32_t max_size,
lessthan_predicate_t less_than) lessthan_predicate_t less_than)
{ {
ordered_array_t to_ret; ordered_array_t to_ret;
to_ret.array = malloc(max_size * sizeof(array_type_t)); to_ret.array = malloc(max_size * sizeof(array_type_t));
memset(to_ret.array, 0, max_size * sizeof(array_type_t)); memset(to_ret.array, 0, max_size * sizeof(array_type_t));
to_ret.size = 0; to_ret.size = 0;
to_ret.max_size = max_size; to_ret.max_size = max_size;
to_ret.less_than = less_than; to_ret.less_than = less_than;
return to_ret; return to_ret;
} }
ordered_array_t place_ordered_array(void * addr, ordered_array_t place_ordered_array(void *addr, uint32_t max_size,
uint32_t max_size, lessthan_predicate_t less_than)
lessthan_predicate_t less_than)
{ {
ordered_array_t to_ret; ordered_array_t to_ret;
to_ret.array = (array_type_t *) addr; to_ret.array = (array_type_t *)addr;
memset(to_ret.array, 0, max_size * sizeof(array_type_t)); memset(to_ret.array, 0, max_size * sizeof(array_type_t));
to_ret.size = 0; to_ret.size = 0;
to_ret.max_size = max_size; to_ret.max_size = max_size;
to_ret.less_than = less_than; to_ret.less_than = less_than;
return to_ret; return to_ret;
} }
void destroy_ordered_array(ordered_array_t * array) void destroy_ordered_array(ordered_array_t *array)
{ {
free(array->array); free(array->array);
} }
void insert_ordered_array(array_type_t item, ordered_array_t * array) void insert_ordered_array(array_type_t item, ordered_array_t *array)
{ {
assert(array->less_than); assert(array->less_than);
uint32_t iterator = 0; uint32_t iterator = 0;
while (iterator < array->size && array->less_than(array->array[iterator], while (iterator < array->size &&
item)) array->less_than(array->array[iterator], item)) {
{ iterator++;
iterator++; }
}
// Just add at the end of the array. // Just add at the end of the array.
if (iterator == array->size) if (iterator == array->size) {
{ array->array[array->size++] = item;
array->array[array->size++] = item; } else {
} array_type_t tmp = array->array[iterator];
else array->array[iterator] = item;
{
array_type_t tmp = array->array[iterator];
array->array[iterator] = item;
while (iterator < array->size) while (iterator < array->size) {
{ iterator++;
iterator++; array_type_t tmp2 = array->array[iterator];
array_type_t tmp2 = array->array[iterator]; array->array[iterator] = tmp;
array->array[iterator] = tmp; tmp = tmp2;
tmp = tmp2; }
} array->size++;
array->size++; }
}
} }
array_type_t lookup_ordered_array(uint32_t i, ordered_array_t * array) array_type_t lookup_ordered_array(uint32_t i, ordered_array_t *array)
{ {
assert(i < array->size); assert(i < array->size);
return array->array[i]; return array->array[i];
} }
void remove_ordered_array(uint32_t i, ordered_array_t * array) void remove_ordered_array(uint32_t i, ordered_array_t *array)
{ {
while (i < array->size) while (i < array->size) {
{ array->array[i] = array->array[i + 1];
array->array[i] = array->array[i + 1]; i++;
i++; }
}
array->size--; array->size--;
} }
+11 -13
View File
@@ -8,29 +8,27 @@
void spinlock_init(spinlock_t *spinlock) void spinlock_init(spinlock_t *spinlock)
{ {
(*spinlock) = 0; (*spinlock) = 0;
} }
void spinlock_lock(spinlock_t *spinlock) void spinlock_lock(spinlock_t *spinlock)
{ {
while (true) while (true) {
{ if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0) {
if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0) break;
{ }
break; while (*spinlock)
} cpu_relax();
while (*spinlock) cpu_relax(); }
}
} }
void spinlock_unlock(spinlock_t *spinlock) void spinlock_unlock(spinlock_t *spinlock)
{ {
barrier(); barrier();
atomic_set(spinlock, SPINLOCK_FREE);
atomic_set(spinlock, SPINLOCK_FREE);
} }
bool_t spinlock_trylock(spinlock_t *spinlock) bool_t spinlock_trylock(spinlock_t *spinlock)
{ {
return (bool_t) (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0); return (bool_t)(atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0);
} }
+34 -55
View File
@@ -22,7 +22,6 @@ void puts(char *str)
int getchar(void) int getchar(void)
{ {
#if 1
char c; char c;
while (true) { while (true) {
read(STDIN_FILENO, &c, 1); read(STDIN_FILENO, &c, 1);
@@ -30,76 +29,56 @@ int getchar(void)
break; break;
} }
return c; return c;
#else
int tmpchar;
while ((tmpchar = keyboard_getc()) == -1)
;
return tmpchar;
#endif
} }
char *gets(char *str) char *gets(char *str)
{ {
int count = 0; // Check the input string.
char tmp[255]; if (str == NULL)
memset(tmp, '\0', 255); return NULL;
// Buffer for reading input.
do { char buffer[GETS_BUFFERSIZE];
int c = getchar(); memset(buffer, '\0', GETS_BUFFERSIZE);
// Char pointer to the buffer.
// Return Key. char *cptr = buffer;
if (c == '\n') { // Character storage and counter to prevent overflow.
int ch, counter = 0;
// Read until we find a newline or we exceed the buffer size.
while (((ch = getchar()) != '\n') && (counter++ < GETS_BUFFERSIZE)) {
// If we encounter EOF, stop.
if (ch == EOF) {
// EOF at start of line return NULL.
if (cptr == str)
return NULL;
break; break;
} }
// Backspace key. // The character is stored at address, and the pointer is incremented.
*cptr++ = ch;
if (c == '\b') { }
if (count > 0) { // Add the null-terminating character.
count--; *cptr = '\0';
} // Copy the string we have read.
} else { strcpy(str, buffer);
tmp[count++] = (char)c; // Return a pointer to the original string.
}
} while (count < 255);
tmp[count] = '\0';
/* tmp cant simply be returned, it is allocated in this stack frame and
* it will be lost!
*/
strcpy(str, tmp);
return str; return str;
} }
int atoi(const char *str) int atoi(const char *str)
{ {
// Initialize sign as positive. // Check the input string.
int sign = 1; if (str == NULL)
return 0;
// Initialize sign.
int sign = (str[0] == '-') ? -1 : +1;
// Initialize the result. // Initialize the result.
int result = 0; int result = 0;
// Initialize the index.
int i = 0;
// If the number is negative, then update the sign.
if (str[0] == '-') {
sign = -1;
}
// Check that the rest of the numbers are digits. // Check that the rest of the numbers are digits.
for (i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i) { for (int i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i)
if (!isdigit(str[i])) { if (!isdigit(str[i]))
return -1; return -1;
}
}
// Iterate through all digits and update the result. // Iterate through all digits and update the result.
for (i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i) { for (int i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i)
result = (result * 10) + str[i] - '0'; result = (result * 10) + str[i] - '0';
}
return sign * result; return sign * result;
} }
@@ -129,7 +108,7 @@ size_t scanf(const char *format, ...)
for (; *format; format++) { for (; *format; format++) {
if (*format == '%') { if (*format == '%') {
// Declare an input string. // Declare an input string.
char input[255]; char input[GETS_BUFFERSIZE];
// Get the input string. // Get the input string.
gets(input); gets(input);
// Evaluate the length of the string. // Evaluate the length of the string.
+31 -42
View File
@@ -8,71 +8,60 @@
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
/// Used to align the memory.
#define ALIGN(x) \
(((x) + (sizeof(size_t) - 1)) & ~(sizeof(size_t) - 1))
void *malloc(unsigned int size) void *malloc(unsigned int size)
{ {
void *_res; void *_res;
DEFN_SYSCALL1(_res, __NR_brk, size); DEFN_SYSCALL1(_res, __NR_brk, size);
return _res; return _res;
} }
void free(void *p) void free(void *p)
{ {
int _res; int _res;
DEFN_SYSCALL1(_res, __NR_free, p); DEFN_SYSCALL1(_res, __NR_free, p);
} }
void *calloc(size_t element_number, size_t element_size) void *calloc(size_t element_number, size_t element_size)
{ {
void *ptr = malloc(element_number * element_size); void *ptr = malloc(element_number * element_size);
if (ptr) if (ptr) {
{ memset(ptr, 0, element_number * element_size);
memset(ptr, 0, element_number * element_size); }
}
return ptr; return ptr;
} }
void **mmalloc(size_t n, size_t size)
{
void **ret = (void **) malloc(n * sizeof(void *));
for (size_t i = 0; i < n; i++)
{
*(ret + i) = malloc(size);
}
return ret;
}
void mfree(void **src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
free(*(src + i));
}
free(src);
}
/// Seed used to generate random numbers. /// Seed used to generate random numbers.
int rseed = 0; static int rseed = 0;
inline void srand(int x) inline void srand(int x)
{ {
rseed = x; rseed = x;
} }
#ifndef MS_RAND
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31) - 1)
/// @brief Returns a pseudo-random integral number in the range /// @brief Returns a pseudo-random integral number in the range
/// between 0 and RAND_MAX. /// between 0 and RAND_MAX.
inline int rand() inline int rand()
{ {
return rseed = (rseed * 1103515245 + 12345) & RAND_MAX; return rseed = (rseed * 1103515245U + 12345U) & RAND_MAX;
} }
// MS rand.
#else
/// The maximum 32bit value returned by the rand function.
#define RAND_MAX_32 ((1U << 31) - 1)
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 15) - 1)
/// @brief Returns a pseudo-random integral number in the range
/// between 0 and RAND_MAX.
inline int rand()
{
return (rseed = (rseed * 214013 + 2531011) & RAND_MAX_32) >> 16;
}
<<<<<<< HEAD
#endif
+2 -3
View File
@@ -328,7 +328,7 @@ char *strerror(int errnum)
#ifdef ELIBMAX #ifdef ELIBMAX
case ELIBMAX: case ELIBMAX:
strcpy(error, strcpy(error,
"Attempting to link in more shared libraries than system limit"); "Attempting to link in more shared libraries than system limit");
break; break;
#endif #endif
#ifdef ELIBEXEC #ifdef ELIBEXEC
@@ -368,8 +368,7 @@ char *strerror(int errnum)
#endif #endif
#ifdef EAFNOSUPPORT #ifdef EAFNOSUPPORT
case EAFNOSUPPORT: case EAFNOSUPPORT:
strcpy(error, strcpy(error, "Address family not supported by protocol family");
"Address family not supported by protocol family");
break; break;
#endif #endif
#ifdef EPROTOTYPE #ifdef EPROTOTYPE
+20
View File
@@ -0,0 +1,20 @@
/// MentOS, The Mentoring Operating system project
/// @file close.c
/// @brief
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "unistd.h"
#include "errno.h"
#include "syscall.h"
int close(int fd)
{
int retval;
DEFN_SYSCALL1(retval, __NR_close, fd);
if (retval < 0) {
errno = -retval;
retval = -1;
}
return retval;
}
+3 -3
View File
@@ -11,9 +11,9 @@
pid_t getpid() pid_t getpid()
{ {
pid_t ret; pid_t ret;
DEFN_SYSCALL0(ret, __NR_getpid); DEFN_SYSCALL0(ret, __NR_getpid);
return ret; return ret;
} }
+21
View File
@@ -0,0 +1,21 @@
/// MentOS, The Mentoring Operating system project
/// @file mkdir.c
/// @brief Make directory functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "syscall.h"
#include "unistd.h"
#include "errno.h"
#include "stat.h"
int mkdir(const char *path, mode_t mode)
{
ssize_t retval;
DEFN_SYSCALL2(retval, __NR_mkdir, path, mode);
if (retval < 0) {
errno = -retval;
retval = -1;
}
return retval;
}
+7 -9
View File
@@ -10,15 +10,13 @@
int open(const char *pathname, int flags, mode_t mode) int open(const char *pathname, int flags, mode_t mode)
{ {
ssize_t retval; ssize_t retval;
DEFN_SYSCALL3(retval, __NR_open, pathname, flags, mode); DEFN_SYSCALL3(retval, __NR_open, pathname, flags, mode);
if (retval < 0) if (retval < 0) {
{ errno = -retval;
errno = -retval; retval = -1;
retval = -1; }
return retval;
}
return retval;
} }
+7 -8
View File
@@ -10,15 +10,14 @@
ssize_t read(int fd, void *buf, size_t nbytes) ssize_t read(int fd, void *buf, size_t nbytes)
{ {
ssize_t retval; ssize_t retval;
DEFN_SYSCALL3(retval, __NR_read, fd, buf, nbytes); DEFN_SYSCALL3(retval, __NR_read, fd, buf, nbytes);
if (retval < 0) if (retval < 0) {
{ errno = -retval;
errno = -retval; retval = -1;
retval = -1; }
}
return retval; return retval;
} }
+21
View File
@@ -0,0 +1,21 @@
/// MentOS, The Mentoring Operating system project
/// @file stat.c
/// @brief Stat functions.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "syscall.h"
#include "unistd.h"
#include "errno.h"
#include "stat.h"
int stat(const char *path, stat_t *buf)
{
ssize_t retval;
DEFN_SYSCALL2(retval, __NR_stat, path, buf);
if (retval < 0) {
errno = -retval;
retval = -1;
}
return retval;
}
+19
View File
@@ -793,11 +793,30 @@ void *krealloc(void *ptr, uint32_t size)
return __do_realloc(&kernel_heap, ptr, size); return __do_realloc(&kernel_heap, ptr, size);
} }
void **kmmalloc(size_t n, size_t size)
{
void **ret = (void **) kmalloc(n * sizeof(void *));
for (size_t i = 0; i < n; i++)
{
*(ret + i) = kmalloc(size);
}
return ret;
}
void kfree(void *ptr) void kfree(void *ptr)
{ {
__do_free(&kernel_heap, ptr); __do_free(&kernel_heap, ptr);
} }
void kmfree(void **src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
kfree(*(src + i));
}
kfree(src);
}
/// @brief Find the current user heap. /// @brief Find the current user heap.
/// @return The heap structure if heap exists, otherwise NULL. /// @return The heap structure if heap exists, otherwise NULL.
static struct vm_area_struct *find_user_heap() static struct vm_area_struct *find_user_heap()
+26 -26
View File
@@ -190,40 +190,40 @@ static bool_t pmm_check()
/// @param zone A memory zone. /// @param zone A memory zone.
static void buddy_system_init(zone_t *zone) static void buddy_system_init(zone_t *zone)
{ {
// Initialize the free_lists of each area of the zone. // Initialize the free_lists of each area of the zone.
for (unsigned int order = 0; order < MAX_ORDER; order++) { for (unsigned int order = 0; order < MAX_ORDER; order++) {
free_area_t *area = zone->free_area + order; free_area_t *area = zone->free_area + order;
area->nr_free = 0; area->nr_free = 0;
list_head_init(&area->free_list); list_head_init(&area->free_list);
} }
// Current base page descriptor of the zone. // Current base page descriptor of the zone.
page_t *page = zone->zone_mem_map; page_t *page = zone->zone_mem_map;
// Address of the last page descriptor of the zone. // Address of the last page descriptor of the zone.
page_t *last_page = page + zone->size; page_t *last_page = page + zone->size;
// Get the free area collecting the larges block of page frames. // Get the free area collecting the larges block of page frames.
const unsigned int order = MAX_ORDER - 1; const unsigned int order = MAX_ORDER - 1;
free_area_t *area = zone->free_area + order; free_area_t *area = zone->free_area + order;
// Add all zone's pages to the largest free area block. // Add all zone's pages to the largest free area block.
uint32_t block_size = 1UL << order; uint32_t block_size = 1UL << order;
while ((page + block_size) <= last_page) { while ((page + block_size) <= last_page) {
/* page has already the _count field set to -1, /* page has already the _count field set to -1,
* therefore only save the order of the page. * therefore only save the order of the page.
*/ */
page->private = order; page->private = order;
// Insert page as first element in the list. // Insert page as first element in the list.
list_head_add_tail(&page->lru, &area->free_list); list_head_add_tail(&page->lru, &area->free_list);
// Increase the number of free block of the free_area_t. // Increase the number of free block of the free_area_t.
area->nr_free++; area->nr_free++;
page += block_size; page += block_size;
} }
assert(page == last_page && assert(page == last_page &&
"Memory size is not aligned to MAX_ORDER size!"); "Memory size is not aligned to MAX_ORDER size!");
} }
/// @brief Initializes the memory attributes. /// @brief Initializes the memory attributes.
+175 -54
View File
@@ -7,74 +7,195 @@
#include "multiboot.h" #include "multiboot.h"
#include "bitops.h" #include "bitops.h"
#include "debug.h" #include "debug.h"
#include "panic.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit)))
static inline multiboot_memory_map_t *first_mmap_entry(multiboot_info_t *info)
{
if (!has_flag(info->flags, MULTIBOOT_FLAG_MMAP))
return NULL;
return (multiboot_memory_map_t *)((uintptr_t)info->mmap_addr);
}
static inline multiboot_memory_map_t *
next_mmap_entry(multiboot_info_t *info, multiboot_memory_map_t *entry)
{
uintptr_t next = ((uintptr_t)entry) + entry->size + sizeof(entry->size);
if (next >= info->mmap_addr + info->mmap_length)
return NULL;
return (multiboot_memory_map_t *)next;
}
static inline multiboot_memory_map_t *
next_mmap_entry_of_type(multiboot_info_t *info, multiboot_memory_map_t *entry,
uint32_t type)
{
do {
entry = next_mmap_entry(info, entry);
} while (entry && entry->type != type);
return entry;
}
static inline multiboot_memory_map_t *
first_mmap_entry_of_type(multiboot_info_t *info, uint32_t type)
{
multiboot_memory_map_t *entry = first_mmap_entry(info);
if (entry && (entry->type == type))
return entry;
return next_mmap_entry_of_type(info, entry, type);
}
static inline char *mmap_type_name(multiboot_memory_map_t *entry)
{
if (entry->type == MULTIBOOT_MEMORY_AVAILABLE)
return "AVAILABLE";
if (entry->type == MULTIBOOT_MEMORY_RESERVED)
return "RESERVED";
return "NONE";
}
static inline multiboot_module_t *first_module(multiboot_info_t *info)
{
if (!has_flag(info->flags, MULTIBOOT_FLAG_MODS))
return NULL;
if (!info->mods_count)
return NULL;
return (multiboot_module_t *)(uintptr_t)info->mods_addr;
}
static inline multiboot_module_t *next_module(multiboot_info_t *info,
multiboot_module_t *mod)
{
multiboot_module_t *first =
(multiboot_module_t *)((uintptr_t)info->mods_addr);
++mod;
if ((mod - first) >= info->mods_count)
return NULL;
return mod;
}
void dump_multiboot(multiboot_info_t *mbi) void dump_multiboot(multiboot_info_t *mbi)
{ {
dbg_print("\n--------------------------------------------------\n"); dbg_print("\n--------------------------------------------------\n");
dbg_print("MULTIBOOT header at 0x%x:\n", mbi); dbg_print("MULTIBOOT header at 0x%x:\n", mbi);
dbg_print("Flags : 0x%x\n", mbi->flags);
// Print out the flags.
dbg_print("%-16s = 0x%x\n", "flags", mbi->flags);
// Are mem_* valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MEM)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_MEM)) {
dbg_print("Mem Lo: 0x%x\n", mbi->mem_lower * K); dbg_print("%-16s = %u Kb (%u Mb)\n", "mem_lower", mbi->mem_lower,
dbg_print("Mem Hi: 0x%x (%dMB)\n", mbi->mem_upper * K, mbi->mem_lower / K);
(mbi->mem_upper / 1024)); dbg_print("%-16s = %u Kb (%u Mb)\n", "mem_upper", mbi->mem_upper,
mbi->mem_upper / K);
dbg_print("%-16s = %u Kb (%u Mb)\n", "total",
mbi->mem_lower + mbi->mem_upper,
(mbi->mem_lower + mbi->mem_upper) / K);
} }
// Is boot_device valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_DEVICE)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_DEVICE)) {
dbg_print("Boot d: 0x%x\n", mbi->boot_device); dbg_print("%-16s = 0x%x (0x%x)", "boot_device", mbi->boot_device);
} switch ((mbi->boot_device) & 0xFF000000) {
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) { case 0x00000000:
dbg_print("cmdlin: 0x%x (%s)\n", mbi->cmdline, (char *)mbi->cmdline); dbg_print("(floppy)\n");
} break;
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) { case 0x80000000:
dbg_print("Mods : 0x%x\n", mbi->mods_count); dbg_print("(disk)\n");
break;
multiboot_module_t *mod = (multiboot_module_t *)mbi->mods_addr; default:
dbg_print("(unknown)\n");
if (mbi->mods_count > 0) {
for (uint32_t i = 0; i < mbi->mods_count && i < MAX_MODULES;
i++, mod++) {
uint32_t start = mod->mod_start;
uint32_t end = mod->mod_end;
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
}
/* Last implementation
for (uint32_t i = 0; i < mbi->mods_count; ++i)
{
// uint32_t start = *((uint32_t *) (mbi->mods_addr + 8 * i));
uint32_t start = mbi->mods_addr + 8 * i;
// uint32_t end = *((uint32_t *) (mbi->mods_addr + 8 * i + 4));
uint32_t end = mbi->mods_addr + 8 * i + 4;
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
}
*/
} }
} }
// Is the command line passed?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) {
dbg_print("%-16s = %s\n", "cmdline", (char *)mbi->cmdline);
}
// Are mods_* valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) {
dbg_print("%-16s = %d\n", "mods_count", mbi->mods_count);
dbg_print("%-16s = 0x%x\n", "mods_addr", mbi->mods_addr);
multiboot_module_t *mod = first_module(mbi);
for (int i = 0; mod; ++i, mod = next_module(mbi, mod)) {
dbg_print(" [%2d] "
"mod_start = 0x%x, "
"mod_end = 0x%x, "
"cmdline = %s\n",
i, mod->mod_start, mod->mod_end, (char *)mod->cmdline);
}
}
// Bits 4 and 5 are mutually exclusive!
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT) &&
has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
kernel_panic("Both bits 4 and 5 are set.\n");
return;
}
// Is the symbol table of a.out valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT)) {
dbg_print("AOUT t : 0x%x\n", mbi->u.aout_sym.tabsize); multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
dbg_print("AOUT s : 0x%x\n", mbi->u.aout_sym.strsize); dbg_print("multiboot_aout_symbol_table: tabsize = 0x%0x, "
dbg_print("AOUT a : 0x%x\n", mbi->u.aout_sym.addr); "strsize = 0x%x, addr = 0x%x\n",
dbg_print("AOUT r : 0x%x\n", mbi->u.aout_sym.reserved); multiboot_aout_sym->tabsize, multiboot_aout_sym->strsize,
multiboot_aout_sym->addr);
} }
// Is the section header table of ELF valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
dbg_print("ELF n : 0x%x\n", mbi->u.elf_sec.num); multiboot_elf_section_header_table_t *multiboot_elf_sec =
dbg_print("ELF s : 0x%x\n", mbi->u.elf_sec.size); &(mbi->u.elf_sec);
dbg_print("ELF a : 0x%x\n", mbi->u.elf_sec.addr); dbg_print("multiboot_elf_sec: num = %u, size = 0x%x,"
dbg_print("ELF h : 0x%x\n", mbi->u.elf_sec.shndx); " addr = 0x%x, shndx = 0x%x\n",
multiboot_elf_sec->num, multiboot_elf_sec->size,
multiboot_elf_sec->addr, multiboot_elf_sec->shndx);
}
// Are mmap_* valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MMAP)) {
dbg_print("%-16s = 0x%x\n", "mmap_addr", mbi->mmap_addr);
dbg_print("%-16s = 0x%x (%d entries)\n", "mmap_length",
mbi->mmap_length,
mbi->mmap_length / sizeof(multiboot_memory_map_t));
multiboot_memory_map_t *mmap = first_mmap_entry(mbi);
for (int i = 0; mmap; ++i, mmap = next_mmap_entry(mbi, mmap)) {
dbg_print(" [%2d] "
"base_addr = 0x%09x%09x, "
"length = 0x%09x%09x, "
"type = 0x%x (%s)\n",
i, mmap->base_addr_high, mmap->base_addr_low,
mmap->length_high, mmap->length_low, mmap->type,
mmap_type_name(mmap));
}
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_DRIVE_INFO)) {
dbg_print("Drives: 0x%x\n", mbi->drives_length);
dbg_print("Addr : 0x%x\n", mbi->drives_addr);
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CONFIG_TABLE)) {
dbg_print("Config: 0x%x\n", mbi->config_table);
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_BOOT_LOADER_NAME)) {
dbg_print("boot_loader_name: %s\n", (char *)mbi->boot_loader_name);
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_APM_TABLE)) {
dbg_print("APM : 0x%x\n", mbi->apm_table);
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_VBE_INFO)) {
dbg_print("VBE Co: 0x%x\n", mbi->vbe_control_info);
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_info);
dbg_print("VBE In: 0x%x\n", mbi->vbe_mode);
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg);
dbg_print("VBE of: 0x%x\n", mbi->vbe_interface_off);
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
} }
dbg_print("MMap : 0x%x\n", mbi->mmap_length);
dbg_print("Addr : 0x%x\n", mbi->mmap_addr);
dbg_print("Drives: 0x%x\n", mbi->drives_length);
dbg_print("Addr : 0x%x\n", mbi->drives_addr);
dbg_print("Config: 0x%x\n", mbi->config_table);
dbg_print("Loader: 0x%x (%s)\n", mbi->boot_loader_name,
(char *)mbi->boot_loader_name);
dbg_print("APM : 0x%x\n", mbi->apm_table);
dbg_print("VBE Co: 0x%x\n", mbi->vbe_control_info);
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_info);
dbg_print("VBE In: 0x%x\n", mbi->vbe_mode);
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg);
dbg_print("VBE of: 0x%x\n", mbi->vbe_interface_off);
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
dbg_print("--------------------------------------------------\n"); dbg_print("--------------------------------------------------\n");
dbg_print("\n"); dbg_print("\n");
} }
+14 -14
View File
@@ -71,7 +71,7 @@ task_struct *create_init_process()
// Enable the interrupts. // Enable the interrupts.
init_proc->thread.eflags = init_proc->thread.eflags | EFLAG_IF; init_proc->thread.eflags = init_proc->thread.eflags | EFLAG_IF;
// Clear the current working directory. // Clear the current working directory.
memset(init_proc->cwd, '\0', MAX_PATH_LENGTH); memset(init_proc->cwd, '\0', PATH_MAX);
// Set the state of the process as running. // Set the state of the process as running.
init_proc->state = TASK_RUNNING; init_proc->state = TASK_RUNNING;
// Active the current process. // Active the current process.
@@ -284,19 +284,19 @@ int sys_execve(pt_regs *r)
PUSH_ON_STACK(current->thread.useresp, int, argc); PUSH_ON_STACK(current->thread.useresp, int, argc);
PUSH_ON_STACK(current->thread.useresp, uintptr_t, (uintptr_t)exit_handler); PUSH_ON_STACK(current->thread.useresp, uintptr_t, (uintptr_t)exit_handler);
// dbg_print("_ARGV:0x%09x {\n", _argv); // dbg_print("_ARGV:0x%09x {\n", _argv);
// for (int i = 0; _argv[i] != NULL; ++i) { // for (int i = 0; _argv[i] != NULL; ++i) {
// dbg_print("\t[%d][0x%09x]%s\n", i, _argv[i], _argv[i]); // dbg_print("\t[%d][0x%09x]%s\n", i, _argv[i], _argv[i]);
// } // }
// dbg_print("}\n"); // dbg_print("}\n");
// //
// if (_envp != NULL) { // if (_envp != NULL) {
// dbg_print("_ENVP:0x%09x {\n", _envp); // dbg_print("_ENVP:0x%09x {\n", _envp);
// for (int i = 0; _envp[i] != NULL; ++i) { // for (int i = 0; _envp[i] != NULL; ++i) {
// dbg_print("\t[%d][0x%09x]%s\n", i, _envp[i], _envp[i]); // dbg_print("\t[%d][0x%09x]%s\n", i, _envp[i], _envp[i]);
// } // }
// dbg_print("}\n"); // dbg_print("}\n");
// } // }
// Perform the switch to the new process. // Perform the switch to the new process.
do_switch(current, r); do_switch(current, r);
+12
View File
@@ -17,6 +17,7 @@
#include "rbtree.h" #include "rbtree.h"
#include "stdlib.h" #include "stdlib.h"
#include "list_head.h" #include "list_head.h"
#include "deadlock_simulation.h"
/// @brief Assembly function setting the kernel stack to jump into /// @brief Assembly function setting the kernel stack to jump into
/// location in Ring 3 mode (USER mode). /// location in Ring 3 mode (USER mode).
@@ -68,6 +69,11 @@ void kernel_initialize_scheduler()
runqueue.curr = NULL; runqueue.curr = NULL;
// Reset the number of active tasks. // Reset the number of active tasks.
runqueue.num_active = 0; runqueue.num_active = 0;
#if ENABLE_DEADLOCK_PREVENTION
// Simulate deadlock.
deadlock_simulation();
#endif
} }
void enqueue_task(task_struct *process) void enqueue_task(task_struct *process)
@@ -125,12 +131,14 @@ void kernel_schedule(pt_regs *f)
} }
//========================================================================== //==========================================================================
#if 0
// Print, for debugging purpose, data about the current process. // Print, for debugging purpose, data about the current process.
if (runqueue.num_active > 2) { if (runqueue.num_active > 2) {
dbg_print("PID:%3d, PRIO:%3d, VRUNTIME:%9d, SUM_EXEC:%9d\n", dbg_print("PID:%3d, PRIO:%3d, VRUNTIME:%9d, SUM_EXEC:%9d\n",
next_process->pid, next_process->se.prio, next_process->pid, next_process->se.prio,
next_process->se.vruntime, next_process->se.sum_exec_runtime); next_process->se.vruntime, next_process->se.sum_exec_runtime);
} }
#endif
//==== Context switch ====================================================== //==== Context switch ======================================================
// Update the context of the current process. // Update the context of the current process.
@@ -377,6 +385,10 @@ void sys_exit(int exit_code)
} }
// Free the space occupied by the stack. // Free the space occupied by the stack.
destroy_process_image(runqueue.curr->mm); destroy_process_image(runqueue.curr->mm);
// Clean resources needed by.
for (size_t i = 0; i < TASK_RESOURCE_MAX_AMOUNT; i++) {
runqueue.curr->resources[i] = NULL;
}
// Debugging message. // Debugging message.
dbg_print("Process %d exited with value %d\n", runqueue.curr->pid, dbg_print("Process %d exited with value %d\n", runqueue.curr->pid,
exit_code); exit_code);
+44 -36
View File
@@ -13,61 +13,69 @@
task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec) task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec)
{ {
// Pointer to the next task to schedule. // Pointer to the next task to schedule.
task_struct *next = NULL; task_struct *next = NULL;
#if defined(SCHEDULER_RR) #if defined(SCHEDULER_RR)
//==== Implementatin of the Round-Robin Scheduling algorithm ============ //==== Implementatin of the Round-Robin Scheduling algorithm ============
// nNode = next(c)
struct list_head *nNode = runqueue->curr->run_list.next;
// if isHead(L, nNode)
if (nNode == &runqueue->queue)
nNode = nNode->next;
//======================================================================= // n = entry(nNode)
next = list_entry(nNode, struct task_struct, run_list);
//=======================================================================
#elif defined(SCHEDULER_PRIORITY) #elif defined(SCHEDULER_PRIORITY)
//==== Implementatin of the Priority Scheduling algorithm =============== //==== Implementatin of the Priority Scheduling algorithm ===============
// get the first element of the list // get the first element of the list
next = list_entry(/*...*/); next = list_entry(/*...*/);
// Get its static priority. // Get its static priority.
time_t min = /*...*/ time_t min = /*...*/
list_head *it; list_head *it;
// Inter over the runqueue to find the task with the smallest priority value // Inter over the runqueue to find the task with the smallest priority value
list_for_each (it, &runqueue->queue) { list_for_each (it, &runqueue->queue) {
task_struct *entry = list_entry(/*...*/); task_struct *entry = list_entry(/*...*/);
// Check entry has a lower priority // Check entry has a lower priority
if (/*...*/) { if (/*...*/) {
/*...*/ /*...*/
} }
} }
//======================================================================= //=======================================================================
#elif defined(SCHEDULER_CFS) #elif defined(SCHEDULER_CFS)
//==== Implementatin of the Completely Fair Scheduling ================== //==== Implementatin of the Completely Fair Scheduling ==================
// Get the weight of the current process. // Get the weight of the current process.
// (use GET_WEIGHT macro!) // (use GET_WEIGHT macro!)
int weight = /*...*/ int weight = /*...*/
if (weight != NICE_0_LOAD) { if (weight != NICE_0_LOAD) {
// get the multiplicative factor for its delta_exec. // get the multiplicative factor for its delta_exec.
double factor = /*...*/ double factor = /*...*/
// weight the delta_exec with the multiplicative factor. // weight the delta_exec with the multiplicative factor.
delta_exec = // ... delta_exec = // ...
} }
// Update vruntime of the current process. // Update vruntime of the current process.
// ... // ...
// Inter over the runqueue to find the task with the smallest vruntime value // Inter over the runqueue to find the task with the smallest vruntime value
// ... // ...
//======================================================================== //========================================================================
#else #else
#error "You should enable a scheduling algorithm!" #error "You should enable a scheduling algorithm!"
#endif #endif
assert(next && "No valid task selected. Have you implemented a scheduling algorithm?"); assert(next && "No valid task selected. Have you implemented a scheduling algorithm?");
return next; return next;
} }
+49 -63
View File
@@ -11,88 +11,74 @@
#include "stdio.h" #include "stdio.h"
#include "initrd.h" #include "initrd.h"
#include "debug.h" #include "debug.h"
#include "syscall_types.h"
#include "assert.h"
#include "errno.h"
DIR *opendir(const char *path) DIR *opendir(const char *path)
{ {
char absolute_path[MAX_PATH_LENGTH]; char absolute_path[PATH_MAX];
DIR *pdir = NULL; DIR *pdir = NULL;
strcpy(absolute_path, path); strcpy(absolute_path, path);
// If the first character is not the '/' then get the absolute path. // If the first character is not the '/' then get the absolute path.
if (absolute_path[0] != '/') if (absolute_path[0] != '/') {
{ if (!get_absolute_path(absolute_path)) {
if (!get_absolute_path(absolute_path)) dbg_print("Cannot get the absolute path.\n");
{
dbg_print("Cannot get the absolute path.\n");
return NULL; return NULL;
} }
} }
// Get the mount point id. // Get the mount point id.
int32_t mp_id = get_mountpoint_id(absolute_path); int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0) if (mp_id < 0) {
{ printf("opendir: cannot open directory '%s':"
printf("opendir: cannot open directory '%s':" "Cannot find mount-point\n",
"Cannot find mount-point\n", absolute_path); absolute_path);
return NULL; return NULL;
} }
if (mountpoint_list[mp_id].dir_op.opendir_f == NULL) if (mountpoint_list[mp_id].dir_op.opendir_f == NULL) {
{ printf("opendir: cannot open directory '%s':"
printf("opendir: cannot open directory '%s':" "No opendir function\n",
"No opendir function\n", absolute_path); absolute_path);
return NULL; return NULL;
} }
pdir = mountpoint_list[mp_id].dir_op.opendir_f(absolute_path); pdir = mountpoint_list[mp_id].dir_op.opendir_f(absolute_path);
// If the directiry is correctly open, set the handle. // If the directiry is correctly open, set the handle.
if (pdir != NULL) if (pdir != NULL) {
{ pdir->fd = mp_id;
pdir->handle = mp_id; }
}
return pdir; return pdir;
} }
int closedir(DIR *dirp) int closedir(DIR *dirp)
{ {
if (dirp == NULL) if (dirp == NULL) {
{ printf("closedir: cannot close directory :"
printf("closedir: cannot close directory :" "Directory pointer is not valid\n");
"Directory pointer is not valid\n");
return -1; return -1;
} }
if (mountpoint_list[dirp->handle].dir_op.closedir_f == NULL) if (mountpoint_list[dirp->fd].dir_op.closedir_f == NULL) {
{ printf("closedir: cannot close directory '%s':"
printf("closedir: cannot close directory '%s':" "No closedir function\n",
"No closedir function\n", dirp->path); dirp->path);
return -1; return -1;
} }
return mountpoint_list[dirp->fd].dir_op.closedir_f(dirp);
return mountpoint_list[dirp->handle].dir_op.closedir_f(dirp);
} }
dirent_t *readdir(DIR *dirp) dirent_t *readdir(DIR *dirp)
{ {
if (dirp == NULL) dirent_t *dent;
{ // Call the readdir system call.
printf("readdir: cannot read directory :" DEFN_SYSCALL1(dent, __NR_readdir, dirp);
"Directory pointer is not valid\n"); return dent;
return NULL;
}
if (mountpoint_list[dirp->handle].dir_op.readdir_f == NULL)
{
printf("readdir: cannot read directory '%s':"
"No readdir function\n", dirp->path);
return NULL;
}
return mountpoint_list[dirp->handle].dir_op.readdir_f(dirp);
} }
+20 -49
View File
@@ -4,63 +4,34 @@
/// @copyright (c) 2019 This file is distributed under the MIT License. /// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details. /// See LICENSE.md for details.
#include "vfs.h"
#include "stdio.h"
#include "fcntl.h"
#include "kheap.h"
#include "errno.h"
#include "initrd.h"
#include "string.h"
#include "unistd.h" #include "unistd.h"
int close(int fildes) #include "string.h"
{ #include "limits.h"
if (fildes < 0) #include "stdio.h"
{ #include "vfs.h"
return -1;
}
if (fd_list[fildes].fs_spec_id >= -1)
{
int mp_id = fd_list[fildes].mountpoint_id;
if (mountpoint_list[mp_id].operations.close_f != NULL)
{
int fs_fd = fd_list[fildes].fs_spec_id;
mountpoint_list[mp_id].operations.close_f(fs_fd);
}
fd_list[fildes].fs_spec_id = -1;
fd_list[fildes].mountpoint_id = -1;
}
else
{
return -1;
}
return 0;
}
int rmdir(const char *path) int rmdir(const char *path)
{ {
char absolute_path[MAX_PATH_LENGTH]; char absolute_path[PATH_MAX];
strcpy(absolute_path, path); strcpy(absolute_path, path);
if (path[0] != '/') if (path[0] != '/') {
{ get_absolute_path(absolute_path);
get_absolute_path(absolute_path); }
}
int32_t mp_id = get_mountpoint_id(absolute_path); int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0) if (mp_id < 0) {
{ printf("rmdir: failed to remove '%s':"
printf("rmdir: failed to remove '%s':" "Cannot find mount-point\n",
"Cannot find mount-point\n", path); path);
return -1; return -1;
} }
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL) if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL) {
{ return -1;
return -1; }
}
return mountpoint_list[mp_id].dir_op.rmdir_f(absolute_path); return mountpoint_list[mp_id].dir_op.rmdir_f(absolute_path);
} }
+6 -6
View File
@@ -10,11 +10,11 @@
int uname(utsname_t *os_infos) int uname(utsname_t *os_infos)
{ {
// Uname code goes here. // Uname code goes here.
strcpy(os_infos->sysname, OS_NAME); strcpy(os_infos->sysname, OS_NAME);
strcpy(os_infos->version, OS_VERSION); strcpy(os_infos->version, OS_VERSION);
strcpy(os_infos->nodename, "testbed"); strcpy(os_infos->nodename, "testbed");
strcpy(os_infos->machine, "i686"); strcpy(os_infos->machine, "i686");
return 0; return 0;
} }
+9 -9
View File
@@ -9,15 +9,15 @@
#include "stdio.h" #include "stdio.h"
#include "video.h" #include "video.h"
void printk(const char * format, ...) void printk(const char *format, ...)
{ {
char buffer[4096]; char buffer[4096];
va_list ap; va_list ap;
// Start variabile argument's list. // Start variabile argument's list.
va_start (ap, format); va_start(ap, format);
int len = vsprintf(buffer, format, ap); int len = vsprintf(buffer, format, ap);
va_end (ap); va_end(ap);
for (size_t i = 0; (i < len); ++i) for (size_t i = 0; (i < len); ++i)
video_putc(buffer[i]); video_putc(buffer[i]);
} }
+12 -3
View File
@@ -5,7 +5,6 @@
/// See LICENSE.md for details. /// See LICENSE.md for details.
#include "syscall.h" #include "syscall.h"
#include "sys.h"
#include "shm.h" #include "shm.h"
#include "isr.h" #include "isr.h"
#include "errno.h" #include "errno.h"
@@ -17,7 +16,8 @@
#include "process.h" #include "process.h"
#include "irqflags.h" #include "irqflags.h"
#include "scheduler.h" #include "scheduler.h"
#include "read_write.h"
#include "smart_sem_kernel.h"
/// @brief The signature of a function call. /// @brief The signature of a function call.
typedef int (*SystemCall)(); typedef int (*SystemCall)();
@@ -48,6 +48,10 @@ void syscall_init()
sys_call_table[__NR_read] = (SystemCall)sys_read; sys_call_table[__NR_read] = (SystemCall)sys_read;
sys_call_table[__NR_write] = (SystemCall)sys_write; sys_call_table[__NR_write] = (SystemCall)sys_write;
sys_call_table[__NR_open] = (SystemCall)sys_open; sys_call_table[__NR_open] = (SystemCall)sys_open;
sys_call_table[__NR_close] = (SystemCall)sys_close;
sys_call_table[__NR_stat] = (SystemCall)sys_stat;
sys_call_table[__NR_mkdir] = (SystemCall)sys_mkdir;
sys_call_table[__NR_readdir] = (SystemCall)sys_readdir;
sys_call_table[__NR_getpid] = (SystemCall)sys_getpid; sys_call_table[__NR_getpid] = (SystemCall)sys_getpid;
sys_call_table[__NR_getppid] = (SystemCall)sys_getppid; sys_call_table[__NR_getppid] = (SystemCall)sys_getppid;
sys_call_table[__NR_vfork] = (SystemCall)sys_vfork; sys_call_table[__NR_vfork] = (SystemCall)sys_vfork;
@@ -57,10 +61,15 @@ void syscall_init()
sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid; sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid;
sys_call_table[__NR_chdir] = (SystemCall)sys_chdir; sys_call_table[__NR_chdir] = (SystemCall)sys_chdir;
sys_call_table[__NR_getcwd] = (SystemCall)sys_getcwd; sys_call_table[__NR_getcwd] = (SystemCall)sys_getcwd;
sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid;
sys_call_table[__NR_brk] = (SystemCall)umalloc; // TODO: sys_brk sys_call_table[__NR_brk] = (SystemCall)umalloc; // TODO: sys_brk
sys_call_table[__NR_free] = (SystemCall)ufree; // TODO: sys_brk sys_call_table[__NR_free] = (SystemCall)ufree; // TODO: sys_brk
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
isr_install_handler(SYSTEM_CALL, &syscall_handler, "syscall_handler"); isr_install_handler(SYSTEM_CALL, &syscall_handler, "syscall_handler");
} }
+36 -48
View File
@@ -15,57 +15,45 @@
void cmd_cd(int argc, char **argv) void cmd_cd(int argc, char **argv)
{ {
DIR *dirp = NULL; DIR *dirp = NULL;
char path[MAX_PATH_LENGTH]; char path[PATH_MAX];
memset(path, 0, MAX_PATH_LENGTH); memset(path, 0, PATH_MAX);
char current_path[MAX_PATH_LENGTH]; char current_path[PATH_MAX];
getcwd(current_path, MAX_PATH_LENGTH); getcwd(current_path, PATH_MAX);
if (argc <= 1) if (argc <= 1) {
{ strcpy(path, "/");
strcpy(path, "/"); } else if (argc > 2) {
} printf("%s: too many arguments\n\n", argv[0]);
else if (argc > 2)
{
printf("%s: too many arguments\n\n", argv[0]);
return; return;
} } else if (strncmp(argv[1], "..", 2) == 0) {
else if (strncmp(argv[1], "..", 2) == 0) if (strcmp(current_path, dirname(current_path)) == 0) {
{ return;
if (strcmp(current_path, dirname(current_path)) == 0) }
{ strcpy(path, dirname(current_path));
return; } else if (strncmp(argv[1], ".", 1) == 0) {
} return;
strcpy(path, dirname(current_path)); } else {
} // Copy the current path.
else if (strncmp(argv[1], ".", 1) == 0) strcpy(path, current_path);
{ // Get the absolute path.
return; get_absolute_path(path);
} // If the current directory is not the root, add a '/'.
else if (strcmp(path, "/") != 0) {
{ strncat(path, "/", 1);
// Copy the current path. }
strcpy(path, current_path); // Concatenate the input dir.
// Get the absolute path. strncat(path, argv[1], strlen(argv[1]));
get_absolute_path(path); }
// If the current directory is not the root, add a '/'.
if (strcmp(path, "/") != 0)
{
strncat(path, "/", 1);
}
// Concatenate the input dir.
strncat(path, argv[1], strlen(argv[1]));
}
dirp = opendir(path); dirp = opendir(path);
if (dirp == NULL) if (dirp == NULL) {
{ printf("%s: no such file or directory: %s\n\n", argv[0], argv[1]);
printf("%s: no such file or directory: %s\n\n", argv[0], argv[1]);
return; return;
} }
chdir(path); chdir(path);
closedir(dirp); closedir(dirp);
} }
+123
View File
@@ -0,0 +1,123 @@
/// MentOS, The Mentoring Operating system project
/// @file cmd_deadlock.c
/// @brief Source file of deadlock shell command to test deadlock behavior with tasks and shared resources.
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "commands.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "wait.h"
#include "smart_sem_user.h"
#define DEFAULT_ITER "1"
/// @brief Task 1 for reproducing deadlock on resource r1 and r2.
static int _deadlock_task1(int argc, char **argv, char **envp);
/// @brief Task 2 for reproducing deadlock on resource r1 and r2.
static int _deadlock_task2(int argc, char **argv, char **envp);
/// @brief Mutex semaphores that manage the resources access.
int mutex_r1, mutex_r2;
/// @brief Resources accessed by tasks.
uint32_t r1 = 0, r2 = 0;
static int _deadlock_task1(int argc, char **argv, char **envp)
{
(void) envp;
pid_t cpid2;
size_t iter = (size_t) atoi(argc > 1 ? argv[1] : DEFAULT_ITER);
if ((cpid2 = vfork()) == 0) {
char *_argv[] = {"_deadlock_task2", argc > 1 ? argv[1] : DEFAULT_ITER, (char *) NULL};
char *_envp[] = {(char *) NULL};
execve((const char *) _deadlock_task2, _argv, _envp);
printf("cmd_deadlock should not arrive here\n");
return 0;
}
for (size_t i = 0; i < iter; i++) {
sem_acquire(mutex_r1);
sem_acquire(mutex_r2); //< DEADLOCK!
// Access shared resources.
uint32_t tmp = r1;
r1 = r2;
r2 = tmp;
r1++;
printf("[T1] { r1: %4i, r2: %4i }\n", r1, r2);
sem_release(mutex_r2);
sem_release(mutex_r1);
}
int status;
waitpid(cpid2, &status, 0);
return 0;
}
static int _deadlock_task2(int argc, char **argv, char **envp)
{
(void) envp;
size_t iter = (size_t) atoi(argc > 1 ? argv[1] : DEFAULT_ITER);
for (size_t i = 0; i < iter; i++) {
sem_acquire(mutex_r2);
sem_acquire(mutex_r1); //< DEADLOCK!
// Access shared resources.
uint32_t tmp = r2;
r2 = r1;
r1 = tmp;
r2++;
printf("[T2] { r1: %4i, r2: %4i }\n", r1, r2);
sem_release(mutex_r1);
sem_release(mutex_r2);
}
return 0;
}
void cmd_deadlock(int argc, char **argv)
{
mutex_r1 = sem_create();
mutex_r2 = sem_create();
sem_init(mutex_r1);
sem_init(mutex_r2);
pid_t cpid1;
char *iter_str = DEFAULT_ITER;
if (argc > 2 && (strcmp(argv[1], "-i") == 0)) {
iter_str = argv[2];
}
if ((cpid1 = vfork()) == 0) {
char *_argv[] = {"_deadlock_task1", iter_str, (char *) NULL};
char *_envp[] = {(char *) NULL};
execve((const char *) _deadlock_task1, _argv, _envp);
printf("cmd_deadlock should not arrive here\n");
return;
}
int status;
waitpid(cpid1, &status, 0);
sem_destroy(mutex_r1);
sem_destroy(mutex_r2);
}
+38 -54
View File
@@ -11,59 +11,43 @@
void cmd_drv_load(int argc, char **argv) void cmd_drv_load(int argc, char **argv)
{ {
if (argc < 2) if (argc < 2) {
{ printf(
printf( "No driver inserted or bad usage! Type %s --help for the usage.\n",
"No driver inserted or bad usage! Type %s --help for the usage.\n", argv[0]);
argv[0]); } else {
} if ((_kstrncmp(argv[1], "-r", 2) == 0)) {
else if ((argv[2] != NULL)) {
{ if (_kstrncmp(argv[2], "mouse", 5) == 0) {
if ((_kstrncmp(argv[1], "-r", 2) == 0)) printf("Disattivamento %s in corso..\n", argv[2]);
{ mouse_disable();
if ((argv[2] != NULL)) } else
{ printf("FATAL: Driver %s not found.\n", argv[2]);
if (_kstrncmp(argv[2], "mouse", 5) == 0) } else
{ printf("Warning, no driver name inserted!\n");
printf("Disattivamento %s in corso..\n", argv[2]); } else if (_kstrncmp(argv[1], "mouse", 5) == 0) {
mouse_disable(); // Enabling mouse.
} mouse_install();
else } else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
printf("FATAL: Driver %s not found.\n", argv[2]); (_kstrncmp(argv[1], "-h", 2) == 0)) {
} printf("---------------------------------------------------\n"
else "Driver tool to load and kill driver\n"
printf("Warning, no driver name inserted!\n"); "Simple to use, just type:\n"
} "\n"
else if (_kstrncmp(argv[1], "mouse", 5) == 0) "Usage: %s -<options> driver_name\n"
{ "\t-> %s module_name - to load driver\n"
// Enabling mouse. "\t-> %s -r module_name - to kill driver\n"
mouse_install(); "---------------------------------------------------\n",
} argv[0], argv[0], argv[0]);
else if ((_kstrncmp(argv[1], "--help", 6) == 0) || } else {
(_kstrncmp(argv[1], "-h", 2) == 0)) if ((_kstrncmp(argv[1], "-r", 2) == 0) &&
{ (_kstrncmp(argv[2], "mouse", 5) == -1)) {
printf("---------------------------------------------------\n" printf("FATAL: Driver %s not found.\n", argv[2]);
"Driver tool to load and kill driver\n" }
"Simple to use, just type:\n"
"\n"
"Usage: %s -<options> driver_name\n"
"\t-> %s module_name - to load driver\n"
"\t-> %s -r module_name - to kill driver\n"
"---------------------------------------------------\n",
argv[0], argv[0], argv[0]);
}
else
{
if ((_kstrncmp(argv[1], "-r", 2) == 0) &&
(_kstrncmp(argv[2], "mouse", 5) == -1))
{
printf("FATAL: Driver %s not found.\n", argv[2]);
}
else else {
{ printf("FATAL: Driver %s not found.\n", argv[1]);
printf("FATAL: Driver %s not found.\n", argv[1]); }
} }
} }
}
} }
+10 -14
View File
@@ -9,18 +9,14 @@
void cmd_echo(int argc, char **argv) void cmd_echo(int argc, char **argv)
{ {
int i = argc; int i = argc;
int j = 0; int j = 0;
if (argc == 1) if (argc == 1) {
{ printf("");
printf(""); } else {
} while (--i > 0) {
else printf("%s ", argv[++j]);
{ }
while (--i > 0) }
{ printf("\n");
printf("%s ", argv[++j]);
}
}
printf("\n");
} }
+29 -37
View File
@@ -10,49 +10,41 @@
extern struct shmid_ds *head; extern struct shmid_ds *head;
void cmd_ipcrm(int argc, char **argv){ void cmd_ipcrm(int argc, char **argv)
if (argc != 2) {
{ if (argc != 2) {
printf("Bad arguments: you have to specify only IPC id, see ipcs.\n"); printf("Bad arguments: you have to specify only IPC id, see ipcs.\n");
return; return;
} }
struct shmid_ds *shmid_ds = head; struct shmid_ds *shmid_ds = head;
struct shmid_ds *prev = NULL; struct shmid_ds *prev = NULL;
while (shmid_ds != NULL) while (shmid_ds != NULL) {
{ char strid[10];
char strid[10]; int_to_str(strid, (shmid_ds->shm_perm).seq, 10);
int_to_str(strid, (shmid_ds ->shm_perm).seq, 10);
if (strcmp(strid, argv[1]) == 0) if (strcmp(strid, argv[1]) == 0) {
{ break;
break; }
}
prev = shmid_ds; prev = shmid_ds;
shmid_ds = shmid_ds -> next; shmid_ds = shmid_ds->next;
} }
if (shmid_ds == NULL) if (shmid_ds == NULL) {
{ printf("No shared memory find. \n");
printf("No shared memory find. \n"); } else {
} kfree(shmid_ds->shm_location);
else
{
kfree(shmid_ds -> shm_location);
// shmid_ds = head. // shmid_ds = head.
if (prev == NULL) if (prev == NULL) {
{ head = head->next;
head = head -> next; } else {
} prev->next = shmid_ds->next;
else }
{
prev -> next = shmid_ds -> next;
}
kfree(shmid_ds); kfree(shmid_ds);
} }
} }
+44 -59
View File
@@ -14,85 +14,70 @@ extern struct shmid_ds *head;
static void print_sem_stat() static void print_sem_stat()
{ {
printf("Semaphores: \n"); printf("Semaphores: \n");
printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE",
"OWNER", "GROUP"); "OWNER", "GROUP");
printf("%-20s %-10s %-20s \n\n", "", "Semaphores not implemented", ""); printf("%-20s %-10s %-20s \n\n", "", "Semaphores not implemented", "");
} }
static void print_shm_stat() static void print_shm_stat()
{ {
struct shmid_ds *shm_list = head; struct shmid_ds *shm_list = head;
printf("Shared Memory: \n"); printf("Shared Memory: \n");
printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE",
"OWNER", "GROUP"); "OWNER", "GROUP");
while (shm_list != NULL) while (shm_list != NULL) {
{ char mode[12];
char mode[12]; strmode((shm_list->shm_perm).mode, mode);
strmode((shm_list->shm_perm).mode, mode);
printf("%-10s %-10i %-10i %-10s %-10s %-10s \n", printf("%-10s %-10i %-10i %-10s %-10s %-10s \n", "m",
"m", (shm_list->shm_perm).seq, (shm_list->shm_perm).key, mode, "-",
(shm_list->shm_perm).seq, "-");
(shm_list->shm_perm).key,
mode,
"-", "-");
shm_list = shm_list->next; shm_list = shm_list->next;
} }
printf("\n"); printf("\n");
} }
static void print_msg_stat() static void print_msg_stat()
{ {
printf("Message Queues: \n"); printf("Message Queues: \n");
printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE",
"OWNER", "GROUP"); "OWNER", "GROUP");
printf("%-20s %-10s %-20s \n\n", "", "Message Queues not implemented", ""); printf("%-20s %-10s %-20s \n\n", "", "Message Queues not implemented", "");
} }
void cmd_ipcs(int argc, char **argv) void cmd_ipcs(int argc, char **argv)
{ {
if (argc > 2) if (argc > 2) {
{ printf("Too much arguments.\n");
printf("Too much arguments.\n");
return; return;
} }
char datehour[100] = ""; char datehour[100] = "";
strdatehour(datehour); strdatehour(datehour);
printf("IPC status from "OS_NAME" as of %s\n", datehour); printf("IPC status from " OS_NAME " as of %s\n", datehour);
if (argc == 2) if (argc == 2) {
{ if (strcmp(argv[1], "-s") == 0) {
if (strcmp(argv[1], "-s") == 0) print_sem_stat();
{ } else if (strcmp(argv[1], "-m") == 0) {
print_sem_stat(); print_shm_stat();
} } else if (strcmp(argv[1], "-q") == 0) {
else if (strcmp(argv[1], "-m") == 0) print_msg_stat();
{ } else {
print_shm_stat(); printf("Option not recognize.\n");
} }
else if (strcmp(argv[1], "-q") == 0) } else {
{ print_sem_stat();
print_msg_stat(); print_shm_stat();
} print_msg_stat();
else }
{
printf("Option not recognize.\n");
}
}
else
{
print_sem_stat();
print_shm_stat();
print_msg_stat();
}
return; return;
} }
+2 -2
View File
@@ -92,8 +92,8 @@ void cmd_ls(int argc, char **argv)
print_ls(dirp, flags); print_ls(dirp, flags);
} }
if (no_directory) { if (no_directory) {
char cwd[MAX_PATH_LENGTH]; char cwd[PATH_MAX];
getcwd(cwd, MAX_PATH_LENGTH); getcwd(cwd, PATH_MAX);
DIR *dirp = opendir(cwd); DIR *dirp = opendir(cwd);
if (dirp == NULL) { if (dirp == NULL) {
printf("%s: cannot access '%s': %s\n\n", argv[0], cwd, "unknown"); printf("%s: cannot access '%s': %s\n\n", argv[0], cwd, "unknown");
+25 -29
View File
@@ -13,39 +13,35 @@
void cmd_more(int argc, char **argv) void cmd_more(int argc, char **argv)
{ {
if (argc != 2) if (argc != 2) {
{ printf("%s: missing operand.\n", argv[0]);
printf("%s: missing operand.\n", argv[0]); printf("Try '%s --help' for more information.\n\n", argv[0]);
printf("Try '%s --help' for more information.\n\n", argv[0]);
return; return;
} }
if (strcmp(argv[1], "--help") == 0) if (strcmp(argv[1], "--help") == 0) {
{ printf("Prints the content of the given file.\n");
printf("Prints the content of the given file.\n"); printf("Usage:\n");
printf("Usage:\n"); printf(" %s <file>\n\n", argv[0]);
printf(" %s <file>\n\n", argv[0]);
return; return;
} }
int fd = open(argv[1], O_RDONLY, 42); int fd = open(argv[1], O_RDONLY, 42);
if (fd < 0) if (fd < 0) {
{ printf("%s: Cannot stat file '%s': %s\n\n", argv[0], argv[1],
printf("%s: Cannot stat file '%s': %s\n\n", "unknown" /*strerror(errno)*/);
argv[0], argv[1],"unknown"/*strerror(errno)*/);
return; return;
} }
char c; char c;
// Put on the standard output the characters. // Put on the standard output the characters.
while (read(fd, &c, 1) > 0) while (read(fd, &c, 1) > 0) {
{ putchar(c);
putchar(c); }
} putchar('\n');
putchar('\n'); putchar('\n');
putchar('\n'); close(fd);
close(fd);
} }
+31 -36
View File
@@ -14,49 +14,44 @@
void cmd_newfile(int argc, char **argv) void cmd_newfile(int argc, char **argv)
{ {
if (argc != 2) if (argc != 2) {
{ printf("%s: missing operand.\n", argv[0]);
printf("%s: missing operand.\n", argv[0]); printf("Try '%s --help' for more information.\n\n", argv[0]);
printf("Try '%s --help' for more information.\n\n", argv[0]);
return; return;
} }
if (strcmp(argv[1], "--help") == 0) if (strcmp(argv[1], "--help") == 0) {
{ printf("Makes a new file, and prompt for it's content.\n");
printf("Makes a new file, and prompt for it's content.\n"); printf("Usage:\n");
printf("Usage:\n"); printf(" %s <filename>\n", argv[0]);
printf(" %s <filename>\n", argv[0]);
return; return;
} }
char text[256]; char text[256];
printf("Filename: %s\n", argv[1]); printf("Filename: %s\n", argv[1]);
int fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 0); int fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 0);
if (fd < 0) if (fd < 0) {
{ printf("%s: Cannot create file '%s': %s\n\n", argv[0], argv[1],
printf("%s: Cannot create file '%s': %s\n\n", "unknown" /*strerror(errno)*/);
argv[0], argv[1], "unknown"/*strerror(errno)*/);
return; return;
} }
printf("Type one line of text here (new line to complete):\n"); printf("Type one line of text here (new line to complete):\n");
scanf("%s", text); scanf("%s", text);
if (write(fd, text, strlen(text)) == -1) if (write(fd, text, strlen(text)) == -1) {
{ printf("%s: Cannot write on file '%s': %s\n\n", argv[0], argv[1],
printf("%s: Cannot write on file '%s': %s\n\n", "unknown" /*strerror(errno)*/);
argv[0], argv[1], "unknown"/*strerror(errno)*/);
return; return;
} }
if (close(fd) == -1) if (close(fd) == -1) {
{ printf("%s: Cannot close file '%s': %s\n\n", argv[0], argv[1],
printf("%s: Cannot close file '%s': %s\n\n", "unknown" /*strerror(errno)*/);
argv[0], argv[1], "unknown"/*strerror(errno)*/);
return; return;
} }
} }
+5 -5
View File
@@ -11,9 +11,9 @@
void cmd_pwd(int argc, char **argv) void cmd_pwd(int argc, char **argv)
{ {
(void) argc; (void)argc;
(void) argv; (void)argv;
char cwd[MAX_PATH_LENGTH]; char cwd[PATH_MAX];
getcwd(cwd, MAX_PATH_LENGTH); getcwd(cwd, PATH_MAX);
printf("%s\n", cwd); printf("%s\n", cwd);
} }
+17 -20
View File
@@ -12,29 +12,26 @@
void cmd_rmdir(int argc, char **argv) void cmd_rmdir(int argc, char **argv)
{ {
// Check the number of arguments. // Check the number of arguments.
if (argc != 2) if (argc != 2) {
{ printf("Bad usage.\n");
printf("Bad usage.\n"); printf("Try 'rmdir --help' for more information.\n");
printf("Try 'rmdir --help' for more information.\n");
return; return;
} }
if (strcmp(argv[1], "--help") == 0) if (strcmp(argv[1], "--help") == 0) {
{ printf("Removes a directory.\n");
printf("Removes a directory.\n"); printf("Usage:\n");
printf("Usage:\n"); printf(" rmdir <directory>\n");
printf(" rmdir <directory>\n");
return; return;
} }
if (rmdir(argv[1]) != 0) if (rmdir(argv[1]) != 0) {
{ printf("%s: failed to remove '%s': %s\n\n", argv[0], argv[1],
printf("%s: failed to remove '%s': %s\n\n", "unknown" /*strerror(errno)*/);
argv[0], argv[1], "unknown"/*strerror(errno)*/);
return; return;
} }
} }
+2 -2
View File
@@ -42,10 +42,10 @@ void cmd_uname(int argc, char **argv)
printf("Micro: %d\n", OS_MICRO_VERSION); printf("Micro: %d\n", OS_MICRO_VERSION);
// CPU Info. // CPU Info.
printf("\nCPU:"); printf("\nCPU:");
video_set_color(BRIGHT_RED); video_set_color(BRIGHT_RED);
video_move_cursor(61, video_get_line()); video_move_cursor(61, video_get_line());
printf(sinfo.cpu_vendor); printf(sinfo.cpu_vendor);
video_set_color(WHITE); video_set_color(WHITE);
printf("\n"); printf("\n");

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