[PintOS] Project 2 키워드 정리 (User mode / Kernel mode, System Call, File descriptor, Atomic operation, Interrupt)

2024. 5. 20. 19:29크래프톤 정글 5기/공부

 

# Todo

1. 개념
2. Why this concept need ?
3. How use this concept in project ?

 


User mode / Kernel mode

 

❓ Definition :

- Application이 시스템 결함을 일으키는 것을 방지하고자 2가지 모드가 제공된다
- Mode bit로 모드를 구분 (0 == kernel / 1 == user) 

1) User mode :

- 사용자 프로그램이 실행되는 모드 / 제한된 권한을 가짐
- User application code가 실행되는 영역
- 시스템 자원에 직접 접근이 불간으하며, OS가 제공하는 시스템 콜을 통해 필요한 자원을 요청할 수 있음

2) Kernel mode :

- OS kernel이 실행되는 모드 / 모든 시스템 자원에 접근할 수 있는 권한을 가짐
- Privileged Instruction (하드웨어 제어 명령어) 실행되는 영역
- 하드웨어를 직접 제어 / 시스템 콜 처리 / 메모리 관리 / 프로세스 스케줄링 등의 작업 수행
- kernel mode에서의 오류나 버그는 시스템 전체에 영향을 줄 수 있음
🔥 Why this concept need ?

- 시스템의 안정성과 보안을 향상시키기 위해 도입된 개념
- User application의 직접적인 하드웨어 접근 차단 -> 시스템 리소스 보호
- 프로세스 간 메모리 격리 -> 프로세스의 독립성 보장
  : 각 프로그램에 독립적인 가상 메모리 주소를 allocate 해야한다는 의미 ?
- 커널 모드에서의 Privileged Instruction 보장 -> 시스템 무결성 유지

 


System Call

 

❓ Definition :

- OS가 제공하는 기능을 응용 프로그램이 요청하기 위해 사용하는 프로그래밍 인터페이스
- 응용 프로그램은 하드웨어 자원 관리를 할 수 없고, 해당 동작은 OS 기능으로 가능함
- 응용 프로그램은 시스템 콜을 호출하여 커널 모드로 진입하고, OS 기능을 사용할 수 있게 됨
- 이 때 시스템 콜을 호출하는 것도 API로 wrapping된 코드를 사용

✅ Type :

1) 프로세스 제어
    fork(): 새로운 프로세스를 생성 / 부모 프로세스와 자식 프로세스가 동일한 프로그램을 실행, 부모 프로세스의 상태를 자식 프로세스가 복사
    exec(): 새로운 프로그램을 실행 / 현재 프로세스의 주소 공간을 새로운 프로그램으로 교체
    wait(): 자식 프로세스의 종료 대기 / 자식 프로세스가 종료되면 그에 대한 정보를 반환
    exit(): 현재 프로세스를 종료
	
2) 파일 관리
    open(): 파일을 열고, 파일 디스크립터를 반환
    close(): 파일 디스크립터로 지정된 파일을 닫음
    read(): 파일에서 데이터를 읽음
    write(): 파일에 데이터를 작성
    seek(): 파일 내에서 특정 위치로 이동
	
3) 장치 관리
    ioctl(): 특정 장치에 대한 제어 명령을 수행
    read(), write(): 장치로부터 데이터를 읽거나 데이터를 기록
	
4) 정보 유지
    getpid(): 현재 프로세스의 ID를 반환
    getuid(), getgid(): 현재 사용자 ID와 그룹 ID를 반환
    time(): 현재 시간을 반환
	
5) 통신
    pipe(): IPC를 위한 파이프를 생성 / 파이프는 [A 프로세스의 출력 -> B 프로세스의 입력] 연결하는 단방향 통신 채널
    shm_open(): 공유 메모리 세그먼트를 생성하거나 액세스 / 공유 메모리는 프로세스 간 메모리 영역 공유 가능케 함
    mmap(): 프로세스의 주소 공간에 파일이나 장치 매핑 -> 프로세스가 파일이나 장치를 직접 메모리에 액세스 하는 것 처럼 다룰 수 있음
	
6) 보호
    chmod(), chown(): 파일의 권한을 변경
    umask(): 파일 생성 시의 기본 권한을 설정
    setuid(), setgid(): 프로세스의 실행 권한을 변경
	
✅ Operation process :

1) User mode에서 Applcation 실행 중 syscall 호출
2) syscall에 인자 전달 -> Interrupt 발생
3) Kernel mode로 전환 -> syscall 처리 루틴 실행
4) Kernel은 요청받은 서비스를 수행 -> 결과를 반환
5) User mode로 전환 -> 다시 Application 실행

✅ Implementation properties :

- 각 OS마다 고유한 syscall Interface 보유
- syscall은 일반적으로 wrapper method type으로 제공됨
- syscall 번호를 사용하여 커널 내부의 해당 서비스 루틴을 호출하는 것

✅ Systemcall & Protection :

- syscall은 사용자 프로그램이 직접적으로 하드웨어에 접근하는 것을 방지 -> 시스템 보안 유지
- OS는 syscall Interface를 통해 접근 권한을 검사하고 제어함

✅ Systemcall Overhead :

- Context Switching과 비슷하게, User mode <-> Kernel mode 전환 동작으로 오버헤드 발생 가능성
🔥 Why this concept need ?

1) Using operating system function (=Control Hardward resources)
- 하드웨어 조작은 operating system의 서비스로만 동작이 가능하다
- operating system이 메모리에 모두 적재하기에는 무리가 있기에, 주요 기능을 kernel이라는 이름으로
  메모리에 상주시킨다
- application은 syscall이라는 함수를 통해 kernel로 signal을 보내는 것
- signal을 받은 kernel은 결과를 반환하고, 다시 제어권을 user에게 전환한다

2) Protection
- 사용자 프로그램 (=application)이 직접적으로 하드웨어 조작을 한다면, 시스템 결함이 생기기 쉽다

=> user mode -> kernel mode 전환을 위해 필요한 signal function
🔥 How use this concept in project ?

- pintOS에서 제공하는 syscall number, Interface 기반으로 syscall function을 작성하는 것
- Application에서 syscall과 함께 전달한 인자의 유효성을 검사하고, 권한을 확인해야 할 것
- 각 syscall의 동작과, 적절한 인자와 권한을 전달하는 동작을 구현하는게 main goal이지 않을 까 추측
- 또한 User mode <-> Kernel mode 전환 시 발생하는 오버헤드, 동기화 문제도 해결해야 할 듯

    # Claude 3 Opus opinion : main syscall to implementation in pintOS project
    void halt(void): 운영 체제를 종료합니다.
    void exit(int status): 현재 사용자 프로그램을 종료합니다.
    pid_t exec(const char *file): 새로운 사용자 프로그램을 실행합니다.
    int wait(pid_t pid): 자식 프로세스가 종료될 때까지 기다립니다.
    bool create(const char *file, unsigned initial_size): 새로운 파일을 생성합니다.
    bool remove(const char *file): 파일을 삭제합니다.
    int open(const char *file): 파일을 열고 파일 디스크립터를 반환합니다.
    int filesize(int fd): 열린 파일의 크기를 반환합니다.
    int read(int fd, void *buffer, unsigned size): 파일에서 데이터를 읽습니다.
    int write(int fd, const void *buffer, unsigned size): 파일에 데이터를 씁니다.
    void seek(int fd, unsigned position): 파일 내에서 위치를 변경합니다.
    unsigned tell(int fd): 현재 파일 위치를 반환합니다.
    void close(int fd): 파일을 닫습니다.

 

 

printf() 함수가 syscall 호출 이후의 동작 흐름

 

# printf() -> write() 과정

1. 라이브러리 함수 (printf) 호출

2. 라이브러리 함수 내에서 시스템 콜(write) 호출

3. 시스템 콜마다 다른 고유 인덱스(write = 4)를 레지스터에 저장한다

4. 0x80 인터럽트를 발생시킨다 (커널 모드로 전환)

5. IDT(Interrupt Descriptor Table)을 참조하여 system_call()을 호출한다

6. 이때 레지스터에 저장된 인덱스 4를 system_call() 함수 내에 전달한다

7. sys_call_table을 참조해 해당 인덱스에 맞는 기능(sys_write)을 호출한다.

8. 동작 완료 이후 사용자 모드로 전환한다.

 


File descriptor

 

❓ Definition :

- OS에서 열려있는 파일이나 입출력 자원을 식별하기 위해 사용되는 추상적인 값
- 프로세스가 파일을 열거나 새로 생성하면, OS는 해당 파일에 대한 파일 디스크립터를 반환
- 파일 디스크립터를 사용하여 프로세스는 파일에 대한 작업 수행이 가능해짐

Properties :

- 음이 아닌 정수 값으로 표현
- 프로세스마다 독립적인 File descriptor Table 가짐
- 동일한 파일에 여러 프로세스가 접근하면, 서로 다른 파일 디스크립터를 받는다
- 0(표준 입력 stdin), 1(표준 출력 stdout), 2(표준 에러 stderr)
	따라서 우리가 사용할 수 있는 값은 3 이상부터

생성 & 소멸 :

- 파일을 열거나 생성할 때, OS는 파일 디스크립터를 반환
- 파일을 닫으면, 해당 File descriptor는 더 이상 유효하지 않게 되며, 다른 파일을 열 때 재사용 됨
- 프로세스가 종료되면, 해당 프로세스가 열었던 모든 파일이 자동으로 닫히고, File descriptor 소멸
🔥 Why this concept need ?

- File descriptor : 프로세스와 파일 시스템 간 인터페이스 역할을 함
- UNIX 계열에서 모든 객체를 파일로 관리 -> 파일에 대한 추상화를 제공하는 것

- File descriptor 사용으로 Application이 파일 시스템에 접근할 수 있도록 한다
- File 관련된 syscall을 안전하고 효율적으로 처리할 수 있게 한다
🔥 How use this concept in project ?

- Application에서 File 관련 syscall 호출 : File descriptor 이용해서 File 식별
- syscall handler에서 전달받은 file descriptor 기반으로 작업을 수행함
- 각 Process는 고유의 File descriptor table 보유 
    -> 동일한 File에 여러 Process 접근 시 각기 다른 file descriptor 할당을 해야 함

 


Atomic operation

❓ Definition :

- 시스템에서 중단되거나 방해받지 않고 완료되는 작업 단위
- 한 번에 완전히 수행되거나, 전혀 수행되지 않음
- Multi threading, 병행 프로그래밍 환경에서 중요한 개념

Properties :

- 원자적 연산은 중간 상태를 가지지 않음 / 작업이 완료되기 전까지는 중간 결과가 보이지 않음
- 원자적 연산은 다른 작업에 의해 중단되거나 간섭받지 않음
- 시스템의 일관성을 유지하는 데 도움을 줌 (data 불일치 / race condition 방지)
🔥 Why this concept need ?

- 공유 자원에 대한 동시 접근을 제어하기 위해 필요함
    -> 동일한 data에 여러 process 접근 시, 원자적 연산을 통해 data 무결성 유지 가능

- 시스템의 안정성과 예측 가능성을 향상시킴
    -> 원자적 연산을 통해 작업의 순서와 결과를 예측할 수 있음

- pintOS project 1에서, [semaphore, lock, condition variable] 사용한 것과 같음
🔥 How use this concept in project ?

- 동기화 문제를 해결하기 위해 원자적 연산을 수행해아 함
  -> syscall을 호출하여 kernel mode로 진입하는 순서를 관리할 때 쓰이지 않을까 ?
	
- system call handler에서 커널 데이터 구조에 대한 접근 동기화 시 쓰임

- project 1에서 사용한 interrupt level disable과 같은 동작이 또 쓰일듯
✅ Webproxy lab에서 공부한 Transaction과 비슷한 느낌인듯 ?

- Transaction은 DB의 상태를 변화시키기 위해 수행하는 작업의 단위

✅ Properties of Transactoin :

1. 원자성
    - transaction 도중 문제가 발생한 경우 : 실패 처리 -> 다시 실행 (~ 모두 성공)
    - 중간 상태가 존재하지 않는다.
	 
2. 일관성
    - Transaction 완료 후에도 DB가 일관된 상태로 유지되어야 함
	 
3. 고립성
    - 하나의 Transaction이 실행되며 데이터의 변경을 야기한다면 다른 Transaction은 해당 데이터 참조 X
	 
4. 지속성
    - Transaction이 성공적으로 완료된다 -> 결과는 영구적으로 반영되어야 함

 


Interrupt

 

 

❓ Definition :

- Processor가 현재 실행 중인 작업을 잠시 중단하고 해당 상황을 처리하는 Mechanism
    [Program 실행 도중 예외 상황이 발생하거나 / I/O 요청으로 인해]
	
- Interrupt 발생 시 Processor는 현재 실행 중인 Instruction의 주소를 저장함
    이후 ISR (Interrupt Service Routine)으로 이동하여 해당 Interrupt 처리
	
✅ Type :

1) Hardware Interrupt :
    - I/O device, Timer 등의 Hardware에서 발생하는 Interrupt
    - System bus를 통해 Interrupt 전달
    - 키보드 입력, Disk I/O 등등
	 
2) Software Interrupt :
    - Program 내에서 의도적으로 발생시키는 Interrupt
    - Systemcall, 예외 상황 등등
    - Interrupt Handling을 통해 Interrupt 처리
	 
✅ Interrupt Handling :

1) Interrupt 발생 
    - Hardware device / Software에서 Interrupt request signal 송출
	 
2) 기존 Instruction 저장
    - Processor는 현재 실행 중인 Instruction 주소와 Register value 스택에 저장
	 
3) Load 'Interrupt Vector'
    - Interrupt vector table에서 해당 Interrupt에 대한 ISR 주소를 가져옴
	 
4) Run 'ISR'
    - Processor는 load된 ISR로 이동하여 해당 Interrupt 처리
	 
5) Restore previous status
    - ISR 실행이 완료되면 저장해 두었던 Instruction 주소와 Register value 복원 및 실행 재개

 

🔥 Why this concept need ?

1) 효율성 향상

    - 하나의 작업이 완료되기 전까지 기다리지 않아도 됨
      -> Processor 자원의 낭비, 시스템 성능 저하를 방지할 수 있음

2) 반응성 향상

    - 외부 이벤트에 대한 시스템의 반응 속도를 높일 수 있음
	 
3) 예외 상황 처리

    - divide by zero, invalid memory access 등과 같은 예외상황 처리가 가능해짐
	 
4) 다중 프로그래밍 환경 지원

    - 여러 프로그램이 동시에 실행되는 동안 Processor resource 효율적으로 공유할 수 있음

 

'크래프톤 정글 5기 > 공부' 카테고리의 다른 글

[PintOS] 2-2 System Call  (1) 2024.06.02
[PintOS] 2-1 Arguments passing  (0) 2024.06.02
[PintOS] 1-3 Advanced Scheduler  (0) 2024.05.18
[PintOS] 1-2 Priority Scheduler, Priority Donation  (0) 2024.05.18
[PintOS] 1-1 Alarm Clock  (0) 2024.05.16