목차
프로그램의 구조와 인터럽트
프로그램의 주소 영역
프로그램의 주소 영역은 크게 코드, 데이터, 스택 영역으로 구분됨
코드 : 실제로 프로그래머가 작성한 코드가 CPU에서 수행할 수 있는 기계어 명령 형태로 변환되어 저장되는 부분
데이터 : 전역 변수 등의 프로그램이 사용하는 데이터를 저장하는 부분
스택 : 함수 호출 시 호출된 함수의 수행을 마치고 복귀할 주소 및 데이터를 임시로 저장하는데 사용되는 공간
함수의 호출과 인터럽트
인터럽트도 함수의 호출과 유사하게 동작한다
함수 호출 시 스택에 복귀할 주소를 넣어두는 것처럼 인터럽트에 의해 CPU를 빼앗긴 위치는 운영체제가 관리하는 PCB에 저장됨
인터럽트 처리가 완료되면 PCB에 저장된 주소를 통해 프로그램의 어느 부분까지 수행되었는지를 파악하여 재개함
컴퓨터 시스템의 작동 개요
CPU의 명령 (일반명령, 특권명령)
일반명령 : 메모리에서 자료를 읽어와 CPU에서 계산하고 결과를 쓰는 일련의 명령들
모든 프로그램이 수행할 수 있음
특권명령 : 보안이 필요한 명령으로 입출력 장치, 타이머 등 각종 장치에 접근하는 명령
항상 운영체제만이 수행할 수 있도록 제한함
프로그램은 특권명령을 스스로 수행할 수 없으므로 운영체제에게 대행을 요청함
프로그램의 실행
Program execution의 의미
- 디스크에 존재하던 실행파일이 메모리에 적재된다는 의미
- 프로그램이 CPU를 할당받고 명령을 수행하고 있는 상태라는 의미
실행 파일의 메모리 적재 방식
실행파일이 메모리에 적재될 때 실행파일 전체가 메모리에 한꺼번에 올라가면 비효율적
따라서 일부분만 메모리에 올라가고 나머지는 디스크의 특정 영역에 내려가 있는 것이 일반적
가상메모리와 논리적 메모리
프로그램마다 가지는 코드, 데이터, 스택 영역은 실제 물리적 메모리의 주소와 독립적으로 각 프로그램마다 독자적으로 가지고 있는 주소 영역
이와 같은 주소 공간을 가상메모리 or 논리적 메모리 라고 부름
운영체제 커널의 데이터 영역
운영체제도 하나의 프로그램이므로 본인만의 코드, 데이터, 스택으로 이루어진 주소공간을 가지고 있음
아랫단의 하드웨어 자원을 관리하기 위한 부분과 윗단의 응용프로그램 및 사용자에게 편리한 서비스를 제공하기 위한 부분이 주를 이룸
이 중 데이터 영역에는 각종 자원을 관리하기 위한 자료구조가 저장됨
CPU, 메모리와 같은 하드웨어 자원을 관리하기 위한 자료구조 뿐만 아니라 프로세스(현재 수행중인 프로그램)을 관리하기 위한 자료구조들도 존재
각 프로세스의 상태, CPU 사용 정보, 메모리 사용 정보 등을 유지하기 위한 자료구조인 PCB와 같은 자료구조가 프로세스 관리를 위한 자료구조의 예시
운영체제 커널의 스택 영역
커널의 스택은 일반 사용자 프로그램의 스택과 마찬가지로 함수호출 시의 복귀 주소를 저장하기 위한 용도로 사용됨
하지만 일반 사용자 프로그램과 달리 커널의 스택에는 수행중인 프로세스마다 별도의 스택이 있음
프로세스가 특권명령을 수행하기 위해 커널에 정의된 시스템 콜을 호출하고 시스템 콜 내부에서 다른 함수를 호출하는 경우 복귀 주소는 커널 내의 주소가 되어 사용자 프로그램으로 돌아가기 위한 별도의 공간이 필요
또한 커널은 일종의 공유 코드로서 모든 사용자 프로그램이 시스템 콜을 통해 커널의 함수에 접근할 수 있으므로 일관성 유지를 위해 각 프로세스마다 별도의 스택을 두어 관리함
유의할 점: 프로그램 내의 함수호출 시 해당 프로그램의 스택에 복귀 주소를 저장하지만 시스템 콜이나 인터럽트 발생으로 CPU의 수행 주체가 운영체제로 바뀌는 경우에는 직전에 수행되던 프로그램의 복귀 정보를 스택이 아닌 PCB에 저장한다는 점
프로그램의 구조와 인터럽트
세가지 종류의 함수 (사용자 정의, 라이브러리, 커널)
프로그램이 사용하는 함수는 크게 사용자 정의함수, 라이브러리 함수, 커널 함수로 나눌 수 있음
사용자 정의함수와 라이브러리 함수는 자신(프로그램)의 주소 공간에 있는 스택을 사용
사용자 정의함수와 라이브러리 함수와 다르게 커널함수는 사용자 프로그램의 주소 공간이 아닌 운영체제 내에 존재
시스템 콜은 프로그램 내 존재하는 코드를 실행하는 것이 아닌 운영체제라는 별개의 프로그램에 CPU를 넘겨서 실행하는 것
인터럽트
인터럽트 메커니즘
CPU는 PC가 가리키는 곳의 명령을 수행하는 일밖에 하지 않음
현재 프로세스로부터 CPU를 회수해 CPU가 다른 일을 하도록 만들기 위해 필요한 것이 인터럽트 메커니즘
인터럽트 라인은 매 명령어 수행마다 체크하며 인터럽트가 발생했다면 운영체제의 인터럽트 처리루틴으로 이동하여 처리
인터럽트 처리 중 또 다른 인터럽트가 발생하는 경우
인터럽트 처리 중 또 다른 인터럽트의 발생은 원칙적으로 허용되지 않음 (데이터의 일관성이 유지되지 않을 수 있기 때문)
하지만 시급하게 CPU를 사용해야하는 상황이 존재하기에 예외 경우가 필요
인터럽트 처리 도중 더 높은 중요도의 인터럽트가 발생한다면 처리 중이던 인터럽트 코드의 수행 지점을 저장하고 우선순위가 더 높은 인터럽트를 처리함
시스템 콜
시스템 콜과 인터럽트 발생의 유사성
시스템 콜은 인터럽트 라인에 인터럽트를 세팅하는 명령을 통해 이루어짐
프로그램이 스스로 인터럽트 라인을 세팅한다는 점만 다를 뿐 시스템 콜은 일반적인 인터럽트의 발생과 유사하게 이루어짐
CPU을 빼앗기는 두 가지 경우
-
타이머에 의해 인터럽트가 발생하는 경우
CPU가 독점되는 것을 방지하기 위해 존재하는 하드웨어인 타이머는 CPU 할당시간이 만료되면 인터럽트를 발생시킴
CPU를 나누어 사용하는 시분할 시스템의 구현을 위해 필수적
-
입출력 요청을 위해 시스템 콜을 하는 경우
입출력 작업은 긴 시간이 걸림
따라서 그 시간동안 CPU를 다른 프로세스에게 이양함
입출력이 완료되면 컨트롤러가 인터럽트를 발생시키며 인터럽트를 처리하는 시점부터 다시 CPU를 얻을 수 있음
프로세스의 두 가지 실행 상태
사용자모드에서의 실행 상태(user mode running)와 커널모드에서의 실행 상태(kernel mode running)
자신의 주소 공간에 정의된 코드를 실행하는 것은 사용자모드에서의 실행 상태
커널의 시스템 콜 함수를 실행하는 것은 커널모드에서의 실행 상태
시스템 콜이 수행되는 동안 CPU를 운영체제 커널에 빼앗긴 것으로 생각할 수도 있지만 커널의 코드가 프로세스 A의 업무를 대행하는 것이므로 프로세스 A는 실행상태에 있는 것으로 간주해야함
(“프로세스 A가 커널모드에서 실행중”이라 해야 맞는 말)
즉, 프로그램의 실행 상태에는 두 가지(user mode, kernel mode)가 있음