개발/유용한코드
운영체제
경주초이
2020. 2. 26. 19:52
컴퓨터 시스템의 구조
-
컴퓨터 내부 장치: CPU, 메모리
컴퓨터 외부 장치: 디스크, 키보드, 마우스, 모니터, 네트워크 장치 등 -
컴퓨터의 업무 처리 방식
컴퓨터 외부 장치에서 컴퓨터 내부로 데이터를 읽어옴: (input)
–> 각종 연산을 수행한 후 그 결과를 컴퓨터 외부장치로 내보냄: 출력(output)
우리가 카톡으로 보낼 메시지를 입력하고 우리가 입력한 내용을 모니터로 확인하는 것도 일종의 입출력 -
컴퓨터내의 각 하드웨어 장치에는 Controller가 있다.
컨트롤러는 일종의 작은 CPU라고도 하며, 각 하드웨어마다 존재하면서 이들을 제어한다.
CPU와 I/O 연산
- 컴퓨터 전체에 CPU라는 중앙처리장치가 있듯이, 컨트롤러는 각 하드웨어 장치마다 존재하면서, 이들을 제어하는 작는 CPU라 할 수 있다.
- 각 장치마다 설치된 컨트롤러에는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리를 가지고 있는데 이를 Local Buffer라 한다.
- 예를들어, 식사를 하며 영화를 보려 한다.
플레이어를 통해 영화 파일을 보려하면, 파일을 열려고 하는 이벤트 발생시, 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 이를 로컬 버퍼에 저장하게 된다.
디스크에서 로컬버퍼로 내용을 다 읽은 후, 이를 CPU에게 알려야 하는데 이 행위를 Interrupt라고 한다.
–> CPU가 데이터를 다 가져왔는지 확인하는 것이 아니라, 장치에 있는 컨트롤러가 체크하는 것 - CPU는 옆에 Interrupt Line을 가지고 있는데, 자신의 일을 하다가 Interrupt Line에 신호가 들어오면 하던일을 멈추고 Interrupt와 관련된 일을 처리한다.
- 인터럽트는 키보드 입력 혹은 디스크에서 데이터를 다 읽어왔다는 등의 이벤트를 CPU에게 알려 줄 필요가 있을 때 컨트롤러가 발생시키는 것이다.
인터럽트의 일반적인 기능
- 운영체제 커널에는 인터럽트가 들어왔을 때 해야 할 일을 미리 다 프로그래밍해서 보관하고 있다.
이렇게 다양한 인터럽트에 대해 각각 처리 해야할 업무들을 정의한 것을 인터럽트 처리 루틴이라고 한다. - 앞의 예와 같이 디스크 컨트롤러가 인터럽트를 발생시키면, CPU는 하던 일을 잠시 멈추고, 이 인터럽트가 발생했을 대 수행해야 할 코드영역(인터럽트 처리 루틴)으로 가서 정의된 일을 수행하게 된다.
이때 수행하는 구체적인 일들은 다음과 같다.- 로컬 버퍼에 있는 내용을 플레이어 프로그램이 사용 할 수 있도록 메모리로 전달
- 플레이어가 CPU를 할당받을 경우 다음 명령(Instruction)을 수행 할 수 있음을 표시
- 운영체제는 할 일을 쉽게 찾아가기 위해 Interrupt Vector를 가지고 있다.
Interrupt Vector : 인터럽트의 종류마다 번호를 정해서 번호에 따라 처리해야 할 코드가 위치한 부분을 포인터로 가리키고 있는 자료구조. - 실제 처리해야 할 내용은 Interrupt Service Routine이라는 다른 곳에 정의된다.
인터럽트 서비스 루틴을 통해 해당하는 인터럽트 처리를 완료하고 나면, 원래 하고 있던 작업으로 돌아가서 하던 일을 계속 진행한다.
그래서 인터럽트 처리 전, 하고 있던 작업에 대한 정보를 반드시 저장해야 하고 운영체제는 이런 정보를 저장하는 별도의 장소를 가지고 있다.
인터럽트 종류
- 인터럽트는 Hardware Interrupt / Software Interrupt로 나뉜다.
- CPU의 서비스가 필요한 경우, CPU옆에 있는 인터럽트 라인에 신호를 보내어 인터럽트가 발생했다고 알려주는 방식은 동일하다.
- Hardware Interrupt는 컨트롤러 등의 하드웨어 장치가 CPU의 인터럽트 라인을 세팅하는 반면, Software Interrupt는 소프트웨어가 그 일을 수행한다는 차이가 있다.
프로그램
- 통상적으로 프로그램은 여러 개의 함수로 구성된다.
- 프로그램의 메모리 구조를 나눠보면 크게 Code, Stack, Data등의 영역으로 나뉜다.
- Stack
- A라는 함수를 실행하는 도중, B 함수를 호출했을 때, B가 종료되고 다시 A가 실행중이던 위치로 돌아가야 하는데, 이를 위한 복구 ㅣ주소를 저장하는 영역이 스택이다.
- Data
- 전역변수 등 프로그램에서 사용하는 각종 데이터가 저장되는 공간.
- Code
- 프로그래머가 작성한 코드가 기계어 명령(Machine Instruction) 형태로 저장되는 영역.
- CPU는 매 시점 코드 부분에 잇는 명령을 하나씩 읽어와서 수행하게 된다.
- Stack
Interrupt Handling
- 인터럽트 핸들링이란 인터럽트가 발생한 경우 처리해야 할 일의 절차를 의미한다.
- 인터럽트는 함수 호출과 유사한 메커니즘으로 처리되는데, CPU역시 인터럽트가 처리되고 난 후 기존에 하던 작업에 대한 정보를 먼저 저장해둔 다음에 인터럽트를 처리해야 한다.
- 운영체제 커널 영역에는 현재 시스템 내에서 수행되는 프로그램들을 관리하기 위한 자료구조인 PCB(Process Control Block)을 가지고 있다.
인터럽트 수행이 끝나면, 프로세스 제어 블록에 저장된 값을 CPU에 다시 복원해 인터럽트 처리 전에 수행하던 작업을 할 수 있다. - 인터럽트 처리루틴은 운영체제 커널 프로그램의 일부이고, 커널 역시 함수구조로 이루어져 있음으로 인터럽트 처리 코드가 수행되는 도중에도 함수 호출이 이루어 질 수 있다.
이를 위해 필요한 것이 Stack이다.
인터럽트의 처리는 커널의 코드를 수행하는 것이므로 인터럽트 처리 중 함수 호출이 발생했을 때 운영 체제 커널의 주소 공간 중 스택 영역을 사용한다. - 현재 N개의 프로그램이 실행 중 일 때, 커널 스택은 현재 실행중인 프로그램 수(N) 만큼 독립적인 공간을 둔다.
이는 비록 커널이 하나의 프로그램이지만, 여러 사용자 프로그램이 수행되는 도중 인터럽트 등에 커널 코드가 수행 될 수 있으므로, 커널은 일종의 공유코드라고 볼 수 있다.
–> 인터럽트 처리 루틴으로 넘어와서 함수 호출이 이루어질 경우, 각 프로세스 별 독자적인 커널 스택을 사용한다.
Software Interrupt
- 통상적으로 하드웨어 인터럽트를 인터럽트라 칭하고, 소프트웨어 인터럽트는 트랩(trap)이라는 용어를 주로 쓴다.
- 소프트웨어 인터럽트의 예
- 예외상황(Exception)
- 프로세스가 0으로 나누는 연산 등의 불가능한 작업을 시도하거나, 메모리 영역을 벗어난 접근을 시도하려 할 때 발생시키는 인터럽트.
- 시스템 콜(System call)
- 프로그램이 자신이 작성하지 않은 코드를 OS로 부터 서비스 받기 위해 발생 시키는 것
- 예를 들어 printf()라는 함수를 이용해 화면에 원하는 내용을 출력 할 수 있지만, 실제 pirntf() 함수를 작성하지는 않는다.
printf()함수의 내용은 이미 라이브러리 함수로 작성되어 있고, 궁극적으로 운영체제 내에 정의된 write()라는 시스템 콜을 호출하기 때문. - 시스템 콜(System call)과 일반적인 함수호출(Funciton call)의 차이 = System call : 운영체제에 정의도니 함수를 호출하는 것
= Function call : 자신이 작성한 함수 또는 라이브러리에 정의된 함수를 호출하는 것
- 예외상황(Exception)
- 소프르웨어 인터럽트는 하드웨어 인터럽트 처럼 컨트롤러가 발생시키는 인터럽트가 아니라 프로그램 수행 도중 직접 CPU에 인터럽트 라인을 세팅하여 발생시킨다.
–> 하드웨어 인터럽트란 각종 하드웨어 장치들이 CPU에게 서비스를 받아야 하는 경우에만 발생시키게 되며, 이는 인터럽트 라인을 통해 CPU에게 전달된다.
–> 소프트웨어 인터럽트란 트랩이라고도 하며, 메모리영역 침범이나 불가능한 연산(ex)0으로 나누기)을 시도하는 예외 상황이나 시스템 콜시에 발생된다.