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
+3 -7
View File
@@ -36,8 +36,7 @@
*/ */
/// @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.
@@ -49,8 +48,7 @@ typedef struct idt_descriptor_t
} __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.
@@ -65,9 +63,7 @@ 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,
uint16_t options,
uint8_t seg_sel); uint8_t seg_sel);
//==== List of exceptions generated internally by the CPU ====================== //==== List of exceptions generated internally by the CPU ======================
+2 -2
View File
@@ -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.
@@ -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) \
+6
View File
@@ -39,3 +39,9 @@
/// 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
+3 -7
View File
@@ -9,8 +9,7 @@
#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.
@@ -46,8 +45,7 @@ typedef struct list_head
/// @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)
@@ -104,9 +102,7 @@ static inline int list_head_empty(list_head const * 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]
+2 -4
View File
@@ -10,8 +10,7 @@
#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.
@@ -19,8 +18,7 @@ typedef struct queue_node_t
} 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.
+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);
+43 -60
View File
@@ -10,42 +10,45 @@
#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
/// Is there a APM table?
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
/// Is there video information?
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 #define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 #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_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5 #define MULTIBOOT_MEMORY_BADRAM 5
// +-------------------+ // +-------------------+
@@ -93,8 +96,7 @@
// +-------------------+ // +-------------------+
/// 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;
@@ -102,8 +104,7 @@ typedef struct multiboot_aout_symbol_table
} 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;
@@ -111,8 +112,7 @@ typedef struct multiboot_elf_section_header_table
} 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;
@@ -122,18 +122,17 @@ typedef struct multiboot_mod_list
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 size;
uint64_t addr; uint32_t base_addr_low;
uint64_t len; uint32_t base_addr_high;
uint32_t length_low;
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;
@@ -151,8 +150,7 @@ typedef struct multiboot_info
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;
@@ -188,15 +186,12 @@ typedef struct multiboot_info
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; uint32_t framebuffer_palette_addr;
uint16_t framebuffer_palette_num_colors; uint16_t framebuffer_palette_num_colors;
}; };
struct struct {
{
uint8_t framebuffer_red_field_position; uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size; uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position; uint8_t framebuffer_green_field_position;
@@ -207,17 +202,5 @@ typedef struct multiboot_info
}; };
} __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);
+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);
+4 -11
View File
@@ -7,13 +7,10 @@
#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;
@@ -25,17 +22,13 @@ typedef struct dirent_t
} 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 handle; int fd;
/// The currently opened entry. /// The currently opened entry.
ino_t cur_entry; ino_t cur_entry;
/// Path to the directory. /// Path to the directory.
char path[NAME_MAX + 1]; char path[NAME_MAX + 1];
/// Next directory item. /// Next directory item.
dirent_t entry; dirent_t entry;
} DIR; } DIR;
-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);
+2 -2
View File
@@ -48,9 +48,9 @@ ssize_t write(int fd, void *buf, size_t nbytes);
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.
+1 -2
View File
@@ -10,8 +10,7 @@
#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];
+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;
+16 -30
View File
@@ -98,16 +98,14 @@ struct {
{ 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" },
@@ -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;
} }
@@ -286,8 +281,7 @@ 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;
} }
@@ -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);
} }
} }
@@ -423,8 +415,7 @@ 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);
@@ -455,8 +446,8 @@ 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,
@@ -475,18 +466,13 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
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",
@@ -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;
}
+6 -88
View File
@@ -4,107 +4,25 @@
/// @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;
} }
+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));
+22 -35
View File
@@ -21,12 +21,10 @@ void get_cpuid(cpuinfo_t *cpuinfo)
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)
@@ -54,8 +52,7 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *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;
@@ -73,16 +70,14 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
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);
} }
@@ -92,12 +87,9 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
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 {
else
{
cpuinfo->brand_string = cpuid_brand_index(registers); cpuinfo->brand_string = cpuid_brand_index(registers);
} }
} }
@@ -107,8 +99,7 @@ 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;
@@ -120,16 +111,14 @@ 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);
@@ -161,8 +150,7 @@ char *cpuid_brand_index(register_t *r)
int bx = (r->ebx & 0xFF); int bx = (r->ebx & 0xFF);
if (bx > 0x17) if (bx > 0x17) {
{
bx = 0; bx = 0;
} }
@@ -176,18 +164,17 @@ 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 = strncat(temp, (const char *) r->eax, temp =
strlen((const char *) r->eax)); strncat(temp, (const char *)r->eax, strlen((const char *)r->eax));
temp = strncat(temp, (const char *) r->ebx, temp =
strlen((const char *) r->ebx)); strncat(temp, (const char *)r->ebx, strlen((const char *)r->ebx));
temp = strncat(temp, (const char *) r->ecx, temp =
strlen((const char *) r->ecx)); strncat(temp, (const char *)r->ecx, strlen((const char *)r->ecx));
temp = strncat(temp, (const char *) r->edx, temp =
strlen((const char *) r->edx)); strncat(temp, (const char *)r->edx, strlen((const char *)r->edx));
} }
return temp; return temp;
+4 -1
View File
@@ -24,7 +24,10 @@ inline uint16_t inports(uint16_t port)
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)
+4 -10
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,8 +12,7 @@
static void machine_power_off() static void machine_power_off()
{ {
while (true) while (true) {
{
cpu_relax(); cpu_relax();
} }
} }
@@ -40,18 +38,14 @@ int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg)
// 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 &&
magic2 != LINUX_REBOOT_MAGIC2C))
{
return -EINVAL; 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:
+2 -7
View File
@@ -8,9 +8,7 @@
#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,
unsigned int line,
const char *function) const char *function)
{ {
char message[1024]; char message[1024];
@@ -19,9 +17,6 @@ void __assert_fail(const char *assertion,
"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,
(function ? function : "NO_FUN"),
assertion);
kernel_panic(message); kernel_panic(message);
} }
+26 -53
View File
@@ -8,15 +8,13 @@
#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;
@@ -31,15 +29,11 @@ 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++)) {
*/
while ((c = *key++))
{
hash = c + (hash << 6) + (hash << 16) - hash; hash = c + (hash << 6) + (hash << 16) - hash;
} }
return hash; return hash;
} }
@@ -109,11 +103,9 @@ hashmap_t *hashmap_create_int(size_t size)
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; p = x;
x = x->next; x = x->next;
map->hash_key_free(p->key); map->hash_key_free(p->key);
@@ -129,8 +121,7 @@ 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;
@@ -142,10 +133,8 @@ void *hashmap_set(hashmap_t *map, void *key, void *value)
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; void *out = x->value;
x->value = value; x->value = value;
@@ -169,14 +158,11 @@ 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)) {
if (map->hash_comp(x->key, key))
{
return x->value; return x->value;
} }
x = x->next; x = x->next;
@@ -190,12 +176,10 @@ 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; void *out = x->value;
map->entries[hash] = x->next; map->entries[hash] = x->next;
map->hash_key_free(x->key); map->hash_key_free(x->key);
@@ -206,10 +190,8 @@ void *hashmap_remove(hashmap_t *map, void *key)
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; void *out = x->value;
p->next = x->next; p->next = x->next;
map->hash_key_free(x->key); map->hash_key_free(x->key);
@@ -226,10 +208,8 @@ void *hashmap_remove(hashmap_t *map, void *key)
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;
} }
} }
@@ -242,14 +222,11 @@ 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)) {
if (map->hash_comp(x->key, key))
{
return true; return true;
} }
x = x->next; x = x->next;
@@ -262,11 +239,9 @@ 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); list_insert_back(l, x->key);
x = x->next; x = x->next;
} }
@@ -279,12 +254,10 @@ 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;
} }
+10 -16
View File
@@ -7,11 +7,11 @@
#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;
} }
@@ -19,8 +19,7 @@ int parse_path(char *out, char **cur, char sep, size_t max)
++*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;
@@ -33,12 +32,13 @@ int parse_path(char *out, char **cur, char sep, size_t max)
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);
@@ -46,25 +46,19 @@ char *dirname(const char *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')) {
else if ((last_slash != NULL) && (last_slash[1] == '\0'))
{
// If the slash is the last character, we need to search before it. // If the slash is the last character, we need to search before it.
last_slash = memchr(s, '/', last_slash - s); 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 {
else
{
// Otherwise, return '.'. // Otherwise, return '.'.
return dot; return dot;
} }
+13 -64
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 i = (int)x;
if (x < 0)
return (double)(i - 1);
return (double)i;
} }
int x_i = (int)x;
if (x < 0) {
return (double)(x_i - 1);
} else {
return (double)x_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));
} }
+7 -14
View File
@@ -27,8 +27,7 @@ ordered_array_t create_ordered_array(uint32_t max_size,
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;
@@ -51,24 +50,19 @@ 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 {
else
{
array_type_t tmp = array->array[iterator]; array_type_t tmp = array->array[iterator];
array->array[iterator] = item; 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;
@@ -87,8 +81,7 @@ array_type_t lookup_ordered_array(uint32_t i, ordered_array_t * array)
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++;
} }
+4 -6
View File
@@ -13,20 +13,18 @@ void spinlock_init(spinlock_t *spinlock)
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);
} }
+33 -54
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) {
count--;
} }
} else { // Add the null-terminating character.
tmp[count++] = (char)c; *cptr = '\0';
} // Copy the string we have read.
} while (count < 255); strcpy(str, buffer);
// Return a pointer to the original string.
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.
+21 -32
View File
@@ -8,11 +8,6 @@
#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;
@@ -27,52 +22,46 @@ void free(void *p)
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
+1 -2
View File
@@ -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;
}
+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;
}
+1 -3
View File
@@ -14,11 +14,9 @@ int open(const char *pathname, int flags, mode_t mode)
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;
} }
+1 -2
View File
@@ -14,8 +14,7 @@ ssize_t read(int fd, void *buf, size_t nbytes)
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;
} }
+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()
+161 -40
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) {
case 0x00000000:
dbg_print("(floppy)\n");
break;
case 0x80000000:
dbg_print("(disk)\n");
break;
default:
dbg_print("(unknown)\n");
} }
}
// Is the command line passed?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) {
dbg_print("cmdlin: 0x%x (%s)\n", mbi->cmdline, (char *)mbi->cmdline); dbg_print("%-16s = %s\n", "cmdline", (char *)mbi->cmdline);
} }
// Are mods_* valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) { if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) {
dbg_print("Mods : 0x%x\n", mbi->mods_count); 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 = (multiboot_module_t *)mbi->mods_addr; multiboot_module_t *mod = first_module(mbi);
for (int i = 0; mod; ++i, mod = next_module(mbi, mod)) {
if (mbi->mods_count > 0) { dbg_print(" [%2d] "
for (uint32_t i = 0; i < mbi->mods_count && i < MAX_MODULES; "mod_start = 0x%x, "
i++, mod++) { "mod_end = 0x%x, "
uint32_t start = mod->mod_start; "cmdline = %s\n",
uint32_t end = mod->mod_end; i, mod->mod_start, mod->mod_end, (char *)mod->cmdline);
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end); }
}
// 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;
} }
/* Last implementation // Is the symbol table of a.out valid?
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);
}
*/
}
}
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);
} }
dbg_print("MMap : 0x%x\n", mbi->mmap_length);
dbg_print("Addr : 0x%x\n", mbi->mmap_addr); // 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("Drives: 0x%x\n", mbi->drives_length);
dbg_print("Addr : 0x%x\n", mbi->drives_addr); 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); 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);
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); 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 Co: 0x%x\n", mbi->vbe_control_info);
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_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 In: 0x%x\n", mbi->vbe_mode);
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg); 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 of: 0x%x\n", mbi->vbe_interface_off);
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len); dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
}
dbg_print("--------------------------------------------------\n"); dbg_print("--------------------------------------------------\n");
dbg_print("\n"); dbg_print("\n");
} }
+1 -1
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.
+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);
+8
View File
@@ -19,7 +19,15 @@ task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec)
#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)
+23 -37
View File
@@ -11,18 +11,19 @@
#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;
@@ -31,27 +32,26 @@ DIR *opendir(const char *path)
// 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", absolute_path); "Cannot find mount-point\n",
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", absolute_path); "No opendir function\n",
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;
@@ -59,40 +59,26 @@ DIR *opendir(const char *path)
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", dirp->path); "No closedir function\n",
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);
} }
+10 -39
View File
@@ -4,61 +4,32 @@
/// @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", path); "Cannot find mount-point\n",
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;
} }
+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");
} }
+12 -24
View File
@@ -16,43 +16,32 @@
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) {
else if (argc > 2)
{
printf("%s: too many arguments\n\n", argv[0]); 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) {
{
if (strcmp(current_path, dirname(current_path)) == 0)
{
return; return;
} }
strcpy(path, dirname(current_path)); strcpy(path, dirname(current_path));
} } else if (strncmp(argv[1], ".", 1) == 0) {
else if (strncmp(argv[1], ".", 1) == 0)
{
return; return;
} } else {
else
{
// Copy the current path. // Copy the current path.
strcpy(path, current_path); strcpy(path, current_path);
// Get the absolute path. // Get the absolute path.
get_absolute_path(path); get_absolute_path(path);
// If the current directory is not the root, add a '/'. // If the current directory is not the root, add a '/'.
if (strcmp(path, "/") != 0) if (strcmp(path, "/") != 0) {
{
strncat(path, "/", 1); strncat(path, "/", 1);
} }
// Concatenate the input dir. // Concatenate the input dir.
@@ -60,8 +49,7 @@ void cmd_cd(int argc, char **argv)
} }
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;
+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);
}
+13 -29
View File
@@ -11,37 +11,25 @@
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 {
else if ((_kstrncmp(argv[1], "-r", 2) == 0)) {
{ if ((argv[2] != NULL)) {
if ((_kstrncmp(argv[1], "-r", 2) == 0)) if (_kstrncmp(argv[2], "mouse", 5) == 0) {
{
if ((argv[2] != NULL))
{
if (_kstrncmp(argv[2], "mouse", 5) == 0)
{
printf("Disattivamento %s in corso..\n", argv[2]); printf("Disattivamento %s in corso..\n", argv[2]);
mouse_disable(); mouse_disable();
} } else
else
printf("FATAL: Driver %s not found.\n", argv[2]); printf("FATAL: Driver %s not found.\n", argv[2]);
} } else
else
printf("Warning, no driver name inserted!\n"); printf("Warning, no driver name inserted!\n");
} } else if (_kstrncmp(argv[1], "mouse", 5) == 0) {
else if (_kstrncmp(argv[1], "mouse", 5) == 0)
{
// Enabling mouse. // Enabling mouse.
mouse_install(); mouse_install();
} } else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
else if ((_kstrncmp(argv[1], "--help", 6) == 0) || (_kstrncmp(argv[1], "-h", 2) == 0)) {
(_kstrncmp(argv[1], "-h", 2) == 0))
{
printf("---------------------------------------------------\n" printf("---------------------------------------------------\n"
"Driver tool to load and kill driver\n" "Driver tool to load and kill driver\n"
"Simple to use, just type:\n" "Simple to use, just type:\n"
@@ -51,17 +39,13 @@ void cmd_drv_load(int argc, char **argv)
"\t-> %s -r module_name - to kill driver\n" "\t-> %s -r module_name - to kill driver\n"
"---------------------------------------------------\n", "---------------------------------------------------\n",
argv[0], argv[0], argv[0]); argv[0], argv[0], argv[0]);
} } else {
else
{
if ((_kstrncmp(argv[1], "-r", 2) == 0) && if ((_kstrncmp(argv[1], "-r", 2) == 0) &&
(_kstrncmp(argv[2], "mouse", 5) == -1)) (_kstrncmp(argv[2], "mouse", 5) == -1)) {
{
printf("FATAL: Driver %s not found.\n", argv[2]); 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]);
} }
} }
+3 -7
View File
@@ -11,14 +11,10 @@ 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 {
else while (--i > 0) {
{
while (--i > 0)
{
printf("%s ", argv[++j]); printf("%s ", argv[++j]);
} }
} }
+8 -16
View File
@@ -10,9 +10,9 @@
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;
@@ -21,13 +21,11 @@ void cmd_ipcrm(int argc, char **argv){
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;
} }
@@ -35,21 +33,15 @@ void cmd_ipcrm(int argc, char **argv){
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 {
else
{
kfree(shmid_ds->shm_location); kfree(shmid_ds->shm_location);
// shmid_ds = head. // shmid_ds = head.
if (prev == NULL) if (prev == NULL) {
{
head = head->next; head = head->next;
} } else {
else
{
prev->next = shmid_ds->next; prev->next = shmid_ds->next;
} }
+11 -26
View File
@@ -28,17 +28,13 @@ static void print_shm_stat()
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;
} }
@@ -56,8 +52,7 @@ static void print_msg_stat()
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;
@@ -68,27 +63,17 @@ void cmd_ipcs(int argc, char **argv)
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(); print_sem_stat();
} } else if (strcmp(argv[1], "-m") == 0) {
else if (strcmp(argv[1], "-m") == 0)
{
print_shm_stat(); print_shm_stat();
} } else if (strcmp(argv[1], "-q") == 0) {
else if (strcmp(argv[1], "-q") == 0)
{
print_msg_stat(); print_msg_stat();
} } else {
else
{
printf("Option not recognize.\n"); printf("Option not recognize.\n");
} }
} } else {
else
{
print_sem_stat(); print_sem_stat();
print_shm_stat(); print_shm_stat();
print_msg_stat(); print_msg_stat();
+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");
+6 -10
View File
@@ -13,16 +13,14 @@
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]);
@@ -31,18 +29,16 @@ void cmd_more(int argc, char **argv)
} }
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');
+11 -16
View File
@@ -14,16 +14,14 @@
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]);
@@ -34,28 +32,25 @@ void cmd_newfile(int argc, char **argv)
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;
} }
+2 -2
View File
@@ -13,7 +13,7 @@ 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);
} }
+5 -8
View File
@@ -13,16 +13,14 @@
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");
@@ -30,10 +28,9 @@ void cmd_rmdir(int argc, char **argv)
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;
} }
+1 -1
View File
@@ -11,7 +11,7 @@
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
#include "unistd.h" #include "unistd.h"
#include <misc/debug.h> #include "debug.h"
int main_init() int main_init()
{ {
+5 -4
View File
@@ -75,7 +75,8 @@ struct {
{ "clear", cmd_clear, "Clears the screen" }, { "clear", cmd_clear, "Clears the screen" },
{ "showpid", cmd_showpid, "Shows the PID of the shell" }, { "showpid", cmd_showpid, "Shows the PID of the shell" },
{ "history", cmd_show_history, "Shows the shell history" }, { "history", cmd_show_history, "Shows the shell history" },
{ "nice", cmd_nice, "Change the nice value of the process" } { "nice", cmd_nice, "Change the nice value of the process" },
{ "deadlock", cmd_deadlock, "Test deadlock behavior" }
}; };
/// @brief Completely delete the current command. /// @brief Completely delete the current command.
@@ -215,8 +216,8 @@ static void shell_print_prompt()
video_set_color(BRIGHT_BLUE); video_set_color(BRIGHT_BLUE);
printf(current_user.username); printf(current_user.username);
video_set_color(WHITE); video_set_color(WHITE);
char cwd[MAX_PATH_LENGTH]; char cwd[PATH_MAX];
getcwd(cwd, MAX_PATH_LENGTH); getcwd(cwd, PATH_MAX);
printf("~:%s# ", cwd); printf("~:%s# ", cwd);
// Update the lower-bounds for the video. // Update the lower-bounds for the video.
lower_bound_x = video_get_column(); lower_bound_x = video_get_column();
@@ -400,7 +401,7 @@ int shell(int argc, char **argv, char **envp)
dbg_print("I'm shell, I'll let my pawn, login, handle any intruder...\n"); dbg_print("I'm shell, I'll let my pawn, login, handle any intruder...\n");
shell_login(); shell_login();
sys_chdir("/"); chdir("/");
current_user.uid = 1; current_user.uid = 1;
current_user.gid = 0; current_user.gid = 0;
+14
View File
@@ -0,0 +1,14 @@
set(CMAKE_SYSTEM_NAME Generic)
if(CMAKE_VERSION VERSION_LESS "3.6.0")
INCLUDE(CMakeForceCompiler)
CMAKE_FORCE_C_COMPILER(i386-elf-gcc Clang)
CMAKE_FORCE_CXX_COMPILER(i386-elf-g++ Clang)
else()
set(CMAKE_C_COMPILER i386-elf-gcc)
set(CMAKE_CXX_COMPILER i386-elf-g++)
set(CMAKE_AR i386-elf-ar)
endif()
set(CMAKE_LINKER i386-elf-ld)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib")