Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool
- AddrSpace::Load(char *filename) {
- NoffHeader noffH;
- unsigned int i, size;
- OpenFile *executable = kernel->fileSystem->Open(filename);
- if (executable == NULL) {
- DEBUG(dbgFile, "\n Error opening file: " << filename);
- return FALSE;
- }
- // read file header
- executable->ReadAt((char *)&noffH, sizeof(noffH), 0);
- if ((noffH.noffMagic != NOFFMAGIC) &&
- (WordToHost(noffH.noffMagic) == NOFFMAGIC))
- SwapHeader(&noffH);
- ASSERT(noffH.noffMagic == NOFFMAGIC);
- kernel->addrLock->P();
- // how many page the user program need?
- #ifdef RDATA
- size = noffH.code.size + noffH.readonlyData.size + noffH.initData.size +
- noffH.uninitData.size + UserStackSize;
- #else
- size = noffH.code.size + noffH.initData.size + noffH.uninitData.size
- + UserStackSize;
- #endif
- numPages = divRoundUp(size, PageSize);
- size = numPages * PageSize;
- DEBUG(dbgAddr, "\nSize: " << size <<
- " | numPages: " << numPages <<
- " | PageSize: " << PageSize <<
- " | Numclear: " << kernel->gPhysPageBitMap->NumClear() << "\n");
- // Check the available memory enough to load new process
- if ((int)numPages > kernel->gPhysPageBitMap->NumClear()) {
- DEBUG(dbgAddr, "Not enough memory for new process");
- numPages = 0;
- delete executable;
- kernel->addrLock->V();
- return FALSE;
- }
- // set up the translation page
- pageTable = new TranslationEntry[numPages];
- for (i = 0; i < numPages; ++i) {
- pageTable[i].virtualPage = i;
- pageTable[i].physicalPage = kernel->gPhysPageBitMap->FindAndSet();
- pageTable[i].valid = TRUE;
- pageTable[i].use = FALSE;
- pageTable[i].dirty = FALSE;
- pageTable[i].readOnly = FALSE;
- bzero(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i].physicalPage * PageSize,
- PageSize);
- }
- kernel->addrLock->V();
- // copy code segment into memory
- int numCodePages = divRoundUp(noffH.code.size, PageSize);
- int lastCodePageSize = (noffH.code.size - 1) % PageSize + 1;
- i = 0;
- if (noffH.code.size > 0) {
- for (int j = 0; j < numCodePages; ++j, ++i) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[j].physicalPage*PageSize,
- (j < numCodePages - 1) ? PageSize : lastCodePageSize,
- noffH.code.inFileAddr + j*PageSize
- );
- }
- }
- #ifdef RDATA
- // copy read-only data segment to main
- int firstReadonlyPageSize = min(PageSize - lastCodePageSize, noffH.readonlyData.size);
- int numReadonlyPages = divRoundUp(noffH.readonlyData.size - firstReadonlyPageSize, PageSize);
- int lastReadonlyPageSize = (noffH.readonlyData.size - firstReadonlyPageSize - 1) % PageSize + 1;
- if (noffH.readonlyData.size > 0) {
- if (lastCodePageSize != PageSize && numCodePages > 0) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i - 1].physicalPage * PageSize + lastCodePageSize,
- firstReadonlyPageSize,
- noffH.readonlyData.inFileAddr
- );
- }
- for (int j = 0; j < numReadonlyPages; ++j, ++i) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i].physicalPage * PageSize,
- (j < numReadonlyPages - 1) ? PageSize : lastReadonlyPageSize,
- noffH.readonlyData.inFileAddr + firstReadonlyPageSize + j*PageSize
- );
- }
- }
- // copy init data segment into memory
- int firstDataPageSize = min(PageSize - lastReadonlyPageSize, noffH.initData.size);
- int numDataPages = divRoundUp(noffH.initData.size - firstDataPageSize, PageSize);
- int lastDataPageSize = (noffH.initData.size - firstDataPageSize - 1) % PageSize + 1;
- if (noffH.initData.size > 0) {
- if (lastReadonlyPageSize != PageSize && numReadonlyPages > 0) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i - 1].physicalPage*PageSize + lastReadonlyPageSize,
- firstDataPageSize,
- noffH.initData.inFileAddr
- );
- }
- for (int j = 0; j < numDataPages; ++j, ++i) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i].physicalPage*PageSize,
- (j < numDataPages - 1) ? PageSize : lastDataPageSize,
- noffH.initData.inFileAddr + firstDataPageSize + j*PageSize
- );
- }
- }
- #else
- // copy init data segment into memory
- int firstDataPageSize = min(PageSize - lastCodePageSize, noffH.initData.size);
- int numDataPages = divRoundUp(noffH.initData.size - firstDataPageSize, PageSize);
- int lastDataPageSize = (noffH.initData.size - firstDataPageSize - 1) % PageSize + 1;
- if (noffH.initData.size > 0) {
- if (lastCodePageSize != PageSize && numCodePages > 0) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i - 1].physicalPage*PageSize + lastCodePageSize,
- firstDataPageSize,
- noffH.initData.inFileAddr
- );
- }
- for (int j = 0; j < numDataPages; ++j, ++i) {
- executable->ReadAt(
- &(kernel->machine->mainMemory[noffH.code.virtualAddr])
- + pageTable[i].physicalPage*PageSize,
- (j < numDataPages - 1) ? PageSize : lastDataPageSize,
- noffH.initData.inFileAddr + firstDataPageSize + j*PageSize
- );
- }
- }
- #endif
- delete executable;
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement