[pintos] project 2

29도 맑음·2021년 10월 13일
0

정gle

목록 보기
10/12

6. Argument Passing

받은 명령어를 단어로 나눠서 스택에 저장

받은 명령어가 /bin/ls -l foo bar 라면 밑의 사진 처럼 나눠서 넣는다

strtok_r를 이용해서 한 단어씩 나눈다.
우리는 64비트로 하기 때문에 8바이트씩 옮겨가면서 저장한다.
중간에 align도 해줘야한다.

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도 많이 고쳐줘야하는데 생략한다.
fork_sema를 이용해서 자식이 up해줄때까지 블락상태를 갖는다.
thread_create (name, PRI_DEFAULT, _do_fork, cur)여기서 자식을 만든다.
내가 자식 쓰레드가 안만들어져서 많이 헤맸었는데, _do_fork에서 if
.R.rax=0을 해주지 않아서였다. 자식스레드의 리턴값은 0으로 해줘야하는데 말이다...ㅎ
이 _do_fork에서 fork_sema를 up해준다.

4) SYS_EXEC
-현재 프로세스를 실행 가능한 상태로 변경하는 시스템 콜이다.
process_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
-부모 프로세스가 자식프로세스를 기다리는 시스템 콜이다.
process_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을 이용하며, 파일이 존재한다면 파일을 파일테이블에 넣고 file descriptor를 반환한다.

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를 받아 파일에 쓰는 시스템 콜이다.
위의 read와 비슷하다.

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
-파일의 position을 바꿔주는 시스템콜인데, 사실 잘 모르겠다...ㅎ

13)SYS_TELL
-파일의 position을 알려주는 시스템콜인데, 이것도 사실 잘 모르겠다.
file_tell함수를 이용하면 된다.

14)SYS_CLOSE
-fd를 받아 파일을 닫는 시스템 콜이다.

8. Deny Write on Executables

실행 중인 파일에는 write를 못하게 해주는 것

file_deny_write함수를 이용한다.

그외 주절주절

이번 꺼는 정말 너무 어려워서 내 선에서 이해할 수 있는 정도만 이해하고 넘어가려고 한다. 다음 3-4는 할 수 있을까...?
이번 꺼는 97점까지 성공했다... 통과 못한게 2개인데... 나중에 시간 되면 다시 찾아보는것으로... 대신 팀끼리 같이한거는 100점맞긴함ㅋㅋㅋㅋ 다시 어디서 실수 했는지 찾아봐야지ㅎㅎㅎ
그리고 이번꺼는 github에서 많이 참고 해서 작성했다.
branch는 young-2이다.

0개의 댓글