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)
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.
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
@@ -28,7 +63,7 @@ add_custom_target(
COMMAND echo "---------------------------------------------"
COMMAND echo "Initializing 'initfs'..."
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 "Done!"
COMMAND echo "---------------------------------------------"
@@ -49,7 +84,6 @@ elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
endif ()
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
SET(EMULATOR_FS -initrd initfs)
+94 -6
View File
@@ -36,6 +36,9 @@ Main Developers:
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:
* nasm
@@ -47,17 +50,44 @@ For compiling the main system:
To run and try:
* qemu-system-x86
* qemu-system-i386
For debugging:
* ccmake
* gdb or cgdb
* cgdb
* 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
-----------------
Compile and boot MentOS with qemu:
Compile and boot MentOS with qemu in Unix systems:
```
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.
**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
-----------------
@@ -80,6 +116,23 @@ MentOS provides three different scheduling algorithms:
* Completely Fair Scheduling
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
cmake ..
@@ -107,13 +160,23 @@ make
make qemu
```
Enable to Buddy System
Enable Buddy System
-----------------
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
cmake ..
@@ -150,6 +213,31 @@ make
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
-----------------
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 |
|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
| 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
| 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 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 | - | - |
| 5 | sys_open | fs/open.c | const char * | int | int | - | - |
| 6 | sys_close | fs/open.c | unsigned int | - | - | - | - |
| 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
| 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
| 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
| 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
| 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
| 13 | sys_time | kernel/time.c | int * | - | - | - | - |
| 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
| 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
| 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
| 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
| 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
| 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
| 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
| 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
| 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
| 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
| 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
| 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
| 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
| 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
| 33 | sys_access | fs/open.c | const char * | int | - | - | - |
| 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
| 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
| 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
| 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
| 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
| 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
| 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
| 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
| 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
| 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
| 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
| 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
| 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
| 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
| 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
| 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
| 52 | sys_umount | fs/super.c | char * | int | - | - | - |
| 54 | sys_ioctl | fs/ioctl.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 | - | - | - |
| 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
| 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
| 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
| 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
| 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
| 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
| 65 | sys_getpgrp | 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 * | - | - |
| 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
| 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
| 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
| 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
| 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
| 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
| 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
| 75 | sys_setrlimit | 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 * | - | - | - |
| 78 | sys_gettimeofday | 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 * | - | - | - |
| 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
| 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
| 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
| 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
| 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
| 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
| 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
| 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
| 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
| 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
| 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
| 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
| 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
| 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
| 99 | sys_statfs | fs/open.c | const char * | 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 | - | - |
| 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
| 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
| 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
| 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
| 106 | sys_newstat | 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 * | - | - | - |
| 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
| 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
| 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
| 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
| 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 * | - |
| 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
| 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
| 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
| 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
| 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
| 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
| 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
| 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
| 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 * | - | - |
| 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
| 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
| 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
| 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
| 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
| 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
| 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
| 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
| 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
| 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
| 138 | sys_setfsuid | kernel/sys.c | uid_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 |
| 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 * |
| 143 | sys_flock | fs/locks.c | unsigned int | unsigned 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 | - | - |
| 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
| 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
| 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
| 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
| 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
| 154 | sys_sched_setparam | 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 * | - | - |
| 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
| 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
| 159 | sys_sched_get_priority_max | 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 * | - | - | - |
| 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
| 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 | - | - |
| 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
| 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 * |
| 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
| 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
| 170 | sys_setresgid | 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 |
| 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 | - |
| 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 | - | - | - |
| 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 * | - | - |
| 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 | - |
| 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 | - | - |
| 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
| 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 | - | - | - |
| 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 | - |
| 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| | | | | | | | |
| S | EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
|:--|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
| 1 | 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
| | 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 1 | 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
| 1 | 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
| 1 | 5 | sys_open | fs/open.c | const char * | int | int | - | - |
| 1 | 6 | sys_close | fs/open.c | int | - | - | - | - |
| 1 | 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
| | 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
| | 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
| | 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
| 1 | 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| 1 | 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
| | 13 | sys_time | kernel/time.c | int * | - | - | - | - |
| | 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
| | 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
| | 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
| 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 | - | - |
| 1 | 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
| | 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
| | 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
| | 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
| | 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
| | 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
| | 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
| | 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
| | 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
| | 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
| | 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
| | 33 | sys_access | fs/open.c | const char * | int | - | - | - |
| 1 | 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
| | 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
| | 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
| | 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
| 1 | 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
| | 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
| | 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
| | 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
| | 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
| | 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
| | 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
| | 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
| | 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
| | 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
| | 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
| | 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
| | 52 | sys_umount | fs/super.c | char * | int | - | - | - |
| | 54 | sys_ioctl | fs/ioctl.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 | - | - | - |
| | 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
| | 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
| | 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
| | 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
| | 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
| 1 | 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
| | 65 | sys_getpgrp | 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 * | - | - |
| | 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
| | 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
| | 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
| | 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
| | 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
| | 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
| | 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
| | 75 | sys_setrlimit | 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 * | - | - | - |
| | 78 | sys_gettimeofday | 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 * | - | - | - |
| | 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
| | 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
| | 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
| | 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
| | 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
| | 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
| 1 | 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
| 1 | 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
| | 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
| | 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
| | 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
| | 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
| | 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
| | 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
| | 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
| | 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
| | 99 | sys_statfs | fs/open.c | const char * | 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 | - | - |
| | 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
| | 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
| | 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
| | 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
| | 106 | sys_newstat | 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 * | - | - | - |
| | 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
| | 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
| | 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
| | 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
| | 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 * | - |
| | 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
| | 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
| | 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
| | 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
| | 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
| | 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
| | 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
| | 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
| | 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
| | 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
| | 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 * | - | - |
| | 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
| | 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
| | 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
| | 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
| | 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
| | 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
| | 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
| | 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
| | 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
| | 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
| | 138 | sys_setfsuid | kernel/sys.c | uid_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 |
| | 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 * |
| | 143 | sys_flock | fs/locks.c | unsigned int | unsigned 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 | - | - |
| | 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
| | 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
| | 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
| | 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
| | 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| | 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
| | 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
| | 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
| | 154 | sys_sched_setparam | 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 * | - | - |
| | 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
| | 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
| | 159 | sys_sched_get_priority_max | 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 * | - | - | - |
| | 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
| | 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 | - | - |
| | 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
| | 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 * |
| | 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
| | 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
| | 170 | sys_setresgid | 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 |
| | 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 | - |
| | 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 | - | - | - |
| | 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 * | - | - |
| | 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 | - |
| | 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 | - | - |
| 1 | 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
| | 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 | - | - | - |
| | 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 | - |
| 1 | 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(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(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} -std=gnu99")
# ------------------------------------------------------------------------------
# Add the includes.
include_directories(inc)
# ------------------------------------------------------------------------------
# Add the source files.
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 <stdlib.h>
#include <string.h>
#include <initfscp.h>
#include <stdbool.h>
#include <stdint.h>
#include <libgen.h>
#include <dirent.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 initrd_file_t headers[MAX_FILES];
static char mount_points[MAX_FILES][MAX_FILENAME_LENGTH];
static initrd_file_t headers[INITFSCP_MAX_FILES];
static char mount_points[INITFSCP_MAX_FILES][INITFSCP_NAME_MAX];
static int mountpoint_idx = 0;
static int header_idx = 0;
static int header_offset = 0;
@@ -91,9 +135,9 @@ static bool open_target_fs(int argc, char *argv[])
static bool init_headers()
{
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;
memset(headers[i].fileName, 0, MAX_FILENAME_LENGTH);
memset(headers[i].fileName, 0, INITFSCP_NAME_MAX);
headers[i].file_type = 0;
headers[i].uid = 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)
{
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];
memset(absolute_path, 0, 256);
@@ -288,7 +332,8 @@ int main(int argc, char *argv[])
// ------------------------------------------------------------------------
// 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");
for (uint32_t i = 1; i < argc; ++i) {
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
+51 -12
View File
@@ -1,10 +1,17 @@
# ------------------------------------------------------------------------------
# Initialize the project.
project(MentOs C ASM)
set(PROJECT_NAME MentOs)
# ------------------------------------------------------------------------------
# Set the project name.
set(PROJECT_NAME MentOs)
# Add operating system specific option.
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
@@ -63,6 +70,16 @@ else (ENABLE_BUDDY_SYSTEM)
message(STATUS "Buddy system disabled.")
endif (ENABLE_BUDDY_SYSTEM)
# ------------------------------------------------------------------------------
# Add the option to enable deadlock prevention.
option(ENABLE_DEADLOCK_PREVENTION "Enables the buddy system" OFF)
if (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Enabling deadlock prevention.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_DEADLOCK_PREVENTION")
else (ENABLE_DEADLOCK_PREVENTION)
message(STATUS "Deadlock prevention disabled.")
endif (ENABLE_DEADLOCK_PREVENTION)
# ------------------------------------------------------------------------------
# Set the compiler options (original).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
@@ -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} -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")
@@ -137,13 +158,11 @@ endif (CMAKE_BUILD_TYPE MATCHES "Release")
# ------------------------------------------------------------------------------
# Set the assembly flags.
enable_language(ASM)
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> <SOURCE> -o <OBJECT>")
# ------------------------------------------------------------------------------
# Add the includes.
@@ -162,6 +181,8 @@ include_directories(
inc/mem
inc/misc
inc/sys
inc/experimental
inc/experimental/math
inc/system
inc/process
inc/elf
@@ -188,10 +209,18 @@ set(SOURCE_FILES
src/drivers/keyboard/keyboard.c
src/drivers/keyboard/keymap.c
src/experimental/smart_sem_kernel.c
src/experimental/smart_sem_user.c
src/experimental/resource.c
src/experimental/math/arr_math.c
src/fs/fcntl.c
src/fs/initrd.c
src/fs/vfs.c
src/fs/read_write.c
src/fs/open.c
src/fs/stat.c
src/fs/readdir.c
src/sys/module.c
src/sys/unistd.c
@@ -204,6 +233,7 @@ set(SOURCE_FILES
src/kernel/sys.c
src/libc/assert.c
src/libc/ctype.c
src/libc/stdio.c
src/libc/string.c
@@ -236,6 +266,9 @@ set(SOURCE_FILES
src/libc/unistd/waitpid.c
src/libc/unistd/chdir.c
src/libc/unistd/getcwd.c
src/libc/unistd/close.c
src/libc/unistd/stat.c
src/libc/unistd/mkdir.c
src/mem/kheap.c
src/mem/paging.c
@@ -245,9 +278,7 @@ set(SOURCE_FILES
src/misc/clock.c
src/misc/debug.c
src/sys/dirent.c
src/sys/stat.c
src/sys/utsname.c
#src/sys/shm.c
src/elf/elf.c
src/descriptor_tables/gdt.c
@@ -297,6 +328,7 @@ set(SOURCE_FILES
src/ui/command/cmd_ipcs.c
src/ui/command/cmd_ipcrm.c
src/ui/command/cmd_nice.c
src/ui/command/cmd_deadlock.c
src/ui/init/init.c
@@ -310,6 +342,13 @@ if (ENABLE_BUDDY_SYSTEM MATCHES "ON")
src/mem/buddysystem.c)
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
if (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
set(SOURCE_FILES
${SOURCE_FILES}
src/experimental/deadlock_prevention.c
src/experimental/deadlock_simulation.c)
endif (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
# ------------------------------------------------------------------------------
# Add the executable.
add_library(${PROJECT_NAME} ${SOURCE_FILES})
@@ -319,7 +358,7 @@ add_library(${PROJECT_NAME} ${SOURCE_FILES})
add_custom_command(
TARGET MentOs
POST_BUILD
COMMAND $(LD)
COMMAND ${CMAKE_LINKER}
-melf_i386
-static
--oformat elf32-i386
+22 -14
View File
@@ -7,20 +7,26 @@
[BITS 32] ; All instructions should be 32-bit.
[EXTERN kmain] ; The start point of our C code
; Grub is informed with this flag to load
; the kernel and kernel modules on a page boundary.
MBOOT_PAGE_ALIGN equ 1<<0
; Grub is informed with this flag to provide the kernel
; with memory information.
MBOOT_MEM_INFO equ 1<<1
; This is the multiboot magic value.
MBOOT_HEADER_MAGIC equ 0x1BADB002
; The magic field should contain this.
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
; This should be in %eax.
MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
; = Specify what GRUB should PROVIDE =========================================
; Align the kernel and kernel modules on i386 page (4KB) boundaries.
MULTIBOOT_PAGE_ALIGN equ 0x00000001
; Provide the kernel with memory information.
MULTIBOOT_MEMORY_INFO equ 0x00000002
; Must pass video information to OS.
MULTIBOOT_VIDEO_MODE equ 0x00000004
; -----------------------------------------------------------------------------
; This is the flag combination that we prepare for Grub
; to read at kernel load time.
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
; 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
; reserve (1024*1024) for the stack on a doubleword boundary
@@ -33,9 +39,12 @@ section .multiboot_header
align 4
; This is the GRUB Multiboot header.
multiboot_header:
dd MBOOT_HEADER_MAGIC
dd MBOOT_HEADER_FLAGS
dd MBOOT_CHECKSUM
; magic
dd MULTIBOOT_HEADER_MAGIC
; flags
dd MULTIBOOT_HEADER_FLAGS
; checksum
dd MULTIBOOT_CHECKSUM
; -----------------------------------------------------------------------------
; SECTION (data)
@@ -61,7 +70,6 @@ kernel_entry:
mov esp, stack_top
; pass the initial ESP
push esp
;mov ebp, esp
; pass Multiboot info structure
push ebx
; pass Multiboot magic number
+3 -7
View File
@@ -36,8 +36,7 @@
*/
/// @brief This structure describes one interrupt gate.
typedef struct idt_descriptor_t
{
typedef struct idt_descriptor_t {
unsigned short offset_low;
unsigned short seg_selector;
// This will ALWAYS be set to 0.
@@ -49,8 +48,7 @@ typedef struct idt_descriptor_t
} __attribute__((packed)) idt_descriptor_t;
/// @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).
unsigned short int limit;
/// The start address of the IDT.
@@ -65,9 +63,7 @@ void init_idt();
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
/// @param seg_sel Il selettore del segmento della GDT.
void idt_set_gate(uint8_t index,
interrupt_handler_t handler,
uint16_t options,
void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
uint8_t seg_sel);
//==== List of exceptions generated internally by the CPU ======================
+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)
{
return 0x80000000 | (pci_extract_bus(device) << 16) |
(pci_extract_slot(device) << 11) |
(pci_extract_func(device) << 8) | ((field)&0xFC);
(pci_extract_slot(device) << 11) | (pci_extract_func(device) << 8) |
((field)&0xFC);
}
// 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.
#define O_RDONLY 0x00
/// Open for writing only.
#define O_WRONLY 0x01
/// Open for reading and writing.
#define O_RDWR 0x02
/// If the file exists, this flag has no effect. Otherwise, the file is created.
#define O_CREAT 0x40
/// The file offset will be set to the end of the file prior to each write.
#define O_APPEND 0x400
/// @brief 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.
/// @param pathname A path to a file.
/// @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.
int magic;
/// The name of the file.
char fileName[MAX_FILENAME_LENGTH];
char fileName[NAME_MAX];
/// The type of the file.
short int file_type;
/// 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 "dirent.h"
#define PATH_SEPARATOR '/'
#define PATH_SEPARATOR_STRING "/"
#define PATH_UP ".."
#define PATH_DOT "."
/// Identifies a file.
#define FS_FILE 0x01
#define FS_FILE 0x01U
/// Identifies a directory.
#define FS_DIRECTORY 0x02
#define FS_DIRECTORY 0x02U
/// Identifies a character devies.
#define FS_CHARDEVICE 0x04
#define FS_CHARDEVICE 0x04U
/// Identifies a block devies.
#define FS_BLOCKDEVICE 0x08
#define FS_BLOCKDEVICE 0x08U
/// Identifies a pipe.
#define FS_PIPE 0x10
#define FS_PIPE 0x10U
/// Identifies a symbolic link.
#define FS_SYMLINK 0x20
#define FS_SYMLINK 0x20U
/// Identifies a mount-point.
#define FS_MOUNTPOINT 0x40
#define FS_MOUNTPOINT 0x40U
/// Function used to open a directory.
typedef DIR *(*opendir_callback)(const char *);
@@ -103,7 +102,7 @@ typedef struct mountpoint_t {
/// The id of the mountpoint.
int32_t mp_id;
/// Name of the mountpoint.
char mountpoint[MAX_FILENAME_LENGTH];
char mountpoint[NAME_MAX];
/// Maschera dei permessi.
unsigned int pmask;
/// User ID.
-9
View File
@@ -12,18 +12,9 @@
#include "stdbool.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.
#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
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
#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 line The line inside the file.
/// @param function The function where the assertion is.
static void __assert_fail(const char *assertion, const char *file,
unsigned int line, 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);
}
void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *function);
/// @brief Assert function.
#define assert(expression) \
+6
View File
@@ -39,3 +39,9 @@
/// Maximum value a `signed long int' can hold.
#define LONG_MIN (-LONG_MAX - 1L)
/// Maximum number of characters in a file name.
#define NAME_MAX 255
/// Maximum number of characters in a path name.
#define PATH_MAX 4096
+3 -7
View File
@@ -9,8 +9,7 @@
#include "stddef.h"
/// @brief Structure used to implement the list_head data structure.
typedef struct list_head
{
typedef struct list_head {
/// @brief The previous element.
struct list_head *prev;
/// @brief The subsequent element.
@@ -46,8 +45,7 @@ typedef struct list_head
/// @brief Initializes the list_head.
/// @param head The head for your list.
#define list_head_init(head) \
(head)->next = (head)->prev = (head)
#define list_head_init(head) (head)->next = (head)->prev = (head)
/// @brief Insert element l2 after l1.
static inline void list_head_insert_after(list_head *l1, list_head *l2)
@@ -104,9 +102,7 @@ static inline int list_head_empty(list_head const * head)
}
/// Insert a new entry between two known consecutive entries.
static inline void __list_add(list_head * new,
list_head * prev,
list_head * next)
static inline void __list_add(list_head *new, list_head *prev, list_head *next)
{
// [prev]-> <-[new]-> <-[next]
+2 -4
View File
@@ -10,8 +10,7 @@
#include "stdbool.h"
/// @brief A node of the queue.
typedef struct queue_node_t
{
typedef struct queue_node_t {
/// The wrapped data.
void *data;
/// The next node of the queue.
@@ -19,8 +18,7 @@ typedef struct queue_node_t
} queue_node_t;
/// @brief The queue.
typedef struct queue_t
{
typedef struct queue_t {
/// The front of the queue.
queue_node_t *front;
/// The back of the queue.
+2
View File
@@ -11,6 +11,8 @@
/// @brief The maximum number of digits of an integer.
#define MAX_DIGITS_IN_INTEGER 11
/// @brief The size of 'gets' buffer.
#define GETS_BUFFERSIZE 255
#ifndef EOF
/// @brief Define the End-Of-File.
+14 -17
View File
@@ -11,29 +11,26 @@
/// @brief Malloc based on the number of elements.
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 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.
#define RAND_MAX ((1U << 31) - 1)
/// The maximum value returned by the rand function.
#define RAND_MAX ((1U << 31U) - 1U)
/// @brief Allows to set the seed of the random value generator.
void srand(int x);
/// @brief Generates a random value.
int rand();
// 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
void *krealloc(void *ptr, unsigned int size);
/// @brief Allocate a matrix with n rows of a specific size.
/// @param n Number of matrix rows.
/// @param size Size of each matrix row.
/// @return Matrix pointer.
void **kmmalloc(size_t n, size_t size);
/// @brief Wrapper function for free.
/// @param p
void kfree(void *p);
/// @brief Free a matrix of n rows.
/// @param src Matrix to free.
/// @param n Number of matrix rows.
void kmfree(void **src, size_t n);
/// @brief Allocates size bytes of uninitialized storage.
//void *malloc(unsigned int size);
+43 -60
View File
@@ -10,42 +10,45 @@
#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
#define MULTIBOOT_FLAG_CMDLINE 0x004
#define MULTIBOOT_FLAG_MODS 0x008
#define MULTIBOOT_FLAG_AOUT 0x010
#define MULTIBOOT_FLAG_ELF 0x020
#define MULTIBOOT_FLAG_MMAP 0x040
#define MULTIBOOT_FLAG_CONFIG 0x080
#define MULTIBOOT_FLAG_LOADER 0x100
#define MULTIBOOT_FLAG_APM 0x200
#define MULTIBOOT_FLAG_VBE 0x400
/// Is there basic lower/upper memory information?
#define MULTIBOOT_FLAG_MEM 0x00000001U
/// is there a boot device set?
#define MULTIBOOT_FLAG_DEVICE 0x00000002U
/// is the command-line defined?
#define MULTIBOOT_FLAG_CMDLINE 0x00000004U
/// are there modules to do something with?
#define MULTIBOOT_FLAG_MODS 0x00000008U
/// is there a symbol table loaded?
#define MULTIBOOT_FLAG_AOUT 0x00000010U
/// is there an ELF section header table?
#define MULTIBOOT_FLAG_ELF 0x00000020U
/// is there a full memory map?
#define MULTIBOOT_FLAG_MMAP 0x00000040U
/// Is there drive info?
#define MULTIBOOT_FLAG_DRIVE_INFO 0x00000080U
/// Is there a config table?
#define MULTIBOOT_FLAG_CONFIG_TABLE 0x00000100U
/// Is there a boot loader name?
#define MULTIBOOT_FLAG_BOOT_LOADER_NAME 0x00000200U
/// Is there a APM table?
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
/// Is there video information?
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
// +-------------------+
@@ -93,8 +96,7 @@
// +-------------------+
/// The symbol table for a.out.
typedef struct multiboot_aout_symbol_table
{
typedef struct multiboot_aout_symbol_table {
uint32_t tabsize;
uint32_t strsize;
uint32_t addr;
@@ -102,8 +104,7 @@ typedef struct multiboot_aout_symbol_table
} multiboot_aout_symbol_table_t;
/// 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 size;
uint32_t addr;
@@ -111,8 +112,7 @@ typedef struct multiboot_elf_section_header_table
} multiboot_elf_section_header_table_t;
// 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.
uint32_t mod_start;
uint32_t mod_end;
@@ -122,18 +122,17 @@ typedef struct multiboot_mod_list
uint32_t pad;
} multiboot_module_t;
// TODO: doxygen comment.
typedef struct multiboot_mmap_entry
{
typedef struct multiboot_memory_map {
uint32_t size;
uint64_t addr;
uint64_t len;
uint32_t base_addr_low;
uint32_t base_addr_high;
uint32_t length_low;
uint32_t length_high;
uint32_t type;
} __attribute__((packed)) multiboot_memory_map_t;
} multiboot_memory_map_t;
// TODO: doxygen comment.
typedef struct multiboot_info
{
typedef struct multiboot_info {
/// Multiboot info version number.
uint32_t flags;
@@ -151,8 +150,7 @@ typedef struct multiboot_info
uint32_t mods_count;
uint32_t mods_addr;
union
{
union {
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
@@ -188,15 +186,12 @@ typedef struct multiboot_info
uint32_t framebuffer_height;
uint32_t framebuffer_bpp;
uint32_t framebuffer_type;
union
{
struct
{
union {
struct {
uint32_t framebuffer_palette_addr;
uint16_t framebuffer_palette_num_colors;
};
struct
{
struct {
uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position;
@@ -207,17 +202,5 @@ typedef struct multiboot_info
};
} __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.
void dump_multiboot(multiboot_info_t *mboot_ptr);
+8 -13
View File
@@ -17,6 +17,7 @@
#include "unistd.h"
#include "list_head.h"
#include "signal_defs.h"
#include "limits.h"
/// The maximum length of a name for a task_struct.
#define TASK_NAME_MAX_LENGTH 100
@@ -24,6 +25,9 @@
/// The default dimension of the stack of a process (1 MByte).
#define DEFAULT_STACK_SIZE 0x100000
/// The maximum number of resources for a task.
#define TASK_RESOURCE_MAX_AMOUNT 32
//==== Task state ==============================================================
// Used in tsk->state
/// The task is running.
@@ -170,7 +174,10 @@ typedef struct task_struct {
int error_no;
/// 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 =========================================================
// - task's attributes:
@@ -195,20 +202,8 @@ typedef struct task_struct {
} task_struct;
/// @brief Create a child process.
pid_t sys_vfork(pt_regs *r);
// TODO: doxygen comment.
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.
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
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.
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
#include "stddef.h"
/// The maximum length for a name.
#define NAME_MAX 30
#include "limits.h"
/// @brief Contains the entries of a directory.
typedef struct dirent_t
{
typedef struct dirent_t {
/// The inode of the entry.
ino_t d_ino;
@@ -25,17 +22,13 @@ typedef struct dirent_t
} dirent_t;
/// @brief Contains information concerning a directory.
typedef struct DIR
{
typedef struct DIR {
/// Filesystem directory handle.
int handle;
int fd;
/// The currently opened entry.
ino_t cur_entry;
/// Path to the directory.
char path[NAME_MAX + 1];
/// Next directory item.
dirent_t entry;
} DIR;
-1
View File
@@ -38,5 +38,4 @@ typedef struct stat_t
/// @return Returns a negative value on failure.
int stat(const char *path, stat_t *buf);
// TODO: doxygen comment.
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);
/// @brief Close a file descriptor.
/// @param fildes The file descriptor.
/// @param fd The file descriptor.
/// @return The result of the operation.
int close(int fildes);
int close(int fd);
/// @brief Removes the given directory.
/// @param path The path to the directory to remove.
+1 -2
View File
@@ -10,8 +10,7 @@
#define SYS_LEN 257
/// @brief Holds information concerning the machine and the os.
typedef struct utsname_t
{
typedef struct utsname_t {
/// The name of the system.
char sysname[SYS_LEN];
+52 -381
View File
@@ -6,7 +6,11 @@
#pragma once
#include "syscall_types.h"
#include "kernel.h"
#include "dirent.h"
#include "types.h"
#include "stat.h"
/// @brief Initialize the system calls.
void syscall_init();
@@ -14,400 +18,67 @@ void syscall_init();
/// @brief Handler for the system calls.
void syscall_handler(pt_regs *r);
// Return result in eax ("=a").
// System call number in eax ("a").
#define DEFN_SYSCALL0(__res, num) \
__asm__ __volatile__("INT $0x80" : "=a"(__res) : "a"(num))
/// The exit() function causes normal process termination.
void sys_exit(int exit_code);
// 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))
/// @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);
#define DEFN_SYSCALL2(__res, num, p1, p2) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2) \
: "a"(num));
/// @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);
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \
__asm__ __volatile__("INT $0x80" \
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \
: "a"(num))
/// @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);
#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))
/// @brief
/// @param fd
/// @return
int sys_close(int fd);
#define DEFN_SYSCALL5(fn, num, P1, P2, P3, P4, P5) \
int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
{ \
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; \
}
/// @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);
#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
#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
//-----------------------------------------------------------------------------
dirent_t *sys_readdir(DIR *dirp);
+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.
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 "kernel.h"
#include "limits.h"
/// Maximum length of credentials.
#define CREDENTIALS_LENGTH 50
@@ -55,7 +56,7 @@ typedef struct userenv_t
char username[CREDENTIALS_LENGTH];
/// The current path.
char cur_path[MAX_PATH_LENGTH];
char cur_path[PATH_MAX];
/// The user identifier.
unsigned int uid;
+16 -30
View File
@@ -98,16 +98,14 @@ struct {
{ 0x010105, "PCI native mode-only controller" },
{ 0x01010a, "ISA Compatibility mode controller, supports both channels "
"switched to PCI native mode" },
{ 0x01010f,
"PCI native mode controller, supports both channels switched "
{ 0x01010f, "PCI native mode controller, supports both channels switched "
"to ISA compatibility mode" },
{ 0x010180,
"ISA Compatibility mode-only controller, supports bus mastering" },
{ 0x010185, "PCI native mode-only controller, supports bus mastering" },
{ 0x01018a, "ISA Compatibility mode controller, supports both channels "
"switched to PCI native mode, supports bus mastering" },
{ 0x01018f,
"PCI native mode controller, supports both channels switched "
{ 0x01018f, "PCI native mode controller, supports both channels switched "
"\to ISA compatibility mode, supports bus mastering" },
{ 0x010200, "Floppy disk controller" },
@@ -154,10 +152,8 @@ struct {
{ 0x060600, "NuBus bridge" },
{ 0x060700, "CardBus bridge" },
// { 0x0608xx , "RACEway bridge" },
{ 0x060940,
"PCI-to-PCI bridge, Semi-transparent, primary facing Host" },
{ 0x060980,
"PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
{ 0x060940, "PCI-to-PCI bridge, Semi-transparent, primary facing Host" },
{ 0x060980, "PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
{ 0x060A00, "InfiniBand-to-PCI host bridge" },
{ 0x068000, "Bridge device" },
@@ -273,8 +269,7 @@ struct {
const char *pci_vendor_lookup(unsigned short vendor_id)
{
for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]);
++i) {
for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]); ++i) {
if (_pci_vendors[i].id == vendor_id) {
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,
unsigned short device_id)
{
for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]);
++i) {
for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]); ++i) {
if (_pci_devices[i].ven_id == vendor_id &&
_pci_devices[i].dev_id == device_id) {
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)
{
for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]);
++i) {
for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]); ++i) {
if (_pci_classes[i].id == class_code) {
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);
}
if (pci_find_type(dev) == PCI_TYPE_BRIDGE) {
pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1),
extra);
pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1), extra);
}
}
@@ -423,8 +415,7 @@ int pci_get_interrupt(uint32_t device)
uint32_t int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1);
dbg_print(
"Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?"
dbg_print("Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?"
"int_line=%d\n",
pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq],
int_line);
@@ -455,8 +446,8 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
void *extra)
{
(void)extra;
dbg_print("%2x:%2x.%d\n", pci_extract_bus(device),
pci_extract_slot(device), pci_extract_func(device), deviceid);
dbg_print("%2x:%2x.%d\n", pci_extract_bus(device), pci_extract_slot(device),
pci_extract_func(device), deviceid);
dbg_print(" Vendor : [0x%06x] %s\n", vendorid,
pci_vendor_lookup(vendorid));
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));
dbg_print(" Header Type : %2d\n",
pci_read_field(device, PCI_HEADER_TYPE, 1));
dbg_print(" BIST : %2d\n",
pci_read_field(device, PCI_BIST, 1));
dbg_print(" BAR0 : 0x%08x",
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(" BIST : %2d\n", pci_read_field(device, PCI_BIST, 1));
dbg_print(" BAR0 : 0x%08x", 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",
pci_read_field(device, PCI_BASE_ADDRESS_2, 4));
dbg_print(" BAR3 : 0x%08x",
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(" BAR3 : 0x%08x", 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(" BAR6 : 0x%08x\n",
pci_read_field(device, PCI_BASE_ADDRESS_5, 4));
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.
/// See LICENSE.md for details.
#include "vfs.h"
#include "debug.h"
#include "kheap.h"
#include "shell.h"
#include "errno.h"
#include "fcntl.h"
#include "string.h"
#include "kernel.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++);
}
#include "vfs.h"
#include "limits.h"
int remove(const char *pathname)
{
char absolute_path[MAX_PATH_LENGTH];
char absolute_path[PATH_MAX];
strcpy(absolute_path, pathname);
if (pathname[0] != '/')
{
if (pathname[0] != '/') {
get_absolute_path(absolute_path);
}
int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0)
{
if (mp_id < 0) {
return -1;
}
if (mountpoint_list[mp_id].operations.remove_f == NULL)
{
if (mountpoint_list[mp_id].operations.remove_f == NULL) {
return -1;
}
+3 -3
View File
@@ -84,7 +84,7 @@ DIR *initfs_opendir(const char *path)
}
DIR *pdir = kmalloc(sizeof(DIR));
pdir->handle = -1;
pdir->fd = -1;
pdir->cur_entry = 0;
strcpy(pdir->path, path);
@@ -217,7 +217,7 @@ int initrd_rmdir(const char *path)
}
// Remove the directory.
direntry->magic = 0;
memset(direntry->fileName, 0, MAX_FILENAME_LENGTH);
memset(direntry->fileName, 0, NAME_MAX);
direntry->file_type = 0;
direntry->uid = 0;
direntry->offset = 0;
@@ -320,7 +320,7 @@ int initfs_remove(const char *path)
// Remove the directory.
file->magic = 0;
memset(file->fileName, 0, MAX_FILENAME_LENGTH);
memset(file->fileName, 0, NAME_MAX);
file->file_type = 0;
file->uid = 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.
#include <misc/debug.h>
#include "read_write.h"
#include "vfs.h"
#include "stdio.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 "string.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.
buf->st_dev = 0;
@@ -23,7 +24,7 @@ int stat(const char *path, stat_t *buf)
buf->st_mtime = 0;
buf->st_ctime = 0;
char absolute_path[MAX_PATH_LENGTH];
char absolute_path[PATH_MAX];
strcpy(absolute_path, path);
if (path[0] != '/')
@@ -51,9 +52,9 @@ int stat(const char *path, stat_t *buf)
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);
int result = -1;
+5 -4
View File
@@ -12,6 +12,7 @@
#include "shell.h"
#include "string.h"
#include "initrd.h"
#include "limits.h"
int current_fd;
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)
{
char relative_path[MAX_PATH_LENGTH];
char relative_path[PATH_MAX];
// Get the size of the 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)
{
if (path[0] != '/') {
char abspath[MAX_PATH_LENGTH];
memset(abspath, '\0', MAX_PATH_LENGTH);
getcwd(abspath, MAX_PATH_LENGTH);
char abspath[PATH_MAX];
memset(abspath, '\0', PATH_MAX);
getcwd(abspath, PATH_MAX);
int abs_size = strlen(abspath);
if (abspath[abs_size - 1] == '/') {
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)
{
__asm__ ("cpuid\n\t" :
"=a" (registers->eax),
"=b" (registers->ebx),
"=c" (registers->ecx),
"=d" (registers->edx) :
"a" (registers->eax));
__asm__("cpuid\n\t"
: "=a"(registers->eax), "=b"(registers->ebx), "=c"(registers->ecx),
"=d"(registers->edx)
: "a"(registers->eax));
}
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);
switch (type)
{
switch (type) {
case 0:
cpuinfo->cpu_type = "Original OEM Processor";
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);
cpuinfo->cpu_family = familyID;
if (familyID == 0x0F)
{
if (familyID == 0x0F) {
cpuinfo->cpu_family += cpuid_get_byte(registers->eax, 0x13, 0xFF);
}
uint32_t model = cpuid_get_byte(registers->eax, 0x3, 0xE);
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);
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);
/* Get brand string to identify the processor */
if (familyID >= 0x0F && model >= 0x03)
{
if (familyID >= 0x0F && model >= 0x03) {
cpuinfo->brand_string = cpuid_brand_string(registers);
}
else
{
} else {
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 i;
for (i = 0; i < ECX_FLAGS_SIZE; ++i)
{
for (i = 0; i < ECX_FLAGS_SIZE; ++i) {
temp = cpuid_get_byte(temp, i, 1);
cpuinfo->cpuid_ecx_flags[i] = temp;
temp = ecx;
@@ -120,16 +111,14 @@ void cpuid_feature_edx(cpuinfo_t *cpuinfo, uint32_t edx)
uint32_t temp = edx;
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);
cpuinfo->cpuid_edx_flags[i] = temp;
temp = edx;
}
}
inline uint32_t cpuid_get_byte(const uint32_t reg,
const uint32_t position,
inline uint32_t cpuid_get_byte(const uint32_t reg, const uint32_t position,
const uint32_t value)
{
return ((reg >> position) & value);
@@ -161,8 +150,7 @@ char *cpuid_brand_index(register_t *r)
int bx = (r->ebx & 0xFF);
if (bx > 0x17)
{
if (bx > 0x17) {
bx = 0;
}
@@ -176,18 +164,17 @@ char *cpuid_brand_string(register_t *r)
{
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;
call_cpuid(r);
temp = strncat(temp, (const char *) r->eax,
strlen((const char *) r->eax));
temp = strncat(temp, (const char *) r->ebx,
strlen((const char *) r->ebx));
temp = strncat(temp, (const char *) r->ecx,
strlen((const char *) r->ecx));
temp = strncat(temp, (const char *) r->edx,
strlen((const char *) r->edx));
temp =
strncat(temp, (const char *)r->eax, strlen((const char *)r->eax));
temp =
strncat(temp, (const char *)r->ebx, strlen((const char *)r->ebx));
temp =
strncat(temp, (const char *)r->ecx, strlen((const char *)r->ecx));
temp =
strncat(temp, (const char *)r->edx, strlen((const char *)r->edx));
}
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)
{
__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)
+4 -10
View File
@@ -4,7 +4,6 @@
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys.h"
#include "stdio.h"
#include "errno.h"
#include "mutex.h"
@@ -13,8 +12,7 @@
static void machine_power_off()
{
while (true)
{
while (true) {
cpu_relax();
}
}
@@ -40,18 +38,14 @@ int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg)
// For safety, we require "magic" arguments.
if (magic1 != LINUX_REBOOT_MAGIC1 ||
(magic2 != LINUX_REBOOT_MAGIC2 &&
magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2B &&
magic2 != LINUX_REBOOT_MAGIC2C))
{
(magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2B && magic2 != LINUX_REBOOT_MAGIC2C)) {
return -EINVAL;
}
mutex_lock(&reboot_mutex, 0);
switch (cmd)
{
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
break;
case LINUX_REBOOT_CMD_CAD_ON:
+2 -7
View File
@@ -8,9 +8,7 @@
#include "stdio.h"
#include "panic.h"
void __assert_fail(const char *assertion,
const char *file,
unsigned int line,
void __assert_fail(const char *assertion, const char *file, unsigned int line,
const char *function)
{
char message[1024];
@@ -19,9 +17,6 @@ void __assert_fail(const char *assertion,
"LINE: %d\n"
"FUNC: %s\n\n"
"Assertion `%s` failed.\n",
file,
line,
(function ? function : "NO_FUN"),
assertion);
file, line, (function ? function : "NO_FUN"), assertion);
kernel_panic(message);
}
+26 -53
View File
@@ -8,15 +8,13 @@
#include "string.h"
#include "stdlib.h"
struct hashmap_entry_t
{
struct hashmap_entry_t {
char *key;
void *value;
struct hashmap_entry_t *next;
};
struct hashmap_t
{
struct hashmap_t {
hashmap_hash_t hash_func;
hashmap_comp_t hash_comp;
hashmap_dupe_t hash_key_dup;
@@ -31,15 +29,11 @@ size_t hashmap_string_hash(void *_key)
size_t hash = 0;
char *key = (char *)_key;
int c;
/*
* This is the so-called "sdbm" hash. It comes from a piece of public
* domain code from a clone of ndbm.
*/
while ((c = *key++))
{
// This is the so-called "sdbm" hash. It comes from a piece of public
// domain code from a clone of ndbm.
while ((c = *key++)) {
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
@@ -109,11 +103,9 @@ hashmap_t *hashmap_create_int(size_t size)
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;
while (x)
{
while (x) {
p = x;
x = x->next;
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;
hashmap_entry_t *x = map->entries[hash];
if (x == NULL)
{
if (x == NULL) {
hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t));
e->key = map->hash_key_dup(key);
e->value = value;
@@ -142,10 +133,8 @@ void *hashmap_set(hashmap_t *map, void *key, void *value)
hashmap_entry_t *p = NULL;
do
{
if (map->hash_comp(x->key, key))
{
do {
if (map->hash_comp(x->key, key)) {
void *out = x->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;
hashmap_entry_t *x = map->entries[hash];
if (x == NULL)
{
if (x == NULL) {
return NULL;
}
do
{
if (map->hash_comp(x->key, key))
{
do {
if (map->hash_comp(x->key, key)) {
return x->value;
}
x = x->next;
@@ -190,12 +176,10 @@ void *hashmap_remove(hashmap_t *map, void *key)
size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t *x = map->entries[hash];
if (x == NULL)
{
if (x == NULL) {
return NULL;
}
if (map->hash_comp(x->key, key))
{
if (map->hash_comp(x->key, key)) {
void *out = x->value;
map->entries[hash] = x->next;
map->hash_key_free(x->key);
@@ -206,10 +190,8 @@ void *hashmap_remove(hashmap_t *map, void *key)
hashmap_entry_t *p = x;
x = x->next;
do
{
if (map->hash_comp(x->key, key))
{
do {
if (map->hash_comp(x->key, key)) {
void *out = x->value;
p->next = x->next;
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)
{
for (size_t i = 0; i < map->size; ++i)
{
if (map->entries[i])
{
for (size_t i = 0; i < map->size; ++i) {
if (map->entries[i]) {
return false;
}
}
@@ -242,14 +222,11 @@ bool_t hashmap_has(hashmap_t *map, void *key)
size_t hash = map->hash_func(key) % map->size;
hashmap_entry_t *x = map->entries[hash];
if (x == NULL)
{
if (x == NULL) {
return false;
}
do
{
if (map->hash_comp(x->key, key))
{
do {
if (map->hash_comp(x->key, key)) {
return true;
}
x = x->next;
@@ -262,11 +239,9 @@ list_t *hashmap_keys(hashmap_t *map)
{
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];
while (x)
{
while (x) {
list_insert_back(l, x->key);
x = x->next;
}
@@ -279,12 +254,10 @@ list_t *hashmap_values(hashmap_t *map)
{
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];
while (x)
{
while (x) {
list_insert_back(l, x->value);
x = x->next;
}
+10 -16
View File
@@ -7,11 +7,11 @@
#include "libgen.h"
#include "string.h"
#include "initrd.h"
#include "limits.h"
int parse_path(char *out, char **cur, char sep, size_t max)
{
if (**cur == '\0')
{
if (**cur == '\0') {
return 0;
}
@@ -19,8 +19,7 @@ int parse_path(char *out, char **cur, char sep, size_t max)
++*cur;
--max;
while ((max > 0) && (**cur != '\0') && (**cur != sep))
{
while ((max > 0) && (**cur != '\0') && (**cur != sep)) {
*out++ = **cur;
++*cur;
--max;
@@ -33,12 +32,13 @@ int parse_path(char *out, char **cur, char sep, size_t max)
char *dirname(const char *path)
{
static char s[MAX_PATH_LENGTH];
static char s[PATH_MAX];
static char dot[2] = ".";
// Check the input path.
if (path == NULL) return dot;
if (path == NULL)
return dot;
// Copy the path to the support string.
strcpy(s, path);
@@ -46,25 +46,19 @@ char *dirname(const char *path)
// Get the last occurrence of '/'.
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
// pointer to the last slash after it.
++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.
last_slash = memchr(s, '/', last_slash - s);
}
if (last_slash != NULL)
{
if (last_slash != NULL) {
// If we have found it, close the string.
last_slash[0] = '\0';
}
else
{
} else {
// Otherwise, return '.'.
return dot;
}
+13 -64
View File
@@ -10,58 +10,23 @@
double round(double x)
{
double out;
__asm__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x));
__asm__ __volatile__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x));
return out;
}
double floor(double x)
{
if (x > -1.0 && x < 1.0) {
if (x >= 0) {
if (x >= 0)
return 0.0;
} else {
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 out;
@@ -85,20 +50,13 @@ double pow(double x, double y)
return out;
}
#endif
long find_nearest_pow_greater(double base, double value)
{
if (base <= 1) {
if (base <= 1)
return -1;
}
long pow_value = 0;
while (pow(base, pow_value) < value) {
while (pow(base, pow_value) < value)
pow_value++;
}
return pow_value;
}
@@ -110,16 +68,14 @@ double exp(double x)
double fabs(double x)
{
double out;
__asm__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x));
__asm__ __volatile__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x));
return out;
}
double sqrt(double x)
{
double out;
__asm__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x));
__asm__ __volatile__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x));
return out;
}
@@ -130,8 +86,7 @@ int isinf(double x)
double f;
} ieee754;
ieee754.f = x;
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
return ((unsigned)(ieee754.u >> 32U) & 0x7fffffffU) == 0x7ff00000U &&
((unsigned)ieee754.u == 0);
}
@@ -142,7 +97,6 @@ int isnan(double x)
double f;
} ieee754;
ieee754.f = x;
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
((unsigned)ieee754.u != 0) >
0x7ff00000;
@@ -156,18 +110,15 @@ double log10(double x)
double ln(double x)
{
double out;
__asm__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x));
__asm__ __volatile__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x));
return out;
}
double logx(double x, double y)
{
// 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 ln(x) / ln(y);
}
@@ -176,7 +127,6 @@ double logx(double x, double y)
double modf(double x, double *intpart)
{
register double absvalue;
if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) {
// It must be an integer.
(*intpart) = x;
@@ -195,7 +145,6 @@ double modf(double x, double *intpart)
(*intpart) = -(*intpart);
}
}
// Signed fractional part.
return (x - (*intpart));
}
+7 -14
View File
@@ -27,8 +27,7 @@ ordered_array_t create_ordered_array(uint32_t max_size,
return to_ret;
}
ordered_array_t place_ordered_array(void * addr,
uint32_t max_size,
ordered_array_t place_ordered_array(void *addr, uint32_t max_size,
lessthan_predicate_t less_than)
{
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);
uint32_t iterator = 0;
while (iterator < array->size && array->less_than(array->array[iterator],
item))
{
while (iterator < array->size &&
array->less_than(array->array[iterator], item)) {
iterator++;
}
// Just add at the end of the array.
if (iterator == array->size)
{
if (iterator == array->size) {
array->array[array->size++] = item;
}
else
{
} else {
array_type_t tmp = array->array[iterator];
array->array[iterator] = item;
while (iterator < array->size)
{
while (iterator < array->size) {
iterator++;
array_type_t tmp2 = array->array[iterator];
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)
{
while (i < array->size)
{
while (i < array->size) {
array->array[i] = array->array[i + 1];
i++;
}
+4 -6
View File
@@ -13,20 +13,18 @@ void spinlock_init(spinlock_t *spinlock)
void spinlock_lock(spinlock_t *spinlock)
{
while (true)
{
if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0)
{
while (true) {
if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0) {
break;
}
while (*spinlock) cpu_relax();
while (*spinlock)
cpu_relax();
}
}
void spinlock_unlock(spinlock_t *spinlock)
{
barrier();
atomic_set(spinlock, SPINLOCK_FREE);
}
+33 -54
View File
@@ -22,7 +22,6 @@ void puts(char *str)
int getchar(void)
{
#if 1
char c;
while (true) {
read(STDIN_FILENO, &c, 1);
@@ -30,76 +29,56 @@ int getchar(void)
break;
}
return c;
#else
int tmpchar;
while ((tmpchar = keyboard_getc()) == -1)
;
return tmpchar;
#endif
}
char *gets(char *str)
{
int count = 0;
char tmp[255];
memset(tmp, '\0', 255);
do {
int c = getchar();
// Return Key.
if (c == '\n') {
// Check the input string.
if (str == NULL)
return NULL;
// Buffer for reading input.
char buffer[GETS_BUFFERSIZE];
memset(buffer, '\0', GETS_BUFFERSIZE);
// Char pointer to the buffer.
char *cptr = buffer;
// 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;
}
// Backspace key.
if (c == '\b') {
if (count > 0) {
count--;
// The character is stored at address, and the pointer is incremented.
*cptr++ = ch;
}
} else {
tmp[count++] = (char)c;
}
} while (count < 255);
tmp[count] = '\0';
/* tmp cant simply be returned, it is allocated in this stack frame and
* it will be lost!
*/
strcpy(str, tmp);
// Add the null-terminating character.
*cptr = '\0';
// Copy the string we have read.
strcpy(str, buffer);
// Return a pointer to the original string.
return str;
}
int atoi(const char *str)
{
// Initialize sign as positive.
int sign = 1;
// Check the input string.
if (str == NULL)
return 0;
// Initialize sign.
int sign = (str[0] == '-') ? -1 : +1;
// Initialize the result.
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.
for (i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i) {
if (!isdigit(str[i])) {
for (int i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i)
if (!isdigit(str[i]))
return -1;
}
}
// 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';
}
return sign * result;
}
@@ -129,7 +108,7 @@ size_t scanf(const char *format, ...)
for (; *format; format++) {
if (*format == '%') {
// Declare an input string.
char input[255];
char input[GETS_BUFFERSIZE];
// Get the input string.
gets(input);
// Evaluate the length of the string.
+21 -32
View File
@@ -8,11 +8,6 @@
#include "stdlib.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 *_res;
@@ -27,52 +22,46 @@ void free(void *p)
DEFN_SYSCALL1(_res, __NR_free, p);
}
void *calloc(size_t element_number, size_t element_size)
{
void *ptr = malloc(element_number * element_size);
if (ptr)
{
if (ptr) {
memset(ptr, 0, element_number * element_size);
}
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.
int rseed = 0;
static int rseed = 0;
inline void srand(int 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
/// between 0 and RAND_MAX.
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
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
strcpy(error,
"Address family not supported by protocol family");
strcpy(error, "Address family not supported by protocol family");
break;
#endif
#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);
if (retval < 0)
{
if (retval < 0) {
errno = -retval;
retval = -1;
}
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);
if (retval < 0)
{
if (retval < 0) {
errno = -retval;
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);
}
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)
{
__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.
/// @return The heap structure if heap exists, otherwise NULL.
static struct vm_area_struct *find_user_heap()
+161 -40
View File
@@ -7,74 +7,195 @@
#include "multiboot.h"
#include "bitops.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)
{
dbg_print("\n--------------------------------------------------\n");
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)) {
dbg_print("Mem Lo: 0x%x\n", mbi->mem_lower * K);
dbg_print("Mem Hi: 0x%x (%dMB)\n", mbi->mem_upper * K,
(mbi->mem_upper / 1024));
dbg_print("%-16s = %u Kb (%u Mb)\n", "mem_lower", mbi->mem_lower,
mbi->mem_lower / K);
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)) {
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)) {
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)) {
dbg_print("Mods : 0x%x\n", mbi->mods_count);
multiboot_module_t *mod = (multiboot_module_t *)mbi->mods_addr;
if (mbi->mods_count > 0) {
for (uint32_t i = 0; i < mbi->mods_count && i < MAX_MODULES;
i++, mod++) {
uint32_t start = mod->mod_start;
uint32_t end = mod->mod_end;
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
dbg_print("%-16s = %d\n", "mods_count", mbi->mods_count);
dbg_print("%-16s = 0x%x\n", "mods_addr", mbi->mods_addr);
multiboot_module_t *mod = first_module(mbi);
for (int i = 0; mod; ++i, mod = next_module(mbi, mod)) {
dbg_print(" [%2d] "
"mod_start = 0x%x, "
"mod_end = 0x%x, "
"cmdline = %s\n",
i, mod->mod_start, mod->mod_end, (char *)mod->cmdline);
}
}
// Bits 4 and 5 are mutually exclusive!
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT) &&
has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
kernel_panic("Both bits 4 and 5 are set.\n");
return;
}
/* Last implementation
for (uint32_t i = 0; i < mbi->mods_count; ++i)
{
// uint32_t start = *((uint32_t *) (mbi->mods_addr + 8 * i));
uint32_t start = mbi->mods_addr + 8 * i;
// uint32_t end = *((uint32_t *) (mbi->mods_addr + 8 * i + 4));
uint32_t end = mbi->mods_addr + 8 * i + 4;
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
}
*/
}
}
// Is the symbol table of a.out valid?
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT)) {
dbg_print("AOUT t : 0x%x\n", mbi->u.aout_sym.tabsize);
dbg_print("AOUT s : 0x%x\n", mbi->u.aout_sym.strsize);
dbg_print("AOUT a : 0x%x\n", mbi->u.aout_sym.addr);
dbg_print("AOUT r : 0x%x\n", mbi->u.aout_sym.reserved);
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
dbg_print("multiboot_aout_symbol_table: tabsize = 0x%0x, "
"strsize = 0x%x, addr = 0x%x\n",
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)) {
dbg_print("ELF n : 0x%x\n", mbi->u.elf_sec.num);
dbg_print("ELF s : 0x%x\n", mbi->u.elf_sec.size);
dbg_print("ELF a : 0x%x\n", mbi->u.elf_sec.addr);
dbg_print("ELF h : 0x%x\n", mbi->u.elf_sec.shndx);
multiboot_elf_section_header_table_t *multiboot_elf_sec =
&(mbi->u.elf_sec);
dbg_print("multiboot_elf_sec: num = %u, size = 0x%x,"
" 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("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("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);
}
if (has_flag(mbi->flags, MULTIBOOT_FLAG_VBE_INFO)) {
dbg_print("VBE Co: 0x%x\n", mbi->vbe_control_info);
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_info);
dbg_print("VBE In: 0x%x\n", mbi->vbe_mode);
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg);
dbg_print("VBE of: 0x%x\n", mbi->vbe_interface_off);
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
}
dbg_print("--------------------------------------------------\n");
dbg_print("\n");
}
+1 -1
View File
@@ -71,7 +71,7 @@ task_struct *create_init_process()
// Enable the interrupts.
init_proc->thread.eflags = init_proc->thread.eflags | EFLAG_IF;
// 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.
init_proc->state = TASK_RUNNING;
// Active the current process.
+12
View File
@@ -17,6 +17,7 @@
#include "rbtree.h"
#include "stdlib.h"
#include "list_head.h"
#include "deadlock_simulation.h"
/// @brief Assembly function setting the kernel stack to jump into
/// location in Ring 3 mode (USER mode).
@@ -68,6 +69,11 @@ void kernel_initialize_scheduler()
runqueue.curr = NULL;
// Reset the number of active tasks.
runqueue.num_active = 0;
#if ENABLE_DEADLOCK_PREVENTION
// Simulate deadlock.
deadlock_simulation();
#endif
}
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.
if (runqueue.num_active > 2) {
dbg_print("PID:%3d, PRIO:%3d, VRUNTIME:%9d, SUM_EXEC:%9d\n",
next_process->pid, next_process->se.prio,
next_process->se.vruntime, next_process->se.sum_exec_runtime);
}
#endif
//==== Context switch ======================================================
// Update the context of the current process.
@@ -377,6 +385,10 @@ void sys_exit(int exit_code)
}
// Free the space occupied by the stack.
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.
dbg_print("Process %d exited with value %d\n", runqueue.curr->pid,
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)
//==== 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)
+23 -37
View File
@@ -11,18 +11,19 @@
#include "stdio.h"
#include "initrd.h"
#include "debug.h"
#include "syscall_types.h"
#include "assert.h"
#include "errno.h"
DIR *opendir(const char *path)
{
char absolute_path[MAX_PATH_LENGTH];
char absolute_path[PATH_MAX];
DIR *pdir = NULL;
strcpy(absolute_path, path);
// If the first character is not the '/' then get the absolute path.
if (absolute_path[0] != '/')
{
if (!get_absolute_path(absolute_path))
{
if (absolute_path[0] != '/') {
if (!get_absolute_path(absolute_path)) {
dbg_print("Cannot get the absolute path.\n");
return NULL;
@@ -31,27 +32,26 @@ DIR *opendir(const char *path)
// Get the mount point id.
int32_t mp_id = get_mountpoint_id(absolute_path);
if (mp_id < 0)
{
if (mp_id < 0) {
printf("opendir: cannot open directory '%s':"
"Cannot find mount-point\n", absolute_path);
"Cannot find mount-point\n",
absolute_path);
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':"
"No opendir function\n", absolute_path);
"No opendir function\n",
absolute_path);
return NULL;
}
pdir = mountpoint_list[mp_id].dir_op.opendir_f(absolute_path);
// If the directiry is correctly open, set the handle.
if (pdir != NULL)
{
pdir->handle = mp_id;
if (pdir != NULL) {
pdir->fd = mp_id;
}
return pdir;
@@ -59,40 +59,26 @@ DIR *opendir(const char *path)
int closedir(DIR *dirp)
{
if (dirp == NULL)
{
if (dirp == NULL) {
printf("closedir: cannot close directory :"
"Directory pointer is not valid\n");
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':"
"No closedir function\n", dirp->path);
"No closedir function\n",
dirp->path);
return -1;
}
return mountpoint_list[dirp->handle].dir_op.closedir_f(dirp);
return mountpoint_list[dirp->fd].dir_op.closedir_f(dirp);
}
dirent_t *readdir(DIR *dirp)
{
if (dirp == NULL)
{
printf("readdir: cannot read directory :"
"Directory pointer is not valid\n");
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);
dirent_t *dent;
// Call the readdir system call.
DEFN_SYSCALL1(dent, __NR_readdir, dirp);
return dent;
}
+10 -39
View File
@@ -4,61 +4,32 @@
/// @copyright (c) 2019 This file is distributed under the MIT License.
/// 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"
int close(int fildes)
{
if (fildes < 0)
{
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;
}
#include "string.h"
#include "limits.h"
#include "stdio.h"
#include "vfs.h"
int rmdir(const char *path)
{
char absolute_path[MAX_PATH_LENGTH];
char absolute_path[PATH_MAX];
strcpy(absolute_path, path);
if (path[0] != '/')
{
if (path[0] != '/') {
get_absolute_path(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':"
"Cannot find mount-point\n", path);
"Cannot find mount-point\n",
path);
return -1;
}
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL)
{
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL) {
return -1;
}
+12 -3
View File
@@ -5,7 +5,6 @@
/// See LICENSE.md for details.
#include "syscall.h"
#include "sys.h"
#include "shm.h"
#include "isr.h"
#include "errno.h"
@@ -17,7 +16,8 @@
#include "process.h"
#include "irqflags.h"
#include "scheduler.h"
#include "read_write.h"
#include "smart_sem_kernel.h"
/// @brief The signature of a function call.
typedef int (*SystemCall)();
@@ -48,6 +48,10 @@ void syscall_init()
sys_call_table[__NR_read] = (SystemCall)sys_read;
sys_call_table[__NR_write] = (SystemCall)sys_write;
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_getppid] = (SystemCall)sys_getppid;
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_chdir] = (SystemCall)sys_chdir;
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_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");
}
+12 -24
View File
@@ -16,43 +16,32 @@
void cmd_cd(int argc, char **argv)
{
DIR *dirp = NULL;
char path[MAX_PATH_LENGTH];
memset(path, 0, MAX_PATH_LENGTH);
char path[PATH_MAX];
memset(path, 0, PATH_MAX);
char current_path[MAX_PATH_LENGTH];
getcwd(current_path, MAX_PATH_LENGTH);
char current_path[PATH_MAX];
getcwd(current_path, PATH_MAX);
if (argc <= 1)
{
if (argc <= 1) {
strcpy(path, "/");
}
else if (argc > 2)
{
} else if (argc > 2) {
printf("%s: too many arguments\n\n", argv[0]);
return;
}
else if (strncmp(argv[1], "..", 2) == 0)
{
if (strcmp(current_path, dirname(current_path)) == 0)
{
} else if (strncmp(argv[1], "..", 2) == 0) {
if (strcmp(current_path, dirname(current_path)) == 0) {
return;
}
strcpy(path, dirname(current_path));
}
else if (strncmp(argv[1], ".", 1) == 0)
{
} else if (strncmp(argv[1], ".", 1) == 0) {
return;
}
else
{
} else {
// Copy the current path.
strcpy(path, current_path);
// Get the absolute path.
get_absolute_path(path);
// If the current directory is not the root, add a '/'.
if (strcmp(path, "/") != 0)
{
if (strcmp(path, "/") != 0) {
strncat(path, "/", 1);
}
// Concatenate the input dir.
@@ -60,8 +49,7 @@ void cmd_cd(int argc, char **argv)
}
dirp = opendir(path);
if (dirp == NULL)
{
if (dirp == NULL) {
printf("%s: no such file or directory: %s\n\n", argv[0], argv[1]);
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)
{
if (argc < 2)
{
if (argc < 2) {
printf(
"No driver inserted or bad usage! Type %s --help for the usage.\n",
argv[0]);
}
else
{
if ((_kstrncmp(argv[1], "-r", 2) == 0))
{
if ((argv[2] != NULL))
{
if (_kstrncmp(argv[2], "mouse", 5) == 0)
{
} else {
if ((_kstrncmp(argv[1], "-r", 2) == 0)) {
if ((argv[2] != NULL)) {
if (_kstrncmp(argv[2], "mouse", 5) == 0) {
printf("Disattivamento %s in corso..\n", argv[2]);
mouse_disable();
}
else
} else
printf("FATAL: Driver %s not found.\n", argv[2]);
}
else
} else
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.
mouse_install();
}
else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
(_kstrncmp(argv[1], "-h", 2) == 0))
{
} else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
(_kstrncmp(argv[1], "-h", 2) == 0)) {
printf("---------------------------------------------------\n"
"Driver tool to load and kill driver\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"
"---------------------------------------------------\n",
argv[0], argv[0], argv[0]);
}
else
{
} else {
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]);
}
else
{
else {
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 j = 0;
if (argc == 1)
{
if (argc == 1) {
printf("");
}
else
{
while (--i > 0)
{
} else {
while (--i > 0) {
printf("%s ", argv[++j]);
}
}
+8 -16
View File
@@ -10,9 +10,9 @@
extern struct shmid_ds *head;
void cmd_ipcrm(int argc, char **argv){
if (argc != 2)
void cmd_ipcrm(int argc, char **argv)
{
if (argc != 2) {
printf("Bad arguments: you have to specify only IPC id, see ipcs.\n");
return;
@@ -21,13 +21,11 @@ void cmd_ipcrm(int argc, char **argv){
struct shmid_ds *shmid_ds = head;
struct shmid_ds *prev = NULL;
while (shmid_ds != NULL)
{
while (shmid_ds != NULL) {
char strid[10];
int_to_str(strid, (shmid_ds->shm_perm).seq, 10);
if (strcmp(strid, argv[1]) == 0)
{
if (strcmp(strid, argv[1]) == 0) {
break;
}
@@ -35,21 +33,15 @@ void cmd_ipcrm(int argc, char **argv){
shmid_ds = shmid_ds->next;
}
if (shmid_ds == NULL)
{
if (shmid_ds == NULL) {
printf("No shared memory find. \n");
}
else
{
} else {
kfree(shmid_ds->shm_location);
// shmid_ds = head.
if (prev == NULL)
{
if (prev == NULL) {
head = head->next;
}
else
{
} else {
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",
"OWNER", "GROUP");
while (shm_list != NULL)
{
while (shm_list != NULL) {
char mode[12];
strmode((shm_list->shm_perm).mode, mode);
printf("%-10s %-10i %-10i %-10s %-10s %-10s \n",
"m",
(shm_list->shm_perm).seq,
(shm_list->shm_perm).key,
mode,
"-", "-");
printf("%-10s %-10i %-10i %-10s %-10s %-10s \n", "m",
(shm_list->shm_perm).seq, (shm_list->shm_perm).key, mode, "-",
"-");
shm_list = shm_list->next;
}
@@ -56,8 +52,7 @@ static void print_msg_stat()
void cmd_ipcs(int argc, char **argv)
{
if (argc > 2)
{
if (argc > 2) {
printf("Too much arguments.\n");
return;
@@ -68,27 +63,17 @@ void cmd_ipcs(int argc, char **argv)
printf("IPC status from " OS_NAME " as of %s\n", datehour);
if (argc == 2)
{
if (strcmp(argv[1], "-s") == 0)
{
if (argc == 2) {
if (strcmp(argv[1], "-s") == 0) {
print_sem_stat();
}
else if (strcmp(argv[1], "-m") == 0)
{
} else if (strcmp(argv[1], "-m") == 0) {
print_shm_stat();
}
else if (strcmp(argv[1], "-q") == 0)
{
} else if (strcmp(argv[1], "-q") == 0) {
print_msg_stat();
}
else
{
} else {
printf("Option not recognize.\n");
}
}
else
{
} else {
print_sem_stat();
print_shm_stat();
print_msg_stat();
+2 -2
View File
@@ -92,8 +92,8 @@ void cmd_ls(int argc, char **argv)
print_ls(dirp, flags);
}
if (no_directory) {
char cwd[MAX_PATH_LENGTH];
getcwd(cwd, MAX_PATH_LENGTH);
char cwd[PATH_MAX];
getcwd(cwd, PATH_MAX);
DIR *dirp = opendir(cwd);
if (dirp == NULL) {
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)
{
if (argc != 2)
{
if (argc != 2) {
printf("%s: missing operand.\n", argv[0]);
printf("Try '%s --help' for more information.\n\n", argv[0]);
return;
}
if (strcmp(argv[1], "--help") == 0)
{
if (strcmp(argv[1], "--help") == 0) {
printf("Prints the content of the given file.\n");
printf("Usage:\n");
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);
if (fd < 0)
{
printf("%s: Cannot stat file '%s': %s\n\n",
argv[0], argv[1],"unknown"/*strerror(errno)*/);
if (fd < 0) {
printf("%s: Cannot stat file '%s': %s\n\n", argv[0], argv[1],
"unknown" /*strerror(errno)*/);
return;
}
char c;
// Put on the standard output the characters.
while (read(fd, &c, 1) > 0)
{
while (read(fd, &c, 1) > 0) {
putchar(c);
}
putchar('\n');
+11 -16
View File
@@ -14,16 +14,14 @@
void cmd_newfile(int argc, char **argv)
{
if (argc != 2)
{
if (argc != 2) {
printf("%s: missing operand.\n", argv[0]);
printf("Try '%s --help' for more information.\n\n", argv[0]);
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("Usage:\n");
printf(" %s <filename>\n", argv[0]);
@@ -34,28 +32,25 @@ void cmd_newfile(int argc, char **argv)
char text[256];
printf("Filename: %s\n", argv[1]);
int fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 0);
if (fd < 0)
{
printf("%s: Cannot create file '%s': %s\n\n",
argv[0], argv[1], "unknown"/*strerror(errno)*/);
if (fd < 0) {
printf("%s: Cannot create file '%s': %s\n\n", argv[0], argv[1],
"unknown" /*strerror(errno)*/);
return;
}
printf("Type one line of text here (new line to complete):\n");
scanf("%s", text);
if (write(fd, text, strlen(text)) == -1)
{
printf("%s: Cannot write on file '%s': %s\n\n",
argv[0], argv[1], "unknown"/*strerror(errno)*/);
if (write(fd, text, strlen(text)) == -1) {
printf("%s: Cannot write on file '%s': %s\n\n", argv[0], argv[1],
"unknown" /*strerror(errno)*/);
return;
}
if (close(fd) == -1)
{
printf("%s: Cannot close file '%s': %s\n\n",
argv[0], argv[1], "unknown"/*strerror(errno)*/);
if (close(fd) == -1) {
printf("%s: Cannot close file '%s': %s\n\n", argv[0], argv[1],
"unknown" /*strerror(errno)*/);
return;
}
+2 -2
View File
@@ -13,7 +13,7 @@ void cmd_pwd(int argc, char **argv)
{
(void)argc;
(void)argv;
char cwd[MAX_PATH_LENGTH];
getcwd(cwd, MAX_PATH_LENGTH);
char cwd[PATH_MAX];
getcwd(cwd, PATH_MAX);
printf("%s\n", cwd);
}
+5 -8
View File
@@ -13,16 +13,14 @@
void cmd_rmdir(int argc, char **argv)
{
// Check the number of arguments.
if (argc != 2)
{
if (argc != 2) {
printf("Bad usage.\n");
printf("Try 'rmdir --help' for more information.\n");
return;
}
if (strcmp(argv[1], "--help") == 0)
{
if (strcmp(argv[1], "--help") == 0) {
printf("Removes a directory.\n");
printf("Usage:\n");
printf(" rmdir <directory>\n");
@@ -30,10 +28,9 @@ void cmd_rmdir(int argc, char **argv)
return;
}
if (rmdir(argv[1]) != 0)
{
printf("%s: failed to remove '%s': %s\n\n",
argv[0], argv[1], "unknown"/*strerror(errno)*/);
if (rmdir(argv[1]) != 0) {
printf("%s: failed to remove '%s': %s\n\n", argv[0], argv[1],
"unknown" /*strerror(errno)*/);
return;
}
+1 -1
View File
@@ -11,7 +11,7 @@
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include <misc/debug.h>
#include "debug.h"
int main_init()
{
+5 -4
View File
@@ -75,7 +75,8 @@ struct {
{ "clear", cmd_clear, "Clears the screen" },
{ "showpid", cmd_showpid, "Shows the PID of the shell" },
{ "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.
@@ -215,8 +216,8 @@ static void shell_print_prompt()
video_set_color(BRIGHT_BLUE);
printf(current_user.username);
video_set_color(WHITE);
char cwd[MAX_PATH_LENGTH];
getcwd(cwd, MAX_PATH_LENGTH);
char cwd[PATH_MAX];
getcwd(cwd, PATH_MAX);
printf("~:%s# ", cwd);
// Update the lower-bounds for the video.
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");
shell_login();
sys_chdir("/");
chdir("/");
current_user.uid = 1;
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")