6/9 System Call

JK·2023년 6월 9일


오늘은 오전에 권영진 교수님의 OS특강이 있어서 오후부터 코드 구현을 시작했습니다(강의 내용은 나중에 정리할 시간이 있다면 정리해서 올려보겠습니다)

check_address

pintos/src/userprog/syscall.c

void check_address(void *addr) {
	if (addr == NULL) {
		exit(-1); //주소가 없을 경우
	}
	if (!is_user_vaddr(addr)) { //유저 영역에 속해있지 않을 경우
		exit(-1);
	}
	if(pml4_get_page(thread_current()->pml4, addr) == NULL) {
		exit(-1);
	}
}

Gitbook에서 시스템 콜 과제 이전에 나오는 User memory access는 이후 시스템 콜 구현할 때 메모리에 접근할 텐데, 이때 접근하는 메모리 주소가 유저 영역인지 커널 영역인지를 체크하라는 과제입니다

해당 주소값이 유저 가상 주소(user_vaddr)에 해당하는지 아닌지 체크하고(is_user_vaddr()은 이미 주어져 있습니다.) 유저 영역이 아니면 종료해줍니다

get_argument같은 경우는 구현하지 않아도 됩니다
32비트 x86에서는 프로그래머가 아래와 같이 직접 함수를 구현해서 스택에 쌓인 인자를 커널로 옮겨주는 작업을 수행해야 했습니다. 하지만 x86-64부터는 아까 위에 설명한 것처럼 syscall이라는 어셈블리어 명령이 추가되어 알아서 밑단에서 스택 인자를 커널로 옮겨줍니다. system call number를 R->rax에, 인자는 %rdi, %rsi, %rdx, %r10, %r8, %r9 에 전달합니다. 그러므로 여기서는 get_argument()를 구현하지 않습니다. 이외에도 32비트와 64비트 간에 약간씩 차이가 있으니 유념해서 구현해야 합니다


write()

int write (int fd, const void *buffer, unsigned size) {
	if (fd == STDOUT_FILENO)
		putbuf(buffer, size);
	return size;
}

과제 구현 테스트를 위해 write가 필요하다고 하여 일부만 구현해봤습니다 파일 디스크립터 번호가 1인 경우에 한해 값을 출력하는 함수를 작성합니다. 이때, 버퍼에 들어있는 값을 size만큼 출력하는 putbut() 함수를 이용합니다

void
putbuf (const char *buffer, size_t n) {
	acquire_console ();
	while (n-- > 0)
		putchar_have_lock (*buffer++);
	release_console ();
}

버퍼 안에 들어있는 값 중 사이즈 N만큼을 console로 출력

이때도 다른 값이 콘솔로 출력하는 것을 막기 위해(동기화) 콘솔을 하나의 자원으로 설정하고 console lock을 거는 것을 확인할 수 있습니다


TIL로 작성한 부분을 제외하고도 수정하거나 만든 함수가 더 있지만 어디가 잘못된 건지 실행이 잘 안 되는 거 같습니다...ㅎㅎ
어제 올린 코드와 오늘 올린 코드는 맞았다고 확신할 수 없어서 나중에 수정하게 된다면 다시 올리겠습니다
지금 공부하는 부분이 어렵고 많이 틀리기도 해서 힘들지만 남은 기간도 열심히 공부해보겠습니다

profile
^^

0개의 댓글