21 Commits

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

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