1 / 26

CS 153 Design of Operating Systems Winter 2016

CS 153 Design of Operating Systems Winter 2016. Lecture 22: System calls and their implementation details. Homework 3 is out!. Due in a week (March 7 th ). System Call. emacs: read(). Trap to kernel mode int 0x80 / sysenter. User mode. Kernel mode.

Download Presentation

CS 153 Design of Operating Systems Winter 2016

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS 153Design of Operating SystemsWinter 2016 Lecture 22: System calls and their implementation details

  2. Homework 3 is out! Due in a week (March 7th)

  3. System Call emacs: read() Trap to kernel mode int 0x80 / sysenter User mode Kernel mode Restore state, return to user level (iret / sysret), resume execution save state Trap handler: Find read handler read() kernel routine

  4. CPU Modes/Privileges • System call • Ring 3  Ring 0

  5. Another view 0xFFFFFFFF Kernel Stack SP2 1G PC2 Kernel Code 0xC0000000 Address Space User Stack SP1 3G PC1 User Code 0x00000000

  6. How to pass arguments in syscalls? • In short, through either registers or user stack Typical 32-bit x86 vs. PintOS • Registers: • Pro: fast • Con: limited number of arguments • Stack: • Pro: general (can support many more arguments) • Con: slower because of more memory accesses

  7. Typical 32-bit x86: Executing system calls • Put syscall number in eax • Set up arg 1 in ebx, arg 2 in ecx, arg 3 in edx • Call int 0x80* - syscall interrupt handler is invoked (traps to kernel) • System call runs. Result in eax * using sysenter is faster, but this is the traditional explanation

  8. Typical 32-bit x86: Executing system calls execve(“/bin/sh”, 0, 0); • Put syscall number in eax • Set up arg 1 in ebx, arg 2 in ecx, arg 3 in edx • Call int 0x80* • System call runs. Result in eax * using sysenter is faster, but this is the traditional explanation

  9. Typical 32-bit x86: Executing system calls execve(“/bin/sh”, 0, 0); execve is 0xb • Put syscall number in eax • Set up arg 1 in ebx, arg 2 in ecx, arg 3 in edx • Call int 0x80* • System call runs. Result in eax * using sysenter is faster, but this is the traditional explanation

  10. Typical 32-bit x86: Executing system calls execve(“/bin/sh”, 0, 0); execve is 0xb • Put syscall number in eax • Set up arg 1 in ebx, arg 2 in ecx, arg 3 in edx • Call int 0x80* • System call runs. Result in eax addr. in ebx, 0 in ecx * using sysenter is faster, but this is the traditional explanation

  11. PintOSsyscalls 0xFFFFFFFF Kernel Stack Kernel Code Arguments pushed to the top of the stack User Stack User Code 0x00000000

  12. Argument passing over stack 0xFFFFFFFF int orange(int a, int b) { char buf[16]; int c, d; if(a > b) c = a; else c = b; d = read_sys(c, buf); return d; } parameterarea (caller) to be createdbeforecalling read after read hasbeen called orange’sinitialstackframe %espstack grow 0x00000000

  13. Argument passing over stack 0xFFFFFFFF int orange(int a, int b) { char buf[16]; int c, d; if(a > b) c = a; else c = b; d = read_sys(c, buf); return d; } parameterarea (caller) Don’t worry!We will walk through theseone by one. to be createdbeforecalling read after read hasbeen called orange’sinitialstackframe %espstack grow 0x00000000

  14. When orange attains control, • return address has already been pushed onto stack by caller %esp

  15. When orange attains control, • return address has already been pushed onto stack by caller • allocate space for locals • subtracting from esp orange’sinitialstackframe %esp

  16. For callerorange to call syscall read, • push arguments to read from right to left (reversed) and the syscall # • from callee’s perspective, argument 1 is nearest in stack (syscall#). See Pintos lib/user/syscall.c %esp

  17. Why push arguments in reverse order? int main(int argc, char**argv) { printf(“String %s, int %d”, argv[0], argc); } int printf(constchar *format, ...); grow main’sstackframe

  18. For callerorange to call syscall read, • push arguments to read from right to left (reversed) and the syscall # • from callee’s perspective, argument 1 is nearest in stack (syscall#). See Pintos lib/user/syscall.c • trap into kernel through the instruction “int 0x30”, which saves the stack pointer and return address on the stack. - The return address will be used by the kernel to return control back to orange (through “iret” instruction) %esp orange’sstackframe

  19. For callerorange to call syscall read, • push arguments to read from right to left (reversed) and the syscall # • from callee’s perspective, argument 1 is nearest in stack (syscall#). See Pintos lib/user/syscall.c • trap into kernel through the instruction “int 0x30”, which saves the stack pointer and return address on the stack. - The return address will be used by the kernel to return control back to orange (through “iret” instruction) • transfer control to interrupt handler. • Pintos from threads/intr-stubs.S -> threads/interrupt.c -> threads/userprog/syscall.c %esp orange’sstackframe = struct intr_frame *frame

  20. When syscallread() attains control, • return address has already been pushed onto stack by orange %esp orange’sstackframe = struct intr_frame *frame

  21. When syscallread() attains control, • return address has already been pushed onto stack by orange • validate the address of “frame->esp” %esp orange’sstackframe = struct intr_frame *frame

  22. When syscallread() attains control, • return address has already been pushed onto stack by orange • validate the address of “frame->esp” • extract the syscall #, the two arguments of read() %esp orange’sstackframe = struct intr_frame *frame

  23. When syscallread() attains control, • return address has already been pushed onto stack by orange • validate the address of “frame->esp” • extract the syscall #, the two arguments of read() • do the syscall (most implementations provided in places such as filesys/file.c already) %esp orange’sstackframe = struct intr_frame *frame

  24. When syscallread() attains control, • return address has already been pushed onto stack by orange • validate the address of “frame->esp” • extract the syscall #, the two arguments of read() • do the syscall (most implementations provided in places such as filesys/file.c already) • return to orange by iret which pops the return addr on the stack %esp orange’sstackframe = struct intr_frame *frame

  25. Passing arguments to main() • As the program is loaded, allocate a page (or more) to serve as user stack • Set up the esp to point to the new page • Put arguments on the top of the stack (pointed to by esp) - Note: stack grows from higher addresses to lower addresses %esp

  26. Why do we need kernel stack? 0xFFFFFFFF Kernel Stack Kernel Code Function calls executed in kernel space need the protected kernel stack that cannot be tampered by user program User Stack User Code 0x00000000

More Related