[Pint OS] Project2 System call ๐Ÿ“ž ์‹ค์ปท ๊ณ ๋ฏผํ•˜๊ธฐ..

์„คํ˜„์•„ยท2025๋…„ 5์›” 21์ผ

โ€ป ์ด ํฌ์ŠคํŒ…์—์„œ๋Š” 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์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • %rip
    CS:APP 3์žฅ์—์„œ ๋ดค๋˜ ๋‚ด์šฉ ์ค‘์— ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ jumpํ–ˆ์„ ๋•Œ, ๊ทธ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋œ ์ดํ›„์— ๊ธฐ์กด ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋Œ์•„์˜ค๊ธฐ ์œ„ํ•ด์„œ jump ์ „์— ๋‹ค์‹œ ๋Œ์•„์˜ฌ ์ฃผ์†Œ๋ฅผ ์Šคํƒ์— push ํ–ˆ์—ˆ๋‹ค.
    user program์ด ์‹œ์Šคํ…œ์ฝœ์„ ํ˜ธ์ถœํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ์ „ํ™˜๋˜๊ธฐ ์ „, ๋‹ค์‹œ ๋Œ์•„์™€์„œ ์‹คํ–‰๋  ์œ„์น˜๋ฅผ %rip ๋ ˆ์ง€์Šคํ„ฐ์— ๋‹ด์•„๋‘”๋‹ค.
  • %rsp
    ๊ทธ๋ฆฌ๊ณ  ์Šคํƒ ๋์„ ๊ฐ€๋ฆฌํ‚ค๋Š” %rsp๋„ intr_frame์— ํฌํ•จ๋œ๋‹ค.
  • R
    gp_registers R์€ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๊ฒฐ๊ณผ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ์ผ๋ฐ˜ ๋ ˆ์ง€์Šคํ„ฐ์ด๋‹ค. ์•„๋งˆ general pointer์ด๋ ค๋‚˜..?
  • ds, cs, ss
    data section, code section, stack section์ด๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค.
    .
    x86-64 ์‹œ์Šคํ…œ์—์„œ๋Š” ์˜๋ฏธ๊ฐ€ ํ๋ฆฟํ•ด์กŒ์ง€๋งŒ, ๋ ˆ๊ฑฐ์‹œ์™€์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด ๋‚จ์•„์žˆ๋‹ค. ๋˜ํ•œ ์œ ์ € ๋ชจ๋“œ์ธ์ง€ ์ปค๋„ ๋ชจ๋“œ์ธ์ง€ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋Š” ์šฉ๋„๋กœ ์“ฐ์ธ๋‹ค๊ณ ๋„ ํ•œ๋‹ค.
    ๊ทธ๋ ‡๋‹ค๋ฉด x86-32 ์‹œ์Šคํ…œ์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜์—ˆ์„๊นŒ?
    ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜์ด ๋„์ž…๋˜๋˜ ์‹œ๊ธฐ, ์ด ๋ ˆ์ง€์Šคํ„ฐ๋“ค์˜ ์—ญํ• ์€ ์ค‘์š”ํ–ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋ธ”๋ก์„ ์ฐธ๊ณ ํ•˜์ž.

    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๋ฅผ ์ปค๋„ ์ž…์žฅ์—์„œ ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

ํ—‰..
์˜ค์ผ€์ด์˜ค์ผ€์ด..

๊ฐ€๋ณด์ž๊ฐ€๋ณด์ž..ใ… ใ… 


User Memory Access

๊นƒ๋ถ์—์„œ๋Š”
%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);
	}
}

System call

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;
	}
}

๊ทธ ๋‹ค์Œ์€ ์‹ค์ œ๋กœ ์‹œ์Šคํ…œ์ฝœ์„ ํ•˜๋‚˜์”ฉ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.(์›์Šค....)
๊นƒ๋ถ์— ๋‚˜์˜จ๋Œ€๋กœ ํ•ด๋ณธ๋‹ค.

halt()

power_off() ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค๊ณ  ํ•œ๋‹ค.

#include "threads/init.h"

void halt(void) {
	power_off();
}

exit()


๊นƒ๋ถ์—๋Š” ํžŒํŠธ๊ฐ€ ์—†์ง€๋งŒ ์œ ํŠœ๋ธŒ์—๋Š” ์žˆ๋”ฐ..!
์œ ํŠœ๋ธŒ๋ฅผ ๊ผญ๊ผญ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ํ™•์‹คํžˆ ์ดํ•ด๊ฐ€ ๋นจ๋ฆฌ ๋˜๊ณ , ๊ฐ์ด ์žกํžŒ๋‹ค.
๋งํฌ ์ฐธ๊ณ 

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()

์—ฌ๊ธฐ์„œ ๋งŽ์ด ํ—ค๋งธ๋‹ค.
์œ„์—์„œ๋Š” ๋ฐ”๋กœ๋ฐ”๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฐ„๋‹จํ•œ ์‹œ์Šคํ…œ์ฝœ์ด์—ˆ์ง€๋งŒ,
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์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

open()

๊นƒ๋ถ์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค.

file์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” file descriptor๋ฅผ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜, ์—†๋‹ค๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
0๊ณผ 1์€ ์ด๋ฏธ ์˜ˆ์•ฝ๋˜์–ด์žˆ์œผ๋‹ˆ, fd๋Š” 2๋ถ€ํ„ฐ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.(0์€ ํ‘œ์ค€ ์ž…๋ ฅ, 1์€ ํ‘œ์ค€ ์ถœ๋ ฅ)
์ฐธ๊ณ ๋กœ, ์›๋ž˜ 2๋ฒˆ์€ ํ‘œ์ค€ ์—๋Ÿฌ๋กœ ์˜ˆ์•ฝ๋˜์–ด์žˆ๊ธด ํ•˜์ง€๋งŒ pintos์—์„œ๋Š” ์ž…์ถœ๋ ฅ๊นŒ์ง€๋งŒ ์ •์˜ํ•œ๋‹ค.

๊ทธ ์•„๋ž˜๋Š” file descriptor์— ๊ด€ํ•˜์—ฌ ๋” ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋‹ค.

  • file descriptor๋Š” ๊ฐ ํ”„๋กœ์„ธ์Šค๋ณ„๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  child thread์—๊ฒŒ๋Š” fd๊ฐ€ ์ƒ์†๋œ๋‹ค. ํ•˜๋‚˜์˜ ํŒŒ์ผ์€ ํ•˜๋‚˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค์—์„œ open๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์„œ๋กœ ๋‹ค๋ฅธ file descriptor๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ํŒŒ์ผ์„ closeํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์„ 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 thread
	struct file** fd_table;
  • syscall.c
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*));
}

close()

fd๋ฅผ ๋‹ซ๋Š”๋‹ค.
fd๋ฅผ ๋‹ซ๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๊ธฐ์กด์— file ๊ตฌ์กฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋˜ ์—ฐ๊ฒฐ์„ ๋Š์–ด์ฃผ๋ฉด ๋œ๋‹ค.

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

filesize()


file_length() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

int filesize(int fd) {
	return file_length(thread_current()->fd_table[fd]);
}

read()

read ์‹œ์Šคํ…œ์ฝœ์€ ๋‘ ๊ฐ€์ง€ case๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค.

  1. fd๊ฐ€ 0์ธ ๊ฒฝ์šฐ, ํ‘œ์ค€์ž…๋ ฅ์œผ๋กœ ์˜ˆ์•ฝ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋“œ์›จ์–ด ์ธํ„ฐ๋ŸฝํŠธ์—์„œ ์ฝ์–ด์™€์•ผ ํ•œ๋‹ค. โ†’ input_getc() ์‚ฌ์šฉ
  2. ๊ทธ์™ธ, fd๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ฝ์–ด์˜จ๋‹ค. โ†’ 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๋Š” ๊ทธ๋ƒฅ ์™„์„ฑ์ด๋ผ๊ณ  ๋ด๋„ ๋œ๋‹ค.

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);
	}
}

seek()

์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ธฐ ์œ„ํ•œ ๋‹ค์Œ byte๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.(์‚ฌ์‹ค ์–ด๋””์— ์“ฐ์ด๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.. ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด์žˆ์–ด์„œ ๊ฐ–๋‹ค ์“ฐ๋ฉด ๋œ๋‹ค..)


void seek(int fd, unsigned position) {
	file_seek(thread_current()->fd_table[fd], position);
}

tell()

์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ธฐ ์œ„ํ•œ ๋‹ค์Œ byte ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.(์ด๊ฒƒ๋„ ์‚ฌ์‹ค ์–ด๋””์— ์“ฐ์ด๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.. ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด์žˆ์–ด์„œ ๊ฐ–๋‹ค ์“ฐ๋ฉด ๋œ๋‹ค..)


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



read-boundary๋Š” ์™œ ํ†ต๊ณผ๊ฐ€ ์•ˆ ๋ ๊นŒ??
๊ฐœ๋ณ„ ์‹คํ–‰ํ•˜๋ฉด ๋˜๋Š”๋ฐ make checkํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.
๊ณ ๋ฏผ ํ•ด๋ณด์ž.

profile
์–ด์„œ์˜ค์„ธ์š”! โ˜บ๏ธ ํ›„ํšŒ ์—†๋Š” ๋‚ด์ผ์„ ์œ„ํ•ด ์˜ค๋Š˜์„ ์—ด์‹ฌํžˆ ์‚ด์•„๊ฐ€๋Š” ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€