NachOS 源码在我上传的资源里面,至于安装参见传送门->NachOS安装
// main.cc
// Driver code to initialize, selftest, and run the
// operating system kernel.
//
// Usage: nachos -d <debugflags> -rs <random seed #>
// -s -x <nachos file> -ci <consoleIn> -co <consoleOut>
// -f -cp <unix file> <nachos file>
// -p <nachos file> -r <nachos file> -l -D
// -n <network reliability> -m <machine id>
// -z -K -C -N
//
// -d causes certain debugging messages to be printed (see debug.h) <debugflags>参数得到不同输出,具体在debug.h
// -rs causes Yield to occur at random (but repeatable) spots 表示是随机数种子,产生时间片
// -z prints the copyright message 打印版权信息
// -s causes user programs to be executed in single-step mode 处于单步模式
// -x runs a user program 加载用户程序,运行在shell里面
// -ci specify file for console input (stdin is the default) 指定linux的文件,进行重定向为标准输入
// -co specify file for console output (stdout is the default) 指定linux的文件,进行重定向为标准输出
// -n sets the network reliability 设定网络的可靠程度
// -m sets this machine's host id (needed for the network) 设定nachos内核设定ID,相互通信的进程通过ID进行区别
// -K run a simple self test of kernel threads and synchronization 开关选项,运行thread库里面test代码,进行内部测试
// -C run an interactive console test 开关选项,运行console测试
// -N run a two-machine network test (see Kernel::NetworkTest) 网络测试
//
// Filesystem-related flags:
// -f forces the Nachos disk to be formatted
// -cp copies a file from UNIX to Nachos
// -p prints a Nachos file to stdout
// -r removes a Nachos file from the file system
// -l lists the contents of the Nachos directory
// -D prints the contents of the entire file system
//
// Note: the file system flags are not used if the stub filesystem
// is being used
//
// Copyright (c) 1992-1996 The Regents of the University of California.
// All rights reserved. See copyright.h for copyright notice and limitation
// of liability and disclaimer of warranty provisions.
#define MAIN
#include "copyright.h"
#undef MAIN
#include "main.h"
#include "filesys.h"
#include "openfile.h"
#include "sysdep.h"
#ifdef TUT
#include "tut.h"
//implements callbacks for unit test
#include "tut_reporter.h"
namespace tut
{
test_runner_singleton runner;
}
#endif TUT
// global variables
Kernel *kernel;
Debug *debug;
//----------------------------------------------------------------------
// Cleanup
// Delete kernel data structures; called when user hits "ctl-C".
//----------------------------------------------------------------------
static void
Cleanup(int x)
{
cerr << "\nCleaning up after signal " << x << "\n";
delete kernel;
}
//-------------------------------------------------------------------
// Constant used by "Copy" and "Print"
// It is the number of bytes read from the Unix file (for Copy)
// or the Nachos file (for Print) by each read operation
//-------------------------------------------------------------------
static const int TransferSize = 128;
#ifndef FILESYS_STUB
//----------------------------------------------------------------------
// Copy
// Copy the contents of the UNIX file "from" to the Nachos file "to"
//----------------------------------------------------------------------
static void
Copy(char *from, char *to)
{
int fd;
OpenFile* openFile;
int amountRead, fileLength;
char *buffer;
// Open UNIX file
if ((fd = OpenForReadWrite(from,FALSE)) < 0) {
printf("Copy: couldn't open input file %s\n", from);
return;
}
// Figure out length of UNIX file
Lseek(fd, 0, 2);
fileLength = Tell(fd);
Lseek(fd, 0, 0);
// Create a Nachos file of the same length
DEBUG('f', "Copying file " << from << " of size " << fileLength << " to file " << to);
if (!kernel->fileSystem->Create(to, fileLength)) { // Create Nachos file
printf("Copy: couldn't create output file %s\n", to);
Close(fd);
return;
}
openFile = kernel->fileSystem->Open(to);
ASSERT(openFile != NULL);
// Copy the data in TransferSize chunks
buffer = new char[TransferSize];
while ((amountRead=ReadPartial(fd, buffer, sizeof(char)*TransferSize)) > 0)
openFile->Write(buffer, amountRead);
delete [] buffer;
// Close the UNIX and the Nachos files
delete openFile;
Close(fd);
}
#endif // FILESYS_STUB
//----------------------------------------------------------------------
// Print
// Print the contents of the Nachos file "name".
//----------------------------------------------------------------------
void
Print(char *name)
{
OpenFile *openFile;
int i, amountRead;
char *buffer;
if ((openFile = kernel->fileSystem->Open(name)) == NULL) {
printf("Print: unable to open file %s\n", name);
return;
}
buffer = new char[TransferSize];
while ((amountRead = openFile->Read(buffer, TransferSize)) > 0)
for (i = 0; i < amountRead; i++)
printf("%c", buffer[i]);
delete [] buffer;
delete openFile; // close the Nachos file
return;
}
//----------------------------------------------------------------------
// main
// Bootstrap the operating system kernel.
//
// Initialize kernel data structures
// Call some test routines
// Call "Run" to start an initial user program running
//
// "argc" is the number of command line arguments (including the name
// of the command) -- ex: "nachos -d +" -> argc = 3
// "argv" is an array of strings, one for each command line argument
// ex: "nachos -d +" -> argv = {"nachos", "-d", "+"}
//----------------------------------------------------------------------
int
main(int argc, char **argv)
{//参数初始化
int i;
char *debugArg = ""; //调试信息是否需要打印
char *userProgName = NULL; // 运行的用户程序default is not to execute a user prog
bool threadTestFlag = false; //线程测试标记
bool consoleTestFlag = false; //终端测试标记
bool networkTestFlag = false; //网络测试标记
#ifndef FILESYS_STUB //如果没有定义自己的文件系统,那么就采用linux文件系统
char *copyUnixFileName = NULL; // linux的文件系统 UNIX file to be copied into Nachos
char *copyNachosFileName = NULL; // 被复制到nachos里面的文件 name of copied file in Nachos
char *printFileName = NULL; //
char *removeFileName = NULL;
bool dirListFlag = false;
bool dumpFlag = false;
#endif //FILESYS_STUB
// some command line arguments are handled here. 参数解析
// those that set kernel parameters are handled in
// the Kernel constructor
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-d") == 0) {//是否有调试选项
ASSERT(i + 1 < argc); // next argument is debug string
debugArg = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "-z") == 0) {
cout << copyright << "\n";
}
else if (strcmp(argv[i], "-x") == 0) {
ASSERT(i + 1 < argc);
userProgName = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "-K") == 0) {
threadTestFlag = TRUE;
}
else if (strcmp(argv[i], "-C") == 0) {
consoleTestFlag = TRUE;
}
else if (strcmp(argv[i], "-N") == 0) {
networkTestFlag = TRUE;
}
#ifndef FILESYS_STUB
else if (strcmp(argv[i], "-cp") == 0) {
ASSERT(i + 2 < argc);
copyUnixFileName = argv[i + 1];
copyNachosFileName = argv[i + 2];
i += 2;
}
else if (strcmp(argv[i], "-p") == 0) {
ASSERT(i + 1 < argc);
printFileName = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "-r") == 0) {
ASSERT(i + 1 < argc);
removeFileName = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "-l") == 0) {
dirListFlag = true;
}
else if (strcmp(argv[i], "-D") == 0) {
dumpFlag = true;
}
#endif //FILESYS_STUB
else if (strcmp(argv[i], "-u") == 0) {
cout << "Partial usage: nachos [-z -d debugFlags]\n";
cout << "Partial usage: nachos [-x programName]\n";
cout << "Partial usage: nachos [-K] [-C] [-N]\n";
#ifndef FILESYS_STUB
cout << "Partial usage: nachos [-cp UnixFile NachosFile]\n";
cout << "Partial usage: nachos [-p fileName] [-r fileName]\n";
cout << "Partial usage: nachos [-l] [-D]\n";
#endif //FILESYS_STUB
}
}
debug = new Debug(debugArg);
DEBUG(dbgThread, "Entering main");//针对debug,增加调试信息
#ifdef TUT
::tut::callback * clbk = new tut::reporter(cout);
::tut::runner.get().set_callback(clbk);
::tut::runner.get().run_tests(); //run all unit tests
#endif
//创建内核对象与初始化
kernel = new Kernel(argc, argv);//创建虚拟机,主控线程,计算机系统
kernel->Initialize();//初始化
CallOnUserAbort(Cleanup); // if user hits ctl-C
// at this point, the kernel is ready to do something
// run some tests, if requested 测试
if (threadTestFlag) {
kernel->ThreadSelfTest(); // test threads and synchronization
}
if (consoleTestFlag) {
kernel->ConsoleTest(); // interactive test of the synchronized console
}
if (networkTestFlag) {
kernel->NetworkTest(); // two-machine test of the network
}
#ifndef FILESYS_STUB//文件系统
if (removeFileName != NULL) {
kernel->fileSystem->Remove(removeFileName);
}
if (copyUnixFileName != NULL && copyNachosFileName != NULL) {
Copy(copyUnixFileName,copyNachosFileName);
}
if (dumpFlag) {
kernel->fileSystem->Print();
}
if (dirListFlag) {
kernel->fileSystem->List();
}
if (printFileName != NULL) {
Print(printFileName);
}
#endif // FILESYS_STUB
// finally, run an initial user program if requested to do so
if (userProgName != NULL) {//判断用户名是否为空,通过-x参数传递的
AddrSpace *space = new AddrSpace;//分配地址空间
ASSERT(space != (AddrSpace *)NULL);
if (space->Load(userProgName)) { // load the program into the space,用户程序加载到这个空间,就绪状态
space->Execute(); // run the program 运行程序
ASSERTNOTREACHED(); // Execute never returns 调用终止程序
}
}
// If we don't run a user program, we may get here.
// Calling "return" would terminate the program.
// Instead, call Halt, which will first clean up, then
// terminate.
kernel->interrupt->Halt();
ASSERTNOTREACHED();
}