• 사용자 프로그램이 시스템 콜을 통해 OS와 상호작용하도록 구현.
• 여러 개의 사용자 프로세스를 동시에 실행할 수 있어야 함.
• 각 프로세스는 하나의 스레드로 동작함.
• 여러 프로세스가 자신이 시스템 전체를 소유한 것처럼 느끼도록 메모리, 스케줄링 등 관리 필요.
• #ifdef VM으로 감싼 코드 블록 내에는 코드를 작성하지 말 것.
⸻
• 지금까지 작성한 코드는 OS 커널 내부 코드였음.
• 이번에는 커널 위에서 실행되는 사용자 프로그램을 다룸.
⸻
실행 가능한 프로그램의 조건
• 메모리에 적재 가능해야 함.
• 직접 구현한 시스템 콜만 사용 가능.
• malloc 사용 불가: 동적 메모리 할당 시스템 콜 미구현.
• 부동소수점 연산 (float, double) 사용 불가: FPU 문맥 저장/복구 미지원.
실행 파일 포맷
• ELF 형식의 실행 파일만 실행 가능.
• userprog/process.c 내 로더 코드로 ELF를 적재함.
컴파일 및 로딩 방법
• x86-64 ELF 실행 파일을 생성할 수 있는 컴파일러/링커 사용 가능.
• 예: gcc + ld 조합
• Pintos 전용 컴파일러 및 링커가 제공됨 → 이걸 사용하는 것이 가장 간편.
⸻
• 파일 시스템(filesys.dsk)에 실행파일을 넣어야 실행 가능.
• make check 등 테스트 스크립트가 실행파일을 파일 시스템에 복사해줌.
• filesys.dsk는 디버깅 중에 손상될 수 있음.
• 백업본을 따로 저장해 두는 것 권장.
⸻
전체 구조
• 가상 메모리(Virtual Memory) = 유저 공간 + 커널 공간
• 유저 가상 메모리: 0 ~ KERN_BASE (threads/vaddr.h)
• 커널 가상 메모리: KERN_BASE ~ (물리 메모리와 1:1 매핑)
프로세스와 메모리 관계
• 각 프로세스는 자신만의 유저 가상 메모리 공간을 가짐.
• 문맥 교환 시:
• 페이지 디렉터리 레지스터(CR3)를 바꿈으로써
• 해당 프로세스의 유저 공간 가상 메모리로 전환됨.
• struct thread는 해당 프로세스의 페이지 테이블을 가리키는 포인터 포함.
커널 가상 메모리
• 모든 프로세스가 동일하게 공유.
• 항상 동일한 방식으로 매핑됨.
• 커널 영역은 물리 메모리와 1:1 매핑됨 (물리 메모리 범위까지만).