πŸ’Ώ KAIST:PINTOS | Concept | SYSCALL

μ΄μˆœκ°„Β·2025λ…„ 5μ›” 22일

KAIST:PINTOS

λͺ©λ‘ 보기
15/23

μ‹œμŠ€ν…œ 콜(System Call)μ΄λž€?

μš΄μ˜μ²΄μ œλŠ” μ‚¬μš©μž ν”„λ‘œκ·Έλž¨(user program)이 직접 ν•˜λ“œμ›¨μ–΄λ‚˜ 컀널 μžμ›μ— μ ‘κ·Όν•˜λŠ” κ±Έ κΈˆμ§€ν•œλ‹€. λŒ€μ‹ , μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ΄ μš΄μ˜μ²΄μ œμ— μš”μ²­(Request) ν•˜λŠ” 곡식적인 μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλŠ”λ°, 이것을 μ‹œμŠ€ν…œ 콜(System Call) 이라고 λΆ€λ₯Έλ‹€.

κ°„λ‹¨νžˆ 말해:

"μ»€λ„λ‹˜, 이거 λŒ€μ‹  ν•΄μ£Όμ„Έμš”!" 라고 μ •μ€‘νžˆ μš”μ²­ν•˜λŠ” 방식.


μ‹œμŠ€ν…œ 콜이 ν•„μš”ν•œ 이유

μš΄μ˜μ²΄μ œκ°€ μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ„ λ³΄ν˜Έν•˜λŠ” λ³΄μ•ˆ 경계(User-Kernel Boundary) λ₯Ό κ°€μ§€κ³  있기 λ•Œλ¬Έμ—, λ‹€μŒκ³Ό 같은 λ™μž‘μ€ 직접 μˆ˜ν–‰ν•  수 μ—†κ³  μ‹œμŠ€ν…œ μ½œμ„ 톡해 μš”μ²­ν•΄μ•Ό ν•œλ‹€:

  • νŒŒμΌμ„ μƒμ„±ν•˜κ±°λ‚˜ 읽고 μ“°κΈ°
  • ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜κΈ°
  • λ””λ°”μ΄μŠ€(μž…μΆœλ ₯ μž₯치) μ‚¬μš©ν•˜κΈ°
  • ν”„λ‘œκ·Έλž¨ μ’…λ£Œν•˜κΈ°

PintOSμ—μ„œ μš°λ¦¬κ°€ κ΅¬ν˜„ν•΄μ•Ό ν•  μ‹œμŠ€ν…œ 콜

PintOSλŠ” μš°λ¦¬κ°€ 직접 μ‹œμŠ€ν…œ 콜 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Όλ§Œ ν…ŒμŠ€νŠΈλ₯Ό 톡과할 수 μžˆλ„λ‘ μ„€κ³„λ˜μ–΄ μžˆλ‹€. 총 4κ°€μ§€ λ²”μ£Όλ‘œ μ •λ¦¬λœλ‹€.


[1] 파일 μ‹œμŠ€ν…œ κ΄€λ ¨ μ‹œμŠ€ν…œ 콜

이름섀λͺ…μ˜ˆμ‹œ ν…ŒμŠ€νŠΈ
create파일 생성create-normal, create-empty
open파일 μ—΄κΈ°open-normal, open-null, open-boundary
close파일 λ‹«κΈ°close-normal, close-twice
read파일 λ˜λŠ” stdin μž…λ ₯read-normal, read-stdin
write파일 λ˜λŠ” stdout 좜λ ₯write-normal, write-stdout
remove파일 μ‚­μ œsyn-remove
filesizeμ—΄λ¦° 파일의 크기 λ°˜ν™˜λ‚΄λΆ€ ν…ŒμŠ€νŠΈμš©
seek, tell파일 μœ„μΉ˜ μ œμ–΄λ‚΄λΆ€ ν…ŒμŠ€νŠΈμš©

κ΅¬ν˜„ μœ„μΉ˜
β†’ userprog/syscall.c 내뢀에 직접 κ΅¬ν˜„ν•˜κ³ 
β†’ syscall_handler() ν•¨μˆ˜μ—μ„œ switch-case둜 λΆ„κΈ° μ²˜λ¦¬ν•œλ‹€.


[2] ν”„λ‘œμ„ΈμŠ€ μ œμ–΄ μ‹œμŠ€ν…œ 콜

이름섀λͺ…μ˜ˆμ‹œ ν…ŒμŠ€νŠΈ
haltPintOS μ’…λ£Œhalt
exitν”„λ‘œμ„ΈμŠ€ μ’…λ£Œexit, wait-simple
forkν˜„μž¬ ν”„λ‘œμ„ΈμŠ€λ₯Ό 볡제fork-once, fork-recursive
execμƒˆλ‘œμš΄ ν”„λ‘œκ·Έλž¨ μ‹€ν–‰exec-once, exec-bad-ptr
waitμžμ‹ ν”„λ‘œμ„ΈμŠ€ κΈ°λ‹€λ¦Όwait-simple, wait-bad-pid

κ΄€λ ¨ ꡬ쑰체

  • struct thread, struct child_info
    κ΅¬ν˜„ μœ„μΉ˜
  • process.c, syscall.c, thread.c λ“±

[3] μž…μΆœλ ₯ κ΄€λ ¨ μ‹œμŠ€ν…œ 콜

  • read() : fd == 0이면 ν‚€λ³΄λ“œ μž…λ ₯
  • write() : fd == 1이면 ν™”λ©΄ 좜λ ₯

stdin, stdout이 μ•„λ‹Œ κ²½μš°μ—λŠ” 파일 λ””μŠ€ν¬λ¦½ν„° ν…Œμ΄λΈ”μ„ 톡해 μ ‘κ·Ό

κ΄€λ ¨ ν…ŒμŠ€νŠΈ
read-stdin, write-stdout, read-bad-fd, write-bad-ptr λ“±


[4] μ˜ˆμ™Έ 처리 및 λ©”λͺ¨λ¦¬ 검증 κ΄€λ ¨

잘λͺ»λœ 포인터, 잘λͺ»λœ 파일 λ””μŠ€ν¬λ¦½ν„°, 컀널 μ˜μ—­ μ ‘κ·Ό λ“± μ˜ˆμ™Έ μΌ€μ΄μŠ€λ“€μ„ μ²˜λ¦¬ν•˜μ§€ μ•ŠμœΌλ©΄ ν…ŒμŠ€νŠΈ μ‹€νŒ¨

ν…ŒμŠ€νŠΈ 이름검증 ν•­λͺ©
read-bad-ptr컀널 λ©”λͺ¨λ¦¬ μ ‘κ·Ό μ‹œλ„ 차단
write-zero0λ°”μ΄νŠΈ write 정상 처리
bad-read2, bad-write2잘λͺ»λœ μ£Όμ†Œ μ ‘κ·Ό 감지
bad-jump, bad-jump2μ‹€ν–‰ 흐름이 μ΄μƒν•œ 경우 처리

λ°©μ–΄ μ½”λ“œ

  • is_user_vaddr(ptr)
  • ptr < PHYS_BASE
  • pml4_get_page() λ“±μœΌλ‘œ μœ νš¨μ„± 검사 ν›„ exit(-1) 호좜

μ‹œμŠ€ν…œ 콜 처리 흐름 μš”μ•½

μœ μ € ν”„λ‘œκ·Έλž¨ syscall β†’ INT 0x80 β†’ syscall_entry.S β†’ syscall_handler() β†’ sys_XXX() 호좜

각 syscall은 컀널 μ˜μ—­μ˜ syscall.c에 μ •μ˜λ˜λ©°, ν•„μš”ν•œ 경우 filesys.c, process.c, thread.c λ“±μ˜ 파일과 μ—°κ³„λ˜μ–΄ λ™μž‘ν•¨.


ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ™€ μ‹œμŠ€ν…œ 콜 λ§€ν•‘

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ν•„μš”ν•œ μ‹œμŠ€ν…œ μ½œλ©”λͺ¨
args-none ~ args-manyexec, exit, waitArgument Passing도 연결됨
halthalt전원 끄기
exitexitexit status 확인
fork-*fork, wait, exitλ©”λͺ¨λ¦¬ 볡사 및 볡제 확인
create-*create파일 생성 μœ νš¨μ„±
open-*open파일 λ””μŠ€ν¬λ¦½ν„° 정상 처리
close-*close파일 ν•΄μ œ 확인
read-*readstdin 및 파일 읽기
write-*writestdout 및 파일 μ“°κΈ°
bad-*λͺ¨λ“  μ‹œμŠ€ν…œ 콜 + μœ νš¨μ„± 검사포인터/FD/경계 였λ₯˜ ν…ŒμŠ€νŠΈ
syn-removeremove파일 μ‚­μ œ
multi-*, lg-*, sm-*전체 연동 ν…ŒμŠ€νŠΈμ‹œμŠ€ν…œμ½œ 전체 κ΅¬ν˜„ κ²€μ¦μš©

정리

  • μ‹œμŠ€ν…œ μ½œμ€ μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ΄ 컀널에 μš”μ²­ν•˜λŠ” μœ μΌν•œ ν†΅λ‘œ
  • μš°λ¦¬κ°€ κ΅¬ν˜„ν•˜λŠ” μ‹œμŠ€ν…œ μ½œμ€ 파일, ν”„λ‘œμ„ΈμŠ€, μž…μΆœλ ₯, μ˜ˆμ™Έ 처리 등을 λ‹€λ£Έ
  • μ‹œμŠ€ν…œμ½œμ€ λ‹¨μˆœνžˆ ν•¨μˆ˜ κ΅¬ν˜„μ΄ μ•„λ‹ˆλΌ λ³΄μ•ˆ 경계, μœ νš¨μ„± 검증, μžμ› κ΄€λ¦¬κΉŒμ§€ λ‹€ ν¬ν•¨ν•˜λŠ” 컀널 κΈ°λŠ₯
  • syscall_handler()κ°€ μ—”νŠΈλ¦¬ν¬μΈνŠΈμ΄κ³ , sys_XXX() ν•¨μˆ˜λ“€μ΄ μ‹€μ œ 처리 λ‹΄λ‹Ή
profile
μ„œνˆ΄μ§€μ–Έμ • 늘 행동이 먼저이기λ₯Ό

0개의 λŒ“κΈ€