Outline TTIT61: Process Programming and Operating Systems System calls Single user program Lab 2 Assignment Sergiu Rafiliu serra@ida.liu.se phone: 282281, room: B 329:228 alean@ida Lab 2 Outline -2- TTIT61 Lab lesson Four Components of a Computer System Lab 2: “System calls” Description Pintos stack Pintos memory Pintos file system Halt, Exit Create, Open/Close Read/Write alean@ida -3- TTIT61 Lab lesson alean@ida -4- System Calls TTIT61 Lab lesson System Call Execution #include <stdio.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> /* System calls are written in bold italic. Type “man 2 sys_call_name” for info in Linux or “man –s 2 sys_call_name” in Solaris */ int fd, n; char buf[1024]; fd = open(“datafile.txt”); n = read(fd, buf, 1024); printf(“Have read %d bytes: %s\n”, n, buf); lseek(fd, 0, SEEK_SET); write(fd, “Some other text”, strlen(“Some other text”) + 1); write(fd, buf, n); close(fd); alean@ida -5- TTIT61 Lab lesson alean@ida -6- TTIT61 Lab lesson Systems Calls Description Systems Calls - Implementation user_program.c System calls: communication between the user program and the kernel functions, called from the user program and performed by the kernel computers often use internal interrupts (traps) to accomplish that switch from user code to system code Calling corresponding function in the wrapper Calling corresponding exception in the kernel #include <syscal.h> bool flag; flag = create(“file.txt”, 1000); Return result back to the user program pintos/src/lib/user/syscall.c System call wrapper bool create (const char *file, unsigned initial_size) { return syscall2 (SYS_CREATE, file, initial_size); } Pintos kernel pintos/src/userprog/syscall.c User exception handler // Your code here! alean@ida -7- TTIT61 Lab lesson alean@ida alean@ida -9- TTIT61 Lab lesson TTIT61 Lab lesson -8- User Program - Example User Programs Located in the Pintos directory: examples/ Compiled with a compiler that produces ELF executable ELF format is used by Linux, Solaris and other operating systems for object files, shared libraries, and executables. Pintos provides a loader for ELF files in userprog/process.c Modify examples/Makefile in order to add other user programs Shutdown program : /* halt.c */ #include <syscall.h> void main(void) { halt(); } alean@ida -10- Pintos disk User programs must be loaded on a disk before they can be run. Unix like file system is implemented in Pintos in filesystem directory. Create a simulated disk using pintos-mkdisk (in userprog/build do this) make a disk of size 2 MB pintos-mkdisk diskname.dsk 2 format the disk pintos –-qemu –f –q copy a program on the disk pintos –-qemu –p programname –a newname -- -q Run a program on the disk pintos --qemu -- run newname alean@ida -11- TTIT61 Lab lesson Return result back to the wrapper TTIT61 Lab lesson Pintos disk example Adding to a disk and running the program echo, with parameter ’x’ in Pintos: pintos-mkdisk fs.dsk 2 pintos –-qemu –f –q pintos –-qemu –p ../../examples/echo –a echo -- -q pintos --qemu -- run ’echo x’ Alternatively you can do this: pintos –-qemu –fs-disk=2 –p ../../examples/echo –a echo -- -f –q run ’echo x’ alean@ida -12- TTIT61 Lab lesson Lab 2 : Task You will need to implement: Useful Files You have to have a look at: create - creates a file. open - opens a file. close - closes a file. read - reads from a file or the console (the keyboard). write - writes to a file or the console (the monitor). halt - halts the processor. exit - Terminates a program and deallocates resources occupied by the program, for example, closes all files opened by the program. pintos/src/lib/user/syscall[.h|.c] – the wrapper… userprog/syscall[.h|.c] – Your implementation of system calls!!! threads/interrupt.[h|c] – important structures!!! lib/syscall-nr.h – system call constants filesys/filesys.[h|c] Pintos file system implementation… examples/lab2test.c – the “official” test program for this lab filesys/file.[h|c] – useful functions for operations with files. Things which you don’t find in “filesys”, you find here userprog/process.c Look up what is here and tell me… alean@ida alean@ida -13- TTIT61 Lab lesson -14- How To Start? TTIT61 Lab lesson Pintos Stack STEP 1 Understand what the user program is Look into “examples” directory Look into Makefile in this directory to understand how the user programs are compiled Compile the user programs by “gmake” STEP 2 Prepare Pintos disk Copy one or two user programs to the disk STEP 3 into userprog/process.c, find setup_stack() *esp = PHYS_BASE; change to *esp = PHYS_BASE - 12; STEP 4 Make sure that you understand the problems which may arise if you access (in the kernel) data stored in the user memory using the pointers provided by the user program as system call arguments. alean@ida -15- TTIT61 Lab lesson alean@ida -16- Create Example bool create (const char *file, unsigned initial_size) Example: create(“file.txt”, 1000); Create Example To implement the system calls, which operate with files, look at “filesys/filesys.[h|c]” and “filesys/file.[h|c]”. Everything is already done! Just call the functions… How to get the call name and parameters? Answer: f->esp How to return a value? Answer: f->eax Hint: So simple? Not yet… … note that, in order to get a string, you will need get a void pointer from esp and then get a char pointer to which points that void pointer. The char pointer will point to the first element of the string … alean@ida -17- TTIT61 Lab lesson TTIT61 Lab lesson Memory issues!!! alean@ida -18- TTIT61 Lab lesson Problem 1: If the pointer above PHYS_BASE, It points to Kernel memory! UNSAFE! All the pointers on the variables, which you get from the user program, must be validated! alean@ida TTIT61 Lab lesson -19- alean@ida Memory Issues in Pintos Kernel VM Physical Memory Kernel process PHYS_BASE Memory Issues in Pintos Kernel VM Physical Memory Kernel process PHYS_BASE Check if the pointer is below User process User process Page directory alean@ida TTIT61 Lab lesson -20- -21- If no entry? a)Kill user b) Handle page fault TTIT61 Lab lesson Page directory Check if the pointer is in the page directory alean@ida -22- If no entry? a)Kill user b) Handle page fault TTIT61 Lab lesson Other System Calls (1) STRUCT THREAD To implement the system calls, which operate with files, look at “filesys/filesys.[h|c]” and “filesys/file.[h|c]”. Everything is already done there. Just call the functions! alean@ida -23- TTIT61 Lab lesson alean@ida -24- TTIT61 Lab lesson Other System Calls (2) int open (const char *file) void close (int fd) Other System Calls (3) int read (int fd, void *buffer, unsigned size) Sink when you manage file IDs! I suggest using an array of *file elements and return indexes of this array as file IDs 0 and 1 IDs must be always reserved for the console! Reads size bytes from the file open as fd into buffer. Returns the number of bytes actually read (0 at end of file), or -1 if the file could not be read (due to a condition other than end of file). Fd 0 reads from the keyboard using input_getc() (defined in devices/input.h). NO SYNCHRONIZATION YET!!! NO SYNCHRONIZATION YET!!! alean@ida -25- TTIT61 Lab lesson alean@ida -26- Other System Calls (4) TTIT61 Lab lesson Other System Calls (5) int write (int fd, const void *buffer, unsigned size) Writes size bytes from buffer to the open file fd. Returns the number of bytes actually written or -1 if the file could not be written. Writing past end-of-file would normally extend the file, but file growth is not implemented by the basic file system. The expected behavior is to write as many bytes as possible up to end-of-file and return the actual number written or -1 if no bytes could be written at all. When fd=1 then the system call should write to the console. Your code which writes to the console should write all of buffer in one call to putbuf() (check lib/kernel/stdio.h and lib/kernel/console.c), at least as long as size is not bigger than a few hundred bytes. (It is reasonable to break up larger buffers.) Otherwise, lines of text output by different processes may end up interleaved on the console, confusing the user. void exit (int status) Terminates the current user program, returning status to the kernel. Conventionally, a status of 0 indicates success and nonzero values indicate errors. Remember to free all the resources will be not needed anymore. This system call will be improved in the following labs. NO SYNCHRONIZATION YET!!! alean@ida -27- TTIT61 Lab lesson Other System Calls (6) alean@ida -29- TTIT61 Lab lesson CLOSE ALL OPEN FILES CLOSE ALL OPEN FILES alean@ida -28- TTIT61 Lab lesson