Nachos – System Calls and Multiprogramming System Calls (1)

advertisement
Sorin Manolache
Nachos – System Calls and Multiprogramming
Sorin Manolache
sorma@ida.liu.se
1
September 14, 2004
Sorin Manolache
System Calls (1)
• in exception.cc, ExceptionHandler
• Create, Open, Close, Read, Write
• Exec, Exit, Join
• syscall signatures found in syscall.h
• syscall.h exists in order to be included in your “user”-level
applications (those that will be cross-compiled to MIPS code)
• unfortunately, Close and Exit exist as functions in Nachos
(sysdep.cc), doing something else
2
September 14, 2004
Sorin Manolache
Syscall (2)
kernel (inside Nachos)
user (progs to be cross-compiled)
void ExceptionHandler(ExceptionType which) {
if (which == SyscallException)
if (type == SC_OPEN) {
/* your code here */
/* the name of the function that
implements the system call does not
necessarily need to be ‘Open’ */
/* let’s say it’s _My_Open and we call it
from here */
} else if (type == SC_READ) {
/* etc. */
...
} else {
/* only assignment 3 */
/* treat here PageFaultExceptions */
/* they may happen if the page is not in the
TLB or it is not in memory */
}
}
#include “syscall.h”
int main(void) {
/* some code */
Open(“foo”); /* system call */
}
• if Open was an ordinary function, it would be
like a call of a function that is found in some
library (like printf, for example)
• then we had to have a function called Open
somewhere and to link with it
• in test/start.s, Open is translated to syscall,
not to call
• when the MIPS emulator inside Nachos emulates the syscall MIPS instruction it will give
control to ExceptionHandler.
void _My_Open(...) {
...
}
September 14, 2004
3
Sorin Manolache
User Space vs. Kernel Space (1)
virtual
machine->mainMemory
int main(void) {
10
char *s = “foo”;
Open(s);
{
char *b = “badluck”; 1997
}
{
char *n = “foobar”; 2050
}
}
physical
physical memory
0
foo
10
1997
3000
bad
2000
bar
2100
int main(void) {
char *f = “bar”;
Create(f);
}
3000
100
3050
luck
foobar
4
September 14, 2004
Sorin Manolache
User Space vs. Kernel Space (2)
• Translate will do the virtual → physical address translation.
You’ll never have to call it directly. ReadMem and WriteMem use
it
• it is not enough to translate the start address and continue reading directly from the physical memory, because of fragmentation
(think of the “badluck” string)
• therefore, before using some data, copy it to the kernel space
(any variable in the nachos program is in the kernel space, only
those in the test programs are in the user space)
5
September 14, 2004
Sorin Manolache
User Space vs. Kernel Space (2)
• Open, Create and Exec will transfer strings (char arrays terminated by ‘\0’ (unbounded)) from the user space to kernel
space
• Read will transfer byte buffers of fixed size from kernel space to
user space
• Write will transfer byte buffers of fixed size from user space to
kernel space
Hint:
Create a function for each of those 3 cases
September 14, 2004
6
Sorin Manolache
Nachos Device Oriented System Calls (1)
• OpenFileId is the handle to the files
• after opening, all operations are performed by means of the
handle
user program:
in kernel:
#include “syscall.h”
case SC_OPEN:
...
OpenFile *ptr = filesys->Open(kFilename);
/* what should we do with ptr? */
...
case SC_READ:
...
ptr->Read(kBuf, size);
/* where do we get the ptr from? */
...
int main(void) {
char buf[20];
OpenFileId fd; /* int actually */
Create(“foo”);
fd = Open(“foo”);
Read(buf, sizeof(buf), fd);
Close(fd);
}
7
September 14, 2004
Sorin Manolache
Nachos Device Oriented System Calls (2)
we keep per process
file descriptor tables
(sound design)
0
1
2
3
0x800b0100
0xffffffff
0x800b0300
0x800b0400
we keep per OS file de- we return (int)ptr (very
scriptor tables (no se- dangerous)
curity)
no table, the OS is un0 0x800b0100
able to perform ANY
1 0xa0100300
checks. It’s very dan2 0x800b0300
gerous a user to have
3 0x800b0400
4 0xa0100400
pointers in the kernel
5 0xffffffff
space
6
0xffffffff
7 0xffffffff
0
1
2
3
0xa0100300
0xa0100400
0xffffffff
0xffffffff
the user deals only
with the table indexes
but what if a process
sends to the OS the
file descriptor of a file
opened by some other
process?
If the sent ptr is not a
valid pointer to an
OpenFile and we call
(OpenFile*)ptr->
Read... disaster
8
September 14, 2004
Sorin Manolache
Nachos Process Oriented System Calls (1)
SpaceId child; /* int */
child = Exec(“foo”);
create a new Thread object
create an address space for it (allocate physical memory for it)
load the process image (from the executable file) in the address space
keep a handle to the thread or addr. space (it doesn’t matter to which of
them as they are bound together)
again, process table vs. pointer cast approach
fork the new thread
decide which should be the function to be passed to Fork (what should
the new thread execute?)
return the handle
Exit(code);
code = Join(child);
September 14, 2004
destroy its addr. space (de-allocate the occupied phys. memory)
let other processes know about its death
if you have a global process table, store the exit code there and
finish the thread, else store the exit code in the thread object
and set the thread to sleep
if the child has not died already
register in the child’s queue of processes that wait its death and go to
sleep
take the exit code from where it is stored and return it
9
Sorin Manolache
Nachos Process Oriented System Calls (2)
• think of a mechanism of who is allowed to Wait/Join another
process
• proposals:
– anybody, but only one or several? (Unix new solution,
waitpid system call)
– only the parent, if the parent dies before the child:
– a grand-parent, or
– the root of all processes (Unix solution)
• if not anybody, then you need some additional data structures
for the process genealogic tree
10
September 14, 2004
Sorin Manolache
Advanced Issues – Re-entrant System Calls
(not really a problem in Nachos)
• what if we get an interrupt from the hardware when running in
kernel mode, as a result the threads are switched, and the new
thread will call the same system call as the one in service just
before the switching?
• make the syscalls atomic (non-pre-emptable)? but what if the
syscall is extremely slow (read from a CD-ROM)?
• the elegant solution is to have re-entrant system calls
• as the same code may run “at the same time”, they are not
allowed to share data (global or static data break re-entrance)
(think at the 3 translation functions, what if the kernel buffer is
unique and we get interrupted in the middle of a translation?)
• make non-re-entrant code (but protect it with mutexes) only
where you cannot otherwise (and make sure that those regions
execute fast)
11
September 14, 2004
Sorin Manolache
Multiprogramming (1)
• where does the MIPS know from how to translate between virtual and physical addresses (ReadMem and WriteMem)?
• each process translates its addresses according to its own
translation scheme
• each AddrSpace object contains its own pageTable that specifies the mapping virtual ↔ physical page
• at any moment in time, machine->pageTable points to the
page table of the currently running thread. The switching is
already implemented (space->RestoreState called from
Scheduler::Run)
September 14, 2004
12
Sorin Manolache
Multiprogramming (2)
• allocation should be done in AddrSpace constructor
• de-allocation in AddrSpace deconstructor
• this time blank only your portion of memory before loading the
process image (right now, the whole memory is blanked)
• use a bitmap (helper class Bitmap)
• each bit corresponds to a page in physical memory
• Bitmap::Find will find you the first unset bit (the first free
page) and it will set the bit (mark the page as taken)
• Bitmap::Clear is handy when de-allocating memory
13
September 14, 2004
Sorin Manolache
Virtual Memory – Assignment 3
• create a file that acts as the swap space on the disk
• use another bitmap to mark free/taken pages on the swap
space
• use OpenFile::ReadTo and OpenFile::WriteTo for
transferring pages between the physical memory
(machine->mainMemory + physicalAddressOfPage)
and the address on the disk
• upon Exec, load as much as you can into the physical memory,
mark the pages as valid, but also as dirty (trick). What does not
fit in, load into the swap space, and set the page as invalid. The
physicalPage field in the pageTable has different meanings
depending where the page is (valid or not)
14
September 14, 2004
Sorin Manolache
Virtual Memory
• page fault exception: either it is not referred in the TLB but it is in
the physical memory, or it is not in the physical memory
• first check, may be it is only not referred in the TLB. If yes, try to
refer it in the TLB, if there is no space anymore in the TLB
decide which reference to remove from the TLB
• if it is not at all in memory, bring it from the disk, try to load it in
the physical memory, if there is no space, replace one page
from the physical memory, refer it in the TLB, remove the reference to the replaced page from the TLB, update the valid bits
• who to replace?
– clean pages (not dirty) (they do not have to be written
on disk, because the copies are identical)
– pages not referred for a long time
• invalidate all references in the TLB upon a switch
September 14, 2004
15
Download