Here is a quick overview of the features implemented in each development phase. |
• |
Traditional libc functions (string.h, vsprintf.h, stdarg.h, setjmp.h... ) and useful macros to manage circular buffers (buffer.h) and circular doubly linked lists (list.h). |
• |
Task manager based on fork/exec functions (non-preemptive processes). |
• |
Task switching implemented with setjmp/longjmp to store and retrieve contexts (tasks_chg_context function in task.c). |
• |
Process context stored in the Process Control Block (PCB) (pcb.h). |
• |
Simple scheduler without priority managed with a list of running processes. |
• |
One stack per process (kernel stack). |
• |
Each process has a parent one (except the init task). |
• |
wait system call to wait for a child termination. |
• |
A process becomes a zombie once it is terminated and before someone waits for it. |
• |
Init task adopts children of dead processes and waits for them. |
• |
Pending signals are handled when switching tasks. |
• |
Default sighandlers kill, suspend or resume a process. |
• |
Stack switching: the kernel stack is used only when running kernel functions. Kernel and user stacks are switched in the following cases: |
- |
system call (user → kernel stack) |
- |
returning from a system call (kernel → user stack) |
- |
execve function (kernel → user stack) |
- |
user sighandler processing (kernel → user stack) |
- |
end of user sighandler processing (user → kernel stack) |
• |
Arguments and environment can be given to a process when it starts (execve function). These arguments and environment variables are copied in the user stack by execve. |
• |
Kernel functions to manage semaphores and read/write mutexes. |
• |
Non recursive read-write mutex implementation with readers priority (several readers can acquire a mutex simultaneously, nobody can acquire a mutex when a writer owns it). |
• |
Disk image containing an ext2 partition loaded in memory at startup. |
• |
Support for ext2 (revision 0) file system with some limitations (no symbolic links, no update of superblock data, no support for behaviour control flags like compression...). |
• |
Set up the Virtual File System (VFS), based on the inode concept. |
• |
stat system call. |
• |
open, close and fstat system calls. |
• |
For each file opened by a process, a file descriptor is created and added to the file descriptors table of the process. The total number of files opened by one process is limited. |
• |
Several file descriptors can reference the same inode. |
• |
Check that file permissions and open mode (read, write, read/write) are compatible when opening a file. |
• |
read and lseek system calls implementation, allowing to read regular files on an ext2 file system. |
• |
readdir system call implementation, allowing to read entries (one by one) of a directory on an ext2 file system. |
• |
Generic implementation to mount file systems on / directory. The proc file system is of course mounted on /. |
• |
/proc contains one directory per process currently allocated in the kernel. The directories are named with the processes’ pid. For each process, the following files are defined: |
- |
/proc/xxx/cmd: contains the command line of the process (argv table). |
- |
/proc/xxx/pid: contains the pid of the process. |
- |
/proc/xxx/ppid: contains the parent pid of the process. |
- |
/proc/xxx/state: contains the state of the process (R: running, S: interruptible sleep, T: stopped, Z: zombie). |
• |
All FS system calls can be used on /proc files (stat, open, close, fstat, read, readdir). |
The following plan is not definitive, but gives a good idea of what could be the next phases in CROCOS: |
• Phase 4: writing into the file system |
Basic write features (creating/deleting files, writing into files...). |
• Phase 5: boot sequence |
CROCOS can run in a real environment (emulator), outside a Linux process. |
• Phase 6: virtual memory |
• Phase 7: load of binaries |
User programs are not anymore linked together with the kernel. exec system call loads a binary file (ELF format ?). |
• Phase 8: tty driver |
• Phase 9: utilities and newlib |
The newlib can be used inside user programs. A shell is implemented. |