Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb8f820383 | |||
| a8201fcdde | |||
| eecb9dcc71 | |||
| feee0b80db | |||
| a5bc390cf0 | |||
| eafaca084f | |||
| f957e05615 | |||
| 05c3f2c033 | |||
| 1236941a9c | |||
| de33947249 | |||
| 05397f24c9 | |||
| 0d8fa6c9cd | |||
| b47110b402 | |||
| f99b9f739c | |||
| 6fd063984a | |||
| bc2623ce99 | |||
| c16a750251 | |||
| c673fb9351 | |||
| 25ffb602ea | |||
| 552e2a073f | |||
| c0e5808656 | |||
| 9368b0d6eb | |||
| 3bfa61d189 | |||
| d9fd3b1646 | |||
| 14d64d25d3 | |||
| dbeed54f2b | |||
| 07bd4d7901 | |||
| 614d3dfd62 |
+36
-2
@@ -1,5 +1,40 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Initialize the project.
|
||||||
|
project(MentOs)
|
||||||
cmake_minimum_required(VERSION 2.8.4)
|
cmake_minimum_required(VERSION 2.8.4)
|
||||||
|
|
||||||
|
message(STATUS "Crosscompiling: ${CMAKE_CROSSCOMPILING}")
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Add operating system specific option.
|
||||||
|
message(STATUS "System name: ${CMAKE_HOST_SYSTEM_NAME}")
|
||||||
|
message(STATUS "Kernel version: ${CMAKE_SYSTEM_VERSION}")
|
||||||
|
if ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE)
|
||||||
|
# Apple MacOSx
|
||||||
|
elseif ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32)
|
||||||
|
# Windows
|
||||||
|
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
||||||
|
else()
|
||||||
|
# Generic Unix System
|
||||||
|
find_program(LSB_RELEASE_EXEC lsb_release)
|
||||||
|
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release
|
||||||
|
OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
message(STATUS "LSB version: ${LSB_RELEASE_VERSION_SHORT}")
|
||||||
|
if (${LSB_RELEASE_VERSION_SHORT} MATCHES "^18")
|
||||||
|
# Ubuntu 18
|
||||||
|
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
||||||
|
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^19")
|
||||||
|
# Ubuntu 19
|
||||||
|
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
|
||||||
|
elseif (${LSB_RELEASE_VERSION_SHORT} MATCHES "^20")
|
||||||
|
# Ubuntu 20
|
||||||
|
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -display gtk)
|
||||||
|
else()
|
||||||
|
set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Add the debugging option.
|
# Add the debugging option.
|
||||||
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
|
set(DEBUGGING_TYPE "DEBUG_STDIO" CACHE STRING
|
||||||
@@ -28,7 +63,7 @@ add_custom_target(
|
|||||||
COMMAND echo "---------------------------------------------"
|
COMMAND echo "---------------------------------------------"
|
||||||
COMMAND echo "Initializing 'initfs'..."
|
COMMAND echo "Initializing 'initfs'..."
|
||||||
COMMAND echo "---------------------------------------------"
|
COMMAND echo "---------------------------------------------"
|
||||||
COMMAND initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
|
COMMAND ./initscp/initfscp -s ${CMAKE_SOURCE_DIR}/files -t ${CMAKE_BINARY_DIR}/initfs -m /dev
|
||||||
COMMAND echo "---------------------------------------------"
|
COMMAND echo "---------------------------------------------"
|
||||||
COMMAND echo "Done!"
|
COMMAND echo "Done!"
|
||||||
COMMAND echo "---------------------------------------------"
|
COMMAND echo "---------------------------------------------"
|
||||||
@@ -49,7 +84,6 @@ elseif (${DEBUGGING_TYPE} STREQUAL DEBUG_STDIO)
|
|||||||
endif ()
|
endif ()
|
||||||
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
|
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -vga std)
|
||||||
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
|
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -k it)
|
||||||
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
|
||||||
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
|
SET(EMULATOR_FLAGS ${EMULATOR_FLAGS} -m ${MEMORY_SIZE})
|
||||||
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
|
SET(EMULATOR_KERNEL -kernel mentos/kernel.bin)
|
||||||
SET(EMULATOR_FS -initrd initfs)
|
SET(EMULATOR_FS -initrd initfs)
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ Main Developers:
|
|||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
MentOS is compatible with the main Unix distribution operating systems. It has been tested with *Ubuntu* and *MacOS*, but specifically tested on *Ubuntu 18.04*.
|
||||||
|
|
||||||
For compiling the main system:
|
For compiling the main system:
|
||||||
|
|
||||||
* nasm
|
* nasm
|
||||||
@@ -47,17 +50,44 @@ For compiling the main system:
|
|||||||
|
|
||||||
To run and try:
|
To run and try:
|
||||||
|
|
||||||
* qemu-system-x86
|
* qemu-system-i386
|
||||||
|
|
||||||
For debugging:
|
For debugging:
|
||||||
|
|
||||||
* ccmake
|
* ccmake
|
||||||
* gdb or cgdb
|
* cgdb
|
||||||
* xterm
|
* xterm
|
||||||
|
|
||||||
|
For MacOS, you have additional dependencies:
|
||||||
|
|
||||||
|
* i386-elf-binutils (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
|
||||||
|
* i386-elf-gcc (from [i386-elf-toolchain](https://github.com/nativeos/homebrew-i386-elf-toolchain))
|
||||||
|
|
||||||
|
Prerequisites installation commands
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
For Ubuntu:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get update && sudo apt-get upgrade -y
|
||||||
|
sudo apt-get install -y build-essential git cmake qemu-system-i386
|
||||||
|
sudo apt-get install -y cgdb xterm #<- for debug only
|
||||||
|
```
|
||||||
|
|
||||||
|
For MacOS:
|
||||||
|
|
||||||
|
You need to install additionally the i386-elf cross-compiler. The simplest installation method is through Homebrew package manager. Install [Homebrew](https://brew.sh/index_it) if you don't already have and exec the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
brew update && brew upgrade
|
||||||
|
brew tap nativeos/i386-elf-toolchain
|
||||||
|
brew install i386-elf-binutils i386-elf-gcc git cmake qemu nasm
|
||||||
|
brew install cgdb xterm #<- for debug only
|
||||||
|
```
|
||||||
|
|
||||||
Compiling MentOS
|
Compiling MentOS
|
||||||
-----------------
|
-----------------
|
||||||
Compile and boot MentOS with qemu:
|
Compile and boot MentOS with qemu in Unix systems:
|
||||||
|
|
||||||
```
|
```
|
||||||
cd <clone_directory>
|
cd <clone_directory>
|
||||||
@@ -70,6 +100,12 @@ make qemu
|
|||||||
|
|
||||||
If you want to access to the shell, use one of the usernames listed in files/passwd.
|
If you want to access to the shell, use one of the usernames listed in files/passwd.
|
||||||
|
|
||||||
|
**For MacOS**, the steps are the same but instead of `cmake ..`, you have to put an additional argument in order to use the i386-elf cross-compiler:
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
|
||||||
|
```
|
||||||
|
|
||||||
Change the scheduling algorithm
|
Change the scheduling algorithm
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@@ -80,6 +116,23 @@ MentOS provides three different scheduling algorithms:
|
|||||||
* Completely Fair Scheduling
|
* Completely Fair Scheduling
|
||||||
|
|
||||||
If you want to change the scheduling algorithm:
|
If you want to change the scheduling algorithm:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# Round Robin scheduling algorithm
|
||||||
|
cmake -DSCHEDULER_TYPE=SCHEDULER_RR ..
|
||||||
|
# Priority scheduling algorithm
|
||||||
|
cmake -DSCHEDULER_TYPE=SCHEDULER_PRIORITY ..
|
||||||
|
# Completely Fair Scheduling algorithm
|
||||||
|
cmake -DSCHEDULER_TYPE=SCHEDULER_CFS ..
|
||||||
|
|
||||||
|
make
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise you can use `ccmake`:
|
||||||
|
|
||||||
```
|
```
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
@@ -107,13 +160,23 @@ make
|
|||||||
make qemu
|
make qemu
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable to Buddy System
|
Enable Buddy System
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
MentOS provides a Buddy System to manage the allocation and deallocation of
|
MentOS provides a Buddy System to manage the allocation and deallocation of
|
||||||
page frames in the physical memory.
|
page frames in physical memory.
|
||||||
|
|
||||||
|
If you want to enable MentOS's Buddy System:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build
|
||||||
|
cmake -DENABLE_BUDDY_SYSTEM=ON ..
|
||||||
|
make
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise you can use `ccmake`:
|
||||||
|
|
||||||
If you want to enable the MentOS's Buddy System:
|
|
||||||
```
|
```
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
@@ -150,6 +213,31 @@ make
|
|||||||
make qemu
|
make qemu
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Enable Deadlock Prevention
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
MentOS implements the Banker's Algorithm to perform deadlock prevention for
|
||||||
|
user-space tasks.
|
||||||
|
|
||||||
|
If you want to enable deadlock prevention in MentOS:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build
|
||||||
|
cmake -DENABLE_DEADLOCK_PREVENTION=ON ..
|
||||||
|
make
|
||||||
|
make qemu
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise you can use `ccmake` as shown previously for Buddy System enablement.
|
||||||
|
|
||||||
|
You can control the behavior of the deadlock algorithm with a shell command
|
||||||
|
line that allows you to run two mis-synchronized processes on two shared
|
||||||
|
resources, bringing the operating system into a possible deadlock state.
|
||||||
|
Of course the deadlock state is not always reached, because the tasks scheduling
|
||||||
|
is nondeterministic. The shell command line is `deadlock [-i <iter>]` where the
|
||||||
|
optional parameter `-i <iter>` specify the number of iterations of created tasks
|
||||||
|
over the shared resources, by default it will perform only 1 iteration.
|
||||||
|
|
||||||
Use Debugger
|
Use Debugger
|
||||||
-----------------
|
-----------------
|
||||||
If you want to use GDB to debug MentOS:
|
If you want to use GDB to debug MentOS:
|
||||||
|
|||||||
+180
-181
@@ -1,181 +1,180 @@
|
|||||||
| EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
|
| S | EAX | Name | Source | EBX | ECX | EDX | ESX | EDI |
|
||||||
|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
|
|:--|:----|:---------------------------|:----------------------------|:-------------------------|:-----------------------------|:------------------------|:----------------|:-----------------|
|
||||||
| 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
|
| 1 | 1 | sys_exit | kernel/exit.c | int | - | - | - | - |
|
||||||
| 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
| | 2 | sys_fork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
||||||
| 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
|
| 1 | 3 | sys_read | fs/read_write.c | unsigned int | char * | size_t | - | - |
|
||||||
| 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
|
| 1 | 4 | sys_write | fs/read_write.c | unsigned int | const char * | size_t | - | - |
|
||||||
| 5 | sys_open | fs/open.c | const char * | int | int | - | - |
|
| 1 | 5 | sys_open | fs/open.c | const char * | int | int | - | - |
|
||||||
| 6 | sys_close | fs/open.c | unsigned int | - | - | - | - |
|
| 1 | 6 | sys_close | fs/open.c | int | - | - | - | - |
|
||||||
| 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
|
| 1 | 7 | sys_waitpid | kernel/exit.c | pid_t | unsigned int * | int | - | - |
|
||||||
| 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
|
| | 8 | sys_creat | fs/open.c | const char * | int | - | - | - |
|
||||||
| 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
|
| | 9 | sys_link | fs/namei.c | const char * | const char * | - | - | - |
|
||||||
| 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
|
| | 10 | sys_unlink | fs/namei.c | const char * | - | - | - | - |
|
||||||
| 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
| 1 | 11 | sys_execve | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
||||||
| 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
|
| 1 | 12 | sys_chdir | fs/open.c | const char * | - | - | - | - |
|
||||||
| 13 | sys_time | kernel/time.c | int * | - | - | - | - |
|
| | 13 | sys_time | kernel/time.c | int * | - | - | - | - |
|
||||||
| 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
|
| | 14 | sys_mknod | fs/namei.c | const char * | int | dev_t | - | - |
|
||||||
| 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
|
| | 15 | sys_chmod | fs/open.c | const char * | mode_t | - | - | - |
|
||||||
| 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
|
| | 16 | sys_lchown | fs/open.c | const char * | uid_t | gid_t | - | - |
|
||||||
| 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
|
| 1 | 18 | sys_stat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
|
||||||
| 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
|
| | 19 | sys_lseek | fs/read_write.c | unsigned int | off_t | unsigned int | - | - |
|
||||||
| 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
|
| 1 | 20 | sys_getpid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
|
| | 21 | sys_mount | fs/super.c | char * | char * | char * | - | - |
|
||||||
| 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
|
| | 22 | sys_oldumount | fs/super.c | char * | - | - | - | - |
|
||||||
| 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
|
| | 23 | sys_setuid | kernel/sys.c | uid_t | - | - | - | - |
|
||||||
| 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
|
| | 24 | sys_getuid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
|
| | 25 | sys_stime | kernel/time.c | int * | - | - | - | - |
|
||||||
| 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
|
| | 26 | sys_ptrace | arch/i386/kernel/ptrace.c | long | long | long | long | - |
|
||||||
| 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
|
| | 27 | sys_alarm | kernel/sched.c | unsigned int | - | - | - | - |
|
||||||
| 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
|
| | 28 | sys_fstat | fs/stat.c | unsigned int | struct __old_kernel_stat * | - | - | - |
|
||||||
| 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
|
| | 29 | sys_pause | arch/i386/kernel/sys_i386.c | - | - | - | - | - |
|
||||||
| 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
|
| | 30 | sys_utime | fs/open.c | char * | struct utimbuf * | - | - | - |
|
||||||
| 33 | sys_access | fs/open.c | const char * | int | - | - | - |
|
| | 33 | sys_access | fs/open.c | const char * | int | - | - | - |
|
||||||
| 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
|
| 1 | 34 | sys_nice | kernel/sched.c | int | - | - | - | - |
|
||||||
| 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
|
| | 36 | sys_sync | fs/buffer.c | - | - | - | - | - |
|
||||||
| 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
|
| | 37 | sys_kill | kernel/signal.c | int | int | - | - | - |
|
||||||
| 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
|
| | 38 | sys_rename | fs/namei.c | const char * | const char * | - | - | - |
|
||||||
| 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
|
| 1 | 39 | sys_mkdir | fs/namei.c | const char * | int | - | - | - |
|
||||||
| 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
|
| | 40 | sys_rmdir | fs/namei.c | const char * | - | - | - | - |
|
||||||
| 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
|
| | 41 | sys_dup | fs/fcntl.c | unsigned int | - | - | - | - |
|
||||||
| 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
|
| | 42 | sys_pipe | arch/i386/kernel/sys_i386.c | unsigned long * | - | - | - | - |
|
||||||
| 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
|
| | 43 | sys_times | kernel/sys.c | struct tms * | - | - | - | - |
|
||||||
| 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
|
| | 45 | sys_brk | mm/mmap.c | unsigned long | - | - | - | - |
|
||||||
| 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
|
| | 46 | sys_setgid | kernel/sys.c | gid_t | - | - | - | - |
|
||||||
| 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
|
| | 47 | sys_getgid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
|
| | 48 | sys_signal | kernel/signal.c | int | __sighandler_t | - | - | - |
|
||||||
| 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
|
| | 49 | sys_geteuid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
|
| | 50 | sys_getegid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
|
| | 51 | sys_acct | kernel/acct.c | const char * | - | - | - | - |
|
||||||
| 52 | sys_umount | fs/super.c | char * | int | - | - | - |
|
| | 52 | sys_umount | fs/super.c | char * | int | - | - | - |
|
||||||
| 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
|
| | 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
|
||||||
| 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - |
|
| | 55 | sys_fcntl | fs/fcntl.c | unsigned int | unsigned int | unsigned long | - | - |
|
||||||
| 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - |
|
| | 57 | sys_setpgid | kernel/sys.c | pid_t | pid_t | - | - | - |
|
||||||
| 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
|
| | 59 | sys_olduname | arch/i386/kernel/sys_i386.c | struct oldold_utsname * | - | - | - | - |
|
||||||
| 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
|
| | 60 | sys_umask | kernel/sys.c | int | - | - | - | - |
|
||||||
| 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
|
| | 61 | sys_chroot | fs/open.c | const char * | - | - | - | - |
|
||||||
| 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
|
| | 62 | sys_ustat | fs/super.c | dev_t | struct ustat * | - | - | - |
|
||||||
| 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
|
| | 63 | sys_dup2 | fs/fcntl.c | unsigned int | unsigned int | - | - | - |
|
||||||
| 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
|
| 1 | 64 | sys_getppid | kernel/sched.c | - | - | - | - | - |
|
||||||
| 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - |
|
| | 65 | sys_getpgrp | kernel/sys.c | - | - | - | - | - |
|
||||||
| 66 | sys_setsid | kernel/sys.c | - | - | - | - | - |
|
| | 66 | sys_setsid | kernel/sys.c | - | - | - | - | - |
|
||||||
| 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
|
| | 67 | sys_sigaction | arch/i386/kernel/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
|
||||||
| 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
|
| | 68 | sys_sgetmask | kernel/signal.c | - | - | - | - | - |
|
||||||
| 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
|
| | 69 | sys_ssetmask | kernel/signal.c | int | - | - | - | - |
|
||||||
| 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
|
| | 70 | sys_setreuid | kernel/sys.c | uid_t | uid_t | - | - | - |
|
||||||
| 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
|
| | 71 | sys_setregid | kernel/sys.c | gid_t | gid_t | - | - | - |
|
||||||
| 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
|
| | 72 | sys_sigsuspend | arch/i386/kernel/signal.c | int | int | old_sigset_t | - | - |
|
||||||
| 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
|
| | 73 | sys_sigpending | kernel/signal.c | old_sigset_t * | - | - | - | - |
|
||||||
| 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
|
| | 74 | sys_sethostname | kernel/sys.c | char * | int | - | - | - |
|
||||||
| 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
|
| | 75 | sys_setrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
|
||||||
| 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
|
| | 76 | sys_getrlimit | kernel/sys.c | unsigned int | struct rlimit * | - | - | - |
|
||||||
| 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - |
|
| | 77 | sys_getrusage | kernel/sys.c | int | struct rusage * | - | - | - |
|
||||||
| 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
|
| | 78 | sys_gettimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
|
||||||
| 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
|
| | 79 | sys_settimeofday | kernel/time.c | struct timeval * | struct timezone * | - | - | - |
|
||||||
| 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - |
|
| | 80 | sys_getgroups | kernel/sys.c | int | gid_t * | - | - | - |
|
||||||
| 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
|
| | 81 | sys_setgroups | kernel/sys.c | int | gid_t * | - | - | - |
|
||||||
|
| | 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
|
||||||
| 83 | sys_symlink | fs/namei.c | const char * | const char * | - | - | - |
|
| | 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
|
||||||
| 84 | sys_lstat | fs/stat.c | char * | struct __old_kernel_stat * | - | - | - |
|
| | 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
|
||||||
| 85 | sys_readlink | fs/stat.c | const char * | char * | int | - | - |
|
| | 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
|
||||||
| 86 | sys_uselib | fs/exec.c | const char * | - | - | - | - |
|
| | 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
|
||||||
| 87 | sys_swapon | mm/swapfile.c | const char * | int | - | - | - |
|
| 1 | 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
|
||||||
| 88 | sys_reboot | kernel/sys.c | int | int | int | void * | - |
|
| 1 | 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
|
||||||
| 89 | old_readdir | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
|
| | 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
|
||||||
| 90 | old_mmap | arch/i386/kernel/sys_i386.c | struct mmap_arg_struct * | - | - | - | - |
|
| | 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
|
||||||
| 91 | sys_munmap | mm/mmap.c | unsigned long | size_t | - | - | - |
|
| | 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
|
||||||
| 92 | sys_truncate | fs/open.c | const char * | unsigned long | - | - | - |
|
| | 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
|
||||||
| 93 | sys_ftruncate | fs/open.c | unsigned int | unsigned long | - | - | - |
|
| | 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
|
||||||
| 94 | sys_fchmod | fs/open.c | unsigned int | mode_t | - | - | - |
|
| | 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
|
||||||
| 95 | sys_fchown | fs/open.c | unsigned int | uid_t | gid_t | - | - |
|
| | 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
|
||||||
| 96 | sys_getpriority | kernel/sys.c | int | int | - | - | - |
|
| | 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
|
||||||
| 97 | sys_setpriority | kernel/sys.c | int | int | int | - | - |
|
| | 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - |
|
||||||
| 99 | sys_statfs | fs/open.c | const char * | struct statfs * | - | - | - |
|
| | 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - |
|
||||||
| 100 | sys_fstatfs | fs/open.c | unsigned int | struct statfs * | - | - | - |
|
| | 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - |
|
||||||
| 101 | sys_ioperm | arch/i386/kernel/ioport.c | unsigned long | unsigned long | int | - | - |
|
| | 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
|
||||||
| 102 | sys_socketcall | net/socket.c | int | unsigned long * | - | - | - |
|
| | 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
|
||||||
| 103 | sys_syslog | kernel/printk.c | int | char * | int | - | - |
|
| | 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
|
||||||
| 104 | sys_setitimer | kernel/itimer.c | int | struct itimerval * | struct itimerval * | - | - |
|
| | 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
|
||||||
| 105 | sys_getitimer | kernel/itimer.c | int | struct itimerval * | - | - | - |
|
| | 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - |
|
||||||
| 106 | sys_newstat | fs/stat.c | char * | struct stat * | - | - | - |
|
| | 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - |
|
||||||
| 107 | sys_newlstat | fs/stat.c | char * | struct stat * | - | - | - |
|
| | 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - |
|
||||||
| 108 | sys_newfstat | fs/stat.c | unsigned int | struct stat * | - | - | - |
|
| | 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
|
||||||
| 109 | sys_uname | arch/i386/kernel/sys_i386.c | struct old_utsname * | - | - | - | - |
|
| | 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
|
||||||
| 110 | sys_iopl | arch/i386/kernel/ioport.c | unsigned long | - | - | - | - |
|
| | 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
|
||||||
| 111 | sys_vhangup | fs/open.c | - | - | - | - | - |
|
| | 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
|
||||||
| 112 | sys_idle | arch/i386/kernel/process.c | - | - | - | - | - |
|
| | 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - |
|
||||||
| 113 | sys_vm86old | arch/i386/kernel/vm86.c | unsigned long | struct vm86plus_struct * | - | - | - |
|
| | 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - |
|
||||||
| 114 | sys_wait4 | kernel/exit.c | pid_t | unsigned long * | int options | struct rusage * | - |
|
| | 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
|
||||||
| 115 | sys_swapoff | mm/swapfile.c | const char * | - | - | - | - |
|
| | 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
|
||||||
| 116 | sys_sysinfo | kernel/info.c | struct sysinfo * | - | - | - | - |
|
| | 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
|
||||||
| 117 | sys_ipc(*Note) | arch/i386/kernel/sys_i386.c | uint | int | int | int | void * |
|
| | 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
|
||||||
| 118 | sys_fsync | fs/buffer.c | unsigned int | - | - | - | - |
|
| | 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
|
||||||
| 119 | sys_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
|
| | 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
||||||
| 120 | sys_clone | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
| | 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
|
||||||
| 121 | sys_setdomainname | kernel/sys.c | char * | int | - | - | - |
|
| | 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
|
||||||
| 122 | sys_newuname | kernel/sys.c | struct new_utsname * | - | - | - | - |
|
| | 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
|
||||||
| 123 | sys_modify_ldt | arch/i386/kernel/ldt.c | int | void * | unsigned long | - | - |
|
| | 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
|
||||||
| 124 | sys_adjtimex | kernel/time.c | struct timex * | - | - | - | - |
|
| | 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - |
|
||||||
| 125 | sys_mprotect | mm/mprotect.c | unsigned long | size_t | unsigned long | - | - |
|
| | 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - |
|
||||||
| 126 | sys_sigprocmask | kernel/signal.c | int | old_sigset_t * | old_sigset_t * | - | - |
|
| | 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
|
||||||
| 127 | sys_create_module | kernel/module.c | const char * | size_t | - | - | - |
|
| | 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
|
||||||
| 128 | sys_init_module | kernel/module.c | const char * | struct module * | - | - | - |
|
| | 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
|
||||||
| 129 | sys_delete_module | kernel/module.c | const char * | - | - | - | - |
|
| | 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
|
||||||
| 130 | sys_get_kernel_syms | kernel/module.c | struct kernel_sym * | - | - | - | - |
|
| | 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
|
||||||
| 131 | sys_quotactl | fs/dquot.c | int | const char * | int | caddr_t | - |
|
| | 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
|
||||||
| 132 | sys_getpgid | kernel/sys.c | pid_t | - | - | - | - |
|
| | 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
|
||||||
| 133 | sys_fchdir | fs/open.c | unsigned int | - | - | - | - |
|
| | 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
|
||||||
| 134 | sys_bdflush | fs/buffer.c | int | long | - | - | - |
|
| | 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
|
||||||
| 135 | sys_sysfs | fs/super.c | int | unsigned long | unsigned long | - | - |
|
| | 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
|
||||||
| 136 | sys_personality | kernel/exec_domain.c | unsigned long | - | - | - | - |
|
| | 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - |
|
||||||
| 138 | sys_setfsuid | kernel/sys.c | uid_t | - | - | - | - |
|
| | 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - |
|
||||||
| 139 | sys_setfsgid | kernel/sys.c | gid_t | - | - | - | - |
|
| | 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int |
|
||||||
| 140 | sys_llseek | fs/read_write.c | unsigned int | unsigned long | unsigned long | loff_t * | unsigned int |
|
| | 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
|
||||||
| 141 | sys_getdents | fs/readdir.c | unsigned int | void * | unsigned int | - | - |
|
| | 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * |
|
||||||
| 142 | sys_select | fs/select.c | int | fd_set * | fd_set * | fd_set * | struct timeval * |
|
| | 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - |
|
||||||
| 143 | sys_flock | fs/locks.c | unsigned int | unsigned int | - | - | - |
|
| | 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - |
|
||||||
| 144 | sys_msync | mm/filemap.c | unsigned long | size_t | int | - | - |
|
| | 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
|
||||||
| 145 | sys_readv | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
|
| | 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
|
||||||
| 146 | sys_writev | fs/read_write.c | unsigned long | const struct iovec * | unsigned long | - | - |
|
| | 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
|
||||||
| 147 | sys_getsid | kernel/sys.c | pid_t | - | - | - | - |
|
| | 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
|
||||||
| 148 | sys_fdatasync | fs/buffer.c | unsigned int | - | - | - | - |
|
| | 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
|
||||||
| 149 | sys_sysctl | kernel/sysctl.c | struct __sysctl_args * | - | - | - | - |
|
| | 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
|
||||||
| 150 | sys_mlock | mm/mlock.c | unsigned long | size_t | - | - | - |
|
| | 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
|
||||||
| 151 | sys_munlock | mm/mlock.c | unsigned long | size_t | - | - | - |
|
| | 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
|
||||||
| 152 | sys_mlockall | mm/mlock.c | int | - | - | - | - |
|
| | 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
|
||||||
| 153 | sys_munlockall | mm/mlock.c | - | - | - | - | - |
|
| | 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
|
||||||
| 154 | sys_sched_setparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
|
| | 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
|
||||||
| 155 | sys_sched_getparam | kernel/sched.c | pid_t | struct sched_param * | - | - | - |
|
| | 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - |
|
||||||
| 156 | sys_sched_setscheduler | kernel/sched.c | pid_t | int | struct sched_param * | - | - |
|
| | 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
|
||||||
| 157 | sys_sched_getscheduler | kernel/sched.c | pid_t | - | - | - | - |
|
| | 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
|
||||||
| 158 | sys_sched_yield | kernel/sched.c | - | - | - | - | - |
|
| | 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - |
|
||||||
| 159 | sys_sched_get_priority_max | kernel/sched.c | int | - | - | - | - |
|
| | 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - |
|
||||||
| 160 | sys_sched_get_priority_min | kernel/sched.c | int | - | - | - | - |
|
| | 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - |
|
||||||
| 161 | sys_sched_rr_get_interval | kernel/sched.c | pid_t | struct timespec * | - | - | - |
|
| | 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
|
||||||
| 162 | sys_nanosleep | kernel/sched.c | struct timespec * | struct timespec * | - | - | - |
|
| | 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - |
|
||||||
| 163 | sys_mremap | mm/mremap.c | unsigned long | unsigned long | unsigned long | unsigned long | - |
|
| | 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - |
|
||||||
| 164 | sys_setresuid | kernel/sys.c | uid_t | uid_t | uid_t | - | - |
|
| | 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
|
||||||
| 165 | sys_getresuid | kernel/sys.c | uid_t * | uid_t * | uid_t * | - | - |
|
| | 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - |
|
||||||
| 166 | sys_vm86 | arch/i386/kernel/vm86.c | struct vm86_struct * | - | - | - | - |
|
| | 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * |
|
||||||
| 167 | sys_query_module | kernel/module.c | const char * | int | char * | size_t | size_t * |
|
| | 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
|
||||||
| 168 | sys_poll | fs/select.c | struct pollfd * | unsigned int | long | - | - |
|
| | 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
|
||||||
| 169 | sys_nfsservctl | fs/filesystems.c | int | void * | void * | - | - |
|
| | 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - |
|
||||||
| 170 | sys_setresgid | kernel/sys.c | gid_t | gid_t | gid_t | - | - |
|
| | 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - |
|
||||||
| 171 | sys_getresgid | kernel/sys.c | gid_t * | gid_t * | gid_t * | - | - |
|
| | 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long |
|
||||||
| 172 | sys_prctl | kernel/sys.c | int | unsigned long | unsigned long | unsigned long | unsigned long |
|
| | 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
|
||||||
| 173 | sys_rt_sigreturn | arch/i386/kernel/signal.c | unsigned long | - | - | - | - |
|
| | 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - |
|
||||||
| 174 | sys_rt_sigaction | kernel/signal.c | int | const struct sigaction * | struct sigaction * | size_t | - |
|
| | 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - |
|
||||||
| 175 | sys_rt_sigprocmask | kernel/signal.c | int | sigset_t * | sigset_t * | size_t | - |
|
| | 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - |
|
||||||
| 176 | sys_rt_sigpending | kernel/signal.c | sigset_t * | size_t | - | - | - |
|
| | 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - |
|
||||||
| 177 | sys_rt_sigtimedwait | kernel/signal.c | const sigset_t * | siginfo_t * | const struct timespec * | size_t | - |
|
| | 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - |
|
||||||
| 178 | sys_rt_sigqueueinfo | kernel/signal.c | int | int | siginfo_t * | - | - |
|
| | 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - |
|
||||||
| 179 | sys_rt_sigsuspend | arch/i386/kernel/signal.c | sigset_t * | size_t | - | - | - |
|
| | 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - |
|
||||||
| 180 | sys_pread | fs/read_write.c | unsigned int | char * | size_t | loff_t | - |
|
| | 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - |
|
||||||
| 181 | sys_pwrite | fs/read_write.c | unsigned int | const char * | size_t | loff_t | - |
|
| | 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - |
|
||||||
| 182 | sys_chown | fs/open.c | const char * | uid_t | gid_t | - | - |
|
| 1 | 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
|
||||||
| 183 | sys_getcwd | fs/dcache.c | char * | unsigned long | - | - | - |
|
| | 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - |
|
||||||
| 184 | sys_capget | kernel/capability.c | cap_user_header_t | cap_user_data_t | - | - | - |
|
| | 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - |
|
||||||
| 185 | sys_capset | kernel/capability.c | cap_user_header_t | const cap_user_data_t | - | - | - |
|
| | 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - |
|
||||||
| 186 | sys_sigaltstack | arch/i386/kernel/signal.c | const stack_t * | stack_t * | - | - | - |
|
| | 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - |
|
||||||
| 187 | sys_sendfile | mm/filemap.c | int | int | off_t * | size_t | - |
|
| 1 | 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
||||||
| 190 | sys_vfork | arch/i386/kernel/process.c | struct pt_regs | - | - | - | - |
|
| | | | | | | | | |
|
||||||
| | | | | | | | |
|
|
||||||
@@ -6,6 +6,12 @@ project(initfscp C ASM)
|
|||||||
# Set the project name.
|
# Set the project name.
|
||||||
set(PROJECT_NAME initfscp)
|
set(PROJECT_NAME initfscp)
|
||||||
|
|
||||||
|
if (CMAKE_CROSSCOMPILING)
|
||||||
|
set(CMAKE_C_COMPILER gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER g++)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||||
|
endif (CMAKE_CROSSCOMPILING)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Set the compiler options (original).
|
# Set the compiler options (original).
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
||||||
@@ -13,10 +19,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Add the includes.
|
|
||||||
include_directories(inc)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Add the source files.
|
# Add the source files.
|
||||||
set(SOURCE_FILES src/initfscp.c)
|
set(SOURCE_FILES src/initfscp.c)
|
||||||
|
|||||||
@@ -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
@@ -4,16 +4,60 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <initfscp.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define INITFSCP_VER "0.3.0"
|
||||||
|
#define INITFSCP_NAME_MAX 255
|
||||||
|
#define INITFSCP_MAX_FILES 32
|
||||||
|
|
||||||
|
#define RESET "\033[00m"
|
||||||
|
#define BLACK "\033[30m"
|
||||||
|
#define RED "\033[31m"
|
||||||
|
#define GREEN "\033[32m"
|
||||||
|
#define YELLOW "\033[33m"
|
||||||
|
#define BLUE "\033[34m"
|
||||||
|
#define MAGENTA "\033[35m"
|
||||||
|
#define CYAN "\033[36m"
|
||||||
|
#define WHITE "\033[37m"
|
||||||
|
|
||||||
|
/// Identifies a file.
|
||||||
|
#define FS_FILE 0x01
|
||||||
|
/// Identifies a directory.
|
||||||
|
#define FS_DIRECTORY 0x02
|
||||||
|
/// Identifies a character devies.
|
||||||
|
#define FS_CHARDEVICE 0x04
|
||||||
|
/// Identifies a block devies.
|
||||||
|
#define FS_BLOCKDEVICE 0x08
|
||||||
|
/// Identifies a pipe.
|
||||||
|
#define FS_PIPE 0x10
|
||||||
|
/// Identifies a symbolic link.
|
||||||
|
#define FS_SYMLINK 0x20
|
||||||
|
/// Identifies a mount-point.
|
||||||
|
#define FS_MOUNTPOINT 0x40
|
||||||
|
|
||||||
|
/// @brief Information concerning a file.
|
||||||
|
typedef struct initrd_file_t {
|
||||||
|
/// Number used as delimiter, it must be set to 0xBF.
|
||||||
|
int magic;
|
||||||
|
/// The name of the file.
|
||||||
|
char fileName[INITFSCP_NAME_MAX];
|
||||||
|
/// The type of the file.
|
||||||
|
short int file_type;
|
||||||
|
/// The uid of the owner.
|
||||||
|
int uid;
|
||||||
|
/// Offset of the starting address.
|
||||||
|
unsigned int offset;
|
||||||
|
/// Dimension of the file.
|
||||||
|
unsigned int length;
|
||||||
|
} initrd_file_t;
|
||||||
|
|
||||||
static FILE *target_fs = NULL;
|
static FILE *target_fs = NULL;
|
||||||
static initrd_file_t headers[MAX_FILES];
|
static initrd_file_t headers[INITFSCP_MAX_FILES];
|
||||||
static char mount_points[MAX_FILES][MAX_FILENAME_LENGTH];
|
static char mount_points[INITFSCP_MAX_FILES][INITFSCP_NAME_MAX];
|
||||||
static int mountpoint_idx = 0;
|
static int mountpoint_idx = 0;
|
||||||
static int header_idx = 0;
|
static int header_idx = 0;
|
||||||
static int header_offset = 0;
|
static int header_offset = 0;
|
||||||
@@ -91,9 +135,9 @@ static bool open_target_fs(int argc, char *argv[])
|
|||||||
static bool init_headers()
|
static bool init_headers()
|
||||||
{
|
{
|
||||||
printf("%-64s", "Initializing headers structures...");
|
printf("%-64s", "Initializing headers structures...");
|
||||||
for (size_t i = 0; i < MAX_FILES; i++) {
|
for (size_t i = 0; i < INITFSCP_MAX_FILES; i++) {
|
||||||
headers[i].magic = 0xBF;
|
headers[i].magic = 0xBF;
|
||||||
memset(headers[i].fileName, 0, MAX_FILENAME_LENGTH);
|
memset(headers[i].fileName, 0, INITFSCP_NAME_MAX);
|
||||||
headers[i].file_type = 0;
|
headers[i].file_type = 0;
|
||||||
headers[i].uid = 0;
|
headers[i].uid = 0;
|
||||||
headers[i].offset = 0;
|
headers[i].offset = 0;
|
||||||
@@ -218,7 +262,7 @@ static bool create_file_headers(char *mountpoint, char *directory)
|
|||||||
static bool write_file_system(char *mountpoint)
|
static bool write_file_system(char *mountpoint)
|
||||||
{
|
{
|
||||||
printf("Copying data to filesystem...\n");
|
printf("Copying data to filesystem...\n");
|
||||||
for (int i = 0; i < MAX_FILES; i++) {
|
for (int i = 0; i < INITFSCP_MAX_FILES; i++) {
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
char absolute_path[256];
|
char absolute_path[256];
|
||||||
memset(absolute_path, 0, 256);
|
memset(absolute_path, 0, 256);
|
||||||
@@ -288,7 +332,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Create file headers.
|
// Create file headers.
|
||||||
header_offset = sizeof(struct initrd_file_t) * MAX_FILES + sizeof(int);
|
header_offset =
|
||||||
|
sizeof(struct initrd_file_t) * INITFSCP_MAX_FILES + sizeof(int);
|
||||||
printf("Creating headers...\n");
|
printf("Creating headers...\n");
|
||||||
for (uint32_t i = 1; i < argc; ++i) {
|
for (uint32_t i = 1; i < argc; ++i) {
|
||||||
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
|
if (is_option_source(argv[i]) && ((i + 1) < argc)) {
|
||||||
|
|||||||
+51
-12
@@ -1,10 +1,17 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Initialize the project.
|
# Initialize the project.
|
||||||
project(MentOs C ASM)
|
project(MentOs C ASM)
|
||||||
|
set(PROJECT_NAME MentOs)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Set the project name.
|
# Add operating system specific option.
|
||||||
set(PROJECT_NAME MentOs)
|
if((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE) # Apple MacOSx
|
||||||
|
set(CMAKE_ASM_COMPILER nasm)
|
||||||
|
elseif ((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32) # Windows
|
||||||
|
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
|
||||||
|
else () # Generic Unix System
|
||||||
|
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
|
||||||
|
endif ()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Find doxygen
|
# Find doxygen
|
||||||
@@ -63,6 +70,16 @@ else (ENABLE_BUDDY_SYSTEM)
|
|||||||
message(STATUS "Buddy system disabled.")
|
message(STATUS "Buddy system disabled.")
|
||||||
endif (ENABLE_BUDDY_SYSTEM)
|
endif (ENABLE_BUDDY_SYSTEM)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Add the option to enable deadlock prevention.
|
||||||
|
option(ENABLE_DEADLOCK_PREVENTION "Enables the buddy system" OFF)
|
||||||
|
if (ENABLE_DEADLOCK_PREVENTION)
|
||||||
|
message(STATUS "Enabling deadlock prevention.")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_DEADLOCK_PREVENTION")
|
||||||
|
else (ENABLE_DEADLOCK_PREVENTION)
|
||||||
|
message(STATUS "Deadlock prevention disabled.")
|
||||||
|
endif (ENABLE_DEADLOCK_PREVENTION)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Set the compiler options (original).
|
# Set the compiler options (original).
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
||||||
@@ -128,6 +145,10 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|||||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized")
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized")
|
||||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
||||||
|
endif()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||||
@@ -137,13 +158,11 @@ endif (CMAKE_BUILD_TYPE MATCHES "Release")
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Set the assembly flags.
|
# Set the assembly flags.
|
||||||
enable_language(ASM)
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
|
||||||
set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/third_party/nasm/bin/nasm)
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
|
||||||
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -g")
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
|
||||||
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O0")
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
|
||||||
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -f elf")
|
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> <SOURCE> -o <OBJECT>")
|
||||||
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -F dwarf")
|
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
@@ -162,6 +181,8 @@ include_directories(
|
|||||||
inc/mem
|
inc/mem
|
||||||
inc/misc
|
inc/misc
|
||||||
inc/sys
|
inc/sys
|
||||||
|
inc/experimental
|
||||||
|
inc/experimental/math
|
||||||
inc/system
|
inc/system
|
||||||
inc/process
|
inc/process
|
||||||
inc/elf
|
inc/elf
|
||||||
@@ -188,10 +209,18 @@ set(SOURCE_FILES
|
|||||||
src/drivers/keyboard/keyboard.c
|
src/drivers/keyboard/keyboard.c
|
||||||
src/drivers/keyboard/keymap.c
|
src/drivers/keyboard/keymap.c
|
||||||
|
|
||||||
|
src/experimental/smart_sem_kernel.c
|
||||||
|
src/experimental/smart_sem_user.c
|
||||||
|
src/experimental/resource.c
|
||||||
|
src/experimental/math/arr_math.c
|
||||||
|
|
||||||
src/fs/fcntl.c
|
src/fs/fcntl.c
|
||||||
src/fs/initrd.c
|
src/fs/initrd.c
|
||||||
src/fs/vfs.c
|
src/fs/vfs.c
|
||||||
src/fs/read_write.c
|
src/fs/read_write.c
|
||||||
|
src/fs/open.c
|
||||||
|
src/fs/stat.c
|
||||||
|
src/fs/readdir.c
|
||||||
|
|
||||||
src/sys/module.c
|
src/sys/module.c
|
||||||
src/sys/unistd.c
|
src/sys/unistd.c
|
||||||
@@ -204,6 +233,7 @@ set(SOURCE_FILES
|
|||||||
|
|
||||||
src/kernel/sys.c
|
src/kernel/sys.c
|
||||||
|
|
||||||
|
src/libc/assert.c
|
||||||
src/libc/ctype.c
|
src/libc/ctype.c
|
||||||
src/libc/stdio.c
|
src/libc/stdio.c
|
||||||
src/libc/string.c
|
src/libc/string.c
|
||||||
@@ -236,6 +266,9 @@ set(SOURCE_FILES
|
|||||||
src/libc/unistd/waitpid.c
|
src/libc/unistd/waitpid.c
|
||||||
src/libc/unistd/chdir.c
|
src/libc/unistd/chdir.c
|
||||||
src/libc/unistd/getcwd.c
|
src/libc/unistd/getcwd.c
|
||||||
|
src/libc/unistd/close.c
|
||||||
|
src/libc/unistd/stat.c
|
||||||
|
src/libc/unistd/mkdir.c
|
||||||
|
|
||||||
src/mem/kheap.c
|
src/mem/kheap.c
|
||||||
src/mem/paging.c
|
src/mem/paging.c
|
||||||
@@ -245,9 +278,7 @@ set(SOURCE_FILES
|
|||||||
src/misc/clock.c
|
src/misc/clock.c
|
||||||
src/misc/debug.c
|
src/misc/debug.c
|
||||||
src/sys/dirent.c
|
src/sys/dirent.c
|
||||||
src/sys/stat.c
|
|
||||||
src/sys/utsname.c
|
src/sys/utsname.c
|
||||||
#src/sys/shm.c
|
|
||||||
src/elf/elf.c
|
src/elf/elf.c
|
||||||
|
|
||||||
src/descriptor_tables/gdt.c
|
src/descriptor_tables/gdt.c
|
||||||
@@ -297,6 +328,7 @@ set(SOURCE_FILES
|
|||||||
src/ui/command/cmd_ipcs.c
|
src/ui/command/cmd_ipcs.c
|
||||||
src/ui/command/cmd_ipcrm.c
|
src/ui/command/cmd_ipcrm.c
|
||||||
src/ui/command/cmd_nice.c
|
src/ui/command/cmd_nice.c
|
||||||
|
src/ui/command/cmd_deadlock.c
|
||||||
|
|
||||||
src/ui/init/init.c
|
src/ui/init/init.c
|
||||||
|
|
||||||
@@ -310,6 +342,13 @@ if (ENABLE_BUDDY_SYSTEM MATCHES "ON")
|
|||||||
src/mem/buddysystem.c)
|
src/mem/buddysystem.c)
|
||||||
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
|
endif (ENABLE_BUDDY_SYSTEM MATCHES "ON")
|
||||||
|
|
||||||
|
if (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
|
||||||
|
set(SOURCE_FILES
|
||||||
|
${SOURCE_FILES}
|
||||||
|
src/experimental/deadlock_prevention.c
|
||||||
|
src/experimental/deadlock_simulation.c)
|
||||||
|
endif (ENABLE_DEADLOCK_PREVENTION MATCHES "ON")
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Add the executable.
|
# Add the executable.
|
||||||
add_library(${PROJECT_NAME} ${SOURCE_FILES})
|
add_library(${PROJECT_NAME} ${SOURCE_FILES})
|
||||||
@@ -319,7 +358,7 @@ add_library(${PROJECT_NAME} ${SOURCE_FILES})
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET MentOs
|
TARGET MentOs
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND $(LD)
|
COMMAND ${CMAKE_LINKER}
|
||||||
-melf_i386
|
-melf_i386
|
||||||
-static
|
-static
|
||||||
--oformat elf32-i386
|
--oformat elf32-i386
|
||||||
|
|||||||
+22
-14
@@ -7,20 +7,26 @@
|
|||||||
[BITS 32] ; All instructions should be 32-bit.
|
[BITS 32] ; All instructions should be 32-bit.
|
||||||
[EXTERN kmain] ; The start point of our C code
|
[EXTERN kmain] ; The start point of our C code
|
||||||
|
|
||||||
; Grub is informed with this flag to load
|
; The magic field should contain this.
|
||||||
; the kernel and kernel modules on a page boundary.
|
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
|
||||||
MBOOT_PAGE_ALIGN equ 1<<0
|
; This should be in %eax.
|
||||||
; Grub is informed with this flag to provide the kernel
|
MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
|
||||||
; with memory information.
|
|
||||||
MBOOT_MEM_INFO equ 1<<1
|
; = Specify what GRUB should PROVIDE =========================================
|
||||||
; This is the multiboot magic value.
|
; Align the kernel and kernel modules on i386 page (4KB) boundaries.
|
||||||
MBOOT_HEADER_MAGIC equ 0x1BADB002
|
MULTIBOOT_PAGE_ALIGN equ 0x00000001
|
||||||
|
; Provide the kernel with memory information.
|
||||||
|
MULTIBOOT_MEMORY_INFO equ 0x00000002
|
||||||
|
; Must pass video information to OS.
|
||||||
|
MULTIBOOT_VIDEO_MODE equ 0x00000004
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
; This is the flag combination that we prepare for Grub
|
; This is the flag combination that we prepare for Grub
|
||||||
; to read at kernel load time.
|
; to read at kernel load time.
|
||||||
MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
|
MULTIBOOT_HEADER_FLAGS equ (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE)
|
||||||
; Grub reads this value to make sure it loads a kernel
|
; Grub reads this value to make sure it loads a kernel
|
||||||
; and not just garbage.
|
; and not just garbage.
|
||||||
MBOOT_CHECKSUM equ - (MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)
|
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||||
|
|
||||||
LOAD_MEMORY_ADDRESS equ 0x00000000
|
LOAD_MEMORY_ADDRESS equ 0x00000000
|
||||||
; reserve (1024*1024) for the stack on a doubleword boundary
|
; reserve (1024*1024) for the stack on a doubleword boundary
|
||||||
@@ -33,9 +39,12 @@ section .multiboot_header
|
|||||||
align 4
|
align 4
|
||||||
; This is the GRUB Multiboot header.
|
; This is the GRUB Multiboot header.
|
||||||
multiboot_header:
|
multiboot_header:
|
||||||
dd MBOOT_HEADER_MAGIC
|
; magic
|
||||||
dd MBOOT_HEADER_FLAGS
|
dd MULTIBOOT_HEADER_MAGIC
|
||||||
dd MBOOT_CHECKSUM
|
; flags
|
||||||
|
dd MULTIBOOT_HEADER_FLAGS
|
||||||
|
; checksum
|
||||||
|
dd MULTIBOOT_CHECKSUM
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; SECTION (data)
|
; SECTION (data)
|
||||||
@@ -61,7 +70,6 @@ kernel_entry:
|
|||||||
mov esp, stack_top
|
mov esp, stack_top
|
||||||
; pass the initial ESP
|
; pass the initial ESP
|
||||||
push esp
|
push esp
|
||||||
;mov ebp, esp
|
|
||||||
; pass Multiboot info structure
|
; pass Multiboot info structure
|
||||||
push ebx
|
push ebx
|
||||||
; pass Multiboot magic number
|
; pass Multiboot magic number
|
||||||
|
|||||||
@@ -36,8 +36,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// @brief This structure describes one interrupt gate.
|
/// @brief This structure describes one interrupt gate.
|
||||||
typedef struct idt_descriptor_t
|
typedef struct idt_descriptor_t {
|
||||||
{
|
|
||||||
unsigned short offset_low;
|
unsigned short offset_low;
|
||||||
unsigned short seg_selector;
|
unsigned short seg_selector;
|
||||||
// This will ALWAYS be set to 0.
|
// This will ALWAYS be set to 0.
|
||||||
@@ -49,8 +48,7 @@ typedef struct idt_descriptor_t
|
|||||||
} __attribute__((packed)) idt_descriptor_t;
|
} __attribute__((packed)) idt_descriptor_t;
|
||||||
|
|
||||||
/// @brief A pointer structure used for informing the CPU about our IDT.
|
/// @brief A pointer structure used for informing the CPU about our IDT.
|
||||||
typedef struct idt_pointer_t
|
typedef struct idt_pointer_t {
|
||||||
{
|
|
||||||
/// The size of the IDT (entry number).
|
/// The size of the IDT (entry number).
|
||||||
unsigned short int limit;
|
unsigned short int limit;
|
||||||
/// The start address of the IDT.
|
/// The start address of the IDT.
|
||||||
@@ -65,9 +63,7 @@ void init_idt();
|
|||||||
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
|
/// @param handler Puntatore alla funzione che gestira' l'interrupt/Eccezione
|
||||||
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
|
/// @param options Le opzioni del descrittore (PRESENT,NOTPRESENT,KERNEL,USER)
|
||||||
/// @param seg_sel Il selettore del segmento della GDT.
|
/// @param seg_sel Il selettore del segmento della GDT.
|
||||||
void idt_set_gate(uint8_t index,
|
void idt_set_gate(uint8_t index, interrupt_handler_t handler, uint16_t options,
|
||||||
interrupt_handler_t handler,
|
|
||||||
uint16_t options,
|
|
||||||
uint8_t seg_sel);
|
uint8_t seg_sel);
|
||||||
|
|
||||||
//==== List of exceptions generated internally by the CPU ======================
|
//==== List of exceptions generated internally by the CPU ======================
|
||||||
|
|||||||
@@ -183,8 +183,8 @@ static inline int pci_extract_func(uint32_t device)
|
|||||||
static inline uint32_t pci_get_addr(uint32_t device, int field)
|
static inline uint32_t pci_get_addr(uint32_t device, int field)
|
||||||
{
|
{
|
||||||
return 0x80000000 | (pci_extract_bus(device) << 16) |
|
return 0x80000000 | (pci_extract_bus(device) << 16) |
|
||||||
(pci_extract_slot(device) << 11) |
|
(pci_extract_slot(device) << 11) | (pci_extract_func(device) << 8) |
|
||||||
(pci_extract_func(device) << 8) | ((field)&0xFC);
|
((field)&0xFC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
// TODO: doxygen comment.
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* @author Mirco De Marchi
|
||||||
|
* @date 2/02/2021
|
||||||
|
* @brief Header file for deadlock prevention algorithms.
|
||||||
|
* @copyright (c) University of Verona
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
/// @brief Resource allocation request status enumeration.
|
||||||
|
typedef enum {
|
||||||
|
SAFE, ///< State safe.
|
||||||
|
WAIT, ///< State waiting.
|
||||||
|
WAIT_UNSAFE, ///< State waiting for unsafe detection.
|
||||||
|
ERROR, ///< State error.
|
||||||
|
} deadlock_status_t;
|
||||||
|
|
||||||
|
/// @brief Request of resources perfomed by a task.
|
||||||
|
/// @param req_vec Array pointer of resource request for each task in the
|
||||||
|
/// system.
|
||||||
|
/// @param task_i Index of task that perform the request to use as array index.
|
||||||
|
/// @param arr_available Array of resources instances currently available.
|
||||||
|
/// @param mat_alloc Matrix of current resources instances allocation of
|
||||||
|
/// each task.
|
||||||
|
/// @param mat_need Matrix of current resources instances need of each
|
||||||
|
/// task. need[i][j] = max[i][j] - alloc[i][j]
|
||||||
|
/// @param n Number of tasks currently in the system.
|
||||||
|
/// @param m Number of resource types in the system (length of req_vec).
|
||||||
|
/// @return Status of the request (see status_t enum).
|
||||||
|
deadlock_status_t request(uint32_t *req_vec, size_t task_i,
|
||||||
|
uint32_t *arr_available, uint32_t ** mat_alloc, uint32_t **mat_need,
|
||||||
|
size_t n, size_t m);
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @author Mirco De Marchi
|
||||||
|
* @date 2/02/2021
|
||||||
|
* @brief Header file for deadlock deterministic simulation.
|
||||||
|
* @copyright (c) University of Verona
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// @brief Deadlock deterministic simulation start function.
|
||||||
|
void deadlock_simulation();
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
@@ -10,31 +10,15 @@
|
|||||||
|
|
||||||
/// Open for reading only.
|
/// Open for reading only.
|
||||||
#define O_RDONLY 0x00
|
#define O_RDONLY 0x00
|
||||||
|
|
||||||
/// Open for writing only.
|
/// Open for writing only.
|
||||||
#define O_WRONLY 0x01
|
#define O_WRONLY 0x01
|
||||||
|
|
||||||
/// Open for reading and writing.
|
/// Open for reading and writing.
|
||||||
#define O_RDWR 0x02
|
#define O_RDWR 0x02
|
||||||
|
|
||||||
/// If the file exists, this flag has no effect. Otherwise, the file is created.
|
/// If the file exists, this flag has no effect. Otherwise, the file is created.
|
||||||
#define O_CREAT 0x40
|
#define O_CREAT 0x40
|
||||||
|
|
||||||
/// The file offset will be set to the end of the file prior to each write.
|
/// The file offset will be set to the end of the file prior to each write.
|
||||||
#define O_APPEND 0x400
|
#define O_APPEND 0x400
|
||||||
|
|
||||||
/// @brief Given a pathname for a file, open() returns a file
|
|
||||||
/// descriptor, a small, nonnegative integer for use in
|
|
||||||
/// subsequent system calls.
|
|
||||||
/// @param pathname A pathname for a file.
|
|
||||||
/// @param flags Used to set the file status flags and file access modes
|
|
||||||
/// of the open file description.
|
|
||||||
/// @param mode Specifies the file mode bits be applied when a new file
|
|
||||||
/// is created.
|
|
||||||
/// @return Returns a file descriptor, a small, nonnegative integer
|
|
||||||
/// for use in subsequent system calls.
|
|
||||||
int sys_open(const char *pathname, int flags, mode_t mode);
|
|
||||||
|
|
||||||
/// @brief Deletes the file whose name is specified in filename.
|
/// @brief Deletes the file whose name is specified in filename.
|
||||||
/// @param pathname A path to a file.
|
/// @param pathname A path to a file.
|
||||||
/// @return On success, zero is returned. On error, -1 is returned,
|
/// @return On success, zero is returned. On error, -1 is returned,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ typedef struct initrd_file_t {
|
|||||||
/// Number used as delimiter, it must be set to 0xBF.
|
/// Number used as delimiter, it must be set to 0xBF.
|
||||||
int magic;
|
int magic;
|
||||||
/// The name of the file.
|
/// The name of the file.
|
||||||
char fileName[MAX_FILENAME_LENGTH];
|
char fileName[NAME_MAX];
|
||||||
/// The type of the file.
|
/// The type of the file.
|
||||||
short int file_type;
|
short int file_type;
|
||||||
/// The uid of the owner.
|
/// The uid of the owner.
|
||||||
|
|||||||
@@ -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
@@ -10,26 +10,25 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "dirent.h"
|
#include "dirent.h"
|
||||||
|
|
||||||
|
#define PATH_SEPARATOR '/'
|
||||||
|
#define PATH_SEPARATOR_STRING "/"
|
||||||
|
#define PATH_UP ".."
|
||||||
|
#define PATH_DOT "."
|
||||||
|
|
||||||
/// Identifies a file.
|
/// Identifies a file.
|
||||||
#define FS_FILE 0x01
|
#define FS_FILE 0x01U
|
||||||
|
|
||||||
/// Identifies a directory.
|
/// Identifies a directory.
|
||||||
#define FS_DIRECTORY 0x02
|
#define FS_DIRECTORY 0x02U
|
||||||
|
|
||||||
/// Identifies a character devies.
|
/// Identifies a character devies.
|
||||||
#define FS_CHARDEVICE 0x04
|
#define FS_CHARDEVICE 0x04U
|
||||||
|
|
||||||
/// Identifies a block devies.
|
/// Identifies a block devies.
|
||||||
#define FS_BLOCKDEVICE 0x08
|
#define FS_BLOCKDEVICE 0x08U
|
||||||
|
|
||||||
/// Identifies a pipe.
|
/// Identifies a pipe.
|
||||||
#define FS_PIPE 0x10
|
#define FS_PIPE 0x10U
|
||||||
|
|
||||||
/// Identifies a symbolic link.
|
/// Identifies a symbolic link.
|
||||||
#define FS_SYMLINK 0x20
|
#define FS_SYMLINK 0x20U
|
||||||
|
|
||||||
/// Identifies a mount-point.
|
/// Identifies a mount-point.
|
||||||
#define FS_MOUNTPOINT 0x40
|
#define FS_MOUNTPOINT 0x40U
|
||||||
|
|
||||||
/// Function used to open a directory.
|
/// Function used to open a directory.
|
||||||
typedef DIR *(*opendir_callback)(const char *);
|
typedef DIR *(*opendir_callback)(const char *);
|
||||||
@@ -103,7 +102,7 @@ typedef struct mountpoint_t {
|
|||||||
/// The id of the mountpoint.
|
/// The id of the mountpoint.
|
||||||
int32_t mp_id;
|
int32_t mp_id;
|
||||||
/// Name of the mountpoint.
|
/// Name of the mountpoint.
|
||||||
char mountpoint[MAX_FILENAME_LENGTH];
|
char mountpoint[NAME_MAX];
|
||||||
/// Maschera dei permessi.
|
/// Maschera dei permessi.
|
||||||
unsigned int pmask;
|
unsigned int pmask;
|
||||||
/// User ID.
|
/// User ID.
|
||||||
|
|||||||
@@ -12,18 +12,9 @@
|
|||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
|
|
||||||
/// The maximum length of a file name.
|
|
||||||
#define MAX_FILENAME_LENGTH 64
|
|
||||||
|
|
||||||
/// The maximum length of a path.
|
|
||||||
#define MAX_PATH_LENGTH 256
|
|
||||||
|
|
||||||
/// The maximum number of modules.
|
/// The maximum number of modules.
|
||||||
#define MAX_MODULES 10
|
#define MAX_MODULES 10
|
||||||
|
|
||||||
/// This should be in %eax.
|
|
||||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
|
||||||
|
|
||||||
/// Our kernel now loads at 0xC0000000, so what low memory address such as
|
/// Our kernel now loads at 0xC0000000, so what low memory address such as
|
||||||
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
|
/// 0xb800 you used to access, should be LOAD_MEMORY_ADDRESS + 0xb800
|
||||||
#define LOAD_MEMORY_ADDRESS 0x00000000
|
#define LOAD_MEMORY_ADDRESS 0x00000000
|
||||||
|
|||||||
@@ -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);
|
|
||||||
@@ -15,18 +15,8 @@
|
|||||||
/// @param file The file where the assertion is located.
|
/// @param file The file where the assertion is located.
|
||||||
/// @param line The line inside the file.
|
/// @param line The line inside the file.
|
||||||
/// @param function The function where the assertion is.
|
/// @param function The function where the assertion is.
|
||||||
static void __assert_fail(const char *assertion, const char *file,
|
void __assert_fail(const char *assertion, const char *file, unsigned int line,
|
||||||
unsigned int line, const char *function)
|
const char *function);
|
||||||
{
|
|
||||||
char message[1024];
|
|
||||||
sprintf(message,
|
|
||||||
"FILE: %s\n"
|
|
||||||
"LINE: %d\n"
|
|
||||||
"FUNC: %s\n\n"
|
|
||||||
"Assertion `%s` failed.\n",
|
|
||||||
file, line, (function ? function : "NO_FUN"), assertion);
|
|
||||||
kernel_panic(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Assert function.
|
/// @brief Assert function.
|
||||||
#define assert(expression) \
|
#define assert(expression) \
|
||||||
|
|||||||
@@ -39,3 +39,9 @@
|
|||||||
|
|
||||||
/// Maximum value a `signed long int' can hold.
|
/// Maximum value a `signed long int' can hold.
|
||||||
#define LONG_MIN (-LONG_MAX - 1L)
|
#define LONG_MIN (-LONG_MAX - 1L)
|
||||||
|
|
||||||
|
/// Maximum number of characters in a file name.
|
||||||
|
#define NAME_MAX 255
|
||||||
|
|
||||||
|
/// Maximum number of characters in a path name.
|
||||||
|
#define PATH_MAX 4096
|
||||||
@@ -9,8 +9,7 @@
|
|||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
|
||||||
/// @brief Structure used to implement the list_head data structure.
|
/// @brief Structure used to implement the list_head data structure.
|
||||||
typedef struct list_head
|
typedef struct list_head {
|
||||||
{
|
|
||||||
/// @brief The previous element.
|
/// @brief The previous element.
|
||||||
struct list_head *prev;
|
struct list_head *prev;
|
||||||
/// @brief The subsequent element.
|
/// @brief The subsequent element.
|
||||||
@@ -46,8 +45,7 @@ typedef struct list_head
|
|||||||
|
|
||||||
/// @brief Initializes the list_head.
|
/// @brief Initializes the list_head.
|
||||||
/// @param head The head for your list.
|
/// @param head The head for your list.
|
||||||
#define list_head_init(head) \
|
#define list_head_init(head) (head)->next = (head)->prev = (head)
|
||||||
(head)->next = (head)->prev = (head)
|
|
||||||
|
|
||||||
/// @brief Insert element l2 after l1.
|
/// @brief Insert element l2 after l1.
|
||||||
static inline void list_head_insert_after(list_head *l1, list_head *l2)
|
static inline void list_head_insert_after(list_head *l1, list_head *l2)
|
||||||
@@ -104,9 +102,7 @@ static inline int list_head_empty(list_head const * head)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a new entry between two known consecutive entries.
|
/// Insert a new entry between two known consecutive entries.
|
||||||
static inline void __list_add(list_head * new,
|
static inline void __list_add(list_head *new, list_head *prev, list_head *next)
|
||||||
list_head * prev,
|
|
||||||
list_head * next)
|
|
||||||
{
|
{
|
||||||
// [prev]-> <-[new]-> <-[next]
|
// [prev]-> <-[new]-> <-[next]
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
|
|
||||||
/// @brief A node of the queue.
|
/// @brief A node of the queue.
|
||||||
typedef struct queue_node_t
|
typedef struct queue_node_t {
|
||||||
{
|
|
||||||
/// The wrapped data.
|
/// The wrapped data.
|
||||||
void *data;
|
void *data;
|
||||||
/// The next node of the queue.
|
/// The next node of the queue.
|
||||||
@@ -19,8 +18,7 @@ typedef struct queue_node_t
|
|||||||
} queue_node_t;
|
} queue_node_t;
|
||||||
|
|
||||||
/// @brief The queue.
|
/// @brief The queue.
|
||||||
typedef struct queue_t
|
typedef struct queue_t {
|
||||||
{
|
|
||||||
/// The front of the queue.
|
/// The front of the queue.
|
||||||
queue_node_t *front;
|
queue_node_t *front;
|
||||||
/// The back of the queue.
|
/// The back of the queue.
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
/// @brief The maximum number of digits of an integer.
|
/// @brief The maximum number of digits of an integer.
|
||||||
#define MAX_DIGITS_IN_INTEGER 11
|
#define MAX_DIGITS_IN_INTEGER 11
|
||||||
|
/// @brief The size of 'gets' buffer.
|
||||||
|
#define GETS_BUFFERSIZE 255
|
||||||
|
|
||||||
#ifndef EOF
|
#ifndef EOF
|
||||||
/// @brief Define the End-Of-File.
|
/// @brief Define the End-Of-File.
|
||||||
|
|||||||
+14
-17
@@ -11,29 +11,26 @@
|
|||||||
/// @brief Malloc based on the number of elements.
|
/// @brief Malloc based on the number of elements.
|
||||||
void *calloc(size_t element_number, size_t element_size);
|
void *calloc(size_t element_number, size_t element_size);
|
||||||
|
|
||||||
/// @brief Allows to set the seed of the random value generator.
|
|
||||||
void srand(int x);
|
|
||||||
|
|
||||||
void *malloc(unsigned int size);
|
void *malloc(unsigned int size);
|
||||||
|
|
||||||
void free(void * p);
|
void free(void * p);
|
||||||
|
|
||||||
|
/// @brief Allocate a matrix with n rows of a specific size.
|
||||||
|
/// @param n Number of matrix rows.
|
||||||
|
/// @param size Size of each matrix row.
|
||||||
|
/// @return Matrix pointer.
|
||||||
|
void **mmalloc(size_t n, size_t size);
|
||||||
|
|
||||||
#ifndef MS_RAND
|
/// @brief Free a matrix of n rows.
|
||||||
|
/// @param src Matrix to free.
|
||||||
|
/// @param n Number of matrix rows.
|
||||||
|
void mfree(void **src, size_t n);
|
||||||
|
|
||||||
/// @brief The maximum value of the random.
|
/// The maximum value returned by the rand function.
|
||||||
#define RAND_MAX ((1U << 31) - 1)
|
#define RAND_MAX ((1U << 31U) - 1U)
|
||||||
|
|
||||||
|
/// @brief Allows to set the seed of the random value generator.
|
||||||
|
void srand(int x);
|
||||||
|
|
||||||
/// @brief Generates a random value.
|
/// @brief Generates a random value.
|
||||||
int rand();
|
int rand();
|
||||||
|
|
||||||
// MS rand
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define RAND_MAX_32 ((1U << 31) - 1)
|
|
||||||
|
|
||||||
#define RAND_MAX ((1U << 15) - 1)
|
|
||||||
|
|
||||||
int rand();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -84,10 +84,21 @@ void *kcalloc(unsigned int num, unsigned int size);
|
|||||||
/// @return
|
/// @return
|
||||||
void *krealloc(void *ptr, unsigned int size);
|
void *krealloc(void *ptr, unsigned int size);
|
||||||
|
|
||||||
|
/// @brief Allocate a matrix with n rows of a specific size.
|
||||||
|
/// @param n Number of matrix rows.
|
||||||
|
/// @param size Size of each matrix row.
|
||||||
|
/// @return Matrix pointer.
|
||||||
|
void **kmmalloc(size_t n, size_t size);
|
||||||
|
|
||||||
/// @brief Wrapper function for free.
|
/// @brief Wrapper function for free.
|
||||||
/// @param p
|
/// @param p
|
||||||
void kfree(void *p);
|
void kfree(void *p);
|
||||||
|
|
||||||
|
/// @brief Free a matrix of n rows.
|
||||||
|
/// @param src Matrix to free.
|
||||||
|
/// @param n Number of matrix rows.
|
||||||
|
void kmfree(void **src, size_t n);
|
||||||
|
|
||||||
/// @brief Allocates size bytes of uninitialized storage.
|
/// @brief Allocates size bytes of uninitialized storage.
|
||||||
//void *malloc(unsigned int size);
|
//void *malloc(unsigned int size);
|
||||||
|
|
||||||
|
|||||||
+43
-60
@@ -10,42 +10,45 @@
|
|||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
#define MULTIBOOT_FLAG_MEM 0x001
|
// The magic field should contain this.
|
||||||
|
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||||
|
// This should be in %eax.
|
||||||
|
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||||
|
|
||||||
#define MULTIBOOT_FLAG_DEVICE 0x002
|
/// Is there basic lower/upper memory information?
|
||||||
|
#define MULTIBOOT_FLAG_MEM 0x00000001U
|
||||||
#define MULTIBOOT_FLAG_CMDLINE 0x004
|
/// is there a boot device set?
|
||||||
|
#define MULTIBOOT_FLAG_DEVICE 0x00000002U
|
||||||
#define MULTIBOOT_FLAG_MODS 0x008
|
/// is the command-line defined?
|
||||||
|
#define MULTIBOOT_FLAG_CMDLINE 0x00000004U
|
||||||
#define MULTIBOOT_FLAG_AOUT 0x010
|
/// are there modules to do something with?
|
||||||
|
#define MULTIBOOT_FLAG_MODS 0x00000008U
|
||||||
#define MULTIBOOT_FLAG_ELF 0x020
|
/// is there a symbol table loaded?
|
||||||
|
#define MULTIBOOT_FLAG_AOUT 0x00000010U
|
||||||
#define MULTIBOOT_FLAG_MMAP 0x040
|
/// is there an ELF section header table?
|
||||||
|
#define MULTIBOOT_FLAG_ELF 0x00000020U
|
||||||
#define MULTIBOOT_FLAG_CONFIG 0x080
|
/// is there a full memory map?
|
||||||
|
#define MULTIBOOT_FLAG_MMAP 0x00000040U
|
||||||
#define MULTIBOOT_FLAG_LOADER 0x100
|
/// Is there drive info?
|
||||||
|
#define MULTIBOOT_FLAG_DRIVE_INFO 0x00000080U
|
||||||
#define MULTIBOOT_FLAG_APM 0x200
|
/// Is there a config table?
|
||||||
|
#define MULTIBOOT_FLAG_CONFIG_TABLE 0x00000100U
|
||||||
#define MULTIBOOT_FLAG_VBE 0x400
|
/// Is there a boot loader name?
|
||||||
|
#define MULTIBOOT_FLAG_BOOT_LOADER_NAME 0x00000200U
|
||||||
|
/// Is there a APM table?
|
||||||
|
#define MULTIBOOT_FLAG_APM_TABLE 0x00000400U
|
||||||
|
/// Is there video information?
|
||||||
|
#define MULTIBOOT_FLAG_VBE_INFO 0x00000800U
|
||||||
|
#define MULTIBOOT_FLAG_FRAMEBUFFER_INFO 0x00001000U
|
||||||
|
|
||||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||||
|
|
||||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||||
|
|
||||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||||
|
|
||||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||||
|
|
||||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||||
|
|
||||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||||
|
|
||||||
#define MULTIBOOT_MEMORY_NVS 4
|
#define MULTIBOOT_MEMORY_NVS 4
|
||||||
|
|
||||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||||
|
|
||||||
// +-------------------+
|
// +-------------------+
|
||||||
@@ -93,8 +96,7 @@
|
|||||||
// +-------------------+
|
// +-------------------+
|
||||||
|
|
||||||
/// The symbol table for a.out.
|
/// The symbol table for a.out.
|
||||||
typedef struct multiboot_aout_symbol_table
|
typedef struct multiboot_aout_symbol_table {
|
||||||
{
|
|
||||||
uint32_t tabsize;
|
uint32_t tabsize;
|
||||||
uint32_t strsize;
|
uint32_t strsize;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
@@ -102,8 +104,7 @@ typedef struct multiboot_aout_symbol_table
|
|||||||
} multiboot_aout_symbol_table_t;
|
} multiboot_aout_symbol_table_t;
|
||||||
|
|
||||||
/// The section header table for ELF.
|
/// The section header table for ELF.
|
||||||
typedef struct multiboot_elf_section_header_table
|
typedef struct multiboot_elf_section_header_table {
|
||||||
{
|
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
@@ -111,8 +112,7 @@ typedef struct multiboot_elf_section_header_table
|
|||||||
} multiboot_elf_section_header_table_t;
|
} multiboot_elf_section_header_table_t;
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
// TODO: doxygen comment.
|
||||||
typedef struct multiboot_mod_list
|
typedef struct multiboot_module {
|
||||||
{
|
|
||||||
// The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive.
|
// The memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive.
|
||||||
uint32_t mod_start;
|
uint32_t mod_start;
|
||||||
uint32_t mod_end;
|
uint32_t mod_end;
|
||||||
@@ -122,18 +122,17 @@ typedef struct multiboot_mod_list
|
|||||||
uint32_t pad;
|
uint32_t pad;
|
||||||
} multiboot_module_t;
|
} multiboot_module_t;
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
typedef struct multiboot_memory_map {
|
||||||
typedef struct multiboot_mmap_entry
|
|
||||||
{
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint64_t addr;
|
uint32_t base_addr_low;
|
||||||
uint64_t len;
|
uint32_t base_addr_high;
|
||||||
|
uint32_t length_low;
|
||||||
|
uint32_t length_high;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
} __attribute__((packed)) multiboot_memory_map_t;
|
} multiboot_memory_map_t;
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
// TODO: doxygen comment.
|
||||||
typedef struct multiboot_info
|
typedef struct multiboot_info {
|
||||||
{
|
|
||||||
/// Multiboot info version number.
|
/// Multiboot info version number.
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
@@ -151,8 +150,7 @@ typedef struct multiboot_info
|
|||||||
uint32_t mods_count;
|
uint32_t mods_count;
|
||||||
uint32_t mods_addr;
|
uint32_t mods_addr;
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
multiboot_aout_symbol_table_t aout_sym;
|
multiboot_aout_symbol_table_t aout_sym;
|
||||||
multiboot_elf_section_header_table_t elf_sec;
|
multiboot_elf_section_header_table_t elf_sec;
|
||||||
} u;
|
} u;
|
||||||
@@ -188,15 +186,12 @@ typedef struct multiboot_info
|
|||||||
uint32_t framebuffer_height;
|
uint32_t framebuffer_height;
|
||||||
uint32_t framebuffer_bpp;
|
uint32_t framebuffer_bpp;
|
||||||
uint32_t framebuffer_type;
|
uint32_t framebuffer_type;
|
||||||
union
|
union {
|
||||||
{
|
struct {
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32_t framebuffer_palette_addr;
|
uint32_t framebuffer_palette_addr;
|
||||||
uint16_t framebuffer_palette_num_colors;
|
uint16_t framebuffer_palette_num_colors;
|
||||||
};
|
};
|
||||||
struct
|
struct {
|
||||||
{
|
|
||||||
uint8_t framebuffer_red_field_position;
|
uint8_t framebuffer_red_field_position;
|
||||||
uint8_t framebuffer_red_mask_size;
|
uint8_t framebuffer_red_mask_size;
|
||||||
uint8_t framebuffer_green_field_position;
|
uint8_t framebuffer_green_field_position;
|
||||||
@@ -207,17 +202,5 @@ typedef struct multiboot_info
|
|||||||
};
|
};
|
||||||
} __attribute__((packed)) multiboot_info_t;
|
} __attribute__((packed)) multiboot_info_t;
|
||||||
|
|
||||||
// Be careful that the offset 0 is base_addr_low but no size.
|
|
||||||
/// @brief The memory map.
|
|
||||||
typedef struct memory_map
|
|
||||||
{
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t base_addr_low;
|
|
||||||
uint32_t base_addr_high;
|
|
||||||
uint32_t length_low;
|
|
||||||
uint32_t length_high;
|
|
||||||
uint32_t type;
|
|
||||||
} memory_map_t;
|
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
// TODO: doxygen comment.
|
||||||
void dump_multiboot(multiboot_info_t *mboot_ptr);
|
void dump_multiboot(multiboot_info_t *mboot_ptr);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
#include "list_head.h"
|
#include "list_head.h"
|
||||||
#include "signal_defs.h"
|
#include "signal_defs.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
/// The maximum length of a name for a task_struct.
|
/// The maximum length of a name for a task_struct.
|
||||||
#define TASK_NAME_MAX_LENGTH 100
|
#define TASK_NAME_MAX_LENGTH 100
|
||||||
@@ -24,6 +25,9 @@
|
|||||||
/// The default dimension of the stack of a process (1 MByte).
|
/// The default dimension of the stack of a process (1 MByte).
|
||||||
#define DEFAULT_STACK_SIZE 0x100000
|
#define DEFAULT_STACK_SIZE 0x100000
|
||||||
|
|
||||||
|
/// The maximum number of resources for a task.
|
||||||
|
#define TASK_RESOURCE_MAX_AMOUNT 32
|
||||||
|
|
||||||
//==== Task state ==============================================================
|
//==== Task state ==============================================================
|
||||||
// Used in tsk->state
|
// Used in tsk->state
|
||||||
/// The task is running.
|
/// The task is running.
|
||||||
@@ -170,7 +174,10 @@ typedef struct task_struct {
|
|||||||
int error_no;
|
int error_no;
|
||||||
|
|
||||||
/// The current working directory.
|
/// The current working directory.
|
||||||
char cwd[MAX_PATH_LENGTH];
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
/// Array of resource pointers that task need for.
|
||||||
|
struct resource *resources[TASK_RESOURCE_MAX_AMOUNT];
|
||||||
|
|
||||||
//==== Future work =========================================================
|
//==== Future work =========================================================
|
||||||
// - task's attributes:
|
// - task's attributes:
|
||||||
@@ -195,20 +202,8 @@ typedef struct task_struct {
|
|||||||
|
|
||||||
} task_struct;
|
} task_struct;
|
||||||
|
|
||||||
/// @brief Create a child process.
|
|
||||||
pid_t sys_vfork(pt_regs *r);
|
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
// TODO: doxygen comment.
|
||||||
char *get_current_dir_name();
|
char *get_current_dir_name();
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
|
||||||
void sys_getcwd(char *path, size_t size);
|
|
||||||
|
|
||||||
// TODO: doxygen comment.s
|
|
||||||
void sys_chdir(char const *path);
|
|
||||||
|
|
||||||
/// @brief Replaces the current process image with a new process image.
|
|
||||||
int sys_execve(pt_regs *r);
|
|
||||||
|
|
||||||
/// @brief Create and spawn the init process.
|
/// @brief Create and spawn the init process.
|
||||||
struct task_struct *create_init_process();
|
struct task_struct *create_init_process();
|
||||||
|
|||||||
@@ -62,21 +62,7 @@ void do_switch(task_struct *process, pt_regs *f);
|
|||||||
/// @param process The process that has to be executed
|
/// @param process The process that has to be executed
|
||||||
void enter_user_jmp(uintptr_t location, uintptr_t stack);
|
void enter_user_jmp(uintptr_t location, uintptr_t stack);
|
||||||
|
|
||||||
/// Returns the process ID (PID) of the calling process.
|
|
||||||
pid_t sys_getpid();
|
|
||||||
|
|
||||||
/// Returns the parent process ID (PPID) of the calling process.
|
|
||||||
pid_t sys_getppid();
|
|
||||||
|
|
||||||
/// @brief Sets the priority value of the given task.
|
/// @brief Sets the priority value of the given task.
|
||||||
int set_user_nice(task_struct *p, long nice);
|
int set_user_nice(task_struct *p, long nice);
|
||||||
|
|
||||||
/// @brief Adds the increment to the priority value of the task.
|
|
||||||
int sys_nice(int increment);
|
|
||||||
|
|
||||||
/// @brief Suspends execution of the calling thread until a child specified
|
|
||||||
/// by pid argument has changed state.
|
|
||||||
pid_t sys_waitpid(pid_t pid, int *status, int options);
|
|
||||||
|
|
||||||
/// The exit() function causes normal process termination.
|
|
||||||
void sys_exit(int exit_code);
|
|
||||||
|
|||||||
+4
-11
@@ -7,13 +7,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
#include "limits.h"
|
||||||
/// The maximum length for a name.
|
|
||||||
#define NAME_MAX 30
|
|
||||||
|
|
||||||
/// @brief Contains the entries of a directory.
|
/// @brief Contains the entries of a directory.
|
||||||
typedef struct dirent_t
|
typedef struct dirent_t {
|
||||||
{
|
|
||||||
/// The inode of the entry.
|
/// The inode of the entry.
|
||||||
ino_t d_ino;
|
ino_t d_ino;
|
||||||
|
|
||||||
@@ -25,17 +22,13 @@ typedef struct dirent_t
|
|||||||
} dirent_t;
|
} dirent_t;
|
||||||
|
|
||||||
/// @brief Contains information concerning a directory.
|
/// @brief Contains information concerning a directory.
|
||||||
typedef struct DIR
|
typedef struct DIR {
|
||||||
{
|
|
||||||
/// Filesystem directory handle.
|
/// Filesystem directory handle.
|
||||||
int handle;
|
int fd;
|
||||||
|
|
||||||
/// The currently opened entry.
|
/// The currently opened entry.
|
||||||
ino_t cur_entry;
|
ino_t cur_entry;
|
||||||
|
|
||||||
/// Path to the directory.
|
/// Path to the directory.
|
||||||
char path[NAME_MAX + 1];
|
char path[NAME_MAX + 1];
|
||||||
|
|
||||||
/// Next directory item.
|
/// Next directory item.
|
||||||
dirent_t entry;
|
dirent_t entry;
|
||||||
} DIR;
|
} DIR;
|
||||||
|
|||||||
@@ -38,5 +38,4 @@ typedef struct stat_t
|
|||||||
/// @return Returns a negative value on failure.
|
/// @return Returns a negative value on failure.
|
||||||
int stat(const char *path, stat_t *buf);
|
int stat(const char *path, stat_t *buf);
|
||||||
|
|
||||||
// TODO: doxygen comment.
|
|
||||||
int mkdir(const char *path, mode_t mode);
|
int mkdir(const char *path, mode_t mode);
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ ssize_t write(int fd, void *buf, size_t nbytes);
|
|||||||
int open(const char *pathname, int flags, mode_t mode);
|
int open(const char *pathname, int flags, mode_t mode);
|
||||||
|
|
||||||
/// @brief Close a file descriptor.
|
/// @brief Close a file descriptor.
|
||||||
/// @param fildes The file descriptor.
|
/// @param fd The file descriptor.
|
||||||
/// @return The result of the operation.
|
/// @return The result of the operation.
|
||||||
int close(int fildes);
|
int close(int fd);
|
||||||
|
|
||||||
/// @brief Removes the given directory.
|
/// @brief Removes the given directory.
|
||||||
/// @param path The path to the directory to remove.
|
/// @param path The path to the directory to remove.
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
#define SYS_LEN 257
|
#define SYS_LEN 257
|
||||||
|
|
||||||
/// @brief Holds information concerning the machine and the os.
|
/// @brief Holds information concerning the machine and the os.
|
||||||
typedef struct utsname_t
|
typedef struct utsname_t {
|
||||||
{
|
|
||||||
/// The name of the system.
|
/// The name of the system.
|
||||||
char sysname[SYS_LEN];
|
char sysname[SYS_LEN];
|
||||||
|
|
||||||
|
|||||||
+52
-381
@@ -6,7 +6,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "syscall_types.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "dirent.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "stat.h"
|
||||||
|
|
||||||
/// @brief Initialize the system calls.
|
/// @brief Initialize the system calls.
|
||||||
void syscall_init();
|
void syscall_init();
|
||||||
@@ -14,400 +18,67 @@ void syscall_init();
|
|||||||
/// @brief Handler for the system calls.
|
/// @brief Handler for the system calls.
|
||||||
void syscall_handler(pt_regs *r);
|
void syscall_handler(pt_regs *r);
|
||||||
|
|
||||||
// Return result in eax ("=a").
|
/// The exit() function causes normal process termination.
|
||||||
// System call number in eax ("a").
|
void sys_exit(int exit_code);
|
||||||
#define DEFN_SYSCALL0(__res, num) \
|
|
||||||
__asm__ __volatile__("INT $0x80" : "=a"(__res) : "a"(num))
|
|
||||||
|
|
||||||
// Return result in eax ("=a").
|
/// @brief Read data from a file descriptor.
|
||||||
// System call number in eax ("a").
|
/// @param fd The file descriptor.
|
||||||
// p1 in ebx ("+b").
|
/// @param buf The buffer.
|
||||||
#define DEFN_SYSCALL1(__res, num, p1) \
|
/// @param nbytes The number of bytes to read.
|
||||||
__asm__ __volatile__("INT $0x80" : "=a"(__res), "+b"(p1) : "a"(num))
|
/// @return The number of read characters.
|
||||||
|
ssize_t sys_read(int fd, void *buf, size_t nbytes);
|
||||||
|
|
||||||
#define DEFN_SYSCALL2(__res, num, p1, p2) \
|
/// @brief Write data into a file descriptor.
|
||||||
__asm__ __volatile__("INT $0x80" \
|
/// @param fd The file descriptor.
|
||||||
: "=a"(__res), "+b"(p1), "+c"(p2) \
|
/// @param buf The buffer collecting data to written.
|
||||||
: "a"(num));
|
/// @param nbytes The number of bytes to write.
|
||||||
|
/// @return The number of written bytes.
|
||||||
|
ssize_t sys_write(int fd, void *buf, size_t nbytes);
|
||||||
|
|
||||||
#define DEFN_SYSCALL3(__res, num, p1, p2, p3) \
|
/// @brief Given a pathname for a file, open() returns a file
|
||||||
__asm__ __volatile__("INT $0x80" \
|
/// descriptor, a small, nonnegative integer for use in
|
||||||
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3) \
|
/// subsequent system calls.
|
||||||
: "a"(num))
|
/// @param pathname A pathname for a file.
|
||||||
|
/// @param flags Used to set the file status flags and file access modes
|
||||||
|
/// of the open file description.
|
||||||
|
/// @param mode Specifies the file mode bits be applied when a new file
|
||||||
|
/// is created.
|
||||||
|
/// @return Returns a file descriptor, a small, nonnegative integer
|
||||||
|
/// for use in subsequent system calls.
|
||||||
|
int sys_open(const char *pathname, int flags, mode_t mode);
|
||||||
|
|
||||||
#define DEFN_SYSCALL4(__res, num, p1, p2, p3, p4) \
|
/// @brief
|
||||||
__asm__ __volatile__("INT $0x80" \
|
/// @param fd
|
||||||
: "=a"(__res), "+b"(p1), "+c"(p2), "+d"(p3), "+S"(p4) \
|
/// @return
|
||||||
: "a"(num))
|
int sys_close(int fd);
|
||||||
|
|
||||||
#define DEFN_SYSCALL5(fn, num, P1, P2, P3, P4, P5) \
|
/// @brief Suspends execution of the calling thread until a child specified
|
||||||
int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
/// by pid argument has changed state.
|
||||||
{ \
|
pid_t sys_waitpid(pid_t pid, int *status, int options);
|
||||||
int __res; \
|
|
||||||
__asm__ __volatile__("push eax\n movl %2,%%ebx; INT 0x80; pop %%ebx" \
|
|
||||||
: "=a"(__res) \
|
|
||||||
: "0"(num), "r"((int)(p1)), "c"((int)(p2)), \
|
|
||||||
"d"((int)(p3)), "S"((int)(p4)), \
|
|
||||||
"D"((int)(p5))); \
|
|
||||||
return __res; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __NR_exit 1
|
/// @brief Replaces the current process image with a new process image.
|
||||||
|
int sys_execve(pt_regs *r);
|
||||||
|
|
||||||
#define __NR_fork 2
|
void sys_chdir(char const *path);
|
||||||
|
|
||||||
#define __NR_read 3
|
/// Returns the process ID (PID) of the calling process.
|
||||||
|
pid_t sys_getpid();
|
||||||
|
|
||||||
#define __NR_write 4
|
/// @brief Adds the increment to the priority value of the task.
|
||||||
|
int sys_nice(int increment);
|
||||||
|
|
||||||
#define __NR_open 5
|
/// Returns the parent process ID (PPID) of the calling process.
|
||||||
|
pid_t sys_getppid();
|
||||||
|
|
||||||
#define __NR_close 6
|
int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg);
|
||||||
|
|
||||||
#define __NR_waitpid 7
|
void sys_getcwd(char *path, size_t size);
|
||||||
|
|
||||||
#define __NR_creat 8
|
/// @brief Create a child process.
|
||||||
|
pid_t sys_vfork(pt_regs *r);
|
||||||
|
|
||||||
#define __NR_link 9
|
int sys_stat(const char *path, stat_t *buf);
|
||||||
|
|
||||||
#define __NR_unlink 10
|
int sys_mkdir(const char *path, mode_t mode);
|
||||||
|
|
||||||
#define __NR_execve 11
|
dirent_t *sys_readdir(DIR *dirp);
|
||||||
|
|
||||||
#define __NR_chdir 12
|
|
||||||
|
|
||||||
#define __NR_time 13
|
|
||||||
|
|
||||||
#define __NR_mknod 14
|
|
||||||
|
|
||||||
#define __NR_chmod 15
|
|
||||||
|
|
||||||
#define __NR_lchown 16
|
|
||||||
|
|
||||||
#define __NR_stat 18
|
|
||||||
|
|
||||||
#define __NR_lseek 19
|
|
||||||
|
|
||||||
#define __NR_getpid 20
|
|
||||||
|
|
||||||
#define __NR_mount 21
|
|
||||||
|
|
||||||
#define __NR_oldumount 22
|
|
||||||
|
|
||||||
#define __NR_setuid 23
|
|
||||||
|
|
||||||
#define __NR_getuid 24
|
|
||||||
|
|
||||||
#define __NR_stime 25
|
|
||||||
|
|
||||||
#define __NR_ptrace 26
|
|
||||||
|
|
||||||
#define __NR_alarm 27
|
|
||||||
|
|
||||||
#define __NR_fstat 28
|
|
||||||
|
|
||||||
#define __NR_pause 29
|
|
||||||
|
|
||||||
#define __NR_utime 30
|
|
||||||
|
|
||||||
#define __NR_access 33
|
|
||||||
|
|
||||||
#define __NR_nice 34
|
|
||||||
|
|
||||||
#define __NR_sync 36
|
|
||||||
|
|
||||||
#define __NR_kill 37
|
|
||||||
|
|
||||||
#define __NR_rename 38
|
|
||||||
|
|
||||||
#define __NR_mkdir 39
|
|
||||||
|
|
||||||
#define __NR_rmdir 40
|
|
||||||
|
|
||||||
#define __NR_dup 41
|
|
||||||
|
|
||||||
#define __NR_pipe 42
|
|
||||||
|
|
||||||
#define __NR_times 43
|
|
||||||
|
|
||||||
#define __NR_brk 45
|
|
||||||
|
|
||||||
#define __NR_setgid 46
|
|
||||||
|
|
||||||
#define __NR_getgid 47
|
|
||||||
|
|
||||||
#define __NR_signal 48
|
|
||||||
|
|
||||||
#define __NR_geteuid 49
|
|
||||||
|
|
||||||
#define __NR_getegid 50
|
|
||||||
|
|
||||||
#define __NR_acct 51
|
|
||||||
|
|
||||||
#define __NR_umount 52
|
|
||||||
|
|
||||||
#define __NR_ioctl 54
|
|
||||||
|
|
||||||
#define __NR_fcntl 55
|
|
||||||
|
|
||||||
#define __NR_setpgid 57
|
|
||||||
|
|
||||||
#define __NR_olduname 59
|
|
||||||
|
|
||||||
#define __NR_umask 60
|
|
||||||
|
|
||||||
#define __NR_chroot 61
|
|
||||||
|
|
||||||
#define __NR_ustat 62
|
|
||||||
|
|
||||||
#define __NR_dup2 63
|
|
||||||
|
|
||||||
#define __NR_getppid 64
|
|
||||||
|
|
||||||
#define __NR_getpgrp 65
|
|
||||||
|
|
||||||
#define __NR_setsid 66
|
|
||||||
|
|
||||||
#define __NR_sigaction 67
|
|
||||||
|
|
||||||
#define __NR_sgetmask 68
|
|
||||||
|
|
||||||
#define __NR_ssetmask 69
|
|
||||||
|
|
||||||
#define __NR_setreuid 70
|
|
||||||
|
|
||||||
#define __NR_setregid 71
|
|
||||||
|
|
||||||
#define __NR_sigsuspend 72
|
|
||||||
|
|
||||||
#define __NR_sigpending 73
|
|
||||||
|
|
||||||
#define __NR_sethostname 74
|
|
||||||
|
|
||||||
#define __NR_setrlimit 75
|
|
||||||
|
|
||||||
#define __NR_getrlimit 76
|
|
||||||
|
|
||||||
#define __NR_getrusage 77
|
|
||||||
|
|
||||||
#define __NR_gettimeofday 78
|
|
||||||
|
|
||||||
#define __NR_settimeofday 79
|
|
||||||
|
|
||||||
#define __NR_getgroups 80
|
|
||||||
|
|
||||||
#define __NR_setgroups 81
|
|
||||||
|
|
||||||
#define __NR_symlink 83
|
|
||||||
|
|
||||||
#define __NR_lstat 84
|
|
||||||
|
|
||||||
#define __NR_readlink 85
|
|
||||||
|
|
||||||
#define __NR_uselib 86
|
|
||||||
|
|
||||||
#define __NR_swapon 87
|
|
||||||
|
|
||||||
#define __NR_reboot 88
|
|
||||||
|
|
||||||
#define __NR_readdir 89
|
|
||||||
|
|
||||||
#define __NR_mmap 90
|
|
||||||
|
|
||||||
#define __NR_munmap 91
|
|
||||||
|
|
||||||
#define __NR_truncate 92
|
|
||||||
|
|
||||||
#define __NR_ftruncate 93
|
|
||||||
|
|
||||||
#define __NR_fchmod 94
|
|
||||||
|
|
||||||
#define __NR_fchown 95
|
|
||||||
|
|
||||||
#define __NR_getpriority 96
|
|
||||||
|
|
||||||
#define __NR_setpriority 97
|
|
||||||
|
|
||||||
#define __NR_statfs 99
|
|
||||||
|
|
||||||
#define __NR_fstatfs 100
|
|
||||||
|
|
||||||
#define __NR_ioperm 101
|
|
||||||
|
|
||||||
#define __NR_socketcall 102
|
|
||||||
|
|
||||||
#define __NR_syslog 103
|
|
||||||
|
|
||||||
#define __NR_setitimer 104
|
|
||||||
|
|
||||||
#define __NR_getitimer 105
|
|
||||||
|
|
||||||
#define __NR_newstat 106
|
|
||||||
|
|
||||||
#define __NR_newlstat 107
|
|
||||||
|
|
||||||
#define __NR_newfstat 108
|
|
||||||
|
|
||||||
#define __NR_uname 109
|
|
||||||
|
|
||||||
#define __NR_iopl 110
|
|
||||||
|
|
||||||
#define __NR_vhangup 111
|
|
||||||
|
|
||||||
#define __NR_idle 112
|
|
||||||
|
|
||||||
#define __NR_vm86old 113
|
|
||||||
|
|
||||||
#define __NR_wait4 114
|
|
||||||
|
|
||||||
#define __NR_swapoff 115
|
|
||||||
|
|
||||||
#define __NR_sysinfo 116
|
|
||||||
|
|
||||||
#define __NR_ipc 117
|
|
||||||
|
|
||||||
#define __NR_fsync 118
|
|
||||||
|
|
||||||
#define __NR_sigreturn 119
|
|
||||||
|
|
||||||
#define __NR_clone 120
|
|
||||||
|
|
||||||
#define __NR_setdomainname 121
|
|
||||||
|
|
||||||
#define __NR_newuname 122
|
|
||||||
|
|
||||||
#define __NR_modify_ldt 123
|
|
||||||
|
|
||||||
#define __NR_adjtimex 124
|
|
||||||
|
|
||||||
#define __NR_mprotect 125
|
|
||||||
|
|
||||||
#define __NR_sigprocmask 126
|
|
||||||
|
|
||||||
#define __NR_create_module 127
|
|
||||||
|
|
||||||
#define __NR_init_module 128
|
|
||||||
|
|
||||||
#define __NR_delete_module 129
|
|
||||||
|
|
||||||
#define __NR_get_kernel_syms 130
|
|
||||||
|
|
||||||
#define __NR_quotactl 131
|
|
||||||
|
|
||||||
#define __NR_getpgid 132
|
|
||||||
|
|
||||||
#define __NR_fchdir 133
|
|
||||||
|
|
||||||
#define __NR_bdflush 134
|
|
||||||
|
|
||||||
#define __NR_sysfs 135
|
|
||||||
|
|
||||||
#define __NR_personality 136
|
|
||||||
|
|
||||||
#define __NR_setfsuid 138
|
|
||||||
|
|
||||||
#define __NR_setfsgid 139
|
|
||||||
|
|
||||||
#define __NR_llseek 140
|
|
||||||
|
|
||||||
#define __NR_getdents 141
|
|
||||||
|
|
||||||
#define __NR_select 142
|
|
||||||
|
|
||||||
#define __NR_flock 143
|
|
||||||
|
|
||||||
#define __NR_msync 144
|
|
||||||
|
|
||||||
#define __NR_readv 145
|
|
||||||
|
|
||||||
#define __NR_writev 146
|
|
||||||
|
|
||||||
#define __NR_getsid 147
|
|
||||||
|
|
||||||
#define __NR_fdatasync 148
|
|
||||||
|
|
||||||
#define __NR_sysctl 149
|
|
||||||
|
|
||||||
#define __NR_mlock 150
|
|
||||||
|
|
||||||
#define __NR_munlock 151
|
|
||||||
|
|
||||||
#define __NR_mlockall 152
|
|
||||||
|
|
||||||
#define __NR_munlockall 153
|
|
||||||
|
|
||||||
#define __NR_sched_setparam 154
|
|
||||||
|
|
||||||
#define __NR_sched_getparam 155
|
|
||||||
|
|
||||||
#define __NR_sched_setscheduler 156
|
|
||||||
|
|
||||||
#define __NR_sched_getscheduler 157
|
|
||||||
|
|
||||||
#define __NR_sched_yield 158
|
|
||||||
|
|
||||||
#define __NR_sched_get_priority_max 159
|
|
||||||
|
|
||||||
#define __NR_sched_get_priority_min 160
|
|
||||||
|
|
||||||
#define __NR_sched_rr_get_interval 161
|
|
||||||
|
|
||||||
#define __NR_nanosleep 162
|
|
||||||
|
|
||||||
#define __NR_mremap 163
|
|
||||||
|
|
||||||
#define __NR_setresuid 164
|
|
||||||
|
|
||||||
#define __NR_getresuid 165
|
|
||||||
|
|
||||||
#define __NR_vm86 166
|
|
||||||
|
|
||||||
#define __NR_query_module 167
|
|
||||||
|
|
||||||
#define __NR_poll 168
|
|
||||||
|
|
||||||
#define __NR_nfsservctl 169
|
|
||||||
|
|
||||||
#define __NR_setresgid 170
|
|
||||||
|
|
||||||
#define __NR_getresgid 171
|
|
||||||
|
|
||||||
#define __NR_prctl 172
|
|
||||||
|
|
||||||
#define __NR_rt_sigreturn 173
|
|
||||||
|
|
||||||
#define __NR_rt_sigaction 174
|
|
||||||
|
|
||||||
#define __NR_rt_sigprocmask 175
|
|
||||||
|
|
||||||
#define __NR_rt_sigpending 176
|
|
||||||
|
|
||||||
#define __NR_rt_sigtimedwait 177
|
|
||||||
|
|
||||||
#define __NR_rt_sigqueueinfo 178
|
|
||||||
|
|
||||||
#define __NR_rt_sigsuspend 179
|
|
||||||
|
|
||||||
#define __NR_pread 180
|
|
||||||
|
|
||||||
#define __NR_pwrite 181
|
|
||||||
|
|
||||||
#define __NR_chown 182
|
|
||||||
|
|
||||||
#define __NR_getcwd 183
|
|
||||||
|
|
||||||
#define __NR_capget 184
|
|
||||||
|
|
||||||
#define __NR_capset 185
|
|
||||||
|
|
||||||
#define __NR_sigaltstack 186
|
|
||||||
|
|
||||||
#define __NR_sendfile 187
|
|
||||||
|
|
||||||
#define __NR_vfork 188
|
|
||||||
|
|
||||||
#define __NR_free 189 // TODO: remove me!
|
|
||||||
|
|
||||||
#define SYSCALL_NUMBER 190
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
@@ -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
|
||||||
@@ -91,3 +91,6 @@ void cmd_ipcrm(int argc, char **argv);
|
|||||||
|
|
||||||
/// @brief Change the nice value.
|
/// @brief Change the nice value.
|
||||||
void cmd_nice(int argc, char **argv);
|
void cmd_nice(int argc, char **argv);
|
||||||
|
|
||||||
|
/// @brief Test deadlock behavior with tasks and shared resources.
|
||||||
|
void cmd_deadlock(int argc, char **argv);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
/// Maximum length of credentials.
|
/// Maximum length of credentials.
|
||||||
#define CREDENTIALS_LENGTH 50
|
#define CREDENTIALS_LENGTH 50
|
||||||
@@ -55,7 +56,7 @@ typedef struct userenv_t
|
|||||||
char username[CREDENTIALS_LENGTH];
|
char username[CREDENTIALS_LENGTH];
|
||||||
|
|
||||||
/// The current path.
|
/// The current path.
|
||||||
char cur_path[MAX_PATH_LENGTH];
|
char cur_path[PATH_MAX];
|
||||||
|
|
||||||
/// The user identifier.
|
/// The user identifier.
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
|
|||||||
+16
-30
@@ -98,16 +98,14 @@ struct {
|
|||||||
{ 0x010105, "PCI native mode-only controller" },
|
{ 0x010105, "PCI native mode-only controller" },
|
||||||
{ 0x01010a, "ISA Compatibility mode controller, supports both channels "
|
{ 0x01010a, "ISA Compatibility mode controller, supports both channels "
|
||||||
"switched to PCI native mode" },
|
"switched to PCI native mode" },
|
||||||
{ 0x01010f,
|
{ 0x01010f, "PCI native mode controller, supports both channels switched "
|
||||||
"PCI native mode controller, supports both channels switched "
|
|
||||||
"to ISA compatibility mode" },
|
"to ISA compatibility mode" },
|
||||||
{ 0x010180,
|
{ 0x010180,
|
||||||
"ISA Compatibility mode-only controller, supports bus mastering" },
|
"ISA Compatibility mode-only controller, supports bus mastering" },
|
||||||
{ 0x010185, "PCI native mode-only controller, supports bus mastering" },
|
{ 0x010185, "PCI native mode-only controller, supports bus mastering" },
|
||||||
{ 0x01018a, "ISA Compatibility mode controller, supports both channels "
|
{ 0x01018a, "ISA Compatibility mode controller, supports both channels "
|
||||||
"switched to PCI native mode, supports bus mastering" },
|
"switched to PCI native mode, supports bus mastering" },
|
||||||
{ 0x01018f,
|
{ 0x01018f, "PCI native mode controller, supports both channels switched "
|
||||||
"PCI native mode controller, supports both channels switched "
|
|
||||||
"\to ISA compatibility mode, supports bus mastering" },
|
"\to ISA compatibility mode, supports bus mastering" },
|
||||||
|
|
||||||
{ 0x010200, "Floppy disk controller" },
|
{ 0x010200, "Floppy disk controller" },
|
||||||
@@ -154,10 +152,8 @@ struct {
|
|||||||
{ 0x060600, "NuBus bridge" },
|
{ 0x060600, "NuBus bridge" },
|
||||||
{ 0x060700, "CardBus bridge" },
|
{ 0x060700, "CardBus bridge" },
|
||||||
// { 0x0608xx , "RACEway bridge" },
|
// { 0x0608xx , "RACEway bridge" },
|
||||||
{ 0x060940,
|
{ 0x060940, "PCI-to-PCI bridge, Semi-transparent, primary facing Host" },
|
||||||
"PCI-to-PCI bridge, Semi-transparent, primary facing Host" },
|
{ 0x060980, "PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
|
||||||
{ 0x060980,
|
|
||||||
"PCI-to-PCI bridge, Semi-transparent, secondary facing Host" },
|
|
||||||
{ 0x060A00, "InfiniBand-to-PCI host bridge" },
|
{ 0x060A00, "InfiniBand-to-PCI host bridge" },
|
||||||
{ 0x068000, "Bridge device" },
|
{ 0x068000, "Bridge device" },
|
||||||
|
|
||||||
@@ -273,8 +269,7 @@ struct {
|
|||||||
|
|
||||||
const char *pci_vendor_lookup(unsigned short vendor_id)
|
const char *pci_vendor_lookup(unsigned short vendor_id)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]);
|
for (int i = 0; i < sizeof(_pci_vendors) / sizeof(_pci_vendors[0]); ++i) {
|
||||||
++i) {
|
|
||||||
if (_pci_vendors[i].id == vendor_id) {
|
if (_pci_vendors[i].id == vendor_id) {
|
||||||
return _pci_vendors[i].name;
|
return _pci_vendors[i].name;
|
||||||
}
|
}
|
||||||
@@ -286,8 +281,7 @@ const char *pci_vendor_lookup(unsigned short vendor_id)
|
|||||||
const char *pci_device_lookup(unsigned short vendor_id,
|
const char *pci_device_lookup(unsigned short vendor_id,
|
||||||
unsigned short device_id)
|
unsigned short device_id)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]);
|
for (int i = 0; i < sizeof(_pci_devices) / sizeof(_pci_devices[0]); ++i) {
|
||||||
++i) {
|
|
||||||
if (_pci_devices[i].ven_id == vendor_id &&
|
if (_pci_devices[i].ven_id == vendor_id &&
|
||||||
_pci_devices[i].dev_id == device_id) {
|
_pci_devices[i].dev_id == device_id) {
|
||||||
return _pci_devices[i].name;
|
return _pci_devices[i].name;
|
||||||
@@ -299,8 +293,7 @@ const char *pci_device_lookup(unsigned short vendor_id,
|
|||||||
|
|
||||||
const char *pci_class_lookup(uint32_t class_code)
|
const char *pci_class_lookup(uint32_t class_code)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]);
|
for (int i = 0; i < sizeof(_pci_classes) / sizeof(_pci_classes[0]); ++i) {
|
||||||
++i) {
|
|
||||||
if (_pci_classes[i].id == class_code) {
|
if (_pci_classes[i].id == class_code) {
|
||||||
return _pci_classes[i].name;
|
return _pci_classes[i].name;
|
||||||
}
|
}
|
||||||
@@ -325,8 +318,7 @@ void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func,
|
|||||||
pci_scan_hit(f, dev, extra);
|
pci_scan_hit(f, dev, extra);
|
||||||
}
|
}
|
||||||
if (pci_find_type(dev) == PCI_TYPE_BRIDGE) {
|
if (pci_find_type(dev) == PCI_TYPE_BRIDGE) {
|
||||||
pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1),
|
pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1), extra);
|
||||||
extra);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,8 +415,7 @@ int pci_get_interrupt(uint32_t device)
|
|||||||
|
|
||||||
uint32_t int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1);
|
uint32_t int_line = pci_read_field(device, PCI_INTERRUPT_LINE, 1);
|
||||||
|
|
||||||
dbg_print(
|
dbg_print("Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?"
|
||||||
"Slot is %d, irq pin is %d, so pirq is %d and that maps to %d?"
|
|
||||||
"int_line=%d\n",
|
"int_line=%d\n",
|
||||||
pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq],
|
pci_extract_slot(device), irq_pin, pirq, pci_remaps[pirq],
|
||||||
int_line);
|
int_line);
|
||||||
@@ -455,8 +446,8 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
|
|||||||
void *extra)
|
void *extra)
|
||||||
{
|
{
|
||||||
(void)extra;
|
(void)extra;
|
||||||
dbg_print("%2x:%2x.%d\n", pci_extract_bus(device),
|
dbg_print("%2x:%2x.%d\n", pci_extract_bus(device), pci_extract_slot(device),
|
||||||
pci_extract_slot(device), pci_extract_func(device), deviceid);
|
pci_extract_func(device), deviceid);
|
||||||
dbg_print(" Vendor : [0x%06x] %s\n", vendorid,
|
dbg_print(" Vendor : [0x%06x] %s\n", vendorid,
|
||||||
pci_vendor_lookup(vendorid));
|
pci_vendor_lookup(vendorid));
|
||||||
dbg_print(" Device : [0x%06x] %s\n", deviceid,
|
dbg_print(" Device : [0x%06x] %s\n", deviceid,
|
||||||
@@ -475,18 +466,13 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
|
|||||||
pci_read_field(device, PCI_LATENCY_TIMER, 1));
|
pci_read_field(device, PCI_LATENCY_TIMER, 1));
|
||||||
dbg_print(" Header Type : %2d\n",
|
dbg_print(" Header Type : %2d\n",
|
||||||
pci_read_field(device, PCI_HEADER_TYPE, 1));
|
pci_read_field(device, PCI_HEADER_TYPE, 1));
|
||||||
dbg_print(" BIST : %2d\n",
|
dbg_print(" BIST : %2d\n", pci_read_field(device, PCI_BIST, 1));
|
||||||
pci_read_field(device, PCI_BIST, 1));
|
dbg_print(" BAR0 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_0, 4));
|
||||||
dbg_print(" BAR0 : 0x%08x",
|
dbg_print(" BAR1 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_1, 4));
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_0, 4));
|
|
||||||
dbg_print(" BAR1 : 0x%08x",
|
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_1, 4));
|
|
||||||
dbg_print(" BAR2 : 0x%08x\n",
|
dbg_print(" BAR2 : 0x%08x\n",
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_2, 4));
|
pci_read_field(device, PCI_BASE_ADDRESS_2, 4));
|
||||||
dbg_print(" BAR3 : 0x%08x",
|
dbg_print(" BAR3 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_3, 4));
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_3, 4));
|
dbg_print(" BAR4 : 0x%08x", pci_read_field(device, PCI_BASE_ADDRESS_4, 4));
|
||||||
dbg_print(" BAR4 : 0x%08x",
|
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_4, 4));
|
|
||||||
dbg_print(" BAR6 : 0x%08x\n",
|
dbg_print(" BAR6 : 0x%08x\n",
|
||||||
pci_read_field(device, PCI_BASE_ADDRESS_5, 4));
|
pci_read_field(device, PCI_BASE_ADDRESS_5, 4));
|
||||||
dbg_print(" Cardbus CIS : 0x%08x\n",
|
dbg_print(" Cardbus CIS : 0x%08x\n",
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/// MentOS, The Mentoring Operating system project
|
||||||
|
/// @file deadlock_prevention.c
|
||||||
|
/// @brief Deadlock prevention algorithms source code.
|
||||||
|
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
||||||
|
/// See LICENSE.md for details.
|
||||||
|
///
|
||||||
|
/// Complete request() and state_safe() functions, according to what you learnt
|
||||||
|
/// in deadlock lectures.
|
||||||
|
///
|
||||||
|
/// In order to complete the functions I prepared for you a library to manage
|
||||||
|
/// easily arrays. The library is arr_math.h and you can find the documentation
|
||||||
|
/// in include/util/arr_math.h header file.
|
||||||
|
///
|
||||||
|
/// In addition you will find the same data structures that you have seen in
|
||||||
|
/// class:
|
||||||
|
/// - available: number of resources instances currently available;
|
||||||
|
/// - max: matrix of the maximum number of resources instances that each task
|
||||||
|
/// may require;
|
||||||
|
/// - alloc: matrix of current resources instances allocation of each task.
|
||||||
|
/// - need: matrix of current resources instances needs of each task.
|
||||||
|
/// Assume that these data structure are already filled with the
|
||||||
|
/// information described, in other words, you need to use these data structures
|
||||||
|
/// in read-only.
|
||||||
|
///
|
||||||
|
/// Suggestion!
|
||||||
|
/// From arr_math.h you may need only: arr_g_any(), arr_add(), arr_sub(),
|
||||||
|
/// all() and arr_ne();
|
||||||
|
|
||||||
|
#include "deadlock_prevention.h"
|
||||||
|
|
||||||
|
#include "arr_math.h"
|
||||||
|
#include "kheap.h"
|
||||||
|
|
||||||
|
/// @brief Check if the current system resource allocation maintains the system
|
||||||
|
/// in a safe state.
|
||||||
|
/// @param arr_available Array of resources instances currently available.
|
||||||
|
/// @param mat_alloc Matrix of current resources instances allocation of
|
||||||
|
/// each task.
|
||||||
|
/// @param mat_need Matrix of current resources instances need of each
|
||||||
|
/// task.
|
||||||
|
/// @param n Number of tasks currently in the system.
|
||||||
|
/// @param m Number of resource types in the system (length of req_vec).
|
||||||
|
static bool_t state_safe(uint32_t *arr_available, uint32_t **mat_alloc,
|
||||||
|
uint32_t **mat_need, size_t n, size_t m)
|
||||||
|
{
|
||||||
|
// Allocate work as a copy of available.
|
||||||
|
uint32_t *work = memcpy(kmalloc(sizeof(uint32_t) * m), arr_available,
|
||||||
|
sizeof(uint32_t) * m);
|
||||||
|
|
||||||
|
// Allocate finish initialized with all false (zeros).
|
||||||
|
uint32_t *finish = all(kmalloc(sizeof(uint32_t) * n), 0UL, n);
|
||||||
|
uint32_t *all_true = all(kmalloc(sizeof(uint32_t) * n), 1UL, n);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
// Loop while finish is not equal an array all true (ones).
|
||||||
|
while (/* ... */)
|
||||||
|
{
|
||||||
|
// Find a task that can satisfy all the resources it needs.
|
||||||
|
for (i = 0; i < n && (/* ... */ || /* ... */); i++);
|
||||||
|
if (i == n)
|
||||||
|
{
|
||||||
|
// Free memory.
|
||||||
|
kfree(work);
|
||||||
|
kfree(finish);
|
||||||
|
kfree(all_true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Assume to make available the resources that the task found needs.
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free memory.
|
||||||
|
kfree(work);
|
||||||
|
kfree(finish);
|
||||||
|
kfree(all_true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deadlock_status_t request(uint32_t *req_vec, size_t task_i,
|
||||||
|
uint32_t *arr_available, uint32_t ** mat_alloc, uint32_t **mat_need,
|
||||||
|
size_t n, size_t m)
|
||||||
|
{
|
||||||
|
if (/* ... */)
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/* ... */)
|
||||||
|
{
|
||||||
|
return WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to allocate resources.
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
// Check safe state
|
||||||
|
if (/* ... */)
|
||||||
|
{
|
||||||
|
// Restore previous allocation.
|
||||||
|
/* ... */
|
||||||
|
return WAIT_UNSAFE;
|
||||||
|
}
|
||||||
|
return SAFE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,327 @@
|
|||||||
|
/**
|
||||||
|
* @author Mirco De Marchi
|
||||||
|
* @date 2/02/2021
|
||||||
|
* @brief Source file for deadlock deterministic simulation.
|
||||||
|
* @copyright (c) University of Verona
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "deadlock_simulation.h"
|
||||||
|
#include "deadlock_prevention.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "arr_math.h"
|
||||||
|
#include "kheap.h"
|
||||||
|
|
||||||
|
#define SIM_N 2 ///< Task amount on simulation.
|
||||||
|
#define SIM_M 2 ///< Resource type amount on simulation.
|
||||||
|
|
||||||
|
/// @brief Simulation operations types.
|
||||||
|
typedef enum {
|
||||||
|
FREE,
|
||||||
|
LOCK,
|
||||||
|
} op_t;
|
||||||
|
|
||||||
|
/// @brief Structure type for a task resource request.
|
||||||
|
typedef struct request {
|
||||||
|
pid_t req_task; ///< Process id.
|
||||||
|
op_t op; ///< Operation type.
|
||||||
|
uint32_t req_vec[SIM_M]; ///< Resource request vector.
|
||||||
|
} req_t;
|
||||||
|
|
||||||
|
/// @brief Print available resources.
|
||||||
|
static void simulation_stats_available();
|
||||||
|
|
||||||
|
/// @brief Print resource request array.
|
||||||
|
/// @param req_vec Pointer to the resource request array.
|
||||||
|
/// @param length Length of resource request array.
|
||||||
|
static void simulation_stats_request(uint32_t *req_vec, size_t length);
|
||||||
|
|
||||||
|
/// @brief Print stats of resources over tasks matrix.
|
||||||
|
/// @param header_str String name related with the matrix to print.
|
||||||
|
/// @param m Matrix to print stats.
|
||||||
|
/// @param r Row number of the matrix.
|
||||||
|
/// @param c Col number of the matrix.
|
||||||
|
static void simulation_stats_matrix(const char * header_str, uint32_t **m,
|
||||||
|
size_t r, size_t c);
|
||||||
|
|
||||||
|
/// @brief Print system stats.
|
||||||
|
static void simulation_stats();
|
||||||
|
|
||||||
|
/// @brief Simulate a semaphore try lock.
|
||||||
|
static deadlock_status_t simulation_try_lock(uint32_t *req_vec, size_t task_i,
|
||||||
|
size_t n, size_t m);
|
||||||
|
|
||||||
|
/// @brief Simulate a semaphore lock.
|
||||||
|
static void simulation_lock(uint32_t *req_vec, pid_t pid);
|
||||||
|
|
||||||
|
/// @brief Simulate a semaphore free.
|
||||||
|
static void simulation_free(uint32_t *req_vec, pid_t pid);
|
||||||
|
|
||||||
|
/// @brief Simulation initialization.
|
||||||
|
static void simulation_init();
|
||||||
|
|
||||||
|
/// @brief Simulation core.
|
||||||
|
static void simulation_start();
|
||||||
|
|
||||||
|
/// @brief Simulation end.
|
||||||
|
static void simulation_close();
|
||||||
|
|
||||||
|
/// @brief Initial number of instances of resource type R_j currently available.
|
||||||
|
uint32_t initial_available[SIM_M] = {1, 1};
|
||||||
|
/// @brief Initial matrix of maximum resource request that each task require.
|
||||||
|
uint32_t initial_max[SIM_N][SIM_M] = {{1, 1}, {1, 1}};
|
||||||
|
/// @brief Initial matrix of current resource allocation of each task.
|
||||||
|
uint32_t initial_alloc[SIM_N][SIM_M] = {{0, 0}, {0, 0}};
|
||||||
|
|
||||||
|
/// Array of resources instances currently available;
|
||||||
|
uint32_t * arr_available;
|
||||||
|
/// Matrix of the maximum resources instances that each task may require;
|
||||||
|
uint32_t ** mat_max;
|
||||||
|
/// Matrix of current resources instances allocation of each task.
|
||||||
|
uint32_t ** mat_alloc;
|
||||||
|
/// Matrix of current resources instances need of each task.
|
||||||
|
uint32_t ** mat_need;
|
||||||
|
|
||||||
|
/// @brief Simulation requests.
|
||||||
|
req_t req_vec_test[] = {
|
||||||
|
{.req_task=0, .op=LOCK, .req_vec={1, 0}},
|
||||||
|
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
|
||||||
|
{.req_task=0, .op=LOCK, .req_vec={0, 1}},
|
||||||
|
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
|
||||||
|
{.req_task=0, .op=LOCK, .req_vec={0, 1}},
|
||||||
|
{.req_task=0, .op=FREE, .req_vec={0, 1}},
|
||||||
|
{.req_task=1, .op=LOCK, .req_vec={0, 1}},
|
||||||
|
{.req_task=0, .op=FREE, .req_vec={1, 0}},
|
||||||
|
{.req_task=1, .op=LOCK, .req_vec={1, 0}},
|
||||||
|
{.req_task=1, .op=FREE, .req_vec={1, 0}},
|
||||||
|
{.req_task=1, .op=FREE, .req_vec={0, 1}},
|
||||||
|
{.req_task=1, .op=FREE, .req_vec={0, 1}},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void simulation_stats_available()
|
||||||
|
{
|
||||||
|
dbg_print(" { ");
|
||||||
|
for (size_t j = 0; j < SIM_M-1; j++)
|
||||||
|
dbg_print("R_%i: %u, ", j, arr_available[j]);
|
||||||
|
dbg_print("R_%d: %u }", SIM_M-1, arr_available[SIM_M-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_stats_request(uint32_t *req_vec, size_t length)
|
||||||
|
{
|
||||||
|
dbg_print(" { ");
|
||||||
|
for (size_t j = 0; j < length-1; j++)
|
||||||
|
dbg_print("R_%i: %u, ", j, req_vec[j]);
|
||||||
|
dbg_print("R_%i: %u }", length-1, req_vec[length-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_stats_matrix(const char * header_str, uint32_t **m,
|
||||||
|
size_t r, size_t c)
|
||||||
|
{
|
||||||
|
const int col_size = 7;
|
||||||
|
const size_t tot_col = c + 1;
|
||||||
|
size_t j = 0;
|
||||||
|
|
||||||
|
dbg_print(" ");
|
||||||
|
for (j = 0; j < (tot_col * col_size) - 1; j++) dbg_print("-");
|
||||||
|
dbg_print("\n");
|
||||||
|
|
||||||
|
dbg_print("|");
|
||||||
|
const size_t table_space = (tot_col * col_size) - strlen(header_str) - 1;
|
||||||
|
for (j = 0; j < table_space / 2; j++) dbg_print(" ");
|
||||||
|
dbg_print("%s", header_str);
|
||||||
|
for (; j < table_space; j++) dbg_print(" ");
|
||||||
|
dbg_print("|\n");
|
||||||
|
|
||||||
|
dbg_print("| Task |");
|
||||||
|
for (j = 0; j < c; j++) dbg_print(" R_%-2i |", j);
|
||||||
|
dbg_print("\n");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < r; i++)
|
||||||
|
{
|
||||||
|
dbg_print("| %4i |", i);
|
||||||
|
for (j = 0; j < c; j++)
|
||||||
|
dbg_print(" %4u |", m[i][j]);
|
||||||
|
dbg_print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg_print(" ");
|
||||||
|
for (j = 0; j < (tot_col * col_size) - 1; j++) dbg_print("-");
|
||||||
|
dbg_print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_stats()
|
||||||
|
{
|
||||||
|
dbg_print("Tasks N: %i\n", SIM_N);
|
||||||
|
dbg_print("Resources M: %i\n", SIM_M);
|
||||||
|
|
||||||
|
dbg_print("AVAILABLE:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
|
||||||
|
simulation_stats_matrix("MAX", mat_max, SIM_N, SIM_M);
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
simulation_stats_matrix("NEED", mat_need, SIM_N, SIM_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
static deadlock_status_t simulation_try_lock(uint32_t *req_vec, size_t task_i,
|
||||||
|
size_t n, size_t m)
|
||||||
|
{
|
||||||
|
#if ENABLE_DEADLOCK_PREVENTION
|
||||||
|
return request(req_vec, task_i, arr_available, mat_alloc, mat_need, n, m);
|
||||||
|
#else
|
||||||
|
return ERROR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_lock(uint32_t *req_vec, pid_t pid)
|
||||||
|
{
|
||||||
|
if (!(arr_available && mat_max && mat_alloc && mat_need))
|
||||||
|
{
|
||||||
|
dbg_print("Some task-resource matrices NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (simulation_try_lock(req_vec, pid, SIM_N, SIM_M)) {
|
||||||
|
case SAFE:
|
||||||
|
dbg_print("LOCK (task: %d; req_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(") SAFE: enjoy your resource\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
break;
|
||||||
|
case WAIT:
|
||||||
|
dbg_print("LOCK (task %d; req_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(") WAIT: resource busy\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
break;
|
||||||
|
case WAIT_UNSAFE:
|
||||||
|
dbg_print("LOCK (task %d; rec_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(") WAIT UNSAFE: deadlock detected\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
dbg_print("LOCK (task %d; rec_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(") ERROR: max matrix overflow\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_free(uint32_t *req_vec, pid_t pid)
|
||||||
|
{
|
||||||
|
if (arr_l_any(mat_alloc[pid], req_vec, SIM_M))
|
||||||
|
{
|
||||||
|
dbg_print("FREE (task %d; rec_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(") ERROR: try to free a resource not own\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arr_add(arr_available, req_vec, SIM_M);
|
||||||
|
arr_sub(mat_alloc[pid], req_vec, SIM_M);
|
||||||
|
// Check what happen if you uncomment the following line.
|
||||||
|
// arr_add(mat_need[pid], req_vec, SIM_M);
|
||||||
|
|
||||||
|
dbg_print("FREE (task %d; rec_vec:", pid);
|
||||||
|
simulation_stats_request(req_vec, SIM_M);
|
||||||
|
dbg_print(")\n");
|
||||||
|
dbg_print("available:");
|
||||||
|
simulation_stats_available();
|
||||||
|
dbg_print("\n");
|
||||||
|
simulation_stats_matrix("ALLOC", mat_alloc, SIM_N, SIM_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_init()
|
||||||
|
{
|
||||||
|
arr_available = (uint32_t *) kmalloc(SIM_M * sizeof(uint32_t));
|
||||||
|
mat_max = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
|
||||||
|
mat_alloc = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
|
||||||
|
mat_need = (uint32_t **) kmmalloc(SIM_N, SIM_M * sizeof(uint32_t));
|
||||||
|
|
||||||
|
memcpy(arr_available, initial_available, SIM_M * sizeof(uint32_t));
|
||||||
|
for (size_t i = 0; i < SIM_N; i++)
|
||||||
|
{
|
||||||
|
memcpy(mat_max[i], initial_max[i], SIM_M * sizeof(uint32_t));
|
||||||
|
memcpy(mat_alloc[i], initial_alloc[i], SIM_M * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate mat_need[i][j] = mat_max[i][j] - mat_alloc[i][j].
|
||||||
|
for (size_t i = 0; i < SIM_N; i++)
|
||||||
|
{
|
||||||
|
memcpy(mat_need[i], mat_max[i], SIM_M * sizeof(uint32_t));
|
||||||
|
arr_sub(mat_need[i], mat_alloc[i], SIM_M);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_start()
|
||||||
|
{
|
||||||
|
dbg_print("Deadlock Prevention: simulation start\n");
|
||||||
|
for (size_t test = 0; test < sizeof(req_vec_test) / sizeof(req_t); test++)
|
||||||
|
{
|
||||||
|
uint32_t *req_vec = req_vec_test[test].req_vec;
|
||||||
|
pid_t task_pid = req_vec_test[test].req_task;
|
||||||
|
|
||||||
|
switch (req_vec_test[test].op)
|
||||||
|
{
|
||||||
|
case FREE:
|
||||||
|
{
|
||||||
|
simulation_free(req_vec, task_pid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LOCK:
|
||||||
|
{
|
||||||
|
simulation_lock(req_vec, task_pid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
dbg_print("Request vector operation type not recognized\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simulation_close()
|
||||||
|
{
|
||||||
|
kfree(arr_available);
|
||||||
|
kmfree((void **) mat_max, SIM_N);
|
||||||
|
kmfree((void **) mat_alloc, SIM_N);
|
||||||
|
kmfree((void **) mat_need, SIM_N);
|
||||||
|
mat_max = NULL;
|
||||||
|
mat_alloc = NULL;
|
||||||
|
mat_need = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deadlock_simulation(int argc, char **argv)
|
||||||
|
{
|
||||||
|
#if ENABLE_DEADLOCK_PREVENTION
|
||||||
|
dbg_print("Deadlock Prevention: enabled\n");
|
||||||
|
simulation_init();
|
||||||
|
simulation_stats();
|
||||||
|
simulation_start();
|
||||||
|
simulation_close();
|
||||||
|
#else
|
||||||
|
dbg_print("Deadlock Prevention: disabled\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
@@ -4,107 +4,25 @@
|
|||||||
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include "vfs.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "kheap.h"
|
|
||||||
#include "shell.h"
|
|
||||||
#include "errno.h"
|
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "kernel.h"
|
#include "vfs.h"
|
||||||
|
#include "limits.h"
|
||||||
int sys_open(const char *pathname, int flags, mode_t mode)
|
|
||||||
{
|
|
||||||
// Allocate a variable for the path.
|
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
|
||||||
|
|
||||||
// Copy the path to the working variable.
|
|
||||||
strcpy(absolute_path, pathname);
|
|
||||||
|
|
||||||
// If the first character is not the '/' then get the absolute path.
|
|
||||||
if (absolute_path[0] != '/')
|
|
||||||
{
|
|
||||||
if (!get_absolute_path(absolute_path))
|
|
||||||
{
|
|
||||||
dbg_print("Cannot get the absolute path.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for an unused fd.
|
|
||||||
for (current_fd = 0; current_fd < MAX_OPEN_FD; ++current_fd)
|
|
||||||
{
|
|
||||||
if (fd_list[current_fd].mountpoint_id == -1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there is not fd available.
|
|
||||||
if (current_fd == MAX_OPEN_FD)
|
|
||||||
{
|
|
||||||
//errno = EMFILE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the mountpoint.
|
|
||||||
mountpoint_t *mp = get_mountpoint(absolute_path);
|
|
||||||
if (mp == NULL)
|
|
||||||
{
|
|
||||||
//errno = ENODEV;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the function is implemented.
|
|
||||||
if (mp->operations.open_f == NULL)
|
|
||||||
{
|
|
||||||
//errno = ENOSYS;
|
|
||||||
// Reset the file descriptor.
|
|
||||||
close(current_fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t fs_spec_id = mp->operations.open_f(absolute_path, flags, mode);
|
|
||||||
if (fs_spec_id == -1)
|
|
||||||
{
|
|
||||||
// Reset the file descriptor.
|
|
||||||
close(current_fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the file descriptor id.
|
|
||||||
fd_list[current_fd].fs_spec_id = fs_spec_id;
|
|
||||||
|
|
||||||
// Set the mount point id.
|
|
||||||
fd_list[current_fd].mountpoint_id = mp->mp_id;
|
|
||||||
|
|
||||||
// Reset the offset.
|
|
||||||
fd_list[current_fd].offset = 0;
|
|
||||||
|
|
||||||
// Set the flags.
|
|
||||||
fd_list[current_fd].flags_mask = flags;
|
|
||||||
|
|
||||||
// Return the file descriptor and increment it.
|
|
||||||
return (current_fd++);
|
|
||||||
}
|
|
||||||
|
|
||||||
int remove(const char *pathname)
|
int remove(const char *pathname)
|
||||||
{
|
{
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
char absolute_path[PATH_MAX];
|
||||||
strcpy(absolute_path, pathname);
|
strcpy(absolute_path, pathname);
|
||||||
if (pathname[0] != '/')
|
if (pathname[0] != '/') {
|
||||||
{
|
|
||||||
get_absolute_path(absolute_path);
|
get_absolute_path(absolute_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mp_id = get_mountpoint_id(absolute_path);
|
int32_t mp_id = get_mountpoint_id(absolute_path);
|
||||||
if (mp_id < 0)
|
if (mp_id < 0) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mountpoint_list[mp_id].operations.remove_f == NULL)
|
if (mountpoint_list[mp_id].operations.remove_f == NULL) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ DIR *initfs_opendir(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DIR *pdir = kmalloc(sizeof(DIR));
|
DIR *pdir = kmalloc(sizeof(DIR));
|
||||||
pdir->handle = -1;
|
pdir->fd = -1;
|
||||||
pdir->cur_entry = 0;
|
pdir->cur_entry = 0;
|
||||||
strcpy(pdir->path, path);
|
strcpy(pdir->path, path);
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ int initrd_rmdir(const char *path)
|
|||||||
}
|
}
|
||||||
// Remove the directory.
|
// Remove the directory.
|
||||||
direntry->magic = 0;
|
direntry->magic = 0;
|
||||||
memset(direntry->fileName, 0, MAX_FILENAME_LENGTH);
|
memset(direntry->fileName, 0, NAME_MAX);
|
||||||
direntry->file_type = 0;
|
direntry->file_type = 0;
|
||||||
direntry->uid = 0;
|
direntry->uid = 0;
|
||||||
direntry->offset = 0;
|
direntry->offset = 0;
|
||||||
@@ -320,7 +320,7 @@ int initfs_remove(const char *path)
|
|||||||
|
|
||||||
// Remove the directory.
|
// Remove the directory.
|
||||||
file->magic = 0;
|
file->magic = 0;
|
||||||
memset(file->fileName, 0, MAX_FILENAME_LENGTH);
|
memset(file->fileName, 0, NAME_MAX);
|
||||||
file->file_type = 0;
|
file->file_type = 0;
|
||||||
file->uid = 0;
|
file->uid = 0;
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <misc/debug.h>
|
#include <misc/debug.h>
|
||||||
#include "read_write.h"
|
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/// MentOS, The Mentoring Operating system project
|
||||||
|
/// @file readdir.c
|
||||||
|
/// @brief Function for accessing directory entries.
|
||||||
|
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
||||||
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
|
#include "dirent.h"
|
||||||
|
#include "syscall.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
|
dirent_t *sys_readdir(DIR *dirp)
|
||||||
|
{
|
||||||
|
if (dirp == NULL) {
|
||||||
|
printf("readdir: cannot read directory :"
|
||||||
|
"Directory pointer is not valid\n");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (mountpoint_list[dirp->fd].dir_op.readdir_f == NULL) {
|
||||||
|
printf("readdir: cannot read directory '%s':"
|
||||||
|
"No readdir function\n",
|
||||||
|
dirp->path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return mountpoint_list[dirp->fd].dir_op.readdir_f(dirp);
|
||||||
|
}
|
||||||
@@ -9,8 +9,9 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "initrd.h"
|
#include "initrd.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
int stat(const char *path, stat_t *buf)
|
int sys_stat(const char *path, stat_t *buf)
|
||||||
{
|
{
|
||||||
// Reset the structure.
|
// Reset the structure.
|
||||||
buf->st_dev = 0;
|
buf->st_dev = 0;
|
||||||
@@ -23,7 +24,7 @@ int stat(const char *path, stat_t *buf)
|
|||||||
buf->st_mtime = 0;
|
buf->st_mtime = 0;
|
||||||
buf->st_ctime = 0;
|
buf->st_ctime = 0;
|
||||||
|
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
char absolute_path[PATH_MAX];
|
||||||
strcpy(absolute_path, path);
|
strcpy(absolute_path, path);
|
||||||
|
|
||||||
if (path[0] != '/')
|
if (path[0] != '/')
|
||||||
@@ -51,9 +52,9 @@ int stat(const char *path, stat_t *buf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode)
|
int sys_mkdir(const char *path, mode_t mode)
|
||||||
{
|
{
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
char absolute_path[PATH_MAX];
|
||||||
strcpy(absolute_path, path);
|
strcpy(absolute_path, path);
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
+5
-4
@@ -12,6 +12,7 @@
|
|||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "initrd.h"
|
#include "initrd.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
int current_fd;
|
int current_fd;
|
||||||
char *module_start[MAX_MODULES];
|
char *module_start[MAX_MODULES];
|
||||||
@@ -106,7 +107,7 @@ mountpoint_t *get_mountpoint_from_id(int32_t mp_id)
|
|||||||
|
|
||||||
int get_relative_path(uint32_t mp_id, char *path)
|
int get_relative_path(uint32_t mp_id, char *path)
|
||||||
{
|
{
|
||||||
char relative_path[MAX_PATH_LENGTH];
|
char relative_path[PATH_MAX];
|
||||||
|
|
||||||
// Get the size of the path.
|
// Get the size of the path.
|
||||||
size_t path_size = strlen(path);
|
size_t path_size = strlen(path);
|
||||||
@@ -133,9 +134,9 @@ int get_relative_path(uint32_t mp_id, char *path)
|
|||||||
int get_absolute_path(char *path)
|
int get_absolute_path(char *path)
|
||||||
{
|
{
|
||||||
if (path[0] != '/') {
|
if (path[0] != '/') {
|
||||||
char abspath[MAX_PATH_LENGTH];
|
char abspath[PATH_MAX];
|
||||||
memset(abspath, '\0', MAX_PATH_LENGTH);
|
memset(abspath, '\0', PATH_MAX);
|
||||||
getcwd(abspath, MAX_PATH_LENGTH);
|
getcwd(abspath, PATH_MAX);
|
||||||
int abs_size = strlen(abspath);
|
int abs_size = strlen(abspath);
|
||||||
if (abspath[abs_size - 1] == '/') {
|
if (abspath[abs_size - 1] == '/') {
|
||||||
strncat(abspath, path, strlen(path));
|
strncat(abspath, path, strlen(path));
|
||||||
|
|||||||
+22
-35
@@ -21,12 +21,10 @@ void get_cpuid(cpuinfo_t *cpuinfo)
|
|||||||
|
|
||||||
void call_cpuid(register_t *registers)
|
void call_cpuid(register_t *registers)
|
||||||
{
|
{
|
||||||
__asm__ ("cpuid\n\t" :
|
__asm__("cpuid\n\t"
|
||||||
"=a" (registers->eax),
|
: "=a"(registers->eax), "=b"(registers->ebx), "=c"(registers->ecx),
|
||||||
"=b" (registers->ebx),
|
"=d"(registers->edx)
|
||||||
"=c" (registers->ecx),
|
: "a"(registers->eax));
|
||||||
"=d" (registers->edx) :
|
|
||||||
"a" (registers->eax));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers)
|
void cpuid_write_vendor(cpuinfo_t *cpuinfo, register_t *registers)
|
||||||
@@ -54,8 +52,7 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
|
|||||||
|
|
||||||
uint32_t type = cpuid_get_byte(registers->eax, 0xB, 0x3);
|
uint32_t type = cpuid_get_byte(registers->eax, 0xB, 0x3);
|
||||||
|
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
cpuinfo->cpu_type = "Original OEM Processor";
|
cpuinfo->cpu_type = "Original OEM Processor";
|
||||||
break;
|
break;
|
||||||
@@ -73,16 +70,14 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
|
|||||||
uint32_t familyID = cpuid_get_byte(registers->eax, 0x7, 0xE);
|
uint32_t familyID = cpuid_get_byte(registers->eax, 0x7, 0xE);
|
||||||
cpuinfo->cpu_family = familyID;
|
cpuinfo->cpu_family = familyID;
|
||||||
|
|
||||||
if (familyID == 0x0F)
|
if (familyID == 0x0F) {
|
||||||
{
|
|
||||||
cpuinfo->cpu_family += cpuid_get_byte(registers->eax, 0x13, 0xFF);
|
cpuinfo->cpu_family += cpuid_get_byte(registers->eax, 0x13, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t model = cpuid_get_byte(registers->eax, 0x3, 0xE);
|
uint32_t model = cpuid_get_byte(registers->eax, 0x3, 0xE);
|
||||||
cpuinfo->cpu_model = model;
|
cpuinfo->cpu_model = model;
|
||||||
|
|
||||||
if (familyID == 0x06 || familyID == 0x0F)
|
if (familyID == 0x06 || familyID == 0x0F) {
|
||||||
{
|
|
||||||
uint32_t ext_model = cpuid_get_byte(registers->eax, 0xF, 0xE);
|
uint32_t ext_model = cpuid_get_byte(registers->eax, 0xF, 0xE);
|
||||||
cpuinfo->cpu_model += (ext_model << 4);
|
cpuinfo->cpu_model += (ext_model << 4);
|
||||||
}
|
}
|
||||||
@@ -92,12 +87,9 @@ void cpuid_write_proctype(cpuinfo_t *cpuinfo, register_t *registers)
|
|||||||
cpuid_feature_edx(cpuinfo, registers->edx);
|
cpuid_feature_edx(cpuinfo, registers->edx);
|
||||||
|
|
||||||
/* Get brand string to identify the processor */
|
/* Get brand string to identify the processor */
|
||||||
if (familyID >= 0x0F && model >= 0x03)
|
if (familyID >= 0x0F && model >= 0x03) {
|
||||||
{
|
|
||||||
cpuinfo->brand_string = cpuid_brand_string(registers);
|
cpuinfo->brand_string = cpuid_brand_string(registers);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cpuinfo->brand_string = cpuid_brand_index(registers);
|
cpuinfo->brand_string = cpuid_brand_index(registers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,8 +99,7 @@ void cpuid_feature_ecx(cpuinfo_t *cpuinfo, uint32_t ecx)
|
|||||||
uint32_t temp = ecx;
|
uint32_t temp = ecx;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < ECX_FLAGS_SIZE; ++i)
|
for (i = 0; i < ECX_FLAGS_SIZE; ++i) {
|
||||||
{
|
|
||||||
temp = cpuid_get_byte(temp, i, 1);
|
temp = cpuid_get_byte(temp, i, 1);
|
||||||
cpuinfo->cpuid_ecx_flags[i] = temp;
|
cpuinfo->cpuid_ecx_flags[i] = temp;
|
||||||
temp = ecx;
|
temp = ecx;
|
||||||
@@ -120,16 +111,14 @@ void cpuid_feature_edx(cpuinfo_t *cpuinfo, uint32_t edx)
|
|||||||
uint32_t temp = edx;
|
uint32_t temp = edx;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < EDX_FLAGS_SIZE; ++i)
|
for (i = 0; i < EDX_FLAGS_SIZE; ++i) {
|
||||||
{
|
|
||||||
temp = cpuid_get_byte(temp, i, 1);
|
temp = cpuid_get_byte(temp, i, 1);
|
||||||
cpuinfo->cpuid_edx_flags[i] = temp;
|
cpuinfo->cpuid_edx_flags[i] = temp;
|
||||||
temp = edx;
|
temp = edx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t cpuid_get_byte(const uint32_t reg,
|
inline uint32_t cpuid_get_byte(const uint32_t reg, const uint32_t position,
|
||||||
const uint32_t position,
|
|
||||||
const uint32_t value)
|
const uint32_t value)
|
||||||
{
|
{
|
||||||
return ((reg >> position) & value);
|
return ((reg >> position) & value);
|
||||||
@@ -161,8 +150,7 @@ char *cpuid_brand_index(register_t *r)
|
|||||||
|
|
||||||
int bx = (r->ebx & 0xFF);
|
int bx = (r->ebx & 0xFF);
|
||||||
|
|
||||||
if (bx > 0x17)
|
if (bx > 0x17) {
|
||||||
{
|
|
||||||
bx = 0;
|
bx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,18 +164,17 @@ char *cpuid_brand_string(register_t *r)
|
|||||||
{
|
{
|
||||||
char *temp = "";
|
char *temp = "";
|
||||||
|
|
||||||
for (r->eax = 0x80000002; r->eax <= 0x80000004; (r->eax)++)
|
for (r->eax = 0x80000002; r->eax <= 0x80000004; (r->eax)++) {
|
||||||
{
|
|
||||||
r->ebx = r->ecx = r->edx = 0;
|
r->ebx = r->ecx = r->edx = 0;
|
||||||
call_cpuid(r);
|
call_cpuid(r);
|
||||||
temp = strncat(temp, (const char *) r->eax,
|
temp =
|
||||||
strlen((const char *) r->eax));
|
strncat(temp, (const char *)r->eax, strlen((const char *)r->eax));
|
||||||
temp = strncat(temp, (const char *) r->ebx,
|
temp =
|
||||||
strlen((const char *) r->ebx));
|
strncat(temp, (const char *)r->ebx, strlen((const char *)r->ebx));
|
||||||
temp = strncat(temp, (const char *) r->ecx,
|
temp =
|
||||||
strlen((const char *) r->ecx));
|
strncat(temp, (const char *)r->ecx, strlen((const char *)r->ecx));
|
||||||
temp = strncat(temp, (const char *) r->edx,
|
temp =
|
||||||
strlen((const char *) r->edx));
|
strncat(temp, (const char *)r->edx, strlen((const char *)r->edx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ inline uint16_t inports(uint16_t port)
|
|||||||
|
|
||||||
void inportsm(uint16_t port, uint8_t *data, unsigned long size)
|
void inportsm(uint16_t port, uint8_t *data, unsigned long size)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__("rep insw" : "+D" (data), "+c" (size) : "d" (port) : "memory");
|
__asm__ __volatile__("rep insw"
|
||||||
|
: "+D"(data), "+c"(size)
|
||||||
|
: "d"(port)
|
||||||
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t inportl(uint16_t port)
|
inline uint32_t inportl(uint16_t port)
|
||||||
|
|||||||
+4
-10
@@ -4,7 +4,6 @@
|
|||||||
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include "sys.h"
|
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
@@ -13,8 +12,7 @@
|
|||||||
|
|
||||||
static void machine_power_off()
|
static void machine_power_off()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,18 +38,14 @@ int sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg)
|
|||||||
|
|
||||||
// For safety, we require "magic" arguments.
|
// For safety, we require "magic" arguments.
|
||||||
if (magic1 != LINUX_REBOOT_MAGIC1 ||
|
if (magic1 != LINUX_REBOOT_MAGIC1 ||
|
||||||
(magic2 != LINUX_REBOOT_MAGIC2 &&
|
(magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
|
||||||
magic2 != LINUX_REBOOT_MAGIC2A &&
|
magic2 != LINUX_REBOOT_MAGIC2B && magic2 != LINUX_REBOOT_MAGIC2C)) {
|
||||||
magic2 != LINUX_REBOOT_MAGIC2B &&
|
|
||||||
magic2 != LINUX_REBOOT_MAGIC2C))
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&reboot_mutex, 0);
|
mutex_lock(&reboot_mutex, 0);
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd) {
|
||||||
{
|
|
||||||
case LINUX_REBOOT_CMD_RESTART:
|
case LINUX_REBOOT_CMD_RESTART:
|
||||||
break;
|
break;
|
||||||
case LINUX_REBOOT_CMD_CAD_ON:
|
case LINUX_REBOOT_CMD_CAD_ON:
|
||||||
|
|||||||
@@ -8,9 +8,7 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
|
|
||||||
void __assert_fail(const char *assertion,
|
void __assert_fail(const char *assertion, const char *file, unsigned int line,
|
||||||
const char *file,
|
|
||||||
unsigned int line,
|
|
||||||
const char *function)
|
const char *function)
|
||||||
{
|
{
|
||||||
char message[1024];
|
char message[1024];
|
||||||
@@ -19,9 +17,6 @@ void __assert_fail(const char *assertion,
|
|||||||
"LINE: %d\n"
|
"LINE: %d\n"
|
||||||
"FUNC: %s\n\n"
|
"FUNC: %s\n\n"
|
||||||
"Assertion `%s` failed.\n",
|
"Assertion `%s` failed.\n",
|
||||||
file,
|
file, line, (function ? function : "NO_FUN"), assertion);
|
||||||
line,
|
|
||||||
(function ? function : "NO_FUN"),
|
|
||||||
assertion);
|
|
||||||
kernel_panic(message);
|
kernel_panic(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-53
@@ -8,15 +8,13 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
struct hashmap_entry_t
|
struct hashmap_entry_t {
|
||||||
{
|
|
||||||
char *key;
|
char *key;
|
||||||
void *value;
|
void *value;
|
||||||
struct hashmap_entry_t *next;
|
struct hashmap_entry_t *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hashmap_t
|
struct hashmap_t {
|
||||||
{
|
|
||||||
hashmap_hash_t hash_func;
|
hashmap_hash_t hash_func;
|
||||||
hashmap_comp_t hash_comp;
|
hashmap_comp_t hash_comp;
|
||||||
hashmap_dupe_t hash_key_dup;
|
hashmap_dupe_t hash_key_dup;
|
||||||
@@ -31,15 +29,11 @@ size_t hashmap_string_hash(void *_key)
|
|||||||
size_t hash = 0;
|
size_t hash = 0;
|
||||||
char *key = (char *)_key;
|
char *key = (char *)_key;
|
||||||
int c;
|
int c;
|
||||||
/*
|
// This is the so-called "sdbm" hash. It comes from a piece of public
|
||||||
* This is the so-called "sdbm" hash. It comes from a piece of public
|
// domain code from a clone of ndbm.
|
||||||
* domain code from a clone of ndbm.
|
while ((c = *key++)) {
|
||||||
*/
|
|
||||||
while ((c = *key++))
|
|
||||||
{
|
|
||||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +103,9 @@ hashmap_t *hashmap_create_int(size_t size)
|
|||||||
|
|
||||||
void hashmap_free(hashmap_t *map)
|
void hashmap_free(hashmap_t *map)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < map->size; ++i)
|
for (size_t i = 0; i < map->size; ++i) {
|
||||||
{
|
|
||||||
hashmap_entry_t *x = map->entries[i], *p;
|
hashmap_entry_t *x = map->entries[i], *p;
|
||||||
while (x)
|
while (x) {
|
||||||
{
|
|
||||||
p = x;
|
p = x;
|
||||||
x = x->next;
|
x = x->next;
|
||||||
map->hash_key_free(p->key);
|
map->hash_key_free(p->key);
|
||||||
@@ -129,8 +121,7 @@ void *hashmap_set(hashmap_t *map, void *key, void *value)
|
|||||||
size_t hash = map->hash_func(key) % map->size;
|
size_t hash = map->hash_func(key) % map->size;
|
||||||
hashmap_entry_t *x = map->entries[hash];
|
hashmap_entry_t *x = map->entries[hash];
|
||||||
|
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
{
|
|
||||||
hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t));
|
hashmap_entry_t *e = malloc(sizeof(hashmap_entry_t));
|
||||||
e->key = map->hash_key_dup(key);
|
e->key = map->hash_key_dup(key);
|
||||||
e->value = value;
|
e->value = value;
|
||||||
@@ -142,10 +133,8 @@ void *hashmap_set(hashmap_t *map, void *key, void *value)
|
|||||||
|
|
||||||
hashmap_entry_t *p = NULL;
|
hashmap_entry_t *p = NULL;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
if (map->hash_comp(x->key, key)) {
|
||||||
if (map->hash_comp(x->key, key))
|
|
||||||
{
|
|
||||||
void *out = x->value;
|
void *out = x->value;
|
||||||
x->value = value;
|
x->value = value;
|
||||||
|
|
||||||
@@ -169,14 +158,11 @@ void *hashmap_get(hashmap_t *map, void *key)
|
|||||||
size_t hash = map->hash_func(key) % map->size;
|
size_t hash = map->hash_func(key) % map->size;
|
||||||
hashmap_entry_t *x = map->entries[hash];
|
hashmap_entry_t *x = map->entries[hash];
|
||||||
|
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
do
|
do {
|
||||||
{
|
if (map->hash_comp(x->key, key)) {
|
||||||
if (map->hash_comp(x->key, key))
|
|
||||||
{
|
|
||||||
return x->value;
|
return x->value;
|
||||||
}
|
}
|
||||||
x = x->next;
|
x = x->next;
|
||||||
@@ -190,12 +176,10 @@ void *hashmap_remove(hashmap_t *map, void *key)
|
|||||||
size_t hash = map->hash_func(key) % map->size;
|
size_t hash = map->hash_func(key) % map->size;
|
||||||
hashmap_entry_t *x = map->entries[hash];
|
hashmap_entry_t *x = map->entries[hash];
|
||||||
|
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (map->hash_comp(x->key, key))
|
if (map->hash_comp(x->key, key)) {
|
||||||
{
|
|
||||||
void *out = x->value;
|
void *out = x->value;
|
||||||
map->entries[hash] = x->next;
|
map->entries[hash] = x->next;
|
||||||
map->hash_key_free(x->key);
|
map->hash_key_free(x->key);
|
||||||
@@ -206,10 +190,8 @@ void *hashmap_remove(hashmap_t *map, void *key)
|
|||||||
|
|
||||||
hashmap_entry_t *p = x;
|
hashmap_entry_t *p = x;
|
||||||
x = x->next;
|
x = x->next;
|
||||||
do
|
do {
|
||||||
{
|
if (map->hash_comp(x->key, key)) {
|
||||||
if (map->hash_comp(x->key, key))
|
|
||||||
{
|
|
||||||
void *out = x->value;
|
void *out = x->value;
|
||||||
p->next = x->next;
|
p->next = x->next;
|
||||||
map->hash_key_free(x->key);
|
map->hash_key_free(x->key);
|
||||||
@@ -226,10 +208,8 @@ void *hashmap_remove(hashmap_t *map, void *key)
|
|||||||
|
|
||||||
bool_t hashmap_is_empty(hashmap_t *map)
|
bool_t hashmap_is_empty(hashmap_t *map)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < map->size; ++i)
|
for (size_t i = 0; i < map->size; ++i) {
|
||||||
{
|
if (map->entries[i]) {
|
||||||
if (map->entries[i])
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,14 +222,11 @@ bool_t hashmap_has(hashmap_t *map, void *key)
|
|||||||
size_t hash = map->hash_func(key) % map->size;
|
size_t hash = map->hash_func(key) % map->size;
|
||||||
hashmap_entry_t *x = map->entries[hash];
|
hashmap_entry_t *x = map->entries[hash];
|
||||||
|
|
||||||
if (x == NULL)
|
if (x == NULL) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
do
|
do {
|
||||||
{
|
if (map->hash_comp(x->key, key)) {
|
||||||
if (map->hash_comp(x->key, key))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
x = x->next;
|
x = x->next;
|
||||||
@@ -262,11 +239,9 @@ list_t *hashmap_keys(hashmap_t *map)
|
|||||||
{
|
{
|
||||||
list_t *l = list_create();
|
list_t *l = list_create();
|
||||||
|
|
||||||
for (size_t i = 0; i < map->size; ++i)
|
for (size_t i = 0; i < map->size; ++i) {
|
||||||
{
|
|
||||||
hashmap_entry_t *x = map->entries[i];
|
hashmap_entry_t *x = map->entries[i];
|
||||||
while (x)
|
while (x) {
|
||||||
{
|
|
||||||
list_insert_back(l, x->key);
|
list_insert_back(l, x->key);
|
||||||
x = x->next;
|
x = x->next;
|
||||||
}
|
}
|
||||||
@@ -279,12 +254,10 @@ list_t *hashmap_values(hashmap_t *map)
|
|||||||
{
|
{
|
||||||
list_t *l = list_create();
|
list_t *l = list_create();
|
||||||
|
|
||||||
for (size_t i = 0; i < map->size; ++i)
|
for (size_t i = 0; i < map->size; ++i) {
|
||||||
{
|
|
||||||
hashmap_entry_t *x = map->entries[i];
|
hashmap_entry_t *x = map->entries[i];
|
||||||
|
|
||||||
while (x)
|
while (x) {
|
||||||
{
|
|
||||||
list_insert_back(l, x->value);
|
list_insert_back(l, x->value);
|
||||||
x = x->next;
|
x = x->next;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-16
@@ -7,11 +7,11 @@
|
|||||||
#include "libgen.h"
|
#include "libgen.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "initrd.h"
|
#include "initrd.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
int parse_path(char *out, char **cur, char sep, size_t max)
|
int parse_path(char *out, char **cur, char sep, size_t max)
|
||||||
{
|
{
|
||||||
if (**cur == '\0')
|
if (**cur == '\0') {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,8 +19,7 @@ int parse_path(char *out, char **cur, char sep, size_t max)
|
|||||||
++*cur;
|
++*cur;
|
||||||
--max;
|
--max;
|
||||||
|
|
||||||
while ((max > 0) && (**cur != '\0') && (**cur != sep))
|
while ((max > 0) && (**cur != '\0') && (**cur != sep)) {
|
||||||
{
|
|
||||||
*out++ = **cur;
|
*out++ = **cur;
|
||||||
++*cur;
|
++*cur;
|
||||||
--max;
|
--max;
|
||||||
@@ -33,12 +32,13 @@ int parse_path(char *out, char **cur, char sep, size_t max)
|
|||||||
|
|
||||||
char *dirname(const char *path)
|
char *dirname(const char *path)
|
||||||
{
|
{
|
||||||
static char s[MAX_PATH_LENGTH];
|
static char s[PATH_MAX];
|
||||||
|
|
||||||
static char dot[2] = ".";
|
static char dot[2] = ".";
|
||||||
|
|
||||||
// Check the input path.
|
// Check the input path.
|
||||||
if (path == NULL) return dot;
|
if (path == NULL)
|
||||||
|
return dot;
|
||||||
|
|
||||||
// Copy the path to the support string.
|
// Copy the path to the support string.
|
||||||
strcpy(s, path);
|
strcpy(s, path);
|
||||||
@@ -46,25 +46,19 @@ char *dirname(const char *path)
|
|||||||
// Get the last occurrence of '/'.
|
// Get the last occurrence of '/'.
|
||||||
char *last_slash = strrchr(s, '/');
|
char *last_slash = strrchr(s, '/');
|
||||||
|
|
||||||
if (last_slash == s)
|
if (last_slash == s) {
|
||||||
{
|
|
||||||
// If the slash is acutally the first character of the string, move the
|
// If the slash is acutally the first character of the string, move the
|
||||||
// pointer to the last slash after it.
|
// pointer to the last slash after it.
|
||||||
++last_slash;
|
++last_slash;
|
||||||
}
|
} else if ((last_slash != NULL) && (last_slash[1] == '\0')) {
|
||||||
else if ((last_slash != NULL) && (last_slash[1] == '\0'))
|
|
||||||
{
|
|
||||||
// If the slash is the last character, we need to search before it.
|
// If the slash is the last character, we need to search before it.
|
||||||
last_slash = memchr(s, '/', last_slash - s);
|
last_slash = memchr(s, '/', last_slash - s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_slash != NULL)
|
if (last_slash != NULL) {
|
||||||
{
|
|
||||||
// If we have found it, close the string.
|
// If we have found it, close the string.
|
||||||
last_slash[0] = '\0';
|
last_slash[0] = '\0';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Otherwise, return '.'.
|
// Otherwise, return '.'.
|
||||||
return dot;
|
return dot;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-64
@@ -10,58 +10,23 @@
|
|||||||
double round(double x)
|
double round(double x)
|
||||||
{
|
{
|
||||||
double out;
|
double out;
|
||||||
__asm__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x));
|
__asm__ __volatile__("fldln2; fldl %1; frndint" : "=t"(out) : "m"(x));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
double floor(double x)
|
double floor(double x)
|
||||||
{
|
{
|
||||||
if (x > -1.0 && x < 1.0) {
|
if (x > -1.0 && x < 1.0) {
|
||||||
if (x >= 0) {
|
if (x >= 0)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
} else {
|
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
int i = (int)x;
|
||||||
|
if (x < 0)
|
||||||
|
return (double)(i - 1);
|
||||||
|
return (double)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x_i = (int)x;
|
|
||||||
|
|
||||||
if (x < 0) {
|
|
||||||
return (double)(x_i - 1);
|
|
||||||
} else {
|
|
||||||
return (double)x_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
double pow(double base, double ex)
|
|
||||||
{
|
|
||||||
// Power of 0.
|
|
||||||
if (ex == 0)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Negative exponenet.
|
|
||||||
else if (ex < 0)
|
|
||||||
{
|
|
||||||
return 1 / pow(base, -ex);
|
|
||||||
}
|
|
||||||
// Even exponenet.
|
|
||||||
else if ((int) ex % 2 == 0)
|
|
||||||
{
|
|
||||||
float half_pow = pow(base, ex / 2);
|
|
||||||
|
|
||||||
return half_pow * half_pow;
|
|
||||||
}
|
|
||||||
// Integer exponenet.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return base * pow(base, ex - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
double pow(double x, double y)
|
double pow(double x, double y)
|
||||||
{
|
{
|
||||||
double out;
|
double out;
|
||||||
@@ -85,20 +50,13 @@ double pow(double x, double y)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
long find_nearest_pow_greater(double base, double value)
|
long find_nearest_pow_greater(double base, double value)
|
||||||
{
|
{
|
||||||
if (base <= 1) {
|
if (base <= 1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
long pow_value = 0;
|
long pow_value = 0;
|
||||||
|
while (pow(base, pow_value) < value)
|
||||||
while (pow(base, pow_value) < value) {
|
|
||||||
pow_value++;
|
pow_value++;
|
||||||
}
|
|
||||||
|
|
||||||
return pow_value;
|
return pow_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,16 +68,14 @@ double exp(double x)
|
|||||||
double fabs(double x)
|
double fabs(double x)
|
||||||
{
|
{
|
||||||
double out;
|
double out;
|
||||||
__asm__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x));
|
__asm__ __volatile__("fldln2; fldl %1; fabs" : "=t"(out) : "m"(x));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
double sqrt(double x)
|
double sqrt(double x)
|
||||||
{
|
{
|
||||||
double out;
|
double out;
|
||||||
__asm__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x));
|
__asm__ __volatile__("fldln2; fldl %1; fsqrt" : "=t"(out) : "m"(x));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +86,7 @@ int isinf(double x)
|
|||||||
double f;
|
double f;
|
||||||
} ieee754;
|
} ieee754;
|
||||||
ieee754.f = x;
|
ieee754.f = x;
|
||||||
|
return ((unsigned)(ieee754.u >> 32U) & 0x7fffffffU) == 0x7ff00000U &&
|
||||||
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
|
|
||||||
((unsigned)ieee754.u == 0);
|
((unsigned)ieee754.u == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +97,6 @@ int isnan(double x)
|
|||||||
double f;
|
double f;
|
||||||
} ieee754;
|
} ieee754;
|
||||||
ieee754.f = x;
|
ieee754.f = x;
|
||||||
|
|
||||||
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
|
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
|
||||||
((unsigned)ieee754.u != 0) >
|
((unsigned)ieee754.u != 0) >
|
||||||
0x7ff00000;
|
0x7ff00000;
|
||||||
@@ -156,18 +110,15 @@ double log10(double x)
|
|||||||
double ln(double x)
|
double ln(double x)
|
||||||
{
|
{
|
||||||
double out;
|
double out;
|
||||||
__asm__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x));
|
__asm__ __volatile__("fldln2; fldl %1; fyl2x" : "=t"(out) : "m"(x));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
double logx(double x, double y)
|
double logx(double x, double y)
|
||||||
{
|
{
|
||||||
// Base may not equal 1 or be negative.
|
// Base may not equal 1 or be negative.
|
||||||
if (y == 1.f || y < 0.f || ln(y) == 0.f) {
|
if (y == 1.f || y < 0.f || ln(y) == 0.f)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
|
||||||
|
|
||||||
return ln(x) / ln(y);
|
return ln(x) / ln(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +127,6 @@ double logx(double x, double y)
|
|||||||
double modf(double x, double *intpart)
|
double modf(double x, double *intpart)
|
||||||
{
|
{
|
||||||
register double absvalue;
|
register double absvalue;
|
||||||
|
|
||||||
if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) {
|
if ((absvalue = (x >= 0.0) ? x : -x) >= MAXPOWTWO) {
|
||||||
// It must be an integer.
|
// It must be an integer.
|
||||||
(*intpart) = x;
|
(*intpart) = x;
|
||||||
@@ -195,7 +145,6 @@ double modf(double x, double *intpart)
|
|||||||
(*intpart) = -(*intpart);
|
(*intpart) = -(*intpart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signed fractional part.
|
// Signed fractional part.
|
||||||
return (x - (*intpart));
|
return (x - (*intpart));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ ordered_array_t create_ordered_array(uint32_t max_size,
|
|||||||
return to_ret;
|
return to_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ordered_array_t place_ordered_array(void * addr,
|
ordered_array_t place_ordered_array(void *addr, uint32_t max_size,
|
||||||
uint32_t max_size,
|
|
||||||
lessthan_predicate_t less_than)
|
lessthan_predicate_t less_than)
|
||||||
{
|
{
|
||||||
ordered_array_t to_ret;
|
ordered_array_t to_ret;
|
||||||
@@ -51,24 +50,19 @@ void insert_ordered_array(array_type_t item, ordered_array_t * array)
|
|||||||
assert(array->less_than);
|
assert(array->less_than);
|
||||||
|
|
||||||
uint32_t iterator = 0;
|
uint32_t iterator = 0;
|
||||||
while (iterator < array->size && array->less_than(array->array[iterator],
|
while (iterator < array->size &&
|
||||||
item))
|
array->less_than(array->array[iterator], item)) {
|
||||||
{
|
|
||||||
iterator++;
|
iterator++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just add at the end of the array.
|
// Just add at the end of the array.
|
||||||
if (iterator == array->size)
|
if (iterator == array->size) {
|
||||||
{
|
|
||||||
array->array[array->size++] = item;
|
array->array[array->size++] = item;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
array_type_t tmp = array->array[iterator];
|
array_type_t tmp = array->array[iterator];
|
||||||
array->array[iterator] = item;
|
array->array[iterator] = item;
|
||||||
|
|
||||||
while (iterator < array->size)
|
while (iterator < array->size) {
|
||||||
{
|
|
||||||
iterator++;
|
iterator++;
|
||||||
array_type_t tmp2 = array->array[iterator];
|
array_type_t tmp2 = array->array[iterator];
|
||||||
array->array[iterator] = tmp;
|
array->array[iterator] = tmp;
|
||||||
@@ -87,8 +81,7 @@ array_type_t lookup_ordered_array(uint32_t i, ordered_array_t * array)
|
|||||||
|
|
||||||
void remove_ordered_array(uint32_t i, ordered_array_t *array)
|
void remove_ordered_array(uint32_t i, ordered_array_t *array)
|
||||||
{
|
{
|
||||||
while (i < array->size)
|
while (i < array->size) {
|
||||||
{
|
|
||||||
array->array[i] = array->array[i + 1];
|
array->array[i] = array->array[i + 1];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,20 +13,18 @@ void spinlock_init(spinlock_t *spinlock)
|
|||||||
|
|
||||||
void spinlock_lock(spinlock_t *spinlock)
|
void spinlock_lock(spinlock_t *spinlock)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0) {
|
||||||
if (atomic_set_and_test(spinlock, SPINLOCK_BUSY) == 0)
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (*spinlock) cpu_relax();
|
while (*spinlock)
|
||||||
|
cpu_relax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void spinlock_unlock(spinlock_t *spinlock)
|
void spinlock_unlock(spinlock_t *spinlock)
|
||||||
{
|
{
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
atomic_set(spinlock, SPINLOCK_FREE);
|
atomic_set(spinlock, SPINLOCK_FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-54
@@ -22,7 +22,6 @@ void puts(char *str)
|
|||||||
|
|
||||||
int getchar(void)
|
int getchar(void)
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
char c;
|
char c;
|
||||||
while (true) {
|
while (true) {
|
||||||
read(STDIN_FILENO, &c, 1);
|
read(STDIN_FILENO, &c, 1);
|
||||||
@@ -30,76 +29,56 @@ int getchar(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
#else
|
|
||||||
int tmpchar;
|
|
||||||
while ((tmpchar = keyboard_getc()) == -1)
|
|
||||||
;
|
|
||||||
|
|
||||||
return tmpchar;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *gets(char *str)
|
char *gets(char *str)
|
||||||
{
|
{
|
||||||
int count = 0;
|
// Check the input string.
|
||||||
char tmp[255];
|
if (str == NULL)
|
||||||
memset(tmp, '\0', 255);
|
return NULL;
|
||||||
|
// Buffer for reading input.
|
||||||
do {
|
char buffer[GETS_BUFFERSIZE];
|
||||||
int c = getchar();
|
memset(buffer, '\0', GETS_BUFFERSIZE);
|
||||||
|
// Char pointer to the buffer.
|
||||||
// Return Key.
|
char *cptr = buffer;
|
||||||
if (c == '\n') {
|
// Character storage and counter to prevent overflow.
|
||||||
|
int ch, counter = 0;
|
||||||
|
// Read until we find a newline or we exceed the buffer size.
|
||||||
|
while (((ch = getchar()) != '\n') && (counter++ < GETS_BUFFERSIZE)) {
|
||||||
|
// If we encounter EOF, stop.
|
||||||
|
if (ch == EOF) {
|
||||||
|
// EOF at start of line return NULL.
|
||||||
|
if (cptr == str)
|
||||||
|
return NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Backspace key.
|
// The character is stored at address, and the pointer is incremented.
|
||||||
|
*cptr++ = ch;
|
||||||
if (c == '\b') {
|
|
||||||
if (count > 0) {
|
|
||||||
count--;
|
|
||||||
}
|
}
|
||||||
} else {
|
// Add the null-terminating character.
|
||||||
tmp[count++] = (char)c;
|
*cptr = '\0';
|
||||||
}
|
// Copy the string we have read.
|
||||||
} while (count < 255);
|
strcpy(str, buffer);
|
||||||
|
// Return a pointer to the original string.
|
||||||
tmp[count] = '\0';
|
|
||||||
/* tmp cant simply be returned, it is allocated in this stack frame and
|
|
||||||
* it will be lost!
|
|
||||||
*/
|
|
||||||
strcpy(str, tmp);
|
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atoi(const char *str)
|
int atoi(const char *str)
|
||||||
{
|
{
|
||||||
// Initialize sign as positive.
|
// Check the input string.
|
||||||
int sign = 1;
|
if (str == NULL)
|
||||||
|
return 0;
|
||||||
|
// Initialize sign.
|
||||||
|
int sign = (str[0] == '-') ? -1 : +1;
|
||||||
// Initialize the result.
|
// Initialize the result.
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
// Initialize the index.
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
// If the number is negative, then update the sign.
|
|
||||||
if (str[0] == '-') {
|
|
||||||
sign = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the rest of the numbers are digits.
|
// Check that the rest of the numbers are digits.
|
||||||
for (i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i) {
|
for (int i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i)
|
||||||
if (!isdigit(str[i])) {
|
if (!isdigit(str[i]))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate through all digits and update the result.
|
// Iterate through all digits and update the result.
|
||||||
for (i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i) {
|
for (int i = (sign == -1) ? 1 : 0; str[i] != '\0'; ++i)
|
||||||
result = (result * 10) + str[i] - '0';
|
result = (result * 10) + str[i] - '0';
|
||||||
}
|
|
||||||
|
|
||||||
return sign * result;
|
return sign * result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +108,7 @@ size_t scanf(const char *format, ...)
|
|||||||
for (; *format; format++) {
|
for (; *format; format++) {
|
||||||
if (*format == '%') {
|
if (*format == '%') {
|
||||||
// Declare an input string.
|
// Declare an input string.
|
||||||
char input[255];
|
char input[GETS_BUFFERSIZE];
|
||||||
// Get the input string.
|
// Get the input string.
|
||||||
gets(input);
|
gets(input);
|
||||||
// Evaluate the length of the string.
|
// Evaluate the length of the string.
|
||||||
|
|||||||
+21
-32
@@ -8,11 +8,6 @@
|
|||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
/// Used to align the memory.
|
|
||||||
#define ALIGN(x) \
|
|
||||||
(((x) + (sizeof(size_t) - 1)) & ~(sizeof(size_t) - 1))
|
|
||||||
|
|
||||||
|
|
||||||
void *malloc(unsigned int size)
|
void *malloc(unsigned int size)
|
||||||
{
|
{
|
||||||
void *_res;
|
void *_res;
|
||||||
@@ -27,52 +22,46 @@ void free(void *p)
|
|||||||
DEFN_SYSCALL1(_res, __NR_free, p);
|
DEFN_SYSCALL1(_res, __NR_free, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *calloc(size_t element_number, size_t element_size)
|
void *calloc(size_t element_number, size_t element_size)
|
||||||
{
|
{
|
||||||
void *ptr = malloc(element_number * element_size);
|
void *ptr = malloc(element_number * element_size);
|
||||||
if (ptr)
|
if (ptr) {
|
||||||
{
|
|
||||||
memset(ptr, 0, element_number * element_size);
|
memset(ptr, 0, element_number * element_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void **mmalloc(size_t n, size_t size)
|
||||||
|
{
|
||||||
|
void **ret = (void **) malloc(n * sizeof(void *));
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
*(ret + i) = malloc(size);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mfree(void **src, size_t n)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
free(*(src + i));
|
||||||
|
}
|
||||||
|
free(src);
|
||||||
|
}
|
||||||
|
|
||||||
/// Seed used to generate random numbers.
|
/// Seed used to generate random numbers.
|
||||||
int rseed = 0;
|
static int rseed = 0;
|
||||||
|
|
||||||
inline void srand(int x)
|
inline void srand(int x)
|
||||||
{
|
{
|
||||||
rseed = x;
|
rseed = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MS_RAND
|
|
||||||
|
|
||||||
/// The maximum value returned by the rand function.
|
|
||||||
#define RAND_MAX ((1U << 31) - 1)
|
|
||||||
|
|
||||||
/// @brief Returns a pseudo-random integral number in the range
|
/// @brief Returns a pseudo-random integral number in the range
|
||||||
/// between 0 and RAND_MAX.
|
/// between 0 and RAND_MAX.
|
||||||
inline int rand()
|
inline int rand()
|
||||||
{
|
{
|
||||||
return rseed = (rseed * 1103515245 + 12345) & RAND_MAX;
|
return rseed = (rseed * 1103515245U + 12345U) & RAND_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MS rand.
|
|
||||||
#else
|
|
||||||
/// The maximum 32bit value returned by the rand function.
|
|
||||||
#define RAND_MAX_32 ((1U << 31) - 1)
|
|
||||||
|
|
||||||
/// The maximum value returned by the rand function.
|
|
||||||
#define RAND_MAX ((1U << 15) - 1)
|
|
||||||
|
|
||||||
/// @brief Returns a pseudo-random integral number in the range
|
|
||||||
/// between 0 and RAND_MAX.
|
|
||||||
inline int rand()
|
|
||||||
{
|
|
||||||
return (rseed = (rseed * 214013 + 2531011) & RAND_MAX_32) >> 16;
|
|
||||||
}
|
|
||||||
<<<<<<< HEAD
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -368,8 +368,7 @@ char *strerror(int errnum)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef EAFNOSUPPORT
|
#ifdef EAFNOSUPPORT
|
||||||
case EAFNOSUPPORT:
|
case EAFNOSUPPORT:
|
||||||
strcpy(error,
|
strcpy(error, "Address family not supported by protocol family");
|
||||||
"Address family not supported by protocol family");
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef EPROTOTYPE
|
#ifdef EPROTOTYPE
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -14,11 +14,9 @@ int open(const char *pathname, int flags, mode_t mode)
|
|||||||
|
|
||||||
DEFN_SYSCALL3(retval, __NR_open, pathname, flags, mode);
|
DEFN_SYSCALL3(retval, __NR_open, pathname, flags, mode);
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0) {
|
||||||
{
|
|
||||||
errno = -retval;
|
errno = -retval;
|
||||||
retval = -1;
|
retval = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ ssize_t read(int fd, void *buf, size_t nbytes)
|
|||||||
|
|
||||||
DEFN_SYSCALL3(retval, __NR_read, fd, buf, nbytes);
|
DEFN_SYSCALL3(retval, __NR_read, fd, buf, nbytes);
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0) {
|
||||||
{
|
|
||||||
errno = -retval;
|
errno = -retval;
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -793,11 +793,30 @@ void *krealloc(void *ptr, uint32_t size)
|
|||||||
return __do_realloc(&kernel_heap, ptr, size);
|
return __do_realloc(&kernel_heap, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void **kmmalloc(size_t n, size_t size)
|
||||||
|
{
|
||||||
|
void **ret = (void **) kmalloc(n * sizeof(void *));
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
*(ret + i) = kmalloc(size);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void kfree(void *ptr)
|
void kfree(void *ptr)
|
||||||
{
|
{
|
||||||
__do_free(&kernel_heap, ptr);
|
__do_free(&kernel_heap, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kmfree(void **src, size_t n)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
kfree(*(src + i));
|
||||||
|
}
|
||||||
|
kfree(src);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Find the current user heap.
|
/// @brief Find the current user heap.
|
||||||
/// @return The heap structure if heap exists, otherwise NULL.
|
/// @return The heap structure if heap exists, otherwise NULL.
|
||||||
static struct vm_area_struct *find_user_heap()
|
static struct vm_area_struct *find_user_heap()
|
||||||
|
|||||||
+161
-40
@@ -7,74 +7,195 @@
|
|||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "panic.h"
|
||||||
|
|
||||||
|
#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit)))
|
||||||
|
|
||||||
|
static inline multiboot_memory_map_t *first_mmap_entry(multiboot_info_t *info)
|
||||||
|
{
|
||||||
|
if (!has_flag(info->flags, MULTIBOOT_FLAG_MMAP))
|
||||||
|
return NULL;
|
||||||
|
return (multiboot_memory_map_t *)((uintptr_t)info->mmap_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline multiboot_memory_map_t *
|
||||||
|
next_mmap_entry(multiboot_info_t *info, multiboot_memory_map_t *entry)
|
||||||
|
{
|
||||||
|
uintptr_t next = ((uintptr_t)entry) + entry->size + sizeof(entry->size);
|
||||||
|
if (next >= info->mmap_addr + info->mmap_length)
|
||||||
|
return NULL;
|
||||||
|
return (multiboot_memory_map_t *)next;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline multiboot_memory_map_t *
|
||||||
|
next_mmap_entry_of_type(multiboot_info_t *info, multiboot_memory_map_t *entry,
|
||||||
|
uint32_t type)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
entry = next_mmap_entry(info, entry);
|
||||||
|
} while (entry && entry->type != type);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline multiboot_memory_map_t *
|
||||||
|
first_mmap_entry_of_type(multiboot_info_t *info, uint32_t type)
|
||||||
|
{
|
||||||
|
multiboot_memory_map_t *entry = first_mmap_entry(info);
|
||||||
|
if (entry && (entry->type == type))
|
||||||
|
return entry;
|
||||||
|
return next_mmap_entry_of_type(info, entry, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *mmap_type_name(multiboot_memory_map_t *entry)
|
||||||
|
{
|
||||||
|
if (entry->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||||
|
return "AVAILABLE";
|
||||||
|
if (entry->type == MULTIBOOT_MEMORY_RESERVED)
|
||||||
|
return "RESERVED";
|
||||||
|
return "NONE";
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline multiboot_module_t *first_module(multiboot_info_t *info)
|
||||||
|
{
|
||||||
|
if (!has_flag(info->flags, MULTIBOOT_FLAG_MODS))
|
||||||
|
return NULL;
|
||||||
|
if (!info->mods_count)
|
||||||
|
return NULL;
|
||||||
|
return (multiboot_module_t *)(uintptr_t)info->mods_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline multiboot_module_t *next_module(multiboot_info_t *info,
|
||||||
|
multiboot_module_t *mod)
|
||||||
|
{
|
||||||
|
multiboot_module_t *first =
|
||||||
|
(multiboot_module_t *)((uintptr_t)info->mods_addr);
|
||||||
|
++mod;
|
||||||
|
if ((mod - first) >= info->mods_count)
|
||||||
|
return NULL;
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
void dump_multiboot(multiboot_info_t *mbi)
|
void dump_multiboot(multiboot_info_t *mbi)
|
||||||
{
|
{
|
||||||
dbg_print("\n--------------------------------------------------\n");
|
dbg_print("\n--------------------------------------------------\n");
|
||||||
dbg_print("MULTIBOOT header at 0x%x:\n", mbi);
|
dbg_print("MULTIBOOT header at 0x%x:\n", mbi);
|
||||||
dbg_print("Flags : 0x%x\n", mbi->flags);
|
|
||||||
|
// Print out the flags.
|
||||||
|
dbg_print("%-16s = 0x%x\n", "flags", mbi->flags);
|
||||||
|
|
||||||
|
// Are mem_* valid?
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MEM)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MEM)) {
|
||||||
dbg_print("Mem Lo: 0x%x\n", mbi->mem_lower * K);
|
dbg_print("%-16s = %u Kb (%u Mb)\n", "mem_lower", mbi->mem_lower,
|
||||||
dbg_print("Mem Hi: 0x%x (%dMB)\n", mbi->mem_upper * K,
|
mbi->mem_lower / K);
|
||||||
(mbi->mem_upper / 1024));
|
dbg_print("%-16s = %u Kb (%u Mb)\n", "mem_upper", mbi->mem_upper,
|
||||||
|
mbi->mem_upper / K);
|
||||||
|
dbg_print("%-16s = %u Kb (%u Mb)\n", "total",
|
||||||
|
mbi->mem_lower + mbi->mem_upper,
|
||||||
|
(mbi->mem_lower + mbi->mem_upper) / K);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is boot_device valid?
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_DEVICE)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_DEVICE)) {
|
||||||
dbg_print("Boot d: 0x%x\n", mbi->boot_device);
|
dbg_print("%-16s = 0x%x (0x%x)", "boot_device", mbi->boot_device);
|
||||||
|
switch ((mbi->boot_device) & 0xFF000000) {
|
||||||
|
case 0x00000000:
|
||||||
|
dbg_print("(floppy)\n");
|
||||||
|
break;
|
||||||
|
case 0x80000000:
|
||||||
|
dbg_print("(disk)\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dbg_print("(unknown)\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the command line passed?
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CMDLINE)) {
|
||||||
dbg_print("cmdlin: 0x%x (%s)\n", mbi->cmdline, (char *)mbi->cmdline);
|
dbg_print("%-16s = %s\n", "cmdline", (char *)mbi->cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are mods_* valid?
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MODS)) {
|
||||||
dbg_print("Mods : 0x%x\n", mbi->mods_count);
|
dbg_print("%-16s = %d\n", "mods_count", mbi->mods_count);
|
||||||
|
dbg_print("%-16s = 0x%x\n", "mods_addr", mbi->mods_addr);
|
||||||
multiboot_module_t *mod = (multiboot_module_t *)mbi->mods_addr;
|
multiboot_module_t *mod = first_module(mbi);
|
||||||
|
for (int i = 0; mod; ++i, mod = next_module(mbi, mod)) {
|
||||||
if (mbi->mods_count > 0) {
|
dbg_print(" [%2d] "
|
||||||
for (uint32_t i = 0; i < mbi->mods_count && i < MAX_MODULES;
|
"mod_start = 0x%x, "
|
||||||
i++, mod++) {
|
"mod_end = 0x%x, "
|
||||||
uint32_t start = mod->mod_start;
|
"cmdline = %s\n",
|
||||||
uint32_t end = mod->mod_end;
|
i, mod->mod_start, mod->mod_end, (char *)mod->cmdline);
|
||||||
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
|
}
|
||||||
|
}
|
||||||
|
// Bits 4 and 5 are mutually exclusive!
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT) &&
|
||||||
|
has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
|
||||||
|
kernel_panic("Both bits 4 and 5 are set.\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last implementation
|
// Is the symbol table of a.out valid?
|
||||||
for (uint32_t i = 0; i < mbi->mods_count; ++i)
|
|
||||||
{
|
|
||||||
// uint32_t start = *((uint32_t *) (mbi->mods_addr + 8 * i));
|
|
||||||
uint32_t start = mbi->mods_addr + 8 * i;
|
|
||||||
// uint32_t end = *((uint32_t *) (mbi->mods_addr + 8 * i + 4));
|
|
||||||
uint32_t end = mbi->mods_addr + 8 * i + 4;
|
|
||||||
dbg_print("\tModule %d is at 0x%x:0x%x\n", i + 1, start, end);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_AOUT)) {
|
||||||
dbg_print("AOUT t : 0x%x\n", mbi->u.aout_sym.tabsize);
|
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
|
||||||
dbg_print("AOUT s : 0x%x\n", mbi->u.aout_sym.strsize);
|
dbg_print("multiboot_aout_symbol_table: tabsize = 0x%0x, "
|
||||||
dbg_print("AOUT a : 0x%x\n", mbi->u.aout_sym.addr);
|
"strsize = 0x%x, addr = 0x%x\n",
|
||||||
dbg_print("AOUT r : 0x%x\n", mbi->u.aout_sym.reserved);
|
multiboot_aout_sym->tabsize, multiboot_aout_sym->strsize,
|
||||||
|
multiboot_aout_sym->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is the section header table of ELF valid?
|
||||||
if (has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_ELF)) {
|
||||||
dbg_print("ELF n : 0x%x\n", mbi->u.elf_sec.num);
|
multiboot_elf_section_header_table_t *multiboot_elf_sec =
|
||||||
dbg_print("ELF s : 0x%x\n", mbi->u.elf_sec.size);
|
&(mbi->u.elf_sec);
|
||||||
dbg_print("ELF a : 0x%x\n", mbi->u.elf_sec.addr);
|
dbg_print("multiboot_elf_sec: num = %u, size = 0x%x,"
|
||||||
dbg_print("ELF h : 0x%x\n", mbi->u.elf_sec.shndx);
|
" addr = 0x%x, shndx = 0x%x\n",
|
||||||
|
multiboot_elf_sec->num, multiboot_elf_sec->size,
|
||||||
|
multiboot_elf_sec->addr, multiboot_elf_sec->shndx);
|
||||||
}
|
}
|
||||||
dbg_print("MMap : 0x%x\n", mbi->mmap_length);
|
|
||||||
dbg_print("Addr : 0x%x\n", mbi->mmap_addr);
|
// Are mmap_* valid?
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_MMAP)) {
|
||||||
|
dbg_print("%-16s = 0x%x\n", "mmap_addr", mbi->mmap_addr);
|
||||||
|
dbg_print("%-16s = 0x%x (%d entries)\n", "mmap_length",
|
||||||
|
mbi->mmap_length,
|
||||||
|
mbi->mmap_length / sizeof(multiboot_memory_map_t));
|
||||||
|
multiboot_memory_map_t *mmap = first_mmap_entry(mbi);
|
||||||
|
for (int i = 0; mmap; ++i, mmap = next_mmap_entry(mbi, mmap)) {
|
||||||
|
dbg_print(" [%2d] "
|
||||||
|
"base_addr = 0x%09x%09x, "
|
||||||
|
"length = 0x%09x%09x, "
|
||||||
|
"type = 0x%x (%s)\n",
|
||||||
|
i, mmap->base_addr_high, mmap->base_addr_low,
|
||||||
|
mmap->length_high, mmap->length_low, mmap->type,
|
||||||
|
mmap_type_name(mmap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_DRIVE_INFO)) {
|
||||||
dbg_print("Drives: 0x%x\n", mbi->drives_length);
|
dbg_print("Drives: 0x%x\n", mbi->drives_length);
|
||||||
dbg_print("Addr : 0x%x\n", mbi->drives_addr);
|
dbg_print("Addr : 0x%x\n", mbi->drives_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_CONFIG_TABLE)) {
|
||||||
dbg_print("Config: 0x%x\n", mbi->config_table);
|
dbg_print("Config: 0x%x\n", mbi->config_table);
|
||||||
dbg_print("Loader: 0x%x (%s)\n", mbi->boot_loader_name,
|
}
|
||||||
(char *)mbi->boot_loader_name);
|
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_BOOT_LOADER_NAME)) {
|
||||||
|
dbg_print("boot_loader_name: %s\n", (char *)mbi->boot_loader_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_APM_TABLE)) {
|
||||||
dbg_print("APM : 0x%x\n", mbi->apm_table);
|
dbg_print("APM : 0x%x\n", mbi->apm_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_flag(mbi->flags, MULTIBOOT_FLAG_VBE_INFO)) {
|
||||||
dbg_print("VBE Co: 0x%x\n", mbi->vbe_control_info);
|
dbg_print("VBE Co: 0x%x\n", mbi->vbe_control_info);
|
||||||
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_info);
|
dbg_print("VBE Mo: 0x%x\n", mbi->vbe_mode_info);
|
||||||
dbg_print("VBE In: 0x%x\n", mbi->vbe_mode);
|
dbg_print("VBE In: 0x%x\n", mbi->vbe_mode);
|
||||||
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg);
|
dbg_print("VBE se: 0x%x\n", mbi->vbe_interface_seg);
|
||||||
dbg_print("VBE of: 0x%x\n", mbi->vbe_interface_off);
|
dbg_print("VBE of: 0x%x\n", mbi->vbe_interface_off);
|
||||||
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
|
dbg_print("VBE le: 0x%x\n", mbi->vbe_interface_len);
|
||||||
|
}
|
||||||
dbg_print("--------------------------------------------------\n");
|
dbg_print("--------------------------------------------------\n");
|
||||||
dbg_print("\n");
|
dbg_print("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ task_struct *create_init_process()
|
|||||||
// Enable the interrupts.
|
// Enable the interrupts.
|
||||||
init_proc->thread.eflags = init_proc->thread.eflags | EFLAG_IF;
|
init_proc->thread.eflags = init_proc->thread.eflags | EFLAG_IF;
|
||||||
// Clear the current working directory.
|
// Clear the current working directory.
|
||||||
memset(init_proc->cwd, '\0', MAX_PATH_LENGTH);
|
memset(init_proc->cwd, '\0', PATH_MAX);
|
||||||
// Set the state of the process as running.
|
// Set the state of the process as running.
|
||||||
init_proc->state = TASK_RUNNING;
|
init_proc->state = TASK_RUNNING;
|
||||||
// Active the current process.
|
// Active the current process.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "rbtree.h"
|
#include "rbtree.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "list_head.h"
|
#include "list_head.h"
|
||||||
|
#include "deadlock_simulation.h"
|
||||||
|
|
||||||
/// @brief Assembly function setting the kernel stack to jump into
|
/// @brief Assembly function setting the kernel stack to jump into
|
||||||
/// location in Ring 3 mode (USER mode).
|
/// location in Ring 3 mode (USER mode).
|
||||||
@@ -68,6 +69,11 @@ void kernel_initialize_scheduler()
|
|||||||
runqueue.curr = NULL;
|
runqueue.curr = NULL;
|
||||||
// Reset the number of active tasks.
|
// Reset the number of active tasks.
|
||||||
runqueue.num_active = 0;
|
runqueue.num_active = 0;
|
||||||
|
|
||||||
|
#if ENABLE_DEADLOCK_PREVENTION
|
||||||
|
// Simulate deadlock.
|
||||||
|
deadlock_simulation();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void enqueue_task(task_struct *process)
|
void enqueue_task(task_struct *process)
|
||||||
@@ -125,12 +131,14 @@ void kernel_schedule(pt_regs *f)
|
|||||||
}
|
}
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Print, for debugging purpose, data about the current process.
|
// Print, for debugging purpose, data about the current process.
|
||||||
if (runqueue.num_active > 2) {
|
if (runqueue.num_active > 2) {
|
||||||
dbg_print("PID:%3d, PRIO:%3d, VRUNTIME:%9d, SUM_EXEC:%9d\n",
|
dbg_print("PID:%3d, PRIO:%3d, VRUNTIME:%9d, SUM_EXEC:%9d\n",
|
||||||
next_process->pid, next_process->se.prio,
|
next_process->pid, next_process->se.prio,
|
||||||
next_process->se.vruntime, next_process->se.sum_exec_runtime);
|
next_process->se.vruntime, next_process->se.sum_exec_runtime);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//==== Context switch ======================================================
|
//==== Context switch ======================================================
|
||||||
// Update the context of the current process.
|
// Update the context of the current process.
|
||||||
@@ -377,6 +385,10 @@ void sys_exit(int exit_code)
|
|||||||
}
|
}
|
||||||
// Free the space occupied by the stack.
|
// Free the space occupied by the stack.
|
||||||
destroy_process_image(runqueue.curr->mm);
|
destroy_process_image(runqueue.curr->mm);
|
||||||
|
// Clean resources needed by.
|
||||||
|
for (size_t i = 0; i < TASK_RESOURCE_MAX_AMOUNT; i++) {
|
||||||
|
runqueue.curr->resources[i] = NULL;
|
||||||
|
}
|
||||||
// Debugging message.
|
// Debugging message.
|
||||||
dbg_print("Process %d exited with value %d\n", runqueue.curr->pid,
|
dbg_print("Process %d exited with value %d\n", runqueue.curr->pid,
|
||||||
exit_code);
|
exit_code);
|
||||||
|
|||||||
@@ -19,7 +19,15 @@ task_struct *pick_next_task(runqueue_t *runqueue, time_t delta_exec)
|
|||||||
#if defined(SCHEDULER_RR)
|
#if defined(SCHEDULER_RR)
|
||||||
//==== Implementatin of the Round-Robin Scheduling algorithm ============
|
//==== Implementatin of the Round-Robin Scheduling algorithm ============
|
||||||
|
|
||||||
|
// nNode = next(c)
|
||||||
|
struct list_head *nNode = runqueue->curr->run_list.next;
|
||||||
|
|
||||||
|
// if isHead(L, nNode)
|
||||||
|
if (nNode == &runqueue->queue)
|
||||||
|
nNode = nNode->next;
|
||||||
|
|
||||||
|
// n = entry(nNode)
|
||||||
|
next = list_entry(nNode, struct task_struct, run_list);
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
#elif defined(SCHEDULER_PRIORITY)
|
#elif defined(SCHEDULER_PRIORITY)
|
||||||
|
|||||||
+23
-37
@@ -11,18 +11,19 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "initrd.h"
|
#include "initrd.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "syscall_types.h"
|
||||||
|
#include "assert.h"
|
||||||
|
#include "errno.h"
|
||||||
|
|
||||||
DIR *opendir(const char *path)
|
DIR *opendir(const char *path)
|
||||||
{
|
{
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
char absolute_path[PATH_MAX];
|
||||||
DIR *pdir = NULL;
|
DIR *pdir = NULL;
|
||||||
|
|
||||||
strcpy(absolute_path, path);
|
strcpy(absolute_path, path);
|
||||||
// If the first character is not the '/' then get the absolute path.
|
// If the first character is not the '/' then get the absolute path.
|
||||||
if (absolute_path[0] != '/')
|
if (absolute_path[0] != '/') {
|
||||||
{
|
if (!get_absolute_path(absolute_path)) {
|
||||||
if (!get_absolute_path(absolute_path))
|
|
||||||
{
|
|
||||||
dbg_print("Cannot get the absolute path.\n");
|
dbg_print("Cannot get the absolute path.\n");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -31,27 +32,26 @@ DIR *opendir(const char *path)
|
|||||||
|
|
||||||
// Get the mount point id.
|
// Get the mount point id.
|
||||||
int32_t mp_id = get_mountpoint_id(absolute_path);
|
int32_t mp_id = get_mountpoint_id(absolute_path);
|
||||||
if (mp_id < 0)
|
if (mp_id < 0) {
|
||||||
{
|
|
||||||
printf("opendir: cannot open directory '%s':"
|
printf("opendir: cannot open directory '%s':"
|
||||||
"Cannot find mount-point\n", absolute_path);
|
"Cannot find mount-point\n",
|
||||||
|
absolute_path);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mountpoint_list[mp_id].dir_op.opendir_f == NULL)
|
if (mountpoint_list[mp_id].dir_op.opendir_f == NULL) {
|
||||||
{
|
|
||||||
printf("opendir: cannot open directory '%s':"
|
printf("opendir: cannot open directory '%s':"
|
||||||
"No opendir function\n", absolute_path);
|
"No opendir function\n",
|
||||||
|
absolute_path);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdir = mountpoint_list[mp_id].dir_op.opendir_f(absolute_path);
|
pdir = mountpoint_list[mp_id].dir_op.opendir_f(absolute_path);
|
||||||
// If the directiry is correctly open, set the handle.
|
// If the directiry is correctly open, set the handle.
|
||||||
if (pdir != NULL)
|
if (pdir != NULL) {
|
||||||
{
|
pdir->fd = mp_id;
|
||||||
pdir->handle = mp_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pdir;
|
return pdir;
|
||||||
@@ -59,40 +59,26 @@ DIR *opendir(const char *path)
|
|||||||
|
|
||||||
int closedir(DIR *dirp)
|
int closedir(DIR *dirp)
|
||||||
{
|
{
|
||||||
if (dirp == NULL)
|
if (dirp == NULL) {
|
||||||
{
|
|
||||||
printf("closedir: cannot close directory :"
|
printf("closedir: cannot close directory :"
|
||||||
"Directory pointer is not valid\n");
|
"Directory pointer is not valid\n");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (mountpoint_list[dirp->handle].dir_op.closedir_f == NULL)
|
if (mountpoint_list[dirp->fd].dir_op.closedir_f == NULL) {
|
||||||
{
|
|
||||||
printf("closedir: cannot close directory '%s':"
|
printf("closedir: cannot close directory '%s':"
|
||||||
"No closedir function\n", dirp->path);
|
"No closedir function\n",
|
||||||
|
dirp->path);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return mountpoint_list[dirp->fd].dir_op.closedir_f(dirp);
|
||||||
return mountpoint_list[dirp->handle].dir_op.closedir_f(dirp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirent_t *readdir(DIR *dirp)
|
dirent_t *readdir(DIR *dirp)
|
||||||
{
|
{
|
||||||
if (dirp == NULL)
|
dirent_t *dent;
|
||||||
{
|
// Call the readdir system call.
|
||||||
printf("readdir: cannot read directory :"
|
DEFN_SYSCALL1(dent, __NR_readdir, dirp);
|
||||||
"Directory pointer is not valid\n");
|
return dent;
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (mountpoint_list[dirp->handle].dir_op.readdir_f == NULL)
|
|
||||||
{
|
|
||||||
printf("readdir: cannot read directory '%s':"
|
|
||||||
"No readdir function\n", dirp->path);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mountpoint_list[dirp->handle].dir_op.readdir_f(dirp);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-39
@@ -4,61 +4,32 @@
|
|||||||
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
/// @copyright (c) 2019 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include "vfs.h"
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "fcntl.h"
|
|
||||||
#include "kheap.h"
|
|
||||||
#include "errno.h"
|
|
||||||
#include "initrd.h"
|
|
||||||
#include "string.h"
|
|
||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
|
|
||||||
int close(int fildes)
|
#include "string.h"
|
||||||
{
|
#include "limits.h"
|
||||||
if (fildes < 0)
|
#include "stdio.h"
|
||||||
{
|
#include "vfs.h"
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (fd_list[fildes].fs_spec_id >= -1)
|
|
||||||
{
|
|
||||||
int mp_id = fd_list[fildes].mountpoint_id;
|
|
||||||
if (mountpoint_list[mp_id].operations.close_f != NULL)
|
|
||||||
{
|
|
||||||
int fs_fd = fd_list[fildes].fs_spec_id;
|
|
||||||
mountpoint_list[mp_id].operations.close_f(fs_fd);
|
|
||||||
}
|
|
||||||
fd_list[fildes].fs_spec_id = -1;
|
|
||||||
fd_list[fildes].mountpoint_id = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rmdir(const char *path)
|
int rmdir(const char *path)
|
||||||
{
|
{
|
||||||
char absolute_path[MAX_PATH_LENGTH];
|
char absolute_path[PATH_MAX];
|
||||||
strcpy(absolute_path, path);
|
strcpy(absolute_path, path);
|
||||||
|
|
||||||
if (path[0] != '/')
|
if (path[0] != '/') {
|
||||||
{
|
|
||||||
get_absolute_path(absolute_path);
|
get_absolute_path(absolute_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mp_id = get_mountpoint_id(absolute_path);
|
int32_t mp_id = get_mountpoint_id(absolute_path);
|
||||||
if (mp_id < 0)
|
if (mp_id < 0) {
|
||||||
{
|
|
||||||
printf("rmdir: failed to remove '%s':"
|
printf("rmdir: failed to remove '%s':"
|
||||||
"Cannot find mount-point\n", path);
|
"Cannot find mount-point\n",
|
||||||
|
path);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL)
|
if (mountpoint_list[mp_id].dir_op.rmdir_f == NULL) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
#include "sys.h"
|
|
||||||
#include "shm.h"
|
#include "shm.h"
|
||||||
#include "isr.h"
|
#include "isr.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
@@ -17,7 +16,8 @@
|
|||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "irqflags.h"
|
#include "irqflags.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "read_write.h"
|
|
||||||
|
#include "smart_sem_kernel.h"
|
||||||
|
|
||||||
/// @brief The signature of a function call.
|
/// @brief The signature of a function call.
|
||||||
typedef int (*SystemCall)();
|
typedef int (*SystemCall)();
|
||||||
@@ -48,6 +48,10 @@ void syscall_init()
|
|||||||
sys_call_table[__NR_read] = (SystemCall)sys_read;
|
sys_call_table[__NR_read] = (SystemCall)sys_read;
|
||||||
sys_call_table[__NR_write] = (SystemCall)sys_write;
|
sys_call_table[__NR_write] = (SystemCall)sys_write;
|
||||||
sys_call_table[__NR_open] = (SystemCall)sys_open;
|
sys_call_table[__NR_open] = (SystemCall)sys_open;
|
||||||
|
sys_call_table[__NR_close] = (SystemCall)sys_close;
|
||||||
|
sys_call_table[__NR_stat] = (SystemCall)sys_stat;
|
||||||
|
sys_call_table[__NR_mkdir] = (SystemCall)sys_mkdir;
|
||||||
|
sys_call_table[__NR_readdir] = (SystemCall)sys_readdir;
|
||||||
sys_call_table[__NR_getpid] = (SystemCall)sys_getpid;
|
sys_call_table[__NR_getpid] = (SystemCall)sys_getpid;
|
||||||
sys_call_table[__NR_getppid] = (SystemCall)sys_getppid;
|
sys_call_table[__NR_getppid] = (SystemCall)sys_getppid;
|
||||||
sys_call_table[__NR_vfork] = (SystemCall)sys_vfork;
|
sys_call_table[__NR_vfork] = (SystemCall)sys_vfork;
|
||||||
@@ -57,10 +61,15 @@ void syscall_init()
|
|||||||
sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid;
|
sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid;
|
||||||
sys_call_table[__NR_chdir] = (SystemCall)sys_chdir;
|
sys_call_table[__NR_chdir] = (SystemCall)sys_chdir;
|
||||||
sys_call_table[__NR_getcwd] = (SystemCall)sys_getcwd;
|
sys_call_table[__NR_getcwd] = (SystemCall)sys_getcwd;
|
||||||
sys_call_table[__NR_waitpid] = (SystemCall)sys_waitpid;
|
|
||||||
sys_call_table[__NR_brk] = (SystemCall)umalloc; // TODO: sys_brk
|
sys_call_table[__NR_brk] = (SystemCall)umalloc; // TODO: sys_brk
|
||||||
sys_call_table[__NR_free] = (SystemCall)ufree; // TODO: sys_brk
|
sys_call_table[__NR_free] = (SystemCall)ufree; // TODO: sys_brk
|
||||||
|
|
||||||
|
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
|
||||||
|
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
|
||||||
|
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
|
||||||
|
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
|
||||||
|
// sys_call_table[__NR_sem_...] = (SystemCall)sys_sem_...;
|
||||||
|
|
||||||
isr_install_handler(SYSTEM_CALL, &syscall_handler, "syscall_handler");
|
isr_install_handler(SYSTEM_CALL, &syscall_handler, "syscall_handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,43 +16,32 @@
|
|||||||
void cmd_cd(int argc, char **argv)
|
void cmd_cd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
DIR *dirp = NULL;
|
DIR *dirp = NULL;
|
||||||
char path[MAX_PATH_LENGTH];
|
char path[PATH_MAX];
|
||||||
memset(path, 0, MAX_PATH_LENGTH);
|
memset(path, 0, PATH_MAX);
|
||||||
|
|
||||||
char current_path[MAX_PATH_LENGTH];
|
char current_path[PATH_MAX];
|
||||||
getcwd(current_path, MAX_PATH_LENGTH);
|
getcwd(current_path, PATH_MAX);
|
||||||
|
|
||||||
if (argc <= 1)
|
if (argc <= 1) {
|
||||||
{
|
|
||||||
strcpy(path, "/");
|
strcpy(path, "/");
|
||||||
}
|
} else if (argc > 2) {
|
||||||
else if (argc > 2)
|
|
||||||
{
|
|
||||||
printf("%s: too many arguments\n\n", argv[0]);
|
printf("%s: too many arguments\n\n", argv[0]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
} else if (strncmp(argv[1], "..", 2) == 0) {
|
||||||
else if (strncmp(argv[1], "..", 2) == 0)
|
if (strcmp(current_path, dirname(current_path)) == 0) {
|
||||||
{
|
|
||||||
if (strcmp(current_path, dirname(current_path)) == 0)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy(path, dirname(current_path));
|
strcpy(path, dirname(current_path));
|
||||||
}
|
} else if (strncmp(argv[1], ".", 1) == 0) {
|
||||||
else if (strncmp(argv[1], ".", 1) == 0)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy the current path.
|
// Copy the current path.
|
||||||
strcpy(path, current_path);
|
strcpy(path, current_path);
|
||||||
// Get the absolute path.
|
// Get the absolute path.
|
||||||
get_absolute_path(path);
|
get_absolute_path(path);
|
||||||
// If the current directory is not the root, add a '/'.
|
// If the current directory is not the root, add a '/'.
|
||||||
if (strcmp(path, "/") != 0)
|
if (strcmp(path, "/") != 0) {
|
||||||
{
|
|
||||||
strncat(path, "/", 1);
|
strncat(path, "/", 1);
|
||||||
}
|
}
|
||||||
// Concatenate the input dir.
|
// Concatenate the input dir.
|
||||||
@@ -60,8 +49,7 @@ void cmd_cd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dirp = opendir(path);
|
dirp = opendir(path);
|
||||||
if (dirp == NULL)
|
if (dirp == NULL) {
|
||||||
{
|
|
||||||
printf("%s: no such file or directory: %s\n\n", argv[0], argv[1]);
|
printf("%s: no such file or directory: %s\n\n", argv[0], argv[1]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -11,37 +11,25 @@
|
|||||||
|
|
||||||
void cmd_drv_load(int argc, char **argv)
|
void cmd_drv_load(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2) {
|
||||||
{
|
|
||||||
printf(
|
printf(
|
||||||
"No driver inserted or bad usage! Type %s --help for the usage.\n",
|
"No driver inserted or bad usage! Type %s --help for the usage.\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
}
|
} else {
|
||||||
else
|
if ((_kstrncmp(argv[1], "-r", 2) == 0)) {
|
||||||
{
|
if ((argv[2] != NULL)) {
|
||||||
if ((_kstrncmp(argv[1], "-r", 2) == 0))
|
if (_kstrncmp(argv[2], "mouse", 5) == 0) {
|
||||||
{
|
|
||||||
if ((argv[2] != NULL))
|
|
||||||
{
|
|
||||||
if (_kstrncmp(argv[2], "mouse", 5) == 0)
|
|
||||||
{
|
|
||||||
printf("Disattivamento %s in corso..\n", argv[2]);
|
printf("Disattivamento %s in corso..\n", argv[2]);
|
||||||
mouse_disable();
|
mouse_disable();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf("FATAL: Driver %s not found.\n", argv[2]);
|
printf("FATAL: Driver %s not found.\n", argv[2]);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf("Warning, no driver name inserted!\n");
|
printf("Warning, no driver name inserted!\n");
|
||||||
}
|
} else if (_kstrncmp(argv[1], "mouse", 5) == 0) {
|
||||||
else if (_kstrncmp(argv[1], "mouse", 5) == 0)
|
|
||||||
{
|
|
||||||
// Enabling mouse.
|
// Enabling mouse.
|
||||||
mouse_install();
|
mouse_install();
|
||||||
}
|
} else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
|
||||||
else if ((_kstrncmp(argv[1], "--help", 6) == 0) ||
|
(_kstrncmp(argv[1], "-h", 2) == 0)) {
|
||||||
(_kstrncmp(argv[1], "-h", 2) == 0))
|
|
||||||
{
|
|
||||||
printf("---------------------------------------------------\n"
|
printf("---------------------------------------------------\n"
|
||||||
"Driver tool to load and kill driver\n"
|
"Driver tool to load and kill driver\n"
|
||||||
"Simple to use, just type:\n"
|
"Simple to use, just type:\n"
|
||||||
@@ -51,17 +39,13 @@ void cmd_drv_load(int argc, char **argv)
|
|||||||
"\t-> %s -r module_name - to kill driver\n"
|
"\t-> %s -r module_name - to kill driver\n"
|
||||||
"---------------------------------------------------\n",
|
"---------------------------------------------------\n",
|
||||||
argv[0], argv[0], argv[0]);
|
argv[0], argv[0], argv[0]);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((_kstrncmp(argv[1], "-r", 2) == 0) &&
|
if ((_kstrncmp(argv[1], "-r", 2) == 0) &&
|
||||||
(_kstrncmp(argv[2], "mouse", 5) == -1))
|
(_kstrncmp(argv[2], "mouse", 5) == -1)) {
|
||||||
{
|
|
||||||
printf("FATAL: Driver %s not found.\n", argv[2]);
|
printf("FATAL: Driver %s not found.\n", argv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
printf("FATAL: Driver %s not found.\n", argv[1]);
|
printf("FATAL: Driver %s not found.\n", argv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,10 @@ void cmd_echo(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i = argc;
|
int i = argc;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
if (argc == 1)
|
if (argc == 1) {
|
||||||
{
|
|
||||||
printf("");
|
printf("");
|
||||||
}
|
} else {
|
||||||
else
|
while (--i > 0) {
|
||||||
{
|
|
||||||
while (--i > 0)
|
|
||||||
{
|
|
||||||
printf("%s ", argv[++j]);
|
printf("%s ", argv[++j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
extern struct shmid_ds *head;
|
extern struct shmid_ds *head;
|
||||||
|
|
||||||
void cmd_ipcrm(int argc, char **argv){
|
void cmd_ipcrm(int argc, char **argv)
|
||||||
if (argc != 2)
|
|
||||||
{
|
{
|
||||||
|
if (argc != 2) {
|
||||||
printf("Bad arguments: you have to specify only IPC id, see ipcs.\n");
|
printf("Bad arguments: you have to specify only IPC id, see ipcs.\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -21,13 +21,11 @@ void cmd_ipcrm(int argc, char **argv){
|
|||||||
struct shmid_ds *shmid_ds = head;
|
struct shmid_ds *shmid_ds = head;
|
||||||
struct shmid_ds *prev = NULL;
|
struct shmid_ds *prev = NULL;
|
||||||
|
|
||||||
while (shmid_ds != NULL)
|
while (shmid_ds != NULL) {
|
||||||
{
|
|
||||||
char strid[10];
|
char strid[10];
|
||||||
int_to_str(strid, (shmid_ds->shm_perm).seq, 10);
|
int_to_str(strid, (shmid_ds->shm_perm).seq, 10);
|
||||||
|
|
||||||
if (strcmp(strid, argv[1]) == 0)
|
if (strcmp(strid, argv[1]) == 0) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,21 +33,15 @@ void cmd_ipcrm(int argc, char **argv){
|
|||||||
shmid_ds = shmid_ds->next;
|
shmid_ds = shmid_ds->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shmid_ds == NULL)
|
if (shmid_ds == NULL) {
|
||||||
{
|
|
||||||
printf("No shared memory find. \n");
|
printf("No shared memory find. \n");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
kfree(shmid_ds->shm_location);
|
kfree(shmid_ds->shm_location);
|
||||||
|
|
||||||
// shmid_ds = head.
|
// shmid_ds = head.
|
||||||
if (prev == NULL)
|
if (prev == NULL) {
|
||||||
{
|
|
||||||
head = head->next;
|
head = head->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
prev->next = shmid_ds->next;
|
prev->next = shmid_ds->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,17 +28,13 @@ static void print_shm_stat()
|
|||||||
printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE",
|
printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE",
|
||||||
"OWNER", "GROUP");
|
"OWNER", "GROUP");
|
||||||
|
|
||||||
while (shm_list != NULL)
|
while (shm_list != NULL) {
|
||||||
{
|
|
||||||
char mode[12];
|
char mode[12];
|
||||||
strmode((shm_list->shm_perm).mode, mode);
|
strmode((shm_list->shm_perm).mode, mode);
|
||||||
|
|
||||||
printf("%-10s %-10i %-10i %-10s %-10s %-10s \n",
|
printf("%-10s %-10i %-10i %-10s %-10s %-10s \n", "m",
|
||||||
"m",
|
(shm_list->shm_perm).seq, (shm_list->shm_perm).key, mode, "-",
|
||||||
(shm_list->shm_perm).seq,
|
"-");
|
||||||
(shm_list->shm_perm).key,
|
|
||||||
mode,
|
|
||||||
"-", "-");
|
|
||||||
|
|
||||||
shm_list = shm_list->next;
|
shm_list = shm_list->next;
|
||||||
}
|
}
|
||||||
@@ -56,8 +52,7 @@ static void print_msg_stat()
|
|||||||
|
|
||||||
void cmd_ipcs(int argc, char **argv)
|
void cmd_ipcs(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc > 2)
|
if (argc > 2) {
|
||||||
{
|
|
||||||
printf("Too much arguments.\n");
|
printf("Too much arguments.\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -68,27 +63,17 @@ void cmd_ipcs(int argc, char **argv)
|
|||||||
|
|
||||||
printf("IPC status from " OS_NAME " as of %s\n", datehour);
|
printf("IPC status from " OS_NAME " as of %s\n", datehour);
|
||||||
|
|
||||||
if (argc == 2)
|
if (argc == 2) {
|
||||||
{
|
if (strcmp(argv[1], "-s") == 0) {
|
||||||
if (strcmp(argv[1], "-s") == 0)
|
|
||||||
{
|
|
||||||
print_sem_stat();
|
print_sem_stat();
|
||||||
}
|
} else if (strcmp(argv[1], "-m") == 0) {
|
||||||
else if (strcmp(argv[1], "-m") == 0)
|
|
||||||
{
|
|
||||||
print_shm_stat();
|
print_shm_stat();
|
||||||
}
|
} else if (strcmp(argv[1], "-q") == 0) {
|
||||||
else if (strcmp(argv[1], "-q") == 0)
|
|
||||||
{
|
|
||||||
print_msg_stat();
|
print_msg_stat();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Option not recognize.\n");
|
printf("Option not recognize.\n");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_sem_stat();
|
print_sem_stat();
|
||||||
print_shm_stat();
|
print_shm_stat();
|
||||||
print_msg_stat();
|
print_msg_stat();
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ void cmd_ls(int argc, char **argv)
|
|||||||
print_ls(dirp, flags);
|
print_ls(dirp, flags);
|
||||||
}
|
}
|
||||||
if (no_directory) {
|
if (no_directory) {
|
||||||
char cwd[MAX_PATH_LENGTH];
|
char cwd[PATH_MAX];
|
||||||
getcwd(cwd, MAX_PATH_LENGTH);
|
getcwd(cwd, PATH_MAX);
|
||||||
DIR *dirp = opendir(cwd);
|
DIR *dirp = opendir(cwd);
|
||||||
if (dirp == NULL) {
|
if (dirp == NULL) {
|
||||||
printf("%s: cannot access '%s': %s\n\n", argv[0], cwd, "unknown");
|
printf("%s: cannot access '%s': %s\n\n", argv[0], cwd, "unknown");
|
||||||
|
|||||||
@@ -13,16 +13,14 @@
|
|||||||
|
|
||||||
void cmd_more(int argc, char **argv)
|
void cmd_more(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2) {
|
||||||
{
|
|
||||||
printf("%s: missing operand.\n", argv[0]);
|
printf("%s: missing operand.\n", argv[0]);
|
||||||
printf("Try '%s --help' for more information.\n\n", argv[0]);
|
printf("Try '%s --help' for more information.\n\n", argv[0]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[1], "--help") == 0)
|
if (strcmp(argv[1], "--help") == 0) {
|
||||||
{
|
|
||||||
printf("Prints the content of the given file.\n");
|
printf("Prints the content of the given file.\n");
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf(" %s <file>\n\n", argv[0]);
|
printf(" %s <file>\n\n", argv[0]);
|
||||||
@@ -31,18 +29,16 @@ void cmd_more(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(argv[1], O_RDONLY, 42);
|
int fd = open(argv[1], O_RDONLY, 42);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
{
|
printf("%s: Cannot stat file '%s': %s\n\n", argv[0], argv[1],
|
||||||
printf("%s: Cannot stat file '%s': %s\n\n",
|
"unknown" /*strerror(errno)*/);
|
||||||
argv[0], argv[1],"unknown"/*strerror(errno)*/);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
// Put on the standard output the characters.
|
// Put on the standard output the characters.
|
||||||
while (read(fd, &c, 1) > 0)
|
while (read(fd, &c, 1) > 0) {
|
||||||
{
|
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|||||||
@@ -14,16 +14,14 @@
|
|||||||
|
|
||||||
void cmd_newfile(int argc, char **argv)
|
void cmd_newfile(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2) {
|
||||||
{
|
|
||||||
printf("%s: missing operand.\n", argv[0]);
|
printf("%s: missing operand.\n", argv[0]);
|
||||||
printf("Try '%s --help' for more information.\n\n", argv[0]);
|
printf("Try '%s --help' for more information.\n\n", argv[0]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[1], "--help") == 0)
|
if (strcmp(argv[1], "--help") == 0) {
|
||||||
{
|
|
||||||
printf("Makes a new file, and prompt for it's content.\n");
|
printf("Makes a new file, and prompt for it's content.\n");
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf(" %s <filename>\n", argv[0]);
|
printf(" %s <filename>\n", argv[0]);
|
||||||
@@ -34,28 +32,25 @@ void cmd_newfile(int argc, char **argv)
|
|||||||
char text[256];
|
char text[256];
|
||||||
printf("Filename: %s\n", argv[1]);
|
printf("Filename: %s\n", argv[1]);
|
||||||
int fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 0);
|
int fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 0);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
{
|
printf("%s: Cannot create file '%s': %s\n\n", argv[0], argv[1],
|
||||||
printf("%s: Cannot create file '%s': %s\n\n",
|
"unknown" /*strerror(errno)*/);
|
||||||
argv[0], argv[1], "unknown"/*strerror(errno)*/);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Type one line of text here (new line to complete):\n");
|
printf("Type one line of text here (new line to complete):\n");
|
||||||
scanf("%s", text);
|
scanf("%s", text);
|
||||||
if (write(fd, text, strlen(text)) == -1)
|
if (write(fd, text, strlen(text)) == -1) {
|
||||||
{
|
printf("%s: Cannot write on file '%s': %s\n\n", argv[0], argv[1],
|
||||||
printf("%s: Cannot write on file '%s': %s\n\n",
|
"unknown" /*strerror(errno)*/);
|
||||||
argv[0], argv[1], "unknown"/*strerror(errno)*/);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(fd) == -1)
|
if (close(fd) == -1) {
|
||||||
{
|
printf("%s: Cannot close file '%s': %s\n\n", argv[0], argv[1],
|
||||||
printf("%s: Cannot close file '%s': %s\n\n",
|
"unknown" /*strerror(errno)*/);
|
||||||
argv[0], argv[1], "unknown"/*strerror(errno)*/);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ void cmd_pwd(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
char cwd[MAX_PATH_LENGTH];
|
char cwd[PATH_MAX];
|
||||||
getcwd(cwd, MAX_PATH_LENGTH);
|
getcwd(cwd, PATH_MAX);
|
||||||
printf("%s\n", cwd);
|
printf("%s\n", cwd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,14 @@
|
|||||||
void cmd_rmdir(int argc, char **argv)
|
void cmd_rmdir(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Check the number of arguments.
|
// Check the number of arguments.
|
||||||
if (argc != 2)
|
if (argc != 2) {
|
||||||
{
|
|
||||||
printf("Bad usage.\n");
|
printf("Bad usage.\n");
|
||||||
printf("Try 'rmdir --help' for more information.\n");
|
printf("Try 'rmdir --help' for more information.\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[1], "--help") == 0)
|
if (strcmp(argv[1], "--help") == 0) {
|
||||||
{
|
|
||||||
printf("Removes a directory.\n");
|
printf("Removes a directory.\n");
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf(" rmdir <directory>\n");
|
printf(" rmdir <directory>\n");
|
||||||
@@ -30,10 +28,9 @@ void cmd_rmdir(int argc, char **argv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmdir(argv[1]) != 0)
|
if (rmdir(argv[1]) != 0) {
|
||||||
{
|
printf("%s: failed to remove '%s': %s\n\n", argv[0], argv[1],
|
||||||
printf("%s: failed to remove '%s': %s\n\n",
|
"unknown" /*strerror(errno)*/);
|
||||||
argv[0], argv[1], "unknown"/*strerror(errno)*/);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
#include <misc/debug.h>
|
#include "debug.h"
|
||||||
|
|
||||||
int main_init()
|
int main_init()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ struct {
|
|||||||
{ "clear", cmd_clear, "Clears the screen" },
|
{ "clear", cmd_clear, "Clears the screen" },
|
||||||
{ "showpid", cmd_showpid, "Shows the PID of the shell" },
|
{ "showpid", cmd_showpid, "Shows the PID of the shell" },
|
||||||
{ "history", cmd_show_history, "Shows the shell history" },
|
{ "history", cmd_show_history, "Shows the shell history" },
|
||||||
{ "nice", cmd_nice, "Change the nice value of the process" }
|
{ "nice", cmd_nice, "Change the nice value of the process" },
|
||||||
|
{ "deadlock", cmd_deadlock, "Test deadlock behavior" }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Completely delete the current command.
|
/// @brief Completely delete the current command.
|
||||||
@@ -215,8 +216,8 @@ static void shell_print_prompt()
|
|||||||
video_set_color(BRIGHT_BLUE);
|
video_set_color(BRIGHT_BLUE);
|
||||||
printf(current_user.username);
|
printf(current_user.username);
|
||||||
video_set_color(WHITE);
|
video_set_color(WHITE);
|
||||||
char cwd[MAX_PATH_LENGTH];
|
char cwd[PATH_MAX];
|
||||||
getcwd(cwd, MAX_PATH_LENGTH);
|
getcwd(cwd, PATH_MAX);
|
||||||
printf("~:%s# ", cwd);
|
printf("~:%s# ", cwd);
|
||||||
// Update the lower-bounds for the video.
|
// Update the lower-bounds for the video.
|
||||||
lower_bound_x = video_get_column();
|
lower_bound_x = video_get_column();
|
||||||
@@ -400,7 +401,7 @@ int shell(int argc, char **argv, char **envp)
|
|||||||
dbg_print("I'm shell, I'll let my pawn, login, handle any intruder...\n");
|
dbg_print("I'm shell, I'll let my pawn, login, handle any intruder...\n");
|
||||||
shell_login();
|
shell_login();
|
||||||
|
|
||||||
sys_chdir("/");
|
chdir("/");
|
||||||
current_user.uid = 1;
|
current_user.uid = 1;
|
||||||
current_user.gid = 0;
|
current_user.gid = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
Reference in New Issue
Block a user