# 2-1 System Structure & Program Execution 1
컴퓨터에 대한 거시적 분류
- CPU
- 메모리
- I/O 디바이스
input | output |
CPU ⬅️ I/O 디바이스 | CPU ➡️ I/O 디바이스 |
input 디바이스 - 키보드, 컴퓨터, ... | output 디바이스 - 모니터, 프린터, ... 결과를 보여주는 역할 |
컴퓨터 시스템 구조
메모리
- CPU의 작업 공간(원칙적으로 CPU만 접근)
- CPU는 매 클럭 사이클마다 메모리에서 인스트럭션(instruction; 기계어)을 읽음
- 메인 메모리는 CPU만 접근
- I/O 디바이스는 자신의 로컬 버퍼가 존재하기에 데이터를 받아 작업하고,
- 버퍼가 쌓이면 CPU가 그곳의 내용을 읽어 자신의 작업 영역인 메모리에 복사
- CPU는 메모리 / 로컬 버퍼에 모두 접근할 수 있긴 함, 근데 CPU가 모두 접근하면 인터럽트 과다 발생하기에 DMA 컨트롤러를 추가로 둠
- 작은 CPU인 디바이스 컨트롤러는 자기 자신의 로컬 버퍼에만 접근 가능
I/O 디바이스
- 별개의 작업 시스템
하드디스크
- input 역할 - 데이터를 메모리로 읽어 들이기도
- output 역할 - output 디바이스로서의 역할도 수행
디바이스 컨트롤러
- 각 디바이스 전담하는 작은 CPU
- 디스크에서 헤드가 어떻게 움직이고, 어떤 데이터를 읽을지 등 내부를 통제
로컬 버퍼
- 디바이스 컨트롤러의 작업 공간이자 데이터 담는 공간
- 디스크에서 담은 데이터를 메모리로 넘겨주거나 화면 출력 등의 작업을 위해, 실제 데이터는 로컬 버퍼에 담고, 화면에 출력하는 지시는 레지스터 통해 진행(CPU가 I/O 컨트롤러로 전달)
성능 속도 차이
- CPU가 디스크보다 100만 배 정도 빠름
CPU
- CPU가 디스크 직접 관장 x, 디바이스 컨트롤러가 디스크 관장
- CPU는 메모리에서 인스트럭션 읽어 하나씩 실행
- 메모리에만 접근(I/O 에 접근 가능하긴 하지만 직접 접근 시 인터럽트 너무 자주 발생)
- 빠르게 쉬지 않고 일함, 짧은 시간 간격으로 처리 = interactive
- CPU의 레지스터 중 메모리 카운터가 다음에 어디에서 실행할지에 대한 인스트럭션의 메모리 주소를 가지고 있기에, 그 인스트럭션만 실행하는 게 CPU의 역할
- CPU는 본인이 직접 일하는 게 아니라, 메모리의 인스트럭션 지시를 받아 일함
- 인스트럭션 도중 I/O 장치에 접근해야 하면, 디바이스 컨트롤러 통해 읽기나 쓰기 등 명령함
- CPU는 메뉴얼 대로 일함
- 메모리의 몇 번지에 있는 일을 해라(= 인스트럭션) ➡️ 그 다음 메뉴얼의 인스트럭션을 실행하는 행위를 반복
- 위 전체 프로세스는 운영체제가 통제함 ➡️ 이러다 사용자 프로그램에 CPU 연결해주고 ➡️ 프로세스 반복
레지스터
- CPU 안의 메모리보다 빠른, 작은 공간
- CPU가 디바이스 컨트롤러에게 레지스터 통해 작업 지시함
Mode bit
- CPU에서 실행되는 게 운영체제인지, 사용자 프로그램인지 구별해줌
디바이스 컨트롤러
- CPU처럼 하드웨어
- 데이터 저장하는 로컬 버퍼 가짐
- CPU는 하나의 인스트럭션(기계어) 실행 후, 다음 역할 실행하게 하는 작업 반복
- 인스트럭션 실행하다 스캔 / 디스크를 읽거나 / 다른 업무(메모리 외의 역할) 해야할 때, CPU가 직접 디스크에 접근하는 게 아니라, 디바이스(디스크) 컨트롤러에게 일을 시킴
- 그럼 디스크는 컨트롤러로부터 지시 받아, 요청 받은 데이터를 가져와 자신의 로컬 버퍼에 저장
- CPU는 위 과정 동안 쉬지 않고, 메모리에 접근해 다른 작업 실행
디바이스 드라이버
- 소프트웨어
- 운영체제의 코드 중 각 디바이스 처리하기 위한 인터페이스 존재, 여기에 맞게 접근할 수 있개 해주는 소프트웨어
- 하드웨어에 접근하려면 필요
디스크
- 로컬 버퍼에 데이터 넣는 역할
타이머
- 일종의 하드웨어
- 특정 프로그램이 CPU 독점하는 것을 방지
- CPU 제어권이 사용자 ➡️ 운영체제로 넘어오게 해줌
- 무한루프 실행하면 CPU를 계속 사용하게 되는데, 그럼 프로그램 종료나 I/O 작업이나 time sharing 불가함
- 이 사용자 프로그램이 실행될 때 타이머에 값 세팅 후 CPU에 넘겨주는데,
- 세팅된 시간이 되면 타이머가 CPU에 인터럽트 걸어서
- CPU는 하나의 인스트럭션이 끝나면 인터럽트 라인 체크 후, 다음 프로세스를 실행함
- 타이머가 인터럽트 걸면 CPU는 작업하다 잠시 멈추고 다음 프로그램으로 넘어감
- 또는, 처리 결과 출력이나 I/O 해야할 때 프로그램이 자진해서 I/O 해달라고 운영체제에게 CPU를 넘겨주게 됨
- Why? 모든 I/O 인스트럭션은 운영체제 통해 할 수 있기에
- 인스트럭션 처리 ➡️ 인터럽트 라인 체크해서 타이머 걸린 프로그램들 확인
인터럽트
- 사용자가 키보드로 입력한 데이터가 자신의 버퍼에 들어오면 키보드 컨트롤러가 CPU에 인터럽트 걸고,
- 그 상황에 어떤 프로그램이 CPU에서 실행되고 있었어도, 인터럽트가 들어오니 CPU 제어권이 운영체제로 넘어감
- 운영체제는 인터럽트가 왜 들어왔는지 확인 후,
- 입력된 키보드 값을 위에서 키보드 입력 요청한 메모리 공간에 카피해주고,
- 인터럽트로 인해 일시중단된 기존의 사용자에게 다시 CPU 주고,
- 그 사용자에게 할당된 CPU 사용시간이 끝나면 다음 차례에게 넘겨줌
플로우 순서 정리
- CPU가 디스크 컨트롤러에 작업 요청 - 프로그램 1
- 디스크 컨트롤러의 명령에 따라 디스크에서 데이터 읽는 작업 시작
- 위 작업 동안 CPU는 다른 프로그램으로 제어권 넘김 - 프로그램 2 실행
- 디스크 컨트롤러가 작업 끝나면 인터럽트 걸어 CPU에게 알려줌
- 인터럽트 들어왔기에 CPU는 다음 인스트럭션 실행 전, 운영체제에게 자동으로 넘어감 - 프로그램 3 실행 전
- 운영체제는 인터럽트가 왜 들어왔는지 확인 - 프로그램 1 에서 데이터 읽기 요청했음을 확인
- 그럼 CPU 쓰고 있던 프로그램이 끝날 때까지 기다렸다가 - 프로그램 2 끝내고
- 디스크 로컬 버퍼에 있는 데이터를 작업프로그램1 의 메모리에 할당해주고 CPU 제어권 가져옴 - 프로그램 1 의 하위 작업 실행
위와 같이 플로우 진행되는 이유
- 사용자 프로그램은 스스로 I/O 디바이스에 접근 불가
- 운영체제에게 CPU 넘겨주면 운영체제가 그 작업을 I/O 컨트롤러에게 시킴
- 그럼 컨트롤러가 CPU에게 인터럽트 걺
Mode bit
Mode bit = 0
- 모니터 모드 / 커널 모드
- 운영체제가 CPU 가지고 있음
- 메모리나 I/O 에 접근 가능, 아무거나 CPU 에서 실행 가능
- 인터럽트 들어오면 mode bit = 0 으로 바뀐 후 CPU 제어권이 운영체제로 넘어옴
- 일반 명령 수행
Mode bit = 1
- 사용자 모드
- 사용자 프로그램이 CPU 점유 중
- 한정된 인스트럭션만 실행 가능
- 보안 상의 목적이 있기에 특권 명령 수행
- 운영체제에서 사용자로 CPU 넘겨줄 때 mode bit = 1 로 전환
DMA 컨트롤러
- Direct Memory Access controller
- 원래 메모리에 접근하는 건 CPU 하나 뿐이지만, DMA 컨트롤러도 메모리에 접근 가능
- 근데 CPU와 DMA 컨트롤러가 메모리에 동시 접근 시 일관성 깨짐 ➡️ 메모리 컨트롤러가 이 둘을 중재
- I/O가 인터럽트 너무 자주 걸면 CPU가 작업 방해받을 수 있기에, DMA 통해 CPU는 방해 덜 받고 자기 일에 집중
- 로컬 버퍼 작업이 끝나면 거기 있는 데이터를 메모리로 직접 복사해주는 역할 ➡️ 그럼 인터럽트는 한 번만 발생하기에 인터럽트 빈도 줄어듦
입출력 명령
- 특권 명령
- 사용자 프로그램이 CPU 점유
시스템콜
- 운영체제에 부탁
- 사용자 프로그램이 운영체제의 커널 함수 호출(일반 함수 호출과 다름)
- 사용자 프로그램은 운영체제 코드를 직접 수행하는 게 불가하기에, I/O 작업 등 하기 위해 운영체제에 요청
- CPU에서 메인 함수 인스트럭션 실행하다 다른 함수 실행하면 어딘가로 점프
- CPU에서 인스트럭션을 순차적으로 호출하다, 함수 호출이나 if문 조건 충족시키지 못하면 인스트럭션의 메모리 위치가 점프됨
- 내 프로그램이 실행되다 I/O 요청 실행하기 위해 운영체제 함수 호출 = 시스템콜
- 디바이스 컨트롤러가 CPU에 인터럽트 걸듯 시스템콜
순서
- 사용자 프로그램이 실행 중 I/O 작업 필요할 때 직접 주소 점프 못함, mode bit = 1 이기에 사용자 프로그램이 CPU 점유하면 사용자 프로그램 간에서만 점프 가능
- 그럼 사용자 프로그램이 직접 인터럽트 라인 세팅하는 인스트럭션 실행
- 사용자 프로그램이 운영체제에 뭔가 요청하기 위해 소프트웨어에 직접 인터럽트 걸 수 있고, 그럼 CPU는 인터럽트 들어오니 mode bit = 0 으로 바뀌고, 그럼 제어권이 운영체제로 넘어감 ➡️ 운영체제가 CPU 가지고 있기에 디스크 컨트롤러에 데이터 읽어오라 요청 가능
인터럽트
- 사용자 프로그램이 I/O 요청 위해 운영체제에 시스템콜
- I/O 요청 시 발생하는 인터럽트 = 소프트웨어 인터럽트
- 그럼 운영체제는 디바이스 컨트롤러에 I/O 작업 명령함
- 그동안 CPU는 다른 프로그램 수행
- 이후 I/O 작업 끝나면 하드웨어 인터럽트 걸리고
- 디바이스 컨트롤러가 CPU에 I/O 작업 끝났다고 알려줌
- 하드웨어가 CPU에 정보 교신하기 위해 걸 수 있음 = 일반적인 상황 = 타이머나 I/O가 인터럽트 거는 것
- 사용자 프로그램이 돌아가다 직접 처리하지 못하는 I/O 작업 등에 대해 운영체제에 대신 해달라 요청 = 소프트웨어 인터럽트 = 트랩 = 소프트웨어가 인터럽트 건다
Hardware interrupt | Software interrupt |
interrupt (일반적인 의미) | trap |
I/O 요청 끝나면 하드웨어 인터럽트 통해 CPU에 알려줌 | 본인이 직접 인터럽트 걸어 CPU를 운영체제로 넘어가게 함 I/O 요청 시 소프트웨어 인터럽트 |
I/O 컨트롤러가 작업 시
- 시간 오래 걸리니까 CPU는 다음 프로그램 작업 수행
- 그러다 I/O 작업 끝나면 하드웨어 인터럽트 걸림
인터럽트 처리 루틴
- 각 인터럽트마다 처리해야 할 실제 코드
인터럽트 벡터
- 각 종류마다 인터럽트 발생 시 어디에 있는 함수를 실행해야 하는지, 그 함수의 주소를 정의해놓은 일종의 테이블
# 2-1 System Structure & Program Execution 2
컴퓨터 시스템 구조
Computer = Host
- CPU와 메모리가 이에 해당
I/O 디바이스
- 호스트 컴퓨터에 붙어 데이터를 컴퓨터 안에 저장하는 input 혹은 호스트에서 처리된 결과를 내보내는 output 하는 device
디바이스 컨트롤러
- I/O 디바이스 통해 데이터 읽기 / 쓰기 해서 작업 공간인 로컬 버퍼에 데이터 저장
- CPU에게 뭔가 알려주고 싶을 때 디바이스 컨트롤러가 인터럽트 걸어 작업내역 알려줌
CPU
- 매순간 메모리에 올라간 기계어(instruction) 처리
- 0과 1의 조합으로 된, 보통 4 bytes로 된, 정의된 기계어 집합을 하나씩 읽어와 실행
- CPU 안의 레지스터 중 메모리 주소 가리키는 레지스터인 프로그램 카운터 레지스터가 가리키는 메모리의 위치에서 인스트럭션 하나 읽어와 CPU가 그 인스트럭션 실행
- 메모리를 가리키는 프로그램 카운터 레지스터는 다음 주소를 가리키며, + 4 bytes 가 됨
- 메모리 내에서 항상 순차 실행 x, 함수 실행이나 제어 구조의 if문 만족 안 하면 다른 메모리 주소로 점프해 인스트럭션 실행해야 함 ➡️ 더 멀리 있는 인스트럭션 실행
CPU는 아주 빠른 일꾼
- 자기 마음대로 하는 게 아니라, 프로그램 카운터라는 CPU 안의 레지스터가 가리키는 메모리에서 인스트럭션 읽어서 실행하는 역할만 반복
- 다음 인스트럭션 실행 전, 인터럽트 들어온 게 있는지 체크
- 인터럽트가 들어왔다면 지금 프로그램 카운터가 가리키는 메모리 주소에서 인스트럭션 실행하는 게 아니라,
- 지금 하는 작업 잠시 멈추고, 인터럽트 들어오면 CPU를 누가 쓰던 상관 없이 그 제어권이 운영체제에 넘어감
- 그럼 운영체제는 인터럽트마다 왜 인터럽트가 걸렸는지, 그 상황에 맞게 처리해야 할 일이 운영체제 안에 커널 함수로 정의되어 있음
인터럽트 백터
- 인터럽트 종류 별로 몇 번 라인에 인터럽트각 들어갔는지 확인하는 엔트리, 그 인터럽트가 들어오면 메모리 어디에 있는 인스트럭션을 실행해야 하는지 인터럽트 번호와 그 처리 주소(함수 위치)를 쌍으로 가지고 있음
인터럽트 처리 루틴
- 실제 해야 할 일
Mode bit = 0
- CPU가 수행할 수 있는 모든 기계어 집합을 다 실행할 수 있음
- 운영체제가 CPU 가지고 있음
- 다른 사용자 메모리 보기, I/O 작업 등 가능
Mode bit = 1
- 한정된 기계어(인스트럭션)만 실행 가능
- 사용자 프로그램이 CPU 가지고 있음
- 자기 메모리 영역 주소만 보고 일해야 함
I/O 디바이스에서 접근하는 모든 인스트럭션
- Mode bit = 0
- 운영체제만 실행할 수 있게
- I/O 디바이스가 운영체제에 접근하려면 프로그램 카운터 레지스터가 운영체제 주소 영역으로 점프해야 하는데, mode bit = 1 이면 이걸 직접 못하니까 사용자 프로그램이 운영체제에 서비스 요청 시 system call
- 운영체제에 있는 함수를 사용자 프로그램이 요청
- 운영체제 함수 호출 시 의도적으로 인터럽트 라인 세팅
- CPU는 인터럽트 라인이 세팅되면 하던 일을 멈추고, CPU 제어권이 사용자에서 운영체제로 넘어가는 것
하드웨어 인터럽트
- 일반적 의미
- 프로그램이 직접 라인 세팅해 운영체제를 부르는 것 = 소프트웨어 인터럽트 = 트랩
인스트럭션 셋
- 직접 접근 불가 및 잘못된 연산 방지 등 해줌
Timer
- 하드웨어
- 인터럽트 걸 수 있음
- 할당된 시간 끝나면 timer 가 CPU에 인터럽트 걸어주고
- 그럼 사용자 프로그램으로부터 CPU를 뺏어서 운영체제가 사용
- 운영체제는 타이머 인터럽트 도움으로 여러 프로그램을 번갈아 CPU에서 실행시킴
동기식 입출력과 비동기식 입출력
Sync
- 립싱크
- 서로 맞추는 것
Synchronous read
- I/O 장치까지 가서 뭐가 적혀있는지 직접 확인하고 읽어와서 그걸 보고 작업
Synchronous write
- I/O 장치에 뭘 직접 쓰고, 써진 걸 직접 확인
Synchronous I/O
- I/O 요청 후, I/O 작업이 끝나야 사용자 프로그램이 다음 일을 할 수 있음
Asynchronous I/O
- I/O 하라고 던지고, 바로 CPU 얻어와 다른 작업함
Synchronous I/O
- I/O는 커널을 통해서만 가능
- 사용자 프로그램이 I/O 요청을 운영체제의 커널에 하게 되면 그 I/O 장치에 맞는 device driver 거쳐, 실제 하드웨어 통해 I/O 를 읽거나 쓰는 작업
- 이 I/O 작업은 오래 걸림, Why? 사용자가 이를 다 보면서 끝날 때까지 기다린 후 다음 작업
Asynchronous I/O
- I/O 작업 요청만 해놓고, CPU 제어권 얻어서 다른 작업 수행
- I/O는 시간이 걸리고, 이제 끝나면 이를 인터럽트를 통해 알려줌
- I/O 디바이스의 컨트롤러가 인터럽트를 걸어 결과를 알려줌
Sync read
- 보통 읽기 요청 ➡️ 그 값 가지고 와서 작업(순차적)
Async write
- 보통 쓰기 진행 / 그 동안 다른 작업도 진행
- 근데 sync write 하는 경우는 보통 쓰기 ➡️ 잘 써졌는지 확인 필요할 때
순수 sync 와 다른 구현 방법
- Sync I/O 요청 하면
- I/O 작업이 느리니까(CPU가 낭비되는 동안 하나의 I/O만 작업하다 보니, I/O도 낭비될 수 있음)
- 다른 프로그램에 CPU 넘겨주면 그동안 CPU 낭비 없이 다른 작업 진행할 수 있음
- 그 다른 작업에서도 I/O 요청하면 다른 I/O로 던져놓고 또 다른 작업을 CPU에서 수행할 수 있음
- I/O 컨트롤러가 인터럽트 걸어 결과를 알려주면 ➡️ 운영체제로 CPU 제어권이 넘어가고 ➡️ 다른 프로그램에게 CPU 할당
DMA
- 메모리에 접근할 수 있는 장치
- CPU만 접근할 수 있었는데, DMA도 가능
- Too much 인터럽트의 빈도를 낮춰줘, CPU의 효율성을 높여줌
- 블록 단위의 I/O 작업이 끝나면 인터럽트를 한 번만 보내주는 거지
- (원래는 I/O 작업마다 인터럽트를 걸어서 CPU가 방해를 많이 받는데)
- (그림에서의 controller = DMA controller)
서로 다른 입출력 명령어
왼쪽 그림
- 일반적인 I/O 방식
- CPU에서 실행할 수 있는 기계어(인스트럭션)에는 메모리에만 접근하는 인스트럭션과 I/O 장치에 접근하는 인스트럭션이 있음
- 메모리 인스트럭션 – 로드 스토어
- 메모리 주소가 있듯, I/O 디바이스도 주소가 있어, 특정 주소에 I/O 접근하는 인스트럭션 실행하면 그 디바이스에 접근함
오른쪽 그림
- I/O 디바이스에 메모리 주소의 연장 주소를 붙여, 각 번호 주소에 맞는 메모리에 접근하는 인스트럭션 통해 I/O 할 수도 있음
- Memory mapped I/O
저장장치 계층 구조
Green
- 휘발성 – D램 / 캐시 메모리 사용하는 S램 / 전원 나가면 내용 사라지는 레지스터
- 요즘 메인 메모리도 비휘발성인 게 나오고 있긴 함
- CPU가 직접 접근 및 처리 가능, primary = byte 단위 접근
- 위로 갈수록 속도가 빠른 매체, 단위 공간 당 가격이 비쌈, 용량이 적음
레지스터
- Cpu (레지스터 위)안에 레지스터 있음
캐시 메모리
- 캐시 메모리도 cpu 안에 있기도 함
- 캐시 메모리는 메인 메모리보다 용량이 작아 모든 걸 담아두진 못함
- 캐시 메모리는 당장 필요한 것만 메인 메모리에서 끌어다 씀 = 캐싱
- 캐시는 보통 재사용 목적
메인 메모리
- D램으로 구성된 메인 메모리
- D램도 byte 단위, cpu 가 그 자리에서 읽고 실행 가능(excutable)
- Cpu 는 클락 당 인스트럭션 하나 처리
- D램 메모리 접근하려면 적게는 10 ~ 많게는 100 클락 사이클 걸리니 느림
캐싱
- 이런 속도차이 완충하기 위해 캐시 메모리를 두고, 레지스터를 읽어들이는 것
Red
- 시간이 흐르면서 하드디스크(magnetic disk) ➡️ 플래시 메모리 디스크로 변화하기도 함
비휘발성
- CPU가 직접 접근 못함, secondary
- Byte 단위 접근 x, 섹터 단위 접근
- Not excutable
프로그램의 실행
프로그램
- 실행 파일 형태로 파일 시스템에 저장
- 이런 실행 파일 실행 시 메모리로 올라가고, 이게 프로세스가 되어 실행되는 것
Virtual Memory
- 물리적 메모리에 바로 올라가는 게 아니라, 중간에 한 단계 더 거칠 수 있게 해주는 것
Code & Data & Stack
- 어떤 프로그램 실행 시, 그 프로그램의 address space 가 형성되는데 이는 0번지부터 시작하는 메모리 주소 공간임, 이 프로그램만의 독자적 주소 공간이 생김 ➡️ 이 주소 공간은 code, data, stack 으로 구성됨
- Code – 기계어 코드
- Data – 변수 등 프로그램에 사용되는 자료구조
- Stack – 코드가 함수 구조로 되어 있기에, 함수 호출 / 리턴 시 데이터를 쌓았다 꺼내가는 등의 용도로 사용
- 이 독자적 공간을 물리적인 메모리에 올려 실행
- 처음 부팅 시 커널은 항상 상주해 올라가 있으나, 사용자 프로그램은 실행 시 주소 공간 생겼다가, 종료되면 그게 사라짐
- 주소 공간 내의 소스는 당장 필요한 부분만(함수 단위 등) 올라가고, 나머지는 디스크에 내려놓는데, 특히 swap area 에 내려놓음
- 프로그램마다 만들어진 독자적 주소 공간은 실존 공간이 아님
- 쪼개져 메모리 / swap area 등에 위치
File system
- 비휘발성, 내용 유지됨
- 전원이 나가도 내용 유지하는 하드디스크
Swap area
- 메인 메모리의 연장 공간으로 하드 디스크를 사용하는 게 swap area
- 전원 나가면 swap area 에 있는 내용, 메모리에 올라간 부분 모두 사라짐
- 메모리 용량이 한계일 때 메모리 연장 공간으로 사용
- 물리적 메모리도 virtual 메모리처럼 0번지부터 시작
- Virtual 메모리에서 물리적 메모리로 올라갈 때 주소도 변환돼야 함
- 주소 변환해주는 하드웨어 장치 통해 논리적 / virtual 주소가 물리적 주소로 바뀜
운영체제 커널
- 하나의 프로그램
커널 주소 공간의 내용
Data
- 운영체제가 사용하는 여러 자료 구조
- 운영체제는 CPU, 메모리, 디스크 같은 하드웨어 직접 관리 및 통제
- 이런 하드웨어 관리 위해 하드웨어 종류마다 자료구조 만들어 관리
- 운영체제는 프로세스도 관리
- 각 프로그램마다 운영체제가 관리하는 자료구조를 통해 다음에 어떤 프로그램에 할당할지 등 결정
- 프로세스마다 PCB 하나씩 만들어져 관리
Stack
- 함수 호출 / 리턴
- 운영체제의 코드는 여러 프로그램이 요청하면 불러 쓸 수 있음
- 사용자 프로그램이 운영체제의 커널 코드 불러 쓸 수 있기에
- 어떤 사용자 프로그램이 커널의 코드를 실행 중인가에 따라, 사용자 프로그램마다 커널 스택을 따로 두고 있음
사용자 프로그램이 사용하는 함수
함수
- 고급 언어가 아닌, instruction 레벨에서도 계속 쓰임
- 모든 프로그램은 다 함수 구조로 짜여져 있음
- 이 언어가 컴파일 되고 기계어가 되더라도, 함수에 해당하는 부분에 대한 정보가 유지됨
라이브러리 함수
- 워낙 유용해서 남이 만들어 놓은 걸 그대로 가져다 쓰면 됨
사용자 정의 함수 & 라이브러리 함수
- 컴파일에서 실행파일 만들면 내 실행파일 안에 이 함수들이 모두 포함되어 있음
- 사용자 프로세스의 코드 영역에 들어있기에 함수 호출하면 code 단 안에서 점프하며 진행
커널 함수
- 운영체제 안에서 정의됨
- 내 프로그램 안에 들어있는 게 아니고 커널 안에 들어가 있기에, 내 프로그램 안에는 커널 함수의 정의가 없으니 호출만 함
- 내 프로그램이 커널 실행하면 system call 통해 호출, code 단 안에서 점프 불가능
- System call 통해 인터럽트 걸고, CPU 제어권을 운영체제가 받아야 커널 함수 실행 가능
프로그램의 실행
프로그램 실행 단계
- 프로그램이 CPU 직접 잡고 있으면 user mode
- 프로그램이 user mode 안에서 자기가 정의한 사용자 정의 함수 실행 가능
- 근데 system call 하게 되면 이제 그 프로그램의 주소공간에 있는 코드가 아닌, 운영체제 커널에 있는 주소공간의 코드가 실행
- 이 system call 끝나면 기존 프로그램으로 사용자 프로그램으로 CPU 제어권 넘어오고, 본인 코드 실행(가끔 라이브러리 함수도 호출하겠지)
- User ➡️ kernel ➡️ … 반복
'CS' 카테고리의 다른 글
운영체제 - 반효경 #4 Process Management (0) | 2023.03.17 |
---|---|
운영체제 - 반효경 #3 Process (0) | 2023.03.13 |
운영체제 - 반효경 #1 Introduction to Operating Systems (0) | 2023.02.08 |
[CS] About IDE (0) | 2022.03.02 |
[Windows] 명령 프롬프트 CMD 관리자 권한 실행 (0) | 2021.11.24 |
댓글