โป ์ด ํฌ์คํ ์์๋ System call ์ค์์, File manipulation ๋ถ๋ถ๋ง์ ๋ค๋ฃฌ๋ค.
ํ๋ฆ์ด ์๋ง์ผ ๊ฒ์์ ๋ฏธ๋ฆฌ ์ธ๊ธํ๋ค..
.
.
user program์ kernel area์ ์ง์ ์ ๊ทผํ ์ ์๋ค.
์์คํ
์ฝ์ ํตํด ์ปค๋ ๋ชจ๋๋ก ์ง์
ํ์ฌ ํ์ผ์ ์ฝ๋๋ค๋์ง, ์ด๋ค๋์ง, ํ๊ณ ์ ํ๋ ์ผ๋ค์ ์ํํ ์ ์๋ค.
kernel area๋ก ์ง์
ํ๋ ค๋ฉด user program์ system call์ด๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.

์ด ๋, kernel area๋ก ์ง์
ํ๋ฉด context switching์ด ์ผ์ด๋๊ฒ ๋๋ค.
๊ทธ๋ฌ๋ฉด ์ด ์ฌ์ด์ user program์ด ํ๊ณ ์ ํ๋ ์ผ์ ์ด๋ป๊ฒ ๊ธฐ์ตํ์ฌ kernel mode์์ ์ํํ ์ ์์๊น?

์๋ฌ์บ ๋๋ค.
์ฆ, intr_frame์ด๋ผ๋ ์ฅ์น์ ์ ์ ํ๋ก์ธ์ค์ ๋ ์ง์คํฐ๋ฅผ ์ ์ฅํ์ฌ kernel mode๋ก ๋๊ธด๋ค.
kernel์ ์ ์ ํ๊ฒ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ๊ณผ๊ฐ ์๋ค๋ฉด ๋ ์ง์คํฐ์ ์ ์ฅํ์ฌ ์ ์ ํ๋ก์ธ์ค๋ก ๋ค์ ๋๊ธด๋ค.
kernel mode์์ user mode๋ก ๋์ด๊ฐ ๋๋ intr_frame์ ์ฌ์ฉํ์ฌ ๋ณต๊ตฌํ ์ ์๋ค.

gp_registers R์ ์ธ์๋ฅผ ์ ๋ฌํ๊ฑฐ๋ ๊ฒฐ๊ณผ๊ฐ์ ์ ์ฅํ๋ ์ผ๋ฐ ๋ ์ง์คํฐ์ด๋ค. ์๋ง general pointer์ด๋ ค๋..?x86-32 ์์คํ ์์๋ MMU๋ผ๋ ํ๋์จ์ด์ ๋์ ์์ด, ์ค์ง ์ํํธ์จ์ด๋ก๋ง ๊ฐ ์ธ๊ทธ๋จผํธ๋ฅผ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌํ์๋ค.
๊ทธ๋์ ๊ฐ ์ธ๊ทธ๋จผํธ, data ์์ญ์ ์๋ก ๋ค๋ฉด, data segment์ ์ ๊ทผํ๊ธฐ ์ํด์๋ data segment์ base address์ ๊ทธ segment์์์ offset์ด ํ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ์ฃผ์๊ฐ ์ ํจํ ์ฃผ์์ธ์ง ๊ฒ์ฆํด์ผํ๋ค. ๊ฐ segment ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ง์ผ์ฃผ๊ธฐ ์ํด์ Base + Offset + Limit ์ผ๋ก ์ ๊ทผ ๊ฒฝ๊ณ๋ฅผ ์ ์ดํ๋ค.์ฆ, ๊ฐ segment๋ณ๋ก ๋ณ๋์ base address๊ฐ ์์๋ค๋ ๋ง์ด๋ค.
ํ์ง๋ง ์ด ๊ธฐ๋ฒ์ ๋๋ฌด๋๋ฌด๋๋ฌด ๋๋ฆฌ๋ค.
ํน์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ํด๋น segment์ base ์ฃผ์, offset์ ์์์ผ ํ๊ณ , limit์ ํ์ธํด์ผ ํ๋ค. ์ด๋ฅผ ๋๋ค์ ๋ฌผ๋ฆฌ ์ฃผ์๋ก ๋ณํํด์ฃผ์ด์ผ ํ๋ค.ํ์ฌ 64bit ์ฒด์ ์์๋ ํ๋์ ๊ฐ์๋ฉ๋ชจ๋ฆฌ ์์์ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ฐ segment๋ฅผ ๋ถ๋ฆฌํ์ง๋ง, segment ๋จ์๋ก ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํํ๋ ๊ฒ์ด ์๋๋ผ, page ๋จ์๋ก ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ์ ๋งคํํ๋ค.
์ด ๊ธฐ๋ฒ์ด ๊ฐ๋ฅํ ์ด์ ๋ ํ๋์จ์ด์ ๋์์ ๋ฐ๊ธฐ ๋๋ฌธ์ด๋ค. MMU๋ CPU ๋ฐ๋ก ์์์ kernel์ด ๊ด๋ฆฌํ๋ page table์ ์ฐธ๊ณ ํ์ฌ ๋น ๋ฅธ ์๋๋ก ํด๋น page๋ฅผ ๋ฌผ๋ฆฌ ์ฃผ์๋ก ๋ณํํ ์ ์๋ค.
์ฌํํผ ์ด๋ ๊ฒ user program์ system call์ ํตํด kernel mode์์ ์์ ์ ์ํํ ๊ฒฐ๊ณผ๋ฅผ return ๋ฐ์ ์ ์๋ค.

์ด ์๋ฃ๊ฐ Pintos์์ user program์ด system call์ ํธ์ถํ์ฌ return ๋ฐ๊ฒ๋๋ ๊ณผ์ ์ ์ ์ดํดํ ์ ์๋๋ก ๋์๋ค.
user program์ system call์ ํธ์ถํ๋ค. ์ด๋ syscall.c ์ ์ ์๋ ์ธํฐํ์ด์ค์ธ๋ฐ, user mode์์๋ง ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก, kernel mode์์ ์ ์ฒ๋ฆฌํ ์ ์๋๋ก CPU๋ ๋ ์ง์คํฐ์ ๊ฐ ์ธ์๋ค์ ์ธํ
ํ๋ค.
kernel mode๋ก ์ ํ๋๋ฉด, interupt vector table์์ ์ด๋ค ์ฒ๋ฆฌ๋ฅผ ํด์ค์ง ํ๋จํ๋ค.
์ฐ๋ฆฌ๋ system call์ ํธ์ถํ๊ธฐ ๋๋ฌธ์ 0x30์ด๋ผ๋ ๊ฐ์ผ๋ก syscall_handler()๋ก ๋งคํ๋๋ค. ์ด๋, user stack์๋ system call์ ํธ์ถํ๋ฉด์ ๊ฐ์ด ๋๊ธด ์ธ์๋ค์ด CPU์ ์ํด push ๋์ด์๋ค.
์ฐ๋ฆฌ๋ ๋ง์ง๋ง์ผ๋ก syscall_handler๋ฅผ ์ปค๋ ์ ์ฅ์์ ์ ์ ํ๊ฒ ๊ตฌํํด์ฃผ๋ฉด ๋๋ค.
ํ..
์ค์ผ์ด์ค์ผ์ด..
๊ฐ๋ณด์๊ฐ๋ณด์..ใ ใ
๊น๋ถ์์๋
%rdi, %rsi, %rdx, %r10, %r8, and %r9
์ด ์์๋ก ์ธ์๋ค์ด ์ ์ฅ๋์ด kernel area๋ก ๋์ด์จ๋ค๊ณ ํ๋ค.
๊ทธ๋ฌ๋ฉด syscall_handler์์๋ ์ด ์ธ์๋ค์ ์ ์ ํ ์ทจํ๊ณ ์ํ๋ ์์
์ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ๋๊ธด ์ฃผ์๋ฅผ ์ญ์ฐธ์กฐํ์ ๋,
์ ํจํ์ง ์์ ์ฃผ์์ผ ์ ์์ง ์๋.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฒซ๋ฒ์งธ๋ก ์ ํจํ ์ฃผ์์ธ์ง ์๋์ง ํ์ธํด์ฃผ์ด์ผ ํ๋ค.


์๋์ ํด๋นํ๋ค๋ฉด ์ ํจํ์ง ์์ ํฌ์ธํฐ์ธ ๊ฒ์ด๋ค.
1. pointer๊ฐ null์ด๋ค.
2. pointer๊ฐ virtual memory์ ๋งคํ๋์ง ์์๋ค.
3. pointer๊ฐ kernel ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ด๋ค.
void check_address(void* addr) {
if (addr == NULL || !is_user_vaddr(addr) || pml4_get_page(thread_current()->pml4, addr) == NULL)
{
exit(-1);
}
}
kernel์ด system call์ ์ฒ๋ฆฌํ ๋๋ user program์์ ์ ๋ฌ๋ฐ์ ์ธ์๋ค์ ์ ์กฐํฉํด์ ์ ์ ํ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค.
user program์ด ๋๊ธด ์ธ์๋ CPU์ ์ํด register์ ์ ์ ์ฅ๋์ด ๋์ด์จ๋ค.
.
.
ํนํ๋ ์ ๊ธฐ์ตํด์ผ ํ ๊ฒ์

์ด ๋ถ๋ถ์ด๋ค.
%rax์๋ system call number๊ฐ ์ ์ฅ๋๋ค. ์ด ๋ฒํธ์ ๋ฐ๋ผ์ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค.
halt, exit, fork ๋ฑ ๊ฐ๊ฐ์ system call์๋ ๊ณ ์ ํ ๋ฒํธ๊ฐ ์๋ค.
.
.
์ด ๋ฒํธ๋ฅผ ์ด๋ป๊ฒ ์๋๋ฉด,,

์๊ธฐ syscall-nr.h์์ ์ด๋ ๊ฒ ์ฐ๊ธฐ๋ก ์ฝ์ํ๋ค.
.
.
๊ทธ๋ฆฌ๊ณ ๋ ์ค์ํ ์ฌ์ค์
์๋์ ๋ ์ง์คํฐ ์์๋๋ก arguments๊ฐ ์ ๋ฌ๋๋ค๋ ์ ์ด๋ค.
%rdi, %rsi, %rdx, %r10, %r8, %r9
.
.
๋ ์ด ๋ถ๋ถ! ํ๋๋ง ๋

return value๋ %rax์ ์ ์ฅํด์ ๋ฐํํ๋ค.
์์ ๋๋ ์
์ ๋ฐ๋ผ ์๋์ ๊ฐ์ด ์ด๊ธฐ ์ค์ ์ ํด์ค ์ ์๊ฒ ๋ค.
๋ช ๊ฐ์ง system call์ ๊ตฌํํ ์ํ์ ์ฝ๋์ด๋ ์ฐธ๊ณ
syscall_handler() ์ด๊ธฐ ์ค์ void
syscall_handler(struct intr_frame* f UNUSED) {
// TODO: Your implementation goes here.
/* %rdi, %rsi, %rdx, %r10, %r8, and %r9 */
int syscall_number = (int)f->R.rax;
switch (syscall_number)
{
/* Projects 2 and later. */
case SYS_HALT:
halt();
break;
case SYS_EXIT:
exit(f->R.rdi);
break;
case SYS_WRITE:
f->R.rax = write(f->R.rdi, f->R.rsi, f->R.rdx);
break;
case SYS_CREATE:
f->R.rax = create(f->R.rdi, f->R.rsi);
break;
case SYS_REMOVE:
f->R.rax = remove(f->R.rdi);
break;
default:
exit(-1);
break;
}
}
๊ทธ ๋ค์์ ์ค์ ๋ก ์์คํ
์ฝ์ ํ๋์ฉ ๊ตฌํํด์ผ ํ๋ค.(์์ค....)
๊น๋ถ์ ๋์จ๋๋ก ํด๋ณธ๋ค.

power_off() ๋ฅผ ํธ์ถํ๋ฉด ๋๋ค๊ณ ํ๋ค.
#include "threads/init.h"
void halt(void) {
power_off();
}

๊น๋ถ์๋ ํํธ๊ฐ ์์ง๋ง ์ ํ๋ธ์๋ ์๋ฐ..!
์ ํ๋ธ๋ฅผ ๊ผญ๊ผญ ๋ณด๋ ๊ฒ์ด ์ข๋ค. ํ์คํ ์ดํด๊ฐ ๋นจ๋ฆฌ ๋๊ณ , ๊ฐ์ด ์กํ๋ค.
๋งํฌ ์ฐธ๊ณ

thread_exit() ์ ์ฌ์ฉํ์ฌ ๊ตฌํํ๋ฉด ๋๊ณ ,
"name of process: exit(status)" ๋ฅผ ์ถ๋ ฅํด์ผ ํ๋ค.
์ฌ๊ธฐ์์๋ ์ด ํจ์์์ status๊ฐ์ ๋ณ๊ฒฝํ๋ ์ด์ ๋ฅผ ์์์ผ ํ๋ค.
user program์ด ์ข
๋ฃ๋ ๋ ์คํ๋๋ ์์คํ
์ฝ์ด๋ค.
๋ง์ฝ, ์ด ํ๋ก์ธ์ค๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ์๋ค๋ฉด ๋ถ๋ชจ ํ๋ก์ธ์ค์๊ฒ ์ข
๋ฃ๋ฅผ ์๋ ค์ผ ํ๋ค.
๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ํด๋น ํ๋ก์ธ์ค์ ์ํ๋ฅผ ์ถ์ ํ ์ ์๋๋ก ํด์ผํ๋ค.
๋ฐ๋ผ์, thread ๊ตฌ์กฐ์ฒด์ exit_status๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ ์ํ๋ฅผ ์
๋ฐ์ดํธํด์ค๋ค.
/* struct thread */
enum thread_status exit_status;
/* syscall.c */
void exit(int status) {
struct thread* curr = thread_current();
curr->exit_status = status; // ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ์ ์ ์๋๋ก
// thread ์ด๋ฆ ์ถ๋ ฅ
printf("%s: exit(%d)\n", curr->name, status);
thread_exit();
}
์ฌ๊ธฐ์ ๋ง์ด ํค๋งธ๋ค.
์์์๋ ๋ฐ๋ก๋ฐ๋ก ์ฒ๋ฆฌ๋๋ ๊ฐ๋จํ ์์คํ
์ฝ์ด์์ง๋ง,
create ํจ์๋ disk๋ ํ์ธํ๊ณ , sector๋ ํ์ธํ๋ค. ์๋ก์ด ํ์ผ์ ์์ฑํ ๊ณต๊ฐ์ ํ์ธํ ํ์ ํด๋น ํ์ผ๋ช
์ผ๋ก ์์ฑํ๋ค.
๋ฐ๋ผ์ ์๊ฐ์ด ์ข ๊ฑธ๋ฆฐ๋ค.
์ด๋ ์ ํ๋ธ์๋, ๊น๋ถ์๋ ๊ฐ์ด๋๊ฐ ์์ง๋ง ์ฌ๊ธฐ์ ๊ธฐ file ๊ด๋ จ๋ ํ์ผ๋ค์ ๋ค์ ธ๋ณด๋ฉด ๋น์ทํ ๊ธฐ๋ฅ์ ํ๋ ํจ์๊ฐ ์ ์๋์ด์์์ ์ฝ๊ฒ ๋ฐ๊ฒฌํ ์ ์๋ค.

์ด ํจ์๋ค.
์ด๊ฒ๋ง ๊ฐ์ ธ์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
bool create(const char* file, unsigned initial_size) {
check_address(file);
return filesys_create(file, initial_size);
}
์๋ ๊ทผ๋ฐ ์๊พธ ์๋ฌ๊ฐ ๋จ๋ ๊ฑฐ๋ค๐คฌ

์ด๋ ๊ฒ ๋ง์ด๋ค.
์๋, file๋ช
๋ ์ ๋ค์ด๊ฐ๊ณ (์ ์ง๊ธ ์๊ฐ๋ฌ๋๋ฐ thread_create ์, thread๋ช
๋ํ ์ ํ์ฑํด์ค์ผ ํ๋ค)
๋ค ๋ค ์ ์ํ๋๋๋ฐ ์ ์๊พธ ์ ๋๋์ง๊ฐ ์๋๊ณ ..
์ง์ง ๋ฐ๋์ ์ ๋๊ฒ ๋ถ์ก๊ณ ์์๋๋ฐ
์ด๋ฒ์๋ ์ํธ์ฒ์ฌ ๊ถํธ๋์ด ๋์์ฃผ์
จ๋ค.. ํ..
๋ ๋ณธ์ธ ์ผ์ฒ๋ผ ๊ณ ๋ฏผํด์ฃผ์
์ ๊ฐ์ฌํ๋ค ๐ฅฒ
์ฌํผ ๋ฌธ์ ๋ ์์๋ก ์์ฑํด๋ process_wait()์ ์๊ฐ์ด ๋๋ฌด ์งง์์, ๋ฏธ์ฒ create ๋๊ธฐ ์ ์ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ข
๋ฃ๋๋ค๋ ์ ์ด์๋ค.
๋ด๊ฐ ์ ์ด๊ฑธ ์บ์นํ์ง ๋ชปํ์๊น?
๊ตฌ์กฐ๋ฅผ ์ ์ดํดํ์ง ๋ชปํ๊ณ ์์๋ค๊ณ ํ๋จํ๋ค.
๋ ์์๋ณด์.

ํฌ๊ฒ ์ด๋ฐ ํ๋ฆ์ผ๋ก ํ ์คํธ ์ผ์ด์ค๊ฐ ์คํ๋๊ณ ์๋ค.
ํ๋์ฉ ๋ณด์๋ฉด,
์ฐ์ init.c๊ฐ ์คํ๋๋ฉฐ main thread๊ฐ ์์ฑ๋๋ค.
์ด main thread๋ ๋ชจ๋ ํ
์คํธ ์ผ์ด์ค๋ฅผ ์คํ์์ผ์ฃผ๋ root ์ญํ ์ ํ๋ค.

main thread๋
์์ ๊ฐ์ด process_create_initd()๋ฅผ ์ํํ๋ฉฐ ์์ ํ๋ก์ธ์ค๋ฅผ ๋ง๋ค๊ฒ ๋๊ณ ,
๊ทธ ์์ ํ๋ก์ธ์ค๋ฅผ process_wait()์ผ๋ก ์ข
๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ๋ ์์ง process_wait()์ ๊ตฌํํ์ง ์์๊ธฐ ๋๋ฌธ์ ์์ ํ๋ก์ธ์ค๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ , ๊ทธ๋ฅ for๋ฌธ์ ํ์ถํ ๋์๋ง ์คํ๋๊ฒ๋ ์์๋ก ์ค์ ํ์๋ค.
๊ทธ ์ดํ์๋ ์ด๋ ๊ฒ thread_exit()์ ๋ง๋๊ฒ ๋์ด main thread๋ ์ข
๋ฃ๋๋ค.

์ด ๋, ์์ ํ๋ก์ธ์ค๊ฐ ์์ ํ ์คํ๋๊ธฐ ์ ์ ์ข
๋ฃ๋๋ค๋ฉด ๋ฌธ์ ๊ฐ ์๊ธด๋ค.

์์ ํ๋ก์ธ์ค๋ main thread์ ์ํด ์์ฑ๋๊ณ , do_iret()์ ํตํด user program์ผ๋ก ์ ํ๋๋ค.
์ดํ์๋ %rip์ ์ ์ฅ๋ ์ฃผ์๋ก ์ด๋ํ์ฌ ํ
์คํธ ํ์ผ์ ์ํํ๋ค.
๋ง์ฝ, main thread์ ์ข ๋ฃ๊ฐ ํ ์คํธ ํ์ผ์ ์ํ๋ณด๋ค ๋ ์์๊ฒ ๋๋ค๋ฉด ๋ด๊ฐ ๊ฒช์ ๋ฌธ์ ๋ฅผ ๋ง์ฃผํ๊ฒ ๋๋ค..

.
.
.
๋ ํ๋์ ์๋ฌธ์ด ์๊ฒผ๋ค.
์ฝ๋๋ฅผ ๋ดค์ ๋, ์ ์ ํ๋ก๊ทธ๋จ์ด main.c/main() ํจ์๋ถํฐ ์คํ๋๋ค๋ ์ฌ์ค์ ์ด๋ ดํ์ด ๋์น์ฑ๋ค.
make tests/~~ ๋ฅผ ํ์ ๋, ์ถ๋ ฅ๋ฌธ์ด main() ํ๋ก๊ทธ๋จ๊ณผ ๋์ผํ๊ฒ ๋์ค๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ป๊ฒ main() ํ๋ก๊ทธ๋จ์ผ๋ก ์คํ๋๋ ๊ฑธ๊น???
create-normal๋, args-single๋, ์ ์ ํ๋ก๊ทธ๋จ์ ์ ๋ถ main() ํ๋ก๊ทธ๋จ์ด ์์์ ์ด ๋๋ค.
make tests/~~ ๋ฅผ ํ๋ฉด ๋ด๋ถ์ ์ผ๋ก๋ ์๋์ ๋ช
๋ น์ ์คํํ๋ค.
pintos --fs-disk=10 -p tests/userprog/create-normal:create-normal -- -q -f run 'create-normal'

๋ฌด์ฌ์ฝ ์
๋ ฅํ ๋ช
๋ น์ด์์ ์ค์ ์ ๋ถ ์ง์ ํด์ฃผ๊ณ ์์๋ค.
์ด๋ฐ ํ๋ฆ์ผ๋ก ์ฐ๋ฆฌ๋ user program์ ํ
์คํธํ ์ ์๋ค.
๊น๋ถ์์๋ ์ด๋ ๊ฒ ์ค๋ช
ํ๋ค.

file์ด ๋ค์ด๊ฐ ์ ์๋ file descriptor๋ฅผ ์ฐพ์ ๋ฐํํ๊ฑฐ๋, ์๋ค๋ฉด -1์ ๋ฐํํ๋ค.
0๊ณผ 1์ ์ด๋ฏธ ์์ฝ๋์ด์์ผ๋, fd๋ 2๋ถํฐ ์ฌ์ฉํ๋ฉด ๋๋ค.(0์ ํ์ค ์
๋ ฅ, 1์ ํ์ค ์ถ๋ ฅ)
์ฐธ๊ณ ๋ก, ์๋ 2๋ฒ์ ํ์ค ์๋ฌ๋ก ์์ฝ๋์ด์๊ธด ํ์ง๋ง pintos์์๋ ์
์ถ๋ ฅ๊น์ง๋ง ์ ์ํ๋ค.
๊ทธ ์๋๋ file descriptor์ ๊ดํ์ฌ ๋ ์ค๋ช ํ๊ณ ์๋ค.
์์ ๋ด์ฉ์ file descriptor๋ ํ๋ก์ธ์ค ๋ด๋ถ์์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌ๋๋ค๋ ์ ์ ์์ฌํ ์ ์๋ค.
.
.
์ ํ๋ธ ์๋ฃ๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋ ์ดํดํด๋ณด์.

file descriptor๋ Table์ ์ํด ๊ด๋ฆฌ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด table์ 64๊ฐ์ entry๋ฅผ ๊ฐ์ง๋ค. ์ฆ, 0~63๊น์ง ์ฌ์ฉํ ์ ์๋ค.
์ ํ๋ธ์์๋ ์ข ๋ ๋ง์ ํํธ๋ฅผ ์ค๋ค!

file descriptor๋ฅผ ์ด๋ป๊ฒ ์ ์ฅํ ์ ์์ ์ง์ ๋ํด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ ์ํ๋ค.
thread ๊ตฌ์กฐ์ฒด์ file descriptor table์ ๋์ด ๊ด๋ฆฌํด์ผํ๋ฉฐ,
1. double pointer ํน์ 2. pointer array ํํ๋ก ๊ด๋ฆฌํ๊ธฐ๋ฅผ ๊ถ์ฅ(?)ํ๋ค.
next_fd์ ์ ๋ณด๋ ์๋ต ๊ฐ๋ฅํ๊ธฐ์, ๋๋ ์๋ตํ๋ค.
malloc์ ๊ตฌํํ ๋, ํ ๋น ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐพ์ ๋ ์ฌ์ฉํ๋ ์ ๋ต์ผ๋ก first fit, next fit, best fit์ด ์์๋๋ฐ
์ด next_fd๋ฅผ ์ ์ฅํ๋ ์ด์ ๋ next fit๊ณผ ๋น์ทํ ๋งฅ๋ฝ์ผ๋ก ๋ณด๋ค ๋นจ๋ฆฌ ๋น fd๋ฅผ ์ฐพ๊ธฐ ์ํจ์ด ์๋๊น ์๊ฐํ๋ค.
์ฌํผ ๋๋ ์ด๋ ๊ฒ ๊ตฌํํ๋ค.
struct file** fd_table;
int open(const char* file) {
/* open ์ฑ๊ณต์, fd๋ฅผ ๋ฐํํ๊ณ ์คํจ์, -1์ ๋ฐํํ๋ค. */
check_address(file);
struct file* f = filesys_open(file);
if (f == NULL) {
return -1;
}
struct file** fdt = thread_current()->fd_table;
for (int fd = 2;fd < 64;fd++) {
if (fdt[fd] == NULL || fdt[fd] == 0) {
fdt[fd] = f;
return fd;
}
}
return -1; // fdt ์ ๋ถ ํ ๋น๋จ
}
์ฌ๊ธฐ๊น์ง๋ ์ฝ๋ค.
๊ทธ๋ฐ๋ฐ ๊ฝค๋ ๋๋ฅผ ์ ๋จน์ธ ๋ถ๋ถ์ด ์์๋๋ฐ!
๋ฐ๋ก ๊ตฌ์กฐ์ฒด์ fd_table์ ์ถ๊ฐํ๊ณ , ์ด๊ธฐํ๋ฅผ ํด์ฃผ๋ ๊ณผ์ ์์์๋ค.

๋น์ฐํ ๋ชจ๋ thread๊ฐ ์ด๊ธฐํ๋๋ ์ด ํจ์, init_thread()์์ ์ด๊ธฐํ๋ฅผ ํด์ฃผ์๋ค.
๋น์ด์๋ fd๋ 0(NULL)์ด์ด์ผ ํ๊ธฐ์ calloc์ผ๋ก ์ด๊ธฐํ ํด์ฃผ์๋ค.
๊ทธ๋ฐ๋ฐ

์๊พธ๋ง ์ด๋ฐ ์๋ฌ๊ฐ ๋จ๋ ๊ฑฐ๋คใ
.. (์ง๊ธ ๋ณด๋ ์น์ ํ๊ฒ call stack์ ๋ฑ์ด์คฌ์๋ค ใ
assertion์ ๊ฝํ์ ๋์ ๊ฐ๊ณ ์์๋๋ณด๋ค.)
t->status == THREAD_RUNNING
is_thread(t)
์ด ๋ ๋ถ๋ถ์์ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์๋ฌ๊ฐ ์๊ฒผ๋ค.

๊ฒฐ๊ตญ, thread_current()๋ฅผ ํธ์ถํ๋ ์์ ์ ๋ฌธ์ ๊ฐ ์๊ฒผ๋ ๊ฒ..
์์ผ๊น?

system call ์ฝ๋์์ thread_current()๋ฅผ ํธ์ถํ ๊ฒ ๋ฌธ์ ์ธ๊ฐ ์ถ์ด, ๊ณ์ ๊ทธ ๋ถ๋ถ๋ง ํ๋ดค๋๋ฐ ์ด๊ฒ ๋ฌธ์ ๊ฐ ์๋์๋ค.
init_thread()์์๋ ๋ถํ
๊ณผ ๋์์ ์ต์ด์ main thread๋ฅผ ์ด๊ธฐํ ์ค์ ํด์ฃผ๋ ํจ์๋ก๋ ์ฐ์ธ๋ค.
๊ทธ๋ฐ init_thread() ๋ด๋ถ์์ calloc์ ํธ์ถํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
calloc์ ๋ค์ด๊ฐ๋ณด๋ฉด..

calloc -> malloc -> palloc_get_multiple -> lock_acquire -> thread_current
์ด๋ ๊ฒ ์ด๊ธฐํ ๋๊ธฐ๋ ์ ์ thread_current()๋ฅผ ํธ์ถํ๋ค.
์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ์๊ฒผ๋ ๊ฒ์ด๋ค!
๊ทธ๋์ thread_create() ํน์ process_init() ๋ฑ์ผ๋ก ์ฎ๊ฒจ์ฃผ๋ฉด ๋๋ค.
๋๋ ์ด๋ ๊ฒprocess.c ํ์ผ์ ์ด๊ธฐํํด์ฃผ์๋ค.
static void
process_init(void) {
struct thread* current = thread_current();
/* file descriptor ์ด๊ธฐํ */
current->fd_table = calloc(64, sizeof(struct file*));
}

fd๋ฅผ ๋ซ๋๋ค.
fd๋ฅผ ๋ซ๋๋ค๋ ๊ฒ์ ๊ธฐ์กด์ file ๊ตฌ์กฐ์ฒด์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ์ฐ๊ฒฐ์ ๋์ด์ฃผ๋ฉด ๋๋ค.

void close(int fd) {
/* fd๋ฅผ 0์ผ๋ก ๋ฐ๊ฟ์ค๋ค. */
if (fd >= 2 && fd < 64) {
thread_current()->fd_table[fd] = 0;
}
}


file_length() ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
int filesize(int fd) {
return file_length(thread_current()->fd_table[fd]);
}


read ์์คํ ์ฝ์ ๋ ๊ฐ์ง case๋ก ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํด์ผํ๋ค.
input_getc() ์ฌ์ฉfile_read() ์ฌ์ฉ์ด ํจ์๋ ์๋ฌ์ฒ๋ฆฌ๊ฐ ์ค์ํ๋ค.
int read(int fd, void* buffer, unsigned size) {
check_address(buffer);
// ํ์ค ์
๋ ฅ์ ๊ฒฝ์ฐ, ํค๋ณด๋์ ์
๋ ฅ์ ๋ฐ์
if (fd == 0) {
buffer = input_getc();
return size;
}
else {
// ์ณ์ fd์ธ์ง ํ์ธ
if (fd < 2 || fd >= 64) {
return -1;
}
// ์ ๊ทผํ file์ด ๋น์ด์๋์ง ํ์ธ
struct file* read_file = thread_current()->fd_table[fd];
if (read_file == NULL) {
return -1;
}
return file_read(read_file, buffer, size);
}
}
read๋ฅผ ๊ตฌํํ๋ฉด write๋ ๊ทธ๋ฅ ์์ฑ์ด๋ผ๊ณ ๋ด๋ ๋๋ค.


์ด ๊ฒฝ์ฐ๋ ๋ ๊ฐ์ง case๋ก ๊ตฌ๋ถํ์ฌ ๊ตฌํํ๋ค.
1. fd๊ฐ 1์ผ ๊ฒฝ์ฐ, ํ์ค ์ถ๋ ฅ์ผ๋ก ์์ฝ๋์ด์์ด console์ write ํ๋ค. โ putbuf() ์ฌ์ฉ
2. ๊ทธ ์ธ, fd๋ฅผ ์ฐธ์กฐํ์ฌ ํด๋น file์ write ํ๋ค. โ file_write() ์ฌ์ฉ
int write(int fd, const void* buffer, unsigned size) {
check_address(buffer);
if (fd == 1) {
putbuf(buffer, size);
return size;
}
else {
// ์ณ์ fd์ธ์ง ํ์ธ
if (fd < 2 || fd >= 64) {
return -1;
}
// ์ ๊ทผํ file์ด ๋น์ด์๋์ง ํ์ธ
struct file* write_file = thread_current()->fd_table[fd];
if (write_file == NULL) {
return -1;
}
return file_write(write_file, buffer, size);
}
}
์ฝ๊ฑฐ๋ ์ฐ๊ธฐ ์ํ ๋ค์ byte๋ก ๋ฐ๊ฟ์ค๋ค.(์ฌ์ค ์ด๋์ ์ฐ์ด๋์ง ๋ชจ๋ฅด๊ฒ ๋ค.. ์ด๋ฏธ ๊ตฌํ๋์ด์์ด์ ๊ฐ๋ค ์ฐ๋ฉด ๋๋ค..)


void seek(int fd, unsigned position) {
file_seek(thread_current()->fd_table[fd], position);
}
์ฝ๊ฑฐ๋ ์ฐ๊ธฐ ์ํ ๋ค์ byte ์์น๋ฅผ ๋ฐํํ๋ค.(์ด๊ฒ๋ ์ฌ์ค ์ด๋์ ์ฐ์ด๋์ง ๋ชจ๋ฅด๊ฒ ๋ค.. ์ด๋ฏธ ๊ตฌํ๋์ด์์ด์ ๊ฐ๋ค ์ฐ๋ฉด ๋๋ค..)


unsigned tell(int fd) {
return file_tell(thread_current()->fd_table[fd]);
}


read-boundary๋ ์ ํต๊ณผ๊ฐ ์ ๋ ๊น??
๊ฐ๋ณ ์คํํ๋ฉด ๋๋๋ฐ make checkํ๋ฉด ์ ๋๋ค.
๊ณ ๋ฏผ ํด๋ณด์.