Advertisement
minhkhoi1026

addrspace nachos 4.0 (true version)

Jan 9th, 2022
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.00 KB | None | 0 0
  1.  
  2. bool
  3. AddrSpace::Load(char *filename) {
  4. NoffHeader noffH;
  5. unsigned int i, size;
  6. OpenFile *executable = kernel->fileSystem->Open(filename);
  7.  
  8. if (executable == NULL) {
  9. DEBUG(dbgFile, "\n Error opening file: " << filename);
  10. return FALSE;
  11. }
  12.  
  13. // read file header
  14. executable->ReadAt((char *)&noffH, sizeof(noffH), 0);
  15. if ((noffH.noffMagic != NOFFMAGIC) &&
  16. (WordToHost(noffH.noffMagic) == NOFFMAGIC))
  17. SwapHeader(&noffH);
  18. ASSERT(noffH.noffMagic == NOFFMAGIC);
  19.  
  20. kernel->addrLock->P();
  21.  
  22. // how many page the user program need?
  23. #ifdef RDATA
  24. size = noffH.code.size + noffH.readonlyData.size + noffH.initData.size +
  25. noffH.uninitData.size + UserStackSize;
  26. #else
  27. size = noffH.code.size + noffH.initData.size + noffH.uninitData.size
  28. + UserStackSize;
  29. #endif
  30. numPages = divRoundUp(size, PageSize);
  31. size = numPages * PageSize;
  32.  
  33. DEBUG(dbgAddr, "\nSize: " << size <<
  34. " | numPages: " << numPages <<
  35. " | PageSize: " << PageSize <<
  36. " | Numclear: " << kernel->gPhysPageBitMap->NumClear() << "\n");
  37. // Check the available memory enough to load new process
  38. if ((int)numPages > kernel->gPhysPageBitMap->NumClear()) {
  39. DEBUG(dbgAddr, "Not enough memory for new process");
  40. numPages = 0;
  41. delete executable;
  42. kernel->addrLock->V();
  43. return FALSE;
  44. }
  45.  
  46. // set up the translation page
  47. pageTable = new TranslationEntry[numPages];
  48. for (i = 0; i < numPages; ++i) {
  49. pageTable[i].virtualPage = i;
  50. pageTable[i].physicalPage = kernel->gPhysPageBitMap->FindAndSet();
  51. pageTable[i].valid = TRUE;
  52. pageTable[i].use = FALSE;
  53. pageTable[i].dirty = FALSE;
  54. pageTable[i].readOnly = FALSE;
  55. bzero(
  56. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  57. + pageTable[i].physicalPage * PageSize,
  58. PageSize);
  59. }
  60.  
  61. kernel->addrLock->V();
  62.  
  63. // copy code segment into memory
  64. int numCodePages = divRoundUp(noffH.code.size, PageSize);
  65. int lastCodePageSize = (noffH.code.size - 1) % PageSize + 1;
  66.  
  67. i = 0;
  68. if (noffH.code.size > 0) {
  69. for (int j = 0; j < numCodePages; ++j, ++i) {
  70. executable->ReadAt(
  71. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  72. + pageTable[j].physicalPage*PageSize,
  73. (j < numCodePages - 1) ? PageSize : lastCodePageSize,
  74. noffH.code.inFileAddr + j*PageSize
  75. );
  76. }
  77. }
  78.  
  79. #ifdef RDATA
  80. // copy read-only data segment to main
  81. int firstReadonlyPageSize = min(PageSize - lastCodePageSize, noffH.readonlyData.size);
  82. int numReadonlyPages = divRoundUp(noffH.readonlyData.size - firstReadonlyPageSize, PageSize);
  83. int lastReadonlyPageSize = (noffH.readonlyData.size - firstReadonlyPageSize - 1) % PageSize + 1;
  84.  
  85. if (noffH.readonlyData.size > 0) {
  86. if (lastCodePageSize != PageSize && numCodePages > 0) {
  87. executable->ReadAt(
  88. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  89. + pageTable[i - 1].physicalPage * PageSize + lastCodePageSize,
  90. firstReadonlyPageSize,
  91. noffH.readonlyData.inFileAddr
  92. );
  93. }
  94.  
  95. for (int j = 0; j < numReadonlyPages; ++j, ++i) {
  96. executable->ReadAt(
  97. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  98. + pageTable[i].physicalPage * PageSize,
  99. (j < numReadonlyPages - 1) ? PageSize : lastReadonlyPageSize,
  100. noffH.readonlyData.inFileAddr + firstReadonlyPageSize + j*PageSize
  101. );
  102. }
  103. }
  104.  
  105. // copy init data segment into memory
  106. int firstDataPageSize = min(PageSize - lastReadonlyPageSize, noffH.initData.size);
  107. int numDataPages = divRoundUp(noffH.initData.size - firstDataPageSize, PageSize);
  108. int lastDataPageSize = (noffH.initData.size - firstDataPageSize - 1) % PageSize + 1;
  109.  
  110. if (noffH.initData.size > 0) {
  111. if (lastReadonlyPageSize != PageSize && numReadonlyPages > 0) {
  112. executable->ReadAt(
  113. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  114. + pageTable[i - 1].physicalPage*PageSize + lastReadonlyPageSize,
  115. firstDataPageSize,
  116. noffH.initData.inFileAddr
  117. );
  118. }
  119.  
  120. for (int j = 0; j < numDataPages; ++j, ++i) {
  121. executable->ReadAt(
  122. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  123. + pageTable[i].physicalPage*PageSize,
  124. (j < numDataPages - 1) ? PageSize : lastDataPageSize,
  125. noffH.initData.inFileAddr + firstDataPageSize + j*PageSize
  126. );
  127. }
  128. }
  129. #else
  130. // copy init data segment into memory
  131. int firstDataPageSize = min(PageSize - lastCodePageSize, noffH.initData.size);
  132. int numDataPages = divRoundUp(noffH.initData.size - firstDataPageSize, PageSize);
  133. int lastDataPageSize = (noffH.initData.size - firstDataPageSize - 1) % PageSize + 1;
  134.  
  135. if (noffH.initData.size > 0) {
  136. if (lastCodePageSize != PageSize && numCodePages > 0) {
  137. executable->ReadAt(
  138. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  139. + pageTable[i - 1].physicalPage*PageSize + lastCodePageSize,
  140. firstDataPageSize,
  141. noffH.initData.inFileAddr
  142. );
  143. }
  144.  
  145. for (int j = 0; j < numDataPages; ++j, ++i) {
  146. executable->ReadAt(
  147. &(kernel->machine->mainMemory[noffH.code.virtualAddr])
  148. + pageTable[i].physicalPage*PageSize,
  149. (j < numDataPages - 1) ? PageSize : lastDataPageSize,
  150. noffH.initData.inFileAddr + firstDataPageSize + j*PageSize
  151. );
  152. }
  153. }
  154. #endif
  155.  
  156. delete executable;
  157. return TRUE;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement