pintos project2 userprog을 진행하면서 syscall을 진행하던 중 file csapp에서 배웠던 file descriptor에 대해 궁금해졌다.
같은 생각이 들었다.
질문 자체가 좀 이상할 수도 있지만, 생각이 들었다.
현재 pintos를 진행하는데 file 관련 syscall들이 존재한다.
그렇다는 것은 kernel space에서 관리한다고 생각할 수 있겠네?

내가 이해한 구조
파일은 어디서 관리 되는가?의 답은
파일 자체는 hard disk에 있다.
여기서 말하는 파일의 관리가 너무 추상적인 질문처럼 보인다.
그럼 파일을 어디서 어떻게 처리하는가?로 바꾼다면,
커널 공간에서 처리가 된다.
커널 공간에서 작업을 처리한 후
사용자에게 결과값을 반환한다.
어떻게 유저가 파일 관련 함수를 호출하고
사용자 모드 -> 커널 모드로 전환되는지 한번 보자.
int
open (const char *file) {
return syscall1 (SYS_OPEN, file);
}
user가 open 함수를 실행하면, open 함수는 syscall1(SYS_OPEN, file)을 호출한다.
#define syscall1(NUMBER, ARG0) ( \
syscall(((uint64_t) NUMBER), \
((uint64_t) ARG0), 0, 0, 0, 0, 0))
syscall1은 매크로 함수로 syscall을 호출한다.
static __inline int64_t syscall (uint64_t num_, uint64_t a1_, uint64_t a2_,
uint64_t a3_, uint64_t a4_, uint64_t a5_, uint64_t a6_) {
int64_t ret;
register uint64_t *num asm ("rax") = (uint64_t *) num_;
register uint64_t *a1 asm ("rdi") = (uint64_t *) a1_;
register uint64_t *a2 asm ("rsi") = (uint64_t *) a2_;
register uint64_t *a3 asm ("rdx") = (uint64_t *) a3_;
register uint64_t *a4 asm ("r10") = (uint64_t *) a4_;
register uint64_t *a5 asm ("r8") = (uint64_t *) a5_;
register uint64_t *a6 asm ("r9") = (uint64_t *) a6_;
__asm __volatile(
"mov %1, %%rax\n"
"mov %2, %%rdi\n"
"mov %3, %%rsi\n"
"mov %4, %%rdx\n"
"mov %5, %%r10\n"
"mov %6, %%r8\n"
"mov %7, %%r9\n"
"syscall\n"
: "=a" (ret)
: "g" (num), "g" (a1), "g" (a2), "g" (a3), "g" (a4), "g" (a5), "g" (a6)
: "cc", "memory");
return ret;
}

참조: csapp 3장
레지스터의 6개의 arguments를 syscall로 mov하는 과정의 어셈블러 코드인 듯 하다.
그렇게 유저 모드에서 커널 모드로 전환하여, 커널 모드에서 최종적으로 open에 맞은 함수를 실행하게 된다.
결국 파일에 대한 정보는 hard disk에 저장되어 있으며 실제로 커널 모드에서 파일 처리 작업을 할 때 hard disk로부터 가져와 작업을 처리한다.
"아니 커널 영역에서 파일 관련 작업을 처리하니까 커널 스레드가 처리하지 않을까?"라는 생각이였는데,
찾아보니 user thread가 그 작업을 수행한다.
user mode → kernel mode로 전환유저 스레드)가 계속 실행되지만, 이제 허용 범위내에 커널 코드를 실행할 권한을 가짐파일에 대한 궁금점을 찾아보았는데,
솔직히 아직 완벽히 이해하지 못했다....
너무 어렵습니다....



나두 살려줘유