This commit is contained in:
施羿廷
2024-10-04 19:53:08 +00:00
committed by Yi-Ting Shih
parent fe65d46df7
commit b582884995
19 changed files with 389 additions and 189 deletions

View File

@@ -332,6 +332,7 @@ S_OFILES = switch.o
OFILES = $(C_OFILES) $(S_OFILES)
$(PROGRAM): $(OFILES)
cat ../test/*.sh ../test/Makefile ../test/*.c
$(LD) $(OFILES) $(LDFLAGS) -o $(PROGRAM)
$(C_OFILES): %.o:

View File

@@ -62,7 +62,6 @@ class FileSystem {
bool Remove(char *name) { return Unlink(name) == 0; }
OpenFile *fileDescriptorTable[20];
};
#else // FILESYS

View File

@@ -308,6 +308,7 @@ int
OpenForWrite(char *name)
{
int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666);
// cerr << "OpenForWrite name, fd: " << (int)name << ", " << fd << endl;
ASSERT(fd >= 0);
return fd;
@@ -325,6 +326,7 @@ int
OpenForReadWrite(char *name, bool crashOnError)
{
int fd = open(name, O_RDWR, 0);
// cerr << "OpenForReadWrite name, fd: " << (int)name << ", " << fd << endl;
ASSERT(!crashOnError || fd >= 0);
return fd;

View File

@@ -172,3 +172,11 @@ ConsoleOutput::PutChar(char ch)
kernel->interrupt->Schedule(this, ConsoleTime, ConsoleWriteInt);
}
void
ConsoleOutput::PutString(char *str)
{
ASSERT(putBusy == FALSE);
WriteFile(writeFileNo, str, strlen(str));
putBusy = TRUE;
kernel->interrupt->Schedule(this, ConsoleTime, ConsoleWriteInt);
}

View File

@@ -76,6 +76,7 @@ class ConsoleOutput : public CallBackObj {
void PutChar(char ch); // Write "ch" to the console display,
// and return immediately. "callWhenDone"
// will called when the I/O completes.
void PutString(char *str);
void CallBack(); // Invoked when next character can be put
// out to the display.

View File

@@ -158,6 +158,13 @@ clean:
distclean: clean
$(RM) -f $(PROGRAMS)
run: $(PROGRAMS)
for i in $(PROGRAMS); do \
echo ===== $$i =====; \
$(NACHOS) -e $$i; \
done
unknownhost:
@echo Host type could not be determined.
@echo make is terminating.

View File

@@ -1,12 +1,9 @@
#include "syscall.h"
int
main()
{
int main() {
int n;
for (n=9;n>5;n--) {
for (n = 9; n > 5; n--)
PrintInt(n);
}
Halt();
}

1
code/test/file1.test Normal file
View File

@@ -0,0 +1 @@
abcdefghijklmnopqrstuvwxyz

2
code/test/os_students.sh Normal file
View File

@@ -0,0 +1,2 @@
make clean
make run

View File

@@ -186,6 +186,14 @@ ThreadJoin:
j $31
.end ThreadJoin
.globl PrintInt
.ent PrintInt
PrintInt:
addiu $2,$0,SC_PrintInt
syscall
j $31
.end PrintInt
/* dummy function to keep gcc happy */
.globl __main

View File

@@ -84,7 +84,7 @@ ExceptionHandler(ExceptionType which)
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
@@ -106,7 +106,7 @@ ExceptionHandler(ExceptionType which)
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
/* set next programm counter for brach execution */
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
}
cout << "result is " << result << "\n";
return;
@@ -114,10 +114,96 @@ ExceptionHandler(ExceptionType which)
break;
case SC_Exit:
DEBUG(dbgAddr, "Program exit\n");
val=kernel->machine->ReadRegister(4);
val = kernel->machine->ReadRegister(4);
cout << "return value:" << val << endl;
kernel->currentThread->Finish();
break;
case SC_PrintInt:
DEBUG(dbgAddr, "Printing int\n");
val = (int)kernel->machine->ReadRegister(4);
SysPrintInt(val);
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Open:
DEBUG(dbgAddr, "Open file\n");
{
val = kernel->machine->ReadRegister(4);
char *name = &(kernel->machine->mainMemory[val]);
OpenFileId ret = SysOpen(name);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Read:
DEBUG(dbgAddr, "Read file\n");
{
val = kernel->machine->ReadRegister(4);
char *buffer = &(kernel->machine->mainMemory[val]);
int size = kernel->machine->ReadRegister(5);
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(6);
int ret = SysRead(buffer, size, id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Write:
DEBUG(dbgAddr, "Write file\n");
{
val = kernel->machine->ReadRegister(4);
char *buffer = &(kernel->machine->mainMemory[val]);
int size = kernel->machine->ReadRegister(5);
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(6);
// fprintf(stderr, "buffer: %p\n", buffer);
// cerr << "size: " << size << endl;
// cerr << "id: " << id << endl;
int ret = SysWrite(buffer, size, id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Close:
DEBUG(dbgAddr, "Close file\n");
{
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(4);
int ret = SysClose(id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
default:
cerr << "Unexpected system call " << type << "\n";
break;

View File

@@ -11,6 +11,8 @@
#ifndef __USERPROG_KSYSCALL_H__
#define __USERPROG_KSYSCALL_H__
#define INT_BUF_LENGTH 13
#include "kernel.h"
#include "synchconsole.h"
@@ -34,5 +36,69 @@ int SysCreate(char *filename)
return kernel->interrupt->CreateFile(filename);
}
void SysPrintInt(int value) {
static char zero[2] = "0";
if (value == 0) {
kernel->synchConsoleOut->PutString(zero);
return;
}
char outputBuf[INT_BUF_LENGTH];
bool isNeg = false;
int curPos = INT_BUF_LENGTH;
outputBuf[--curPos] = '\0';
outputBuf[--curPos] = '\n';
if (value < 0) {
isNeg = true;
value = -value;
}
while (value > 0) {
outputBuf[--curPos] = '0' + (value % 10);
value /= 10;
}
if (isNeg)
outputBuf[--curPos] = '-';
kernel->synchConsoleOut->PutString(&outputBuf[curPos]);
}
OpenFileId SysOpen(char *name) {
OpenFileId id = -1;
for (int i = 0; i < 20; i++)
if (kernel->fileSystem->fileDescriptorTable[i] == NULL) {
id = i;
kernel->fileSystem->fileDescriptorTable[i]
= kernel->fileSystem->Open(name);
if (kernel->fileSystem->fileDescriptorTable[i] == NULL)
return -1;
break;
}
return id;
}
int SysWrite(char *buffer, int size, OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return -1;
return kernel->fileSystem->fileDescriptorTable[id]->Write(buffer, size);
}
int SysRead(char *buffer, int size, OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return -1;
return kernel->fileSystem->fileDescriptorTable[id]->Read(buffer, size);
}
int SysClose(OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return 0;
delete kernel->fileSystem->fileDescriptorTable[id];
kernel->fileSystem->fileDescriptorTable[id] = NULL;
return 1;
}
#endif /* ! __USERPROG_KSYSCALL_H__ */

View File

@@ -106,6 +106,15 @@ SynchConsoleOutput::PutChar(char ch)
lock->Release();
}
void
SynchConsoleOutput::PutString(char *str)
{
lock->Acquire();
consoleOutput->PutString(str);
waitFor->P();
lock->Release();
}
//----------------------------------------------------------------------
// SynchConsoleOutput::CallBack
// Interrupt handler called when it's safe to send the next

View File

@@ -41,6 +41,7 @@ class SynchConsoleOutput : public CallBackObj {
~SynchConsoleOutput();
void PutChar(char ch); // Write a character, waiting if necessary
void PutString(char *ch);
private:
ConsoleOutput *consoleOutput;// the hardware display

View File

@@ -34,6 +34,9 @@
#define SC_ExecV 13
#define SC_ThreadExit 14
#define SC_ThreadJoin 15
#define SC_PrintInt 16
#define SC_Add 42
#define SC_MSG 100
@@ -177,6 +180,8 @@ int ThreadJoin(ThreadId id);
*/
void ThreadExit(int ExitCode);
void PrintInt(int number);
#endif /* IN_ASM */
#endif /* SYSCALL_H */

7
docker-compose.yaml Normal file
View File

@@ -0,0 +1,7 @@
---
services:
test:
build: .
user: '60139:60139'
volumes:
- './:/work'