CSCC69: Operating Systems Tutorial 2 Some of the slides were borrowed from csc369 course, U of T, St George
Review: How to configure and install Use sftp to upload your file to your account % mkdir ~/cscc69 You should copy your source directory (a1) cscc69 – % cd cscc69 – % cp –r [a1 path]. % cd a1/src %./configure – Check that you have defs.mk in your src
Review: How to configure and install Configure kernel ASST1 – % cd kern/conf – %./config ASST1 Build kernel ASST1 – % cd../compile/ASST1 – % bmake depend – % bmake Install kernel ASST1 – % bmake install
Review: How to configure and install Build user level utilities – % cd../../.. – % bmake – % bmake install Now you have kernel and user utilities.
Review: How to configure and install NOTE: you might get this error while making or installing the kernel: “warnings are treated as errors” – In order to solve this problem: open ~/cscc69/a1/src/mk/os161.config.mk then comment out “WERROR=-Werror” and add “WERROR=“ NOTE: you might also get an error regarding man pages – In that case, open ~/cscc69/a1/src/man/dev/Makefile and make the changes such that you have “MANFILES=“
Review: running the kernel Copy a1/src/sys161.conf file to ~/cscc69/root Change directory to ~/cscc69/root Run sys161 on your OS – % sys161 kernel The system boots, and you see command prompt Type ? To see the menu Type ?o for operation menu Type p /bin/poweroff to shut down
GDB Debugging OS161 requires two terminals – Run OS161 in one terminal with the debug flag Sys161 –w kernel – Connect the debugger to it from another terminal cd ~/cscc69/root Os161-gdb kernel >target remote unix:.sockets/gdb Use.gdbinit files to make debugging easier – GDB executes the files in the.gdbinit files upon startup – You can even define blocks of statements to be executed when called at the command line in GDB
An Example of gdbinit File # Start example.gdbinit file. dir / /src/kern/arch/mips/mips # Above line tells the debugger to parse the assembly files located in that directory. Remember to edit the path to match your source location! define db target remote unix:.sockets/gdb # Above line connects debugger to the waiting kernelend define syscall_time # Defines a macro for GDB to use called "syscall_time"break syscall # Sets a breakpoint on a function called "syscall” break sys___time End # End macro definition define interrupt_b break common_exception break mips_trap break mips_interrupt break exception_return End # End.gdbinit
System Calls User level applications are isolated from the OS in a different protection domain System calls are a way of requesting the services of the OS – Method calls defined in user-level libraries “trap” from user-space to the OS in kernel-space Once control traps to the kernel, a kernel-level system call handler is invoked to service the system call and return the appropriate results to user-space Once the system call is complete, control is given back to the user-level application
Trap Frame The trap frame is used to pass information about the exception, storing the current processor state for later execution The trap handler determines which syscall is being requested by looking at the corresponding code in the trap frame struct (tf->tf_a0) Once the syscall finishes executing, the return value or error code is put back into the trap frame (tf->tf_v0) Read the code: take a look at the whole call stack to get a better idea
OS161 System Call Example: time
How a system call get called? The MIPS syscall instruction will cause a software interruption. After this instruction, the hardware will automatically turn off interrupts, then jump to the code located at 0x – From kern/arch/mips/locore/exception-mips1.S, we can see that mips_general_handler is the code that defined at 0x The assembly code here do a lot of stuff that we don’t need to care. All we need to know that they will save a trapframe on current thread’s kernel stack and call mips_trap in kern/arch/mips/locore/trap.c. Then if this trap (or interruption) is caused by syscall instruction, mips_trap will call syscall in kern/arch/mips/syscall/syscall.c to handle. Then we go to syscall function, we dispatch the syscall according to the call number, then collect the results and return. If every thing is OK, we go back to mips_trap, then to the assembly code common_exception and then go back to user mode.
Creating a New System Call in OS161 Define the new system call code in src/kern/include/kern/syscall.h Define the prototypes for the new syscall – Kernel space: src/kern/include/syscall.h – User space: src/user/include Write the source code for it in src/kern/syscall/new_syscall.c – Be sure to include this new file in src/kern/conf/conf.kern! (so it’s included in the build path) If necessary, define any new error codes in src/kern/include/kern/errno.h Add a case in the handler switch statement in src/kern/arch/mips/syscall/syscall.c Create a test program in user/testbin Rebuild both kernel and user level programs Hint: take a look at what has been done for sys___time system call. You can follow the same pattern.
OS161 System Calls - Reference Manual Go to this website for the description of OS161 system calls – man/syscall/
_exit Name _exit - terminate process Library Standard C Library (libc, -lc) Synopsis #include Void _exit(int exitcode); Description Cause the current process to exit. The exit code exitcode is reported back to other process(es) via the waitpid() call. The process id of the exiting process should not be reused until all processes interested in collecting the exit code with waitpid have done so. (What "interested" means is intentionally left vague; you should design this.) Return Values _exit does not return.
_exit System Call exit only take on integer argument. All we need to do is find our struct process entry using curthread->t_pid. Then indicate that “I’ve exited” and fill the exitcode. The only thing to note that the exitcode must be made using the MACROs in /kern/include/kern/wait.h.