Merge branch 'ytshih/hw2' into 'main'
Ytshih/hw2 See merge request cs_os_group_20/cs_os_project_20_hw!2
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
*.o
|
*.o
|
||||||
|
*.coff
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ RUN apt-get -y install build-essential ed \
|
|||||||
gcc-multilib g++-multilib lib32ncurses5-dev lib32z1 \
|
gcc-multilib g++-multilib lib32ncurses5-dev lib32z1 \
|
||||||
zlib1g:i386 libstdc++6:i386 libc6:i386 libncurses5:i386 \
|
zlib1g:i386 libstdc++6:i386 libc6:i386 libncurses5:i386 \
|
||||||
libgcc1:i386 libstdc++5:i386
|
libgcc1:i386 libstdc++5:i386
|
||||||
|
|
||||||
|
RUN apt-get -y install fish vim less gdb
|
||||||
|
|
||||||
RUN groupadd -g 60139 ytshih && useradd -g 60139 -u 60139 ytshih
|
RUN groupadd -g 60139 ytshih && useradd -g 60139 -u 60139 ytshih
|
||||||
|
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
ENTRYPOINT ["/usr/bin/env"]
|
ENTRYPOINT ["/usr/bin/env"]
|
||||||
CMD ["bash"]
|
CMD ["fish"]
|
||||||
|
|||||||
@@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
make -C build.linux depend
|
make -C build.linux depend
|
||||||
make -C build.linux
|
make -C build.linux -j 16
|
||||||
make -C test
|
make -C test -j 16
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C build.linux clean
|
make -C build.linux distclean
|
||||||
make -C test distclean
|
make -C test distclean
|
||||||
|
|
||||||
run:
|
run:
|
||||||
make -C test run
|
make -C test run
|
||||||
|
|
||||||
|
debug:
|
||||||
|
make -C test debug
|
||||||
|
|||||||
Binary file not shown.
@@ -200,8 +200,8 @@ DEFINES = -DFILESYS_STUB -DRDATA -DSIM_FIX
|
|||||||
# break the thread system. You might want to use -fno-inline if
|
# break the thread system. You might want to use -fno-inline if
|
||||||
# you need to call some inline functions from the debugger.
|
# you need to call some inline functions from the debugger.
|
||||||
|
|
||||||
CFLAGS = -g -Wall $(INCPATH) $(DEFINES) $(HOSTCFLAGS) -DCHANGED -m32
|
CFLAGS = -g -fsanitize=address,undefined -Wall -Wextra $(INCPATH) $(DEFINES) $(HOSTCFLAGS) -DCHANGED -m32
|
||||||
LDFLAGS = -m32
|
LDFLAGS = -fsanitize=address,undefined -m32
|
||||||
CPP_AS_FLAGS= -m32
|
CPP_AS_FLAGS= -m32
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -23,6 +23,7 @@
|
|||||||
#include "copyright.h"
|
#include "copyright.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "synchconsole.h"
|
||||||
|
|
||||||
// String definitions for debugging messages
|
// String definitions for debugging messages
|
||||||
|
|
||||||
@@ -340,7 +341,7 @@ static void
|
|||||||
PrintPending (PendingInterrupt *pending)
|
PrintPending (PendingInterrupt *pending)
|
||||||
{
|
{
|
||||||
cout << "Interrupt handler "<< intTypeNames[pending->type];
|
cout << "Interrupt handler "<< intTypeNames[pending->type];
|
||||||
cout << ", scheduled at " << pending->when;
|
cout << ", scheduled at " << pending->when << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -362,5 +363,5 @@ Interrupt::DumpState()
|
|||||||
void
|
void
|
||||||
Interrupt::PrintInt(int value)
|
Interrupt::PrintInt(int value)
|
||||||
{
|
{
|
||||||
return kernel->PrintInt(value);
|
kernel->synchConsoleOut->PutInt(value);
|
||||||
}
|
}
|
||||||
@@ -13,10 +13,17 @@
|
|||||||
|
|
||||||
// Textual names of the exceptions that can be generated by user program
|
// Textual names of the exceptions that can be generated by user program
|
||||||
// execution, for debugging.
|
// execution, for debugging.
|
||||||
static char* exceptionNames[] = { "no exception", "syscall",
|
static char* exceptionNames[] = {
|
||||||
"page fault/no TLB entry", "page read only",
|
"no exception",
|
||||||
"bus error", "address error", "overflow",
|
"syscall",
|
||||||
"illegal instruction" };
|
"page fault/no TLB entry",
|
||||||
|
"page read only",
|
||||||
|
"bus error",
|
||||||
|
"address error",
|
||||||
|
"overflow",
|
||||||
|
"illegal instruction",
|
||||||
|
"bad memory allocation"
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// CheckEndian
|
// CheckEndian
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ const int NumPhysPages = 128;
|
|||||||
const int MemorySize = (NumPhysPages * PageSize);
|
const int MemorySize = (NumPhysPages * PageSize);
|
||||||
const int TLBSize = 4; // if there is a TLB, make it small
|
const int TLBSize = 4; // if there is a TLB, make it small
|
||||||
|
|
||||||
enum ExceptionType { NoException, // Everything ok!
|
enum ExceptionType {
|
||||||
|
NoException, // Everything ok!
|
||||||
SyscallException, // A program executed a system call.
|
SyscallException, // A program executed a system call.
|
||||||
PageFaultException, // No valid translation found
|
PageFaultException, // No valid translation found
|
||||||
ReadOnlyException, // Write attempted to page marked
|
ReadOnlyException, // Write attempted to page marked
|
||||||
@@ -52,6 +53,7 @@ enum ExceptionType { NoException, // Everything ok!
|
|||||||
// address space
|
// address space
|
||||||
OverflowException, // Integer overflow in add or sub.
|
OverflowException, // Integer overflow in add or sub.
|
||||||
IllegalInstrException, // Unimplemented or reserved instr.
|
IllegalInstrException, // Unimplemented or reserved instr.
|
||||||
|
MemoryLimitException, // Bad allocation
|
||||||
|
|
||||||
NumExceptionTypes
|
NumExceptionTypes
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ Machine::Translate(int virtAddr, int* physAddr, int size, bool writing)
|
|||||||
if (tlb == NULL) { // => page table => vpn is index into table
|
if (tlb == NULL) { // => page table => vpn is index into table
|
||||||
if (vpn >= pageTableSize) {
|
if (vpn >= pageTableSize) {
|
||||||
DEBUG(dbgAddr, "Illegal virtual page # " << virtAddr);
|
DEBUG(dbgAddr, "Illegal virtual page # " << virtAddr);
|
||||||
|
DEBUG(dbgAddr, "vpn, pageTableSize, NumPhysPages: " << vpn << ' ' << pageTableSize << ' ' << NumPhysPages);
|
||||||
return AddressErrorException;
|
return AddressErrorException;
|
||||||
} else if (!pageTable[vpn].valid) {
|
} else if (!pageTable[vpn].valid) {
|
||||||
DEBUG(dbgAddr, "Invalid virtual page # " << virtAddr);
|
DEBUG(dbgAddr, "Invalid virtual page # " << virtAddr);
|
||||||
@@ -233,6 +234,13 @@ Machine::Translate(int virtAddr, int* physAddr, int size, bool writing)
|
|||||||
return ReadOnlyException;
|
return ReadOnlyException;
|
||||||
}
|
}
|
||||||
pageFrame = entry->physicalPage;
|
pageFrame = entry->physicalPage;
|
||||||
|
if (pageFrame == -1) {
|
||||||
|
pageFrame = entry->physicalPage = kernel->frameTable->Allocate();
|
||||||
|
if (pageFrame == -1) {
|
||||||
|
DEBUG(dbgAddr, "Memory Limit exceeded");
|
||||||
|
return MemoryLimitException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the pageFrame is too big, there is something really wrong!
|
// if the pageFrame is too big, there is something really wrong!
|
||||||
// An invalid translation was loaded into the page table or TLB.
|
// An invalid translation was loaded into the page table or TLB.
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ ifeq ($(hosttype),unknown)
|
|||||||
PROGRAMS = unknownhost
|
PROGRAMS = unknownhost
|
||||||
else
|
else
|
||||||
# change this if you create a new test program!
|
# change this if you create a new test program!
|
||||||
PROGRAMS = add halt consoleIO_test1 consoleIO_test2 fileIO_test1 fileIO_test2
|
PROGRAMS = add halt consoleIO_test1 consoleIO_test2 fileIO_test1 fileIO_test2 test
|
||||||
# PROGRAMS = halt
|
# PROGRAMS = halt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -189,6 +189,11 @@ fileIO_test3: fileIO_test3.o start.o
|
|||||||
$(LD) $(LDFLAGS) start.o fileIO_test3.o -o fileIO_test3.coff
|
$(LD) $(LDFLAGS) start.o fileIO_test3.o -o fileIO_test3.coff
|
||||||
$(COFF2NOFF) fileIO_test3.coff fileIO_test3
|
$(COFF2NOFF) fileIO_test3.coff fileIO_test3
|
||||||
|
|
||||||
|
test.o: test.c
|
||||||
|
$(CC) $(CFLAGS) -c test.c
|
||||||
|
test: test.o start.o
|
||||||
|
$(LD) $(LDFLAGS) start.o test.o -o test.coff
|
||||||
|
$(COFF2NOFF) test.coff test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -f *.o *.ii
|
$(RM) -f *.o *.ii
|
||||||
@@ -198,10 +203,11 @@ distclean: clean
|
|||||||
$(RM) -f $(PROGRAMS)
|
$(RM) -f $(PROGRAMS)
|
||||||
|
|
||||||
run: $(PROGRAMS)
|
run: $(PROGRAMS)
|
||||||
for i in $(PROGRAMS); do \
|
timeout 1 $(NACHOS) -e consoleIO_test1 -e consoleIO_test2
|
||||||
echo ===== $$i =====; \
|
echo 'done'
|
||||||
$(NACHOS) -e $$i; \
|
|
||||||
done
|
debug: $(PROGRAMS)
|
||||||
|
timeout 1 $(NACHOS) -e consoleIO_test1 -e consoleIO_test2 -d +
|
||||||
|
|
||||||
|
|
||||||
unknownhost:
|
unknownhost:
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ int main() {
|
|||||||
int n;
|
int n;
|
||||||
for (n = 9; n > 5; n--)
|
for (n = 9; n > 5; n--)
|
||||||
PrintInt(n);
|
PrintInt(n);
|
||||||
Halt();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
|
||||||
int
|
int main()
|
||||||
main()
|
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
for (n=15;n<=19;n++){
|
for (n=15;n<=19;n++){
|
||||||
|
|
||||||
PrintInt(n);
|
PrintInt(n);
|
||||||
}
|
}
|
||||||
Halt();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
code/test/test.c
Normal file
6
code/test/test.c
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Exit(0);
|
||||||
|
}
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
Kernel::Kernel(int argc, char **argv)
|
Kernel::Kernel(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
execfileNum = 0;
|
||||||
|
threadNum = 0;
|
||||||
randomSlice = FALSE;
|
randomSlice = FALSE;
|
||||||
debugUserProg = FALSE;
|
debugUserProg = FALSE;
|
||||||
consoleIn = NULL; // default is stdin
|
consoleIn = NULL; // default is stdin
|
||||||
@@ -113,6 +115,7 @@ Kernel::Initialize()
|
|||||||
#endif // FILESYS_STUB
|
#endif // FILESYS_STUB
|
||||||
postOfficeIn = new PostOfficeInput(10);
|
postOfficeIn = new PostOfficeInput(10);
|
||||||
postOfficeOut = new PostOfficeOutput(reliability);
|
postOfficeOut = new PostOfficeOutput(reliability);
|
||||||
|
frameTable = new FrameTable;
|
||||||
|
|
||||||
interrupt->Enable();
|
interrupt->Enable();
|
||||||
}
|
}
|
||||||
@@ -135,6 +138,7 @@ Kernel::~Kernel()
|
|||||||
delete fileSystem;
|
delete fileSystem;
|
||||||
delete postOfficeIn;
|
delete postOfficeIn;
|
||||||
delete postOfficeOut;
|
delete postOfficeOut;
|
||||||
|
delete frameTable;
|
||||||
|
|
||||||
Exit(0);
|
Exit(0);
|
||||||
}
|
}
|
||||||
@@ -250,12 +254,10 @@ Kernel::NetworkTest() {
|
|||||||
|
|
||||||
void ForkExecute(Thread *t)
|
void ForkExecute(Thread *t)
|
||||||
{
|
{
|
||||||
if ( !t->space->Load(t->getName()) ) {
|
if (!t->space->Load(t->getName()))
|
||||||
return; // executable not found
|
return; // executable not found
|
||||||
}
|
|
||||||
|
|
||||||
t->space->Execute(t->getName());
|
t->space->Execute(t->getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::ExecAll()
|
void Kernel::ExecAll()
|
||||||
@@ -273,9 +275,8 @@ int Kernel::Exec(char* name)
|
|||||||
t[threadNum] = new Thread(name, threadNum);
|
t[threadNum] = new Thread(name, threadNum);
|
||||||
t[threadNum]->space = new AddrSpace();
|
t[threadNum]->space = new AddrSpace();
|
||||||
t[threadNum]->Fork((VoidFunctionPtr) &ForkExecute, (void *)t[threadNum]);
|
t[threadNum]->Fork((VoidFunctionPtr) &ForkExecute, (void *)t[threadNum]);
|
||||||
threadNum++;
|
|
||||||
|
|
||||||
return threadNum-1;
|
return threadNum++;
|
||||||
/*
|
/*
|
||||||
cout << "Total threads number is " << execfileNum << endl;
|
cout << "Total threads number is " << execfileNum << endl;
|
||||||
for (int n=1;n<=execfileNum;n++) {
|
for (int n=1;n<=execfileNum;n++) {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class Kernel {
|
|||||||
FileSystem *fileSystem;
|
FileSystem *fileSystem;
|
||||||
PostOfficeInput *postOfficeIn;
|
PostOfficeInput *postOfficeIn;
|
||||||
PostOfficeOutput *postOfficeOut;
|
PostOfficeOutput *postOfficeOut;
|
||||||
|
FrameTable *frameTable;
|
||||||
|
|
||||||
int hostName; // machine identifier
|
int hostName; // machine identifier
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,71 @@ SwapHeader (NoffHeader *noffH)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FrameTable::Node::Node(int idx):
|
||||||
|
next(nullptr), idx(idx) {}
|
||||||
|
|
||||||
|
FrameTable::FrameTable()
|
||||||
|
{
|
||||||
|
available = NumPhysPages;
|
||||||
|
useCount = new int[NumPhysPages];
|
||||||
|
begin = end = new FrameTable::Node;
|
||||||
|
for (int i = 0; i < NumPhysPages; i++) {
|
||||||
|
useCount[i] = 0;
|
||||||
|
end->idx = i;
|
||||||
|
end->next = new FrameTable::Node;
|
||||||
|
end = end->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameTable::~FrameTable()
|
||||||
|
{
|
||||||
|
delete[] useCount;
|
||||||
|
while (begin != end) {
|
||||||
|
FrameTable::Node *tmpNode = begin;
|
||||||
|
begin = begin->next;
|
||||||
|
delete tmpNode;
|
||||||
|
}
|
||||||
|
delete begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FrameTable::Allocate()
|
||||||
|
{
|
||||||
|
if (available == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int ret = begin->idx;
|
||||||
|
Node *tmp = begin;
|
||||||
|
begin = begin->next;
|
||||||
|
delete tmp;
|
||||||
|
|
||||||
|
--available;
|
||||||
|
useCount[ret]++;
|
||||||
|
|
||||||
|
bzero(kernel->machine->mainMemory + ret * PageSize, PageSize);
|
||||||
|
|
||||||
|
//cerr << "Allocated at page: " << ret << endl;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameTable::Release(int phyPageNum)
|
||||||
|
{
|
||||||
|
useCount[phyPageNum]--;
|
||||||
|
|
||||||
|
if (useCount[phyPageNum] > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
++available;
|
||||||
|
|
||||||
|
//cerr << "Release page: " << end->idx << endl;
|
||||||
|
end->idx = phyPageNum;
|
||||||
|
end->next = new FrameTable::Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FrameTable::RemainSize()
|
||||||
|
{
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// AddrSpace::AddrSpace
|
// AddrSpace::AddrSpace
|
||||||
// Create an address space to run a user program.
|
// Create an address space to run a user program.
|
||||||
@@ -66,20 +131,7 @@ SwapHeader (NoffHeader *noffH)
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
AddrSpace::AddrSpace()
|
AddrSpace::AddrSpace()
|
||||||
{
|
{}
|
||||||
pageTable = new TranslationEntry[NumPhysPages];
|
|
||||||
for (int i = 0; i < NumPhysPages; i++) {
|
|
||||||
pageTable[i].virtualPage = i; // for now, virt page # = phys page #
|
|
||||||
pageTable[i].physicalPage = i;
|
|
||||||
pageTable[i].valid = TRUE;
|
|
||||||
pageTable[i].use = FALSE;
|
|
||||||
pageTable[i].dirty = FALSE;
|
|
||||||
pageTable[i].readOnly = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// zero out the entire address space
|
|
||||||
bzero(kernel->machine->mainMemory, MemorySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// AddrSpace::~AddrSpace
|
// AddrSpace::~AddrSpace
|
||||||
@@ -88,7 +140,10 @@ AddrSpace::AddrSpace()
|
|||||||
|
|
||||||
AddrSpace::~AddrSpace()
|
AddrSpace::~AddrSpace()
|
||||||
{
|
{
|
||||||
delete pageTable;
|
for (int i = 0; i < NumPhysPages; i++)
|
||||||
|
if (pageTable[i].use == TRUE)
|
||||||
|
kernel->frameTable->Release(pageTable[i].physicalPage);
|
||||||
|
delete[] pageTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +160,7 @@ AddrSpace::~AddrSpace()
|
|||||||
bool
|
bool
|
||||||
AddrSpace::Load(char *fileName)
|
AddrSpace::Load(char *fileName)
|
||||||
{
|
{
|
||||||
|
//cerr << "AddrSpace::Load" << endl;
|
||||||
OpenFile *executable = kernel->fileSystem->Open(fileName);
|
OpenFile *executable = kernel->fileSystem->Open(fileName);
|
||||||
NoffHeader noffH;
|
NoffHeader noffH;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
@@ -124,6 +180,11 @@ AddrSpace::Load(char *fileName)
|
|||||||
// how big is address space?
|
// how big is address space?
|
||||||
size = noffH.code.size + noffH.readonlyData.size + noffH.initData.size +
|
size = noffH.code.size + noffH.readonlyData.size + noffH.initData.size +
|
||||||
noffH.uninitData.size + UserStackSize;
|
noffH.uninitData.size + UserStackSize;
|
||||||
|
//cerr << noffH.code.size << ' '
|
||||||
|
// << noffH.readonlyData.size << ' '
|
||||||
|
// << noffH.initData.size << ' '
|
||||||
|
// << noffH.uninitData.size << ' '
|
||||||
|
// << UserStackSize << endl;
|
||||||
// we need to increase the size
|
// we need to increase the size
|
||||||
// to leave room for the stack
|
// to leave room for the stack
|
||||||
#else
|
#else
|
||||||
@@ -131,6 +192,10 @@ AddrSpace::Load(char *fileName)
|
|||||||
size = noffH.code.size + noffH.initData.size + noffH.uninitData.size
|
size = noffH.code.size + noffH.initData.size + noffH.uninitData.size
|
||||||
+ UserStackSize; // we need to increase the size
|
+ UserStackSize; // we need to increase the size
|
||||||
// to leave room for the stack
|
// to leave room for the stack
|
||||||
|
//cerr << noffH.code.size << ' '
|
||||||
|
// << noffH.initData.size << ' '
|
||||||
|
// << noffH.uninitData.size << ' '
|
||||||
|
// << UserStackSize << endl;
|
||||||
#endif
|
#endif
|
||||||
numPages = divRoundUp(size, PageSize);
|
numPages = divRoundUp(size, PageSize);
|
||||||
size = numPages * PageSize;
|
size = numPages * PageSize;
|
||||||
@@ -140,32 +205,60 @@ AddrSpace::Load(char *fileName)
|
|||||||
// at least until we have
|
// at least until we have
|
||||||
// virtual memory
|
// virtual memory
|
||||||
|
|
||||||
|
pageTable = new TranslationEntry[numPages];
|
||||||
|
for (int i = 0; i < numPages; i++) {
|
||||||
|
pageTable[i].virtualPage = i;
|
||||||
|
pageTable[i].physicalPage = -1;
|
||||||
|
pageTable[i].valid = TRUE;
|
||||||
|
pageTable[i].use = FALSE;
|
||||||
|
pageTable[i].dirty = FALSE;
|
||||||
|
pageTable[i].readOnly = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(dbgAddr, "Initializing address space: " << numPages << ", " << size);
|
DEBUG(dbgAddr, "Initializing address space: " << numPages << ", " << size);
|
||||||
|
|
||||||
// then, copy in the code and data segments into memory
|
// then, copy in the code and data segments into memory
|
||||||
// Note: this code assumes that virtual address = physical address
|
|
||||||
if (noffH.code.size > 0) {
|
if (noffH.code.size > 0) {
|
||||||
DEBUG(dbgAddr, "Initializing code segment.");
|
DEBUG(dbgAddr, "Initializing code segment.");
|
||||||
DEBUG(dbgAddr, noffH.code.virtualAddr << ", " << noffH.code.size);
|
DEBUG(dbgAddr, noffH.code.virtualAddr << ", " << noffH.code.size);
|
||||||
|
|
||||||
|
for (size_t cur = 0; cur < (size_t)noffH.code.size; cur += PageSize) {
|
||||||
|
size_t physAddr, size = min((size_t)PageSize, noffH.code.size - cur);
|
||||||
|
Translate(noffH.code.virtualAddr + cur, &physAddr, 1);
|
||||||
|
//cerr << "physAddr, size: " << physAddr << ' ' << size << endl;
|
||||||
|
|
||||||
executable->ReadAt(
|
executable->ReadAt(
|
||||||
&(kernel->machine->mainMemory[noffH.code.virtualAddr]),
|
&(kernel->machine->mainMemory[physAddr]), size,
|
||||||
noffH.code.size, noffH.code.inFileAddr);
|
noffH.code.inFileAddr + cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (noffH.initData.size > 0) {
|
if (noffH.initData.size > 0) {
|
||||||
DEBUG(dbgAddr, "Initializing data segment.");
|
DEBUG(dbgAddr, "Initializing data segment.");
|
||||||
DEBUG(dbgAddr, noffH.initData.virtualAddr << ", " << noffH.initData.size);
|
DEBUG(dbgAddr, noffH.initData.virtualAddr << ", " << noffH.initData.size);
|
||||||
|
|
||||||
|
for (size_t cur = 0; cur < (size_t)noffH.initData.size; cur += PageSize) {
|
||||||
|
size_t physAddr, size = min((size_t)PageSize, noffH.initData.size - cur);
|
||||||
|
Translate(noffH.initData.virtualAddr + cur, &physAddr, 1);
|
||||||
|
|
||||||
executable->ReadAt(
|
executable->ReadAt(
|
||||||
&(kernel->machine->mainMemory[noffH.initData.virtualAddr]),
|
&(kernel->machine->mainMemory[physAddr]), size,
|
||||||
noffH.initData.size, noffH.initData.inFileAddr);
|
noffH.initData.inFileAddr + cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RDATA
|
#ifdef RDATA
|
||||||
if (noffH.readonlyData.size > 0) {
|
if (noffH.readonlyData.size > 0) {
|
||||||
DEBUG(dbgAddr, "Initializing read only data segment.");
|
DEBUG(dbgAddr, "Initializing read only data segment.");
|
||||||
DEBUG(dbgAddr, noffH.readonlyData.virtualAddr << ", " << noffH.readonlyData.size);
|
DEBUG(dbgAddr, noffH.readonlyData.virtualAddr << ", " << noffH.readonlyData.size);
|
||||||
|
|
||||||
|
for (size_t cur = 0; cur < (size_t)noffH.readonlyData.size; cur += PageSize) {
|
||||||
|
size_t physAddr, size = min((size_t)PageSize, noffH.readonlyData.size - cur);
|
||||||
|
Translate(noffH.readonlyData.virtualAddr + cur, &physAddr, 1);
|
||||||
|
|
||||||
executable->ReadAt(
|
executable->ReadAt(
|
||||||
&(kernel->machine->mainMemory[noffH.readonlyData.virtualAddr]),
|
&(kernel->machine->mainMemory[physAddr]),
|
||||||
noffH.readonlyData.size, noffH.readonlyData.inFileAddr);
|
size, noffH.readonlyData.inFileAddr + cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -185,7 +278,7 @@ AddrSpace::Load(char *fileName)
|
|||||||
void
|
void
|
||||||
AddrSpace::Execute(char* fileName)
|
AddrSpace::Execute(char* fileName)
|
||||||
{
|
{
|
||||||
|
//cerr << "AddrSpace::Execute" << endl;
|
||||||
kernel->currentThread->space = this;
|
kernel->currentThread->space = this;
|
||||||
|
|
||||||
this->InitRegisters(); // set the initial register values
|
this->InitRegisters(); // set the initial register values
|
||||||
@@ -288,6 +381,13 @@ AddrSpace::Translate(unsigned int vaddr, unsigned int *paddr, int isReadWrite)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pfn = pte->physicalPage;
|
pfn = pte->physicalPage;
|
||||||
|
if (pfn == -1) {
|
||||||
|
pfn = pte->physicalPage = kernel->frameTable->Allocate();
|
||||||
|
if (pfn == -1) {
|
||||||
|
DEBUG(dbgAddr, "Memory Limit exceeded");
|
||||||
|
return MemoryLimitException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the pageFrame is too big, there is something really wrong!
|
// if the pageFrame is too big, there is something really wrong!
|
||||||
// An invalid translation was loaded into the page table or TLB.
|
// An invalid translation was loaded into the page table or TLB.
|
||||||
@@ -310,7 +410,3 @@ AddrSpace::Translate(unsigned int vaddr, unsigned int *paddr, int isReadWrite)
|
|||||||
|
|
||||||
return NoException;
|
return NoException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,28 @@
|
|||||||
|
|
||||||
#define UserStackSize 1024 // increase this as necessary!
|
#define UserStackSize 1024 // increase this as necessary!
|
||||||
|
|
||||||
|
class FrameTable {
|
||||||
|
public:
|
||||||
|
FrameTable();
|
||||||
|
~FrameTable();
|
||||||
|
|
||||||
|
int Allocate();
|
||||||
|
void Release(int phyPageNum);
|
||||||
|
size_t RemainSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Node {
|
||||||
|
Node *next;
|
||||||
|
int idx;
|
||||||
|
Node(int idx = -1);
|
||||||
|
};
|
||||||
|
|
||||||
|
Node *begin, *end;
|
||||||
|
|
||||||
|
size_t available;
|
||||||
|
int *useCount;
|
||||||
|
};
|
||||||
|
|
||||||
class AddrSpace {
|
class AddrSpace {
|
||||||
public:
|
public:
|
||||||
AddrSpace(); // Create an address space.
|
AddrSpace(); // Create an address space.
|
||||||
@@ -40,8 +62,7 @@ class AddrSpace {
|
|||||||
ExceptionType Translate(unsigned int vaddr, unsigned int *paddr, int mode);
|
ExceptionType Translate(unsigned int vaddr, unsigned int *paddr, int mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TranslationEntry *pageTable; // Assume linear page table translation
|
TranslationEntry *pageTable;
|
||||||
// for now!
|
|
||||||
unsigned int numPages; // Number of pages in the virtual
|
unsigned int numPages; // Number of pages in the virtual
|
||||||
// address space
|
// address space
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user