[pintos] project 2

7308 ワード

6. Argument Passing


受信したコマンドを単語に分割してスタックに保存
受信したコマンドが/bin/ls-l foo barであれば、下の写真のように分けて入れます

strtok rを使用して単語を1つずつ分けます.
私たちは64ビットなので、移動ごとに8バイトのストレージがあります.
真ん中はまた揃えます.
void argument_stack(char **argv, int argc , void **rsp){

	int total_len =0;
	char *token;
	char *save_ptr;

	//스택주소를 감소시키면서 인자를 스택에 삽입
	for(int i=argc-1; i>-1; i--){
		//\0도 포함해야하니까
		int len = strlen(argv[i])+1;
		*rsp -= len;
		total_len += len;
		strlcpy(*rsp, argv[i], len);
		argv[i] = *rsp;
	}

	*rsp -= ((total_len % 8) != 0 ? 8 - (total_len%8) : 0); //word-align
	*rsp -= 8;
	**(uint64_t **)rsp = NULL;
	
	//주소를 스택에 삽입
	for(int i=argc-1; 0<=i; i--){
		*rsp -= 8;
		**(uint64_t **) rsp = argv[i];
	}

	*rsp -= 8;
	**(uint64_t **) rsp = 0;


}

7. System Calls


Syscall-nr.hには、複数のシステム呼び出しがリストされています.私たちはそのシステムの呼び出し時の状況を符号化することができます.その中で私たちがしなければならないのはこのような16のことです.Systemcallの番号はf->R.raxに格納されます.
	SYS_HALT,                   /* Halt the operating system. */
	SYS_EXIT,                   /* Terminate this process. */
	SYS_FORK,                   /* Clone current process. */
	SYS_EXEC,                   /* Switch current process. */
	SYS_WAIT,                   /* Wait for a child process to die. */
	SYS_CREATE,                 /* Create a file. */
	SYS_REMOVE,                 /* Delete a file. */
	SYS_OPEN,                   /* Open a file. */
	SYS_FILESIZE,               /* Obtain a file's size. */
	SYS_READ,                   /* Read from a file. */
	SYS_WRITE,                  /* Write to a file. */
	SYS_SEEK,                   /* Change position in a file. */
	SYS_TELL,                   /* Report current position in a file. */
	SYS_CLOSE,                  /* Close a file. */
1) SYS_HALT
-これはフェントスプログラムを終了するシステムコールです.
Power off()関数を使用すればいいです.
2) SYS_EXIT
-現在のユーザー・プロセスのシステム・プロトコルを終了します.
printf ("%s: exit(%d)\n", thread_name(), status);印刷を終了します.
スレッドexitステータスに切り替えた後、thread exitを使用してプロセスを終了します.
3) SYS_FORK
-現在のプロセスをコピーして、サブプロセスのシステムプロトコルを作成します.
processfork()関数でforkを使用します.
この部分は難しすぎます.^^
tid_t
process_fork (const char *name, struct intr_frame *if_ UNUSED) {
	/* Clone current thread to new thread.*/
	struct thread *cur = thread_current();
	memcpy(&cur->parent_if, if_, sizeof(struct intr_frame));// Pass this intr_frame down to child
	tid_t tid = thread_create (name, PRI_DEFAULT, __do_fork, cur);// 자식 스레드를 만든다
	if(tid == TID_ERROR)	return TID_ERROR;

	//project 7
	struct thread *child = get_child_with_pid(tid); //자식 찾기
	sema_down(&child->fork_sema);
	if(child->exit_status == -1){
		return TID_ERROR;
	}
	//생성한 자식 스레드를 리턴
	return tid;
}
和の弦で代用するdo forkもたくさん修正する必要がありますが、省略しました.
子供がupになるまでfork semaを使用してblock状態を行います.
thread create(name,PRI DEFAULT,do fork,cur)ここでサブアイテムを作成します.
私は子供のThreedをしていないので、ずっとうろうろしていて、do fork中if.R.rax=0はないので.子息スレッドの戻り値はゼロであるべきです...ほほほ
このdo forkでfork semaを開きます.
4) SYS_EXEC
-現在のプロセスを実行可能な状態に変更するシステムプロトコル.
プロセスexec関数を使用します.成功した場合は0を返し、-1を返します.
tid_t exec(const char *file_name){
	int siz = strlen(file_name) + 1;
	char *fn_copy = palloc_get_page(PAL_ZERO);
	if (fn_copy == NULL)
		exit(-1);
	strlcpy(fn_copy, file_name, siz);

	if (process_exec(fn_copy) == -1)
		return -1;

	// Not reachable
	NOT_REACHED();
	return 0;
}
5) SYS_WAIT
-親プロセスは、子プロセスのシステムプロトコルを待機します.
プロセスwaitを使用します.
int
process_wait (tid_t child_tid UNUSED) {
	/* XXX: Hint) The pintos exit if process_wait (initd), we recommend you
	 * XXX:       to add infinite loop here before
	 * XXX:       implementing the process_wait. */
	//project 7
	struct thread *child = get_child_with_pid(child_tid); //자식을 찾아서

	if (child == NULL){
		return -1;
	}

	sema_down(&child->wait_sema);//자식을 기다리고

	int exit_status = child->exit_status;

	list_remove(&child->child_elem);
	sema_up(&child->free_sema);//자식을 이제 놓아줘도 된다.
	return exit_status;
}
6) SYS_CREATE
-新しいファイルを作成するシステムコール.
パラメータとして名前とサイズを受け入れ、filesys create(const char*name,off t initial siz)関数を使用すればよい.
成功するとtrueが失敗するとfalseが返されます.
7) SYS_REMOVE
-ファイルのシステムコールを削除します.
パラメータとして名前を受け入れ、filesys remove(const char*name)関数を使用します.
成功するとtrueが失敗するとfalseが返されます.
8)SYS_OPEN
-fileが開いているシステム呼び出しを受け入れます.
filesys openを使用して、ファイルが存在する場合はファイルテーブルにファイルを入れ、ファイル記述子を返します.
int open(const char *file){
	struct file *fileobj = filesys_open(file);

	if(fileobj==NULL)	return -1;
	int fd = add_file_to_fdt(fileobj);

	if(fd == -1)	file_close(fileobj);

	return fd;
}
int add_file_to_fdt(struct file *file){
	struct thread *cur = thread_current();
	struct file **fdt = cur->fdTable;

	while(cur->fdIdx <  FDCOUNT_LIMIT && fdt[cur->fdIdx])
		cur->fdIdx++;

	if(cur->fdIdx >= FDCOUNT_LIMIT)	return -1;

	fdt[cur->fdIdx] = file;
	return cur->fdIdx;
}
9)SYS_FILESIZE
-fdを受信し、ファイルサイズをバイトに返すシステム呼び出し.
fdからファイルを検索し、file lengthを使用して長さを返します.
10)SYS_READ
-fd読み取りファイルのシステムコールを受信します.
fileobjが1番、すなわちstdinである場合、ユーザが入力した内容が読み出される.
2日なら-回1
他のファイルの場合はfile readでファイルを読み込みます.
ファイルサイズを返します.
int read(int fd, void *buffer, unsigned size){
	int ret;
	struct thread *cur = thread_current();

	struct file *fileobj = find_file_by_fd(fd);
	if(fileobj == NULL)	return -1;

	if(fileobj == 1){
		if(cur->stdin_count ==0){
			// Not reachable
			NOT_REACHED();
			remove_file_from_fdt(fd);
			ret = -1;
		}else{
			int i;
			unsigned char *buf = buffer;
			for(i=0; i<size; i++){
				char c = input_getc();
				*buf++ = c;
				if(c=='\0')	break;
			}
			ret = i;
		}
	}else if( fileobj == 2)	ret = -1;
	else{
		lock_acquire(&file_rw_lock);
		ret = file_read(fileobj, buffer, size);
		lock_release(&file_rw_lock);
	}

	return ret;
}
11)SYS_WRITE
-fdを受信してファイルに書き込むシステム呼び出し.
上の読書と似ています.
int write (int fd, const void *buffer, unsigned size){
	int ret;

	struct file *fileobj = find_file_by_fd(fd);
	if (fileobj == NULL)
		return -1;

	struct thread *cur = thread_current();

	if (fileobj == 2){
		if (cur->stdout_count == 0){
			// Not reachable
			NOT_REACHED();
			remove_file_from_fdt(fd);
			ret = -1;
		}
		else{
			putbuf(buffer, size);
			ret = size;
		}
	}
	else if (fileobj == 1){
		ret = -1;
	}
	else{
		lock_acquire(&file_rw_lock);
		ret = file_write(fileobj, buffer, size);
		lock_release(&file_rw_lock);
	}

	return ret;
}
12)SYS_SEEK
-ファイルの場所を変えるシステムコールだほほほ
13)SYS_TELL
-ファイルの場所を知らせるシステムコールですが、実はよくわかりません.
file tell関数を使用できます.
14)SYS_CLOSE
-fdを受信し、ファイルのシステム呼び出しを閉じます.

8. Deny Write on Executables


実行中のファイルへの書き込みを禁止
file deny write関数を使用します.

くどくど言う


今回は本当に難しかったので、内線が理解できる程度だけ理解したいです.次の3-4はできますか…?
今回は97点まで成功した2つのパスがありません...後で時間があったら探してみます.しかし、私たちのチームが一緒にやったのは100点です.間違いありません.ハハハハ、どこでミスをしたのか探してみましょう.ハハハハ.
そしてこれはGithubが参考にして書いたものです.
分岐はyoung-2です.