Transcript ppt

Applications, Address Spaces,
and Processes
Separating Units of Computation
CSE-451 Processes
1
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
2
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
3
OS/User Protection
Address Space
0x00000000
main() {
int fd = open(“/tmp/foo”);
close(fd);
}
/* Syscall Dispatcher */
// determine requested routine
// transfer control to requested routine
// return result
The Operating
System
CSE-451 Processes
User Program
Syscall dispatch
0x7fffffff
0x80000000
File system
VM system
0xffffffff
4
Privileged Memory Protection
Address
high bits
low bits
Mode
bit
To
memory
Protection Fault
Mode
A
0
High Bit
B
0
Fault?
C
0
0
1
1
1
0
0
1
1
0
C = AB
CSE-451 Processes
5
Inside the User Program
User Program
_open:
load $v0, #SyscallOpen
syscall
cmp $v0, 0
jne
Error
move $a0, $v0
ret
The code
we wrote
Error:
….
Some code
we didn’t
write
syscall_ent:
Syscall dispatch
Error:
...
CSE-451 Processes
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
6
retsys
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
7
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
8
Understanding the Stack
Old stuff
SP
User stack
main
int fd
main+12
0x40040
New stuff
stack at syscall
stack at entry to open
SP
SP
CSE-451 Processes
USP=0x40040
UPC=_open+12
0x83000000
Kernel stack
$a0
$a1
$a2…
syscall_ent+24
9
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
10
Multiple Address Spaces
• Nearly all operating systems support the
abstraction of multiple address spaces
0x00000000
0x00000000
Emacs
0x7fffffff
0x00000000
CC
0x7fffffff
Mail
User mode
0x7fffffff
0x80000000
Kernel mode
0xffffffff
CSE-451 Processes
11
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
12
A Process is a Program in
Execution
Source
Code
File
Process In Memory
static int z = 5;
main(int argc, char **argv)
{ int x = foo();
printf(“%d\n”, x);
}
int foo()
{ return z=23;}
0x00000000
start PC
thread
text
1st instruction
z=5
cc
static data
stack
header: “size, start PC”
0x7fffffff
Executable
File (Program)
heap
text
Create Process
a.out
CSE-451 Processes
13
The Thread Of Control
static int z = 5;
main(int argc, char **argv)
{ int x = foo();
printf(“%d\n”, x);
}
int foo()
{ return z=23;}
argc
argv
_exit
23
23
“%d\n”
main+16
CSE-451 Processes
argc, argv are on the stack
call main
call foo
argc
set z to 23
argv
_exit
return 23
main+4
set x to 23
23
push x
push “%d\n”
call printf
stack
return
Thread
14
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
15
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
16
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
17
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
18
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??
CSE-451 Processes
v0=24266
v0=0
Operating
System
19
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
20
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
21
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
22