Title: Operating Systems 2004 NachOS Introduction
1Operating Systems 2004NachOS Introduction
- Jen-Wei Hsieh
- Yuan-Hao Chang
- Yan-Cheng Lai
- 2004/10/20
2NachOS
- Run as a single UNIX process
- Provide a skeletal OS that supports
- Threads
- User-level processes
- Virtual memory
- Interrupt-driven I/O devices
- Two modes of execution
- Nachos kernel
- Executes when
- Nachos starts up
- A user-program causes a hardware trap (page
fault, system call, etc.) - MIPS simulator
- Initialized and started by Nachos kernel
3How does It Work?
4How does it work? (Cont.)
5How does it work? (Cont.)
6Source Tree
Root directory
C introduction to teach how to write C
Root directory of Nachoss source code
Building directories for different
systems (Platform dependent)
File system
Nachoss library
Source code of Nachos kernel and MIPS simulator
MIPS machine
In/Out message queues
Nachoss sample uer programs
threads
User programs interfaces system calls, address
space, noff format.
The tool to convert user programs from MIPSs
COFF into Nachoss NOFF format
NOFF Nachos Object File Format
7System Start UP
gt ./nathos ?start
code/threads/main.cc main
create kernel object
initialize the system
Invoke user program
No user program
Load user program
System halt and terminate
Run user program
8System Start Up Trace Source Code
- code/threads/main.cc main(int argc, char argv)
- Parse parameters (ex gtnachos x a.out, where x
a.out is a parameter) - Create Nachos kernel and initialize it
- create kernel object. // kernel new
Kernel(argc, argv) - initialize the system // kernel-gtInitialize()
code/threads/kernel.cc KernelInitialize() - Start up interrupt handling // interrupt new
Interrupt - initialize the ready queue and scheduler //
scheduler new Scheduler() - initialize MIPS machine, and Kernels machine
attribute pointes to it // machine new
Machine(debugUserProg) - Run some system testing
- Thread testing, console testing, and network
testing - Invoke user program if any. Otherwise terminate
Nachos. - create an address space to run a user process
// AddrSpace space new AddrSpace,
code/userprog/addrspace.cc - load program into MIPS machines main memory //
space-gtLoad(userProgName) - run the program// space-gtExecute()
code/userprog/addrspace.cc AddrSpaceExecute() - Jump to run the user program //
kernel-gtmachine-gtRun()code/machine/mipssim.cc
Global variable
9Machine Interrupt
MachineRun()
InterruptSetLevel(InOn) to re-enable interrupt
MachineOneInstruction()
Advance the system clock
InterruptOneTick() to advance system clock
Check pending interrupts If timer interrupt
occurs, give up CPU and run next thread in ready
queue
10Machine Object
- Attributes
- registers
- 40 registers accessed by kernel-gtmachine-gtregister
sx where x0-39 - Declared in code/machine/machine.h
- mainMemory
- the main memory of the simulated machine
- const int MemorySize (NumPhysPages PageSize)
in code/machine/machine.h - Default Page size 128bytes, number of
pages128bytes. You can change the number of
pages - Accessed by kernel-gtmachine-gtmainMemoryx where
x0-128128 - Methods
- Run()
- Turn on the MIPS machine
- OneInstruction()
- Execute an instruction of the user program
MachineRun() //in mipssim.cc for ()
OneInstruction(instr)
kernel-gtinterrupt-gtOneTick()
Invoked by kernel-gtmachine-gtRun()
11Interrupt Object
- Simulate interrupts by maintaining an event queue
together with a simulated clock (in
code/machine/interrupt.cc, interrupt.h) - When the clock ticks, the event queue is
examined. - Methods
- OneTick()
- Advance the clock one tick and call CheckIfDue()
to check pending interrupts. - called to advance the systems clock by
- MachineOneInstruction()
- Interrupt re-enabled (called by SetLevel()
function) - CheckIfDue()
- Check pending interupts
- SetLevel()
- Call ChangeLevel() to enable/disable interrupts
- Schedule()
- Schedule a future interrupt event to take place
12Interrupt Object (Cont.)
- InterruptOneTick() //in code/machine/interrupt
.cc -
- // advance simulated time
- stats-gttotalTicks SystemTick
- stats-gtsystemTicks SystemTick
-
- // check any pending interrupts are now ready to
fire - ChangeLevel(IntOn, IntOff) // first, turn
off interrupts - CheckIfDue(FALSE) // check for pending
interrupts - ChangeLevel(IntOff, IntOn) // re-enable
interrupts - if (yieldOnReturn) // if the timer device
handler asked - // for a context switch, ok
to do it now - yieldOnReturn FALSE
- status SystemMode
- kernel-gtcurrentThread-gtYield() // Give up
CPU - status oldStatus
13Thread Life Cycle
ThreadThread()
1. Timer Interrupt or 2. Call ThreadYield() ?
SchedulerFindNextToRun()
ThreadFork()
Call SchedulerReadyToRun()
In ready queue readyList
Event occurs, call SchedulerReadyToRun()
Call SchedulerRun()
Call ThreadSleep()
14Nachos Thread
- Use A List boject, readyList, as the ready queue
of threads - Four status
- Enum ThreadStatus JUST_CREATED, RUNNING, READY,
BLOCKED //In code/threads/thread.h - READY
- The thread will be kept in readyList
- RUNNING
- The global variable currentThread aways points
the currently running thread - BLOCKED
- Blocked to wait for some event until the event
takes place - Not in readyList
- JUST_CREATED
- The thread just created, but not ready to be put
in readyList (not ready to run)
15Thread Object
- Method (in code/threads/thread.cc, thread.h)
- Thread()
- The objects constructor which sets the thread as
JUST_CREATED status. - Fork()
- Allocate stack space for new thread and
initialize the registers - Call SchedulerReadyToRun() Put the thread into
readyList, and set its status as READY. - The selected thread will be executed by
SchedulerRun(), which sets its status as
RUNNING, and then call SWITCH()(in
code/threads/switch.s) to exchange the running
thread - Yield()
- Suspend the calling thread, and put the thread
into the end of readyList - Call SchedulerFindNextToRun() to select another
thread from readyList - Sleep()
- Suspend the current thread
- Change its state to BLOCKED
Note Scheduler is defined in code/threads/schedul
er.cc, shceduler.h
16Timer Object
- Create timer interrupt every TimerTicks
(default100 ticks) - When the timer interrupt takes place, the
scheduler will select another thread from ready
queue (readyList) to run - Enable time sharing scheduling
TimerTimer(bool doRandom, CallBackObj
toCall) SetInterrupt() void
TimerSetInterrupt() int delay
TimerTicks // schedule the next timer device
interrupt kernel-gtinterrupt-gtSchedule(this,
delay, TimerInt)
17Scheduler Object
- Decide which thread to run next.
- Invoked whenever the current thread wishes to
give up the CPU. - Scheduling policy A FIFO readyList with
round-robin fashion - Methods
- ReadyToRun()
- Change the threads status as READY and put it in
the readyList - FindNextToRun()
- Fetch the thread at the front of the readyList
- Run()
- Change the state of the selected thread to
RUNNING - Invoke Switch() to switch from the previous
thread to the selected thread - If the previous thread called ThreadFinished()
, terminate it. (indicated by the global variable
threadToBeDestroyed )
18User-Level Processes
- The Noff format file required
- A single process a thread an address space
- Uesr program is compiled with code/test/start.s
- Entry file code/test/start.s
- MachineRun()
- turn on the simulated MIPS machine
- Instruction by instruction
- MIPS syscall instruction invokes
MachineRaiseException()
19Procedure of a System Call
Load use program into MIPS machine and run
In code/machine/mipssim.cc
MachineRun()
Run instructions of the user program
MachineOneInstruction()
Executing a system call instruction
Executing normal instructions
MIPS machine
MachineRaiseException(SyscallException, 0))
ExceptionHandler(), in code/userprog/exception.cc
Nachos Kernel
Execute the corresponding system call
Back to user program
20Related Code for User Processes
- code/test/start.s
- Startup assembly code for every user program of
Nachos. - code/userprog/syscall.h
- Definitions of the system call prototypes
- code/userprog/exception.cc
- The handler for system calls and other exceptions
is here.
21Starting of a User Program
- code/test/start.s
- Define what is needed for a user program.
- starting point
- User programs system call functions
- startup assembly code of every user program of
Nachos - Initialize and run a C program by jumping to
location 0.
22Exception Types
- Execution errors
- System calls
23The Progress of a System Call in a User Program
- The user program is responsible for
- storing of the system codes in Register 2
- storing of the arguments in Register 4 ,5, 6, and
7. - ExceptionHandler in code/userprog/exception.cc
- Fetch system call number in Register 2.
- Entry point into the Nachos kernel from user
programs - syscall
- exceptions
- Add new exception handlers switch case in switch
case section - Execute the corresponding codes for the system
call. - Increase the PC. (RegPC)
24Declaring of System Call
- code/userprog/syscall.h
- system call codes
- Ex define SC_Halt 0
- Interface for Nachos system calls
- Ex int Add(int op1, int op2)
25The Entry Point into Nachos Kernel
- ExceptionHandler
- code/userprog/execption.cc
- The code for the system call is placed in
Register 2. - arg
- arg1 is in Register 4.
- arg2 is in Register 5.
- arg3 is in Register 6.
- arg4 is in Register 7.
- The return value is in Register 2.
- Note
- If you are handling a system call, don't forget
to increment the PC before return to the user
program.
26Example System Call add(arg1,arg2)
- In ExceptionHandler in code/userprog/execption.cc
- case SC_Add
- // SysAdd is defined in userprog/ksyscall.h
- result SysAdd(/ int op1 /(int)kernel-gtmachine
-gtReadRegister(4), - / int op2 /(int)kernel-gtmachine-gtReadRegister
(5)) - kernel-gtmachine-gtWriteRegister(2,
(int)result) //return value in R2 -
- / Modify return point /
-
- / set previous programm counter (debugging
only)/ - kernel-gtmachine-gtWriteRegister(PrevPCReg,
kernel-gtmachine-gtReadRegister(PCReg)) - / set programm counter to next instruction
(all Instructions are 4 byte wide)/ - kernel-gtmachine-gtWriteRegister(PCReg,
kernel-gtmachine-gtReadRegister(PCReg) 4) -
- / set next programm counter for brach
execution / - kernel-gtmachine-gtWriteRegister(NextPCReg,
kernel-gtmachine-gtReadRegister(PCReg)4) -