addrspace.cc

来自「操作系统课程设计。在UNIX平台下实现Solary操作系统的一些功能」· CC 代码 · 共 216 行

CC
216
字号
/////////////////////////////////////////////////////////////
//FileName		: AddrSpace.cc
//
//Creator		: Li Shouchao(0410716)
//CreateTime	: 2007-1-3
//
//File Desc:
//	1. Routines to manage address spaces (executing user programs).
//	
/////////////////////////////////////////////////////////////
#include "copyright.h"
#include "system.h"
#include "addrspace.h"
#include "noff.h"
#ifdef HOST_SPARC
#include <strings.h>
#endif

//----------------------------------------------------------------------
// SwapHeader
// 	Do little endian to big endian conversion on the bytes in the 
//	object file header, in case the file was generated on a little
//	endian machine, and we're now running on a big endian machine.
//----------------------------------------------------------------------

static void 
SwapHeader (NoffHeader *noffH)
{
	noffH->noffMagic = WordToHost(noffH->noffMagic);
	noffH->code.size = WordToHost(noffH->code.size);
	noffH->code.virtualAddr = WordToHost(noffH->code.virtualAddr);
	noffH->code.inFileAddr = WordToHost(noffH->code.inFileAddr);
	noffH->initData.size = WordToHost(noffH->initData.size);
	noffH->initData.virtualAddr = WordToHost(noffH->initData.virtualAddr);
	noffH->initData.inFileAddr = WordToHost(noffH->initData.inFileAddr);
	noffH->uninitData.size = WordToHost(noffH->uninitData.size);
	noffH->uninitData.virtualAddr = WordToHost(noffH->uninitData.virtualAddr);
	noffH->uninitData.inFileAddr = WordToHost(noffH->uninitData.inFileAddr);
}


//////////////////////////////////////////////////////
// Function name	: AddrSpace::AddrSpace
// Creator			: Fang Wenbin(0410706)
// CreateTime		: 2007-1-19 21:58:44
//
// Function Desc    : Create an address space to run a user program.
// 	The steps of AddrSpace::AddrSpace
//	1.Load the program from a file "executable", and set everything
//		up so that we can start executing user instructions.
//	2. set up the translation from program memory to physical 
//		memory.
//	3. load the disk content to memory
//	Fails if:
//	1.
//	2.
//	3.
// Note				:
// Return type		: 
// Argument         : OpenFile *executable
//////////////////////////////////////////////////////
AddrSpace::AddrSpace(OpenFile *executable)
{
    NoffHeader noffH;
    unsigned int i, size;

    executable->Read((char *)&noffH, sizeof(noffH));
	
    if ((noffH.noffMagic != NOFFMAGIC) && 
		(WordToHost(noffH.noffMagic) == NOFFMAGIC))
    	SwapHeader(&noffH);
    ASSERT(noffH.noffMagic == NOFFMAGIC);

    size = noffH.code.size + noffH.initData.size + noffH.uninitData.size 
			+ UserStackSize;	

    numPages = divRoundUp(size, PageSize);
    size = numPages * PageSize;

    ASSERT(numPages <= NumPhysPages);		

    DEBUG('a', "Initializing address space, num pages %d, size %d\n", 
					numPages, size);

    pageTable = new TranslationEntry[numPages];
    for (i = 0; i < numPages; i++) 
	{
		pageTable[i].physicalPage = machine->s_FindPage();
		pageTable[i].virtualPage = pageTable[i].physicalPage;
		pageTable[i].valid = TRUE;
		pageTable[i].use = FALSE;
		pageTable[i].dirty = FALSE;
		pageTable[i].readOnly = FALSE; 
    }//end for (i = 0...)
    
    //bzero(machine->mainMemory, size);

    if (noffH.code.size > 0) 
	{
		int readSize = noffH.code.size;
///
/// must convert virtual addr to physical addr
///
		int curAddr = pageTable[noffH.code.virtualAddr/PageSize].physicalPage*PageSize + noffH.code.virtualAddr%PageSize;
		int guard = noffH.code.inFileAddr;
	
       	executable->ReadAt(&(machine->mainMemory[curAddr]),
					readSize, guard);
    }// end if (noffH.code...)

    if (noffH.initData.size > 0) 
	{
		int readSize = noffH.initData.size;
///
/// must convert virtual addr to physical addr
///
		int curAddr = pageTable[noffH.initData.virtualAddr/PageSize].physicalPage*PageSize + noffH.initData.virtualAddr%PageSize;
		int guard = noffH.initData.inFileAddr;
	
       	executable->ReadAt(&(machine->mainMemory[curAddr]),
					readSize, guard);
    }//end if (noffH.initData...)

}

//----------------------------------------------------------------------
// AddrSpace::~AddrSpace
// 	Dealloate an address space.  Nothing for now!
//----------------------------------------------------------------------

AddrSpace::~AddrSpace()
{
   delete pageTable;
}

//----------------------------------------------------------------------
// AddrSpace::InitRegisters
// 	Set the initial values for the user-level register set.
//
// 	We write these directly into the "machine" registers, so
//	that we can immediately jump to user code.  Note that these
//	will be saved/restored into the currentThread->userRegisters
//	when this thread is context switched out.
//----------------------------------------------------------------------

void
AddrSpace::InitRegisters()
{
    int i;

    for (i = 0; i < NumTotalRegs; i++)
	machine->WriteRegister(i, 0);

    // Initial program counter -- must be location of "Start"
    machine->WriteRegister(PCReg, 0);	

    // Need to also tell MIPS where next instruction is, because
    // of branch delay possibility
    machine->WriteRegister(NextPCReg, 4);

   // Set the stack register to the end of the address space, where we
   // allocated the stack; but subtract off a bit, to make sure we don't
   // accidentally reference off the end!
    machine->WriteRegister(StackReg, numPages * PageSize - 16);
    DEBUG('a', "Initializing stack register to %d\n", numPages * PageSize - 16);
}

//////////////////////////////////////////////////////
// Function name	: AddrSpace::SaveState
// Creator			: Li Showchao(0410716)
// CreateTime		: 2007-1-19 21:52:44
//
// Function Desc    : 
// 	The steps of AddrSpace::SaveState
//	1. save registers thar this user program used
//	
//	Fails if:
//	1.
//	2.
//	3.
// Note				:
// Return type		: void 
//////////////////////////////////////////////////////
void AddrSpace::SaveState() 
{
	for (int i = 0; i < NumTotalRegs; i++)
		s_reg[i] = machine->ReadRegister(i);	
}



//////////////////////////////////////////////////////
// Function name	: AddrSpace::RestoreState
// Creator			: Fang Wenbin(0410706)
// CreateTime		: 2007-1-19 21:57:21
//
// Function Desc    : 
// 	The steps of AddrSpace::RestoreState
//	1. restore page table 
//	2. restore registers
//	
//	Fails if:
//	1.
//	2.
//	3.
// Note				:
// Return type		: void 
//////////////////////////////////////////////////////
void AddrSpace::RestoreState() 
{
	machine->pageTable = pageTable;
	machine->pageTableSize = numPages;
	for (int i = 0; i < NumTotalRegs; i++)
	 	machine->WriteRegister(i, s_reg[i]);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?