📄 main.cc
字号:
// 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)// -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// -ci specify file for console input (stdin is the default)// -co specify file for console output (stdout is the default)// -n sets the network reliability// -m sets this machine's host id (needed for the network)// -K run a simple self test of kernel threads and synchronization// -C run an interactive console test// -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 variablesKernel *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 voidCopy(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".//----------------------------------------------------------------------voidPrint(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", "+"}//----------------------------------------------------------------------intmain(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 char *copyUnixFileName = NULL; // UNIX file to be copied into Nachos char *copyNachosFileName = NULL; // 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");#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) { 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();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -