---
# System prepended metadata

title: 台科作業系統作業1
tags: [台科, ntust, os, 作業系統, homework]

---

# 台科作業系統作業1
# NTUST OS HOMEWORK 1
gitlab網址:
https://gitlab.com/frakw/nachos2021/-/tree/cf8c749180295f4d784e56374a76668f5281a570
## 安裝
```
$ sudo apt install git csh g++
$ git clone https://gitlab.com/connlabtw21/nachos2021.git
$ cd NachOS2021
$ sudo cp -r usr /
$ cd code
$ make
```
## 測試
```
$ cd userprog
$ ./nachos -e ../test/test1
```
## HW 1:Implement SYSCALL ThreadYield
:::info
syscall.h (usrprog資料夾) :
加入
```c=31
#define SC_ThreadYield	10
```
加入
```c=130
void ThreadYield();
```
定義函式，呼叫此function後，會透過start.s將macro的值傳入`exception.cc`
:::

:::info
start.s (test資料夾) :
加入
```=125
        .globl ThreadYield
        .ent    ThreadYield
ThreadYield:
        addiu $2,$0,SC_ThreadYield
        syscall
        j       $31
        .end ThreadYield
```
注意不要干擾到其他的標籤，貼在`.globl  __main`上方即可
:::

:::info
exception.cc檔案 (usrprog資料夾) :
程式主要就是在這運作的
switch case 中加入
```cpp=93
		case SC_ThreadYield:
		{
			val=kernel->machine->ReadRegister(4);
			cout << "Call ThreadYield" << endl;
			kernel->currentThread->Yield();
			return;
		}
```
:::

:::info
測試檔案example.c (test資料夾) :
```c=
#include "syscall.h"

int main(){
	PrintInt(88);
	ThreadYield();
	PrintInt(99);
    return 0;
}
```
:::

:::info
編譯測試檔案的makefile (test資料夾) : 
all標籤加入example
```make=36
all: halt shell matmult sort test1 test2 example
```
加入example.c的編譯指令
```make=75
example: example.o start.o
	$(LD) $(LDFLAGS) start.o example.o -o example.coff
	../bin/coff2noff example.coff example
```
:::

測試檔案是跟著系統一起編譯的，所以有修改就要重編系統，也就是前面安裝的make指令。


以上的檔案修改後，terminal移至`nachos2021/code`資料夾，然後make，測試example時要移至`nachos2021/code/userprog`

因此建議開2個terminal，一個負責重編系統(make)，另一個測試syscall，才不用一直切換

測試example.c
```
./nachos -e ../test/example -e ../test/test1
```

結果:
![](https://i.imgur.com/QQvZ1Fx.png)
## HW 1:Implement SYSCALL Log
步驟都跟前面一樣

:::info
syscall.h (usrprog資料夾) :
加入
```=34
#define SC_Log		13
```
加入
```=134
void Log(char input);
```
:::

:::info
start.s (test資料夾) :
加入
```=150
	.global Log
	.ent 	Log
Log:
	addiu $2,$0,SC_Log
	syscall
	j	$31
	.end	Log
```
:::

:::info
exception.cc檔案 (usrprog資料夾) :
switch case 中加入 記得include fstream string sstream
```cpp=106
		case SC_Log:
		{
			val=kernel->machine->ReadRegister(4);
			char input = val;
			//cout << "Log : " << input <<endl;
			string student_id = "改成你的學號";
			stringstream ss(student_id.substr(student_id.length()-2,2));
			int last2num;
			ss >> last2num;
			char lower_err_char = 'a' + last2num % 26;
			char upper_err_char = lower_err_char - 32;			
			ofstream output;
			output.open("NachOS.log",std::ios_base::app);
			output << "[" << student_id << "_Log]";
			if((input != lower_err_char) && (input != upper_err_char)){
				output << input;
			}
			else{
				output << "error";			
			}
			output << endl;
			output.close();
			return;
		}
```
:::

:::info
測試檔案example.c (test資料夾) :
```c=
#include "syscall.h"

int main(){
	Log('g');
	Log('o');
	Log('o');
	Log('d');
	Log('m');
	Log('o');
	Log('r');
	Log('n');
	Log('i');
	Log('n');
	Log('g');
	Log(' ');
	Log('f');
	Log('r');
	Log('a');
	Log('k');
	Log('w');
	return 0;
}
```
:::

重編系統，測試:
```
./nachos -e ../test/example
```

結果:
NachOS.log檔案 (usrprog資料夾內) :
```
[你的學號_Log]g
[你的學號_Log]o
[你的學號_Log]o
[你的學號_Log]d
[你的學號_Log]m
[你的學號_Log]o
[你的學號_Log]r
[你的學號_Log]n
[你的學號_Log]i
[你的學號_Log]n
[你的學號_Log]g
[你的學號_Log] 
[你的學號_Log]error
[你的學號_Log]r
[你的學號_Log]a
[你的學號_Log]k
[你的學號_Log]w
```
error的字元是根據你的學號，所以不會一樣(我的是'F'、'f')

###### tags: `台科` `ntust` `os` `作業系統` `homework`