220 likes | 276 Views
Learn about user and kernel memory, syscall dispatch, address spaces, and how processes operate in CSE-451. Explore mode bits, protections, syscall handling, and the stack concept.
E N D
Applications, Address Spaces, and Processes Separating Units of Computation CSE-451 Processes
Definitions • User mode • when the system is executing with the privileged bit off • Kernel mode • when the system is executing with the privileged bit on • Address space • the range of addresses available for a program to use • Legal address space • the range of addresses that a program can use right now CSE-451 Processes
User and Kernel Memory • When the mode bit is set to PRIVILEGED, the kernel can see all of memory • user program, arguments, etc • User memory is like a big data structure for the kernel • But, when the mode bit is off, the user program can only see its own memory • the kernel’s address space is OFF LIMITS • what happens if the user tries? • Good for the OS, and good for the user program CSE-451 Processes
Syscall dispatch OS/User Protection Address Space 0x00000000 main() { int fd = open(“/tmp/foo”); close(fd); } User Program 0x7fffffff /* Syscall Dispatcher */ // determine requested routine // transfer control to requested routine // return result 0x80000000 File system VM system The Operating System 0xffffffff CSE-451 Processes
Address low bits high bits Mode bit To memory Protection Fault C = AB Privileged Memory Protection CSE-451 Processes
Syscall dispatch Inside the User Program User Program _open: load $v0, #SyscallOpen syscall cmp $v0, 0 jne Error move $a0, $v0 ret Error: …. The code we wrote Some code we didn’t write syscall_ent: cmp $v0, #0 // check if good system call jlt Error cmp $v0, #MaxSysCall jgt Error jsr SaveAllNonLinkRegisters load $v0, $v0(SyscallTable) // if so, get api entry point jsr $v0 // go there move $v0, $a0 // result in $a0 load $v0, #0 RestoreAllNonLinkRegisters retsys Error: ... CSE-451 Processes
What Happens on Syscall? • Automatic • Hardware MODE bit flips (go from nonpriv to priv) • Minimal save and restore of context • SP <- Kernel Syscall SP • PC <- Kernel Syscall PC • *SP++ <- User SP • *SP++ <- User PC • What happens on retsys? CSE-451 Processes
And then we pick it up... • Sycall handler checks to make sure we’re asking for a good service • Control is transferred to the service • Result is passed back CSE-451 Processes
Understanding the Stack User stack Old stuff main int fd main+12 0x40040 SP New stuff 0x83000000 USP=0x40040 UPC=_open+12 Kernel stack stack at syscall SP $a0 $a1 $a2… syscall_ent+24 stack at entry to open SP CSE-451 Processes
Concepts So Far • User programs operate out of a different portion of the address space than the kernel • There is a context switch that occurs every time we enter the kernel • Inside the kernel we have expanded privileges • A combination of hardware and software is responsible for this behavior CSE-451 Processes
0x00000000 0x00000000 0x00000000 0x7fffffff 0x7fffffff 0x7fffffff Multiple Address Spaces • Nearly all operating systems support the abstraction of multiple address spaces Emacs CC Mail User mode 0x80000000 Kernel mode 0xffffffff CSE-451 Processes
A Process • Each address space contains a process • a bunch of text & data • a “thread” in execution • A thread represents the flow of control that is active inside a program • deterministic change of state prescribed by the current state and the PC (which is actually part of the current state) CSE-451 Processes
A Process is a Program in Execution Process In Memory static int z = 5; main(int argc, char **argv) { int x = foo(); printf(“%d\n”, x); } int foo() { return z=23;} Source Code File start PC 0x00000000 thread text 1st instruction z=5 static data cc stack header: “size, start PC” heap Executable File (Program) 0x7fffffff text Create Process a.out CSE-451 Processes
The Thread Of Control argc, argv are on the stack call main call foo set z to 23 return 23 set x to 23 push x push “%d\n” call printf return static int z = 5; main(int argc, char **argv) { int x = foo(); printf(“%d\n”, x); } int foo() { return z=23;} argc argv _exit main+4 23 argc argv _exit 23 23 “%d\n” main+16 stack Thread CSE-451 Processes
Where do Processes Come From? • Remember, a process is an address space with some stuff in it and a thread of control • All operating systems have facilities for creating new processes • Some of them (eg, NT) are quite simple: • CreateAddressSpace, WriteAddressSpace, CreateThreadInAddressSpace, StartThread • Others (eg, UNIX) are more subtle, but quite elegant CSE-451 Processes
Processes Under UNIX • In Unix, the fork() system call is the only way to create a new process • int fork() does many things at once: • creates a new address space (called the child) • copies the parent’s address space into the child’s • starts a new thread of control in the child’s address space • parent and child are equivalent -- almost • in parent, fork() returns a non-zero integer • in child, fork() returns a zero. • difference allows parent and child to distinguish • int fork() returns TWICE! CSE-451 Processes
Example main(int argc, char **argv) { char *myName = argv[1]; int cpid = fork(); if (cpid == 0) { printf(“The child of %s is %d\n”, myName, getpid()); exit(0); } else { printf(“My child is %d\n”, cpid); exit(0); } } What does this program print? CSE-451 Processes
Bizarre But Real lace:tmp<15> cc a.c lace:tmp<16> ./a.out foobar The child of foobar is 23874 My child is 23874 Parent Child fork() retsys v0=23874 v0=0 Operating System CSE-451 Processes
Even More Bizarre lace:tmp<15> cc a.c lace:tmp<16> ./a.out foobar The child of foobar is 23874 My child is 23874 lace:tmp<17> ./a.out foobar My child is 24266 The child of foobar is 24266 lace:tmp<18> Parent Child fork() retsys Why do we get a different answer?? v0=24266 v0=0 Operating System CSE-451 Processes
Fork is half the story • Fork() gets us a new address space, but not one that’s all that different. • parent and child share EVERYTHING • memory, operating system state • int exec(char *programName) completes the picture • throws away the contents of the calling address space • replaces it with the program named by programName • starts executing at header.startPC CSE-451 Processes
Starting a new program main(int argc, char **argv) { char *myName = argv[1]; char *progName = argv[2]; int cpid = fork(); if (cpid == 0) { printf(“The child of %s is %d\n”, myName, getpid()); execl(progName, // executable name progName, 0); // null terminated argv printf(“OH NO. THEY LIED TO ME!!!\n”); } else { printf(“My child is %d\n”, cpid); exit(0); } } CSE-451 Processes
Extra Credit for Friday • Write a simple UNIX program to simulate the UNIX shell in a “read/fork/exec” loop • don’t bother with path searches. All commands can be fully qualified CSE451Shell%/bin/cat /etc/motd DEC OSF/1 V3.2 (Rev. 214); Thu Feb 22 08:48:40 PST 1996 DEC OSF/1 V3.2 Worksystem Software (Rev. 214) This is an AFS fileserver. Please run long running jobs (hours) or memory intensive jobs elsewhere. CSE451Shell%/bin/date Sun Apr 5 22:51:50 PDT 1998 CSE-451 Processes