컴퓨터 시스템의 구조

- 컴퓨터 시스템의 구조는
- 컴퓨터 내부 장치인 CPU, 메모리와
- 외부 장치인 디스크, 키보드, 마우스, 모니터, 네트워크 장치 등으로 구분됨.
- 컴퓨터는 외부 장치에서 내부로 데이터를 읽어와서 각종 연산을 수행한 후 그 결과를 외부 장치로 다시 내어 보는 방식으로 업무를 처리함.
- 이 때 컴퓨터 내부로 데이터가 들어오는 것을 입력, 외부 장치로 데이터가 나가는 것을 출력이라 함.
I/O
- 예를 들어 키보드로부터 입력을 받아 컴퓨터가 어떤 연산을 한 후 그 결과를 모니터에 출력하는 경우를 대표적인 입출력이라 함. 따라서 컴퓨터 외부 장치를 입출력 장치라고도 부름.
- 하드웨어에는 컨트롤러 라는 것이 붙어 있음.
- 컨트롤러는 작은 CPU임.
- 예를 들어 메모리를 제어하는 컨트롤러는 메모리 컨트롤러이고, 디스크를 제어하는 컨트롤러는 디스크 컨트롤러임.
- 프로그램이 수행되려면 그 프로그램이 메모리에 올라가 있어야 함.
- 운영 체제는 컴퓨터가 부팅되었을 때부터 항상 수행되면서 각종 자원들을 관리해야 하므로 항상 메모리에 올라가 있음.
- 이 때 운영체제의 코드가 매우 크기 때문에 모든 코드를 다 메모리에 상주시키면 메모리의 낭비가 심하게 됨. 따라서 운영 체제 중 항상 메모리에 올라가 있는 부분은 전체 운영 체제 중 일부분에 해당되는데, 이 부분을 커널이라 함.
CPU와 I/O 연산
- 컴퓨터가 연산을 할 때 입출력 장치들의 I/O 연산은 I/O 컨트롤러가 담당하고, 컴퓨터 내에서 수행되는 연산은 메인 CPU가 담당하게 됨.
- 이 둘은 동시 수행이 가능함.
- 각 장치마다 이를 제어하기 위해 설치된 장치 컨트롤러에는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리를 갖고 있음.
- 이를
로컬 버퍼(local buffer)
라고 부름.
- 디스크나 키보드 등에서 데이터를 읽어오는 경우, 우선 로컬 버퍼에 데이터가 임시로 저장된 후 메모리에 전달됨.
- 이 때 장치에서 로컬 버퍼로 읽어오는 일은 컨트롤러가 담당함.
- ex) 프로그램에서 어떤 디스크에 있는 데이터를 읽어오라는 명령을 내림 → 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽음 → 로컬 버퍼에 저장 → 장치 컨트롤러가 인터럽트를 발생시켜 작업이 완료되었음을 CPU에게 보고 → 프로그램은 CPU에서 다음 일을 수행하도록 명령.
- 이때 인터럽트란 컨트롤러들이 CPU의 서비스가 필요할 때 이를 통보하는 방법을 말함. CPU는 명령 하나를 수행할 때마다 인터럽트가 발생했는지를 체크하고 인터럽트가 발생하면 다음 명령을 수행하기 전에 인터럽트를 처리하고 그렇지 않으면 다음 명령을 계속 수행함.
- 인터럽트는 키보드 입력 혹은 디스크에서 데이터를 다 읽어왔다는 등의 이벤트는 CPU에게 알려줄 필요가 있는 경우 컨트롤러가 발생시키는 것임.
인터럽트의 일반적인 기능
- 운영 체제 커널에는 인터럽트가 들어왔을 때 해야 할 일을 미리 다 프로그래밍해서 보관하고 있음.
- 이처럼 운영 체제가 해야 할 일들을 운영 체제 개발자가 미리 프로그래밍을 해서 커널 내에 포함시켜 두게 됨.
- 그 중 한 가지가 인터럽트 처리 루틴임.
- 인터럽트에는
하드웨어 인터럽트
와소프트웨어 인터럽트
가 있음.
- 운영 체제 커널 내에 있는 인터럽트 처리 루틴은 다양한 인터럽트에 대해 각각 처리해야 할 업무들을 정의하고 있음.
- ex) 디스크 컨트롤러가 인터럽트를 발생시키면 CPU는 하던 일을 멈추고 인터럽트가 발생했을 때 수행햐아 할 코드 영역으로 감.
- 운영 체제는 할 일을 쉽게 찾아가기 위해
인터럽트 벡터
를 가짐. - 인터럽트 벡터란 인터럽트 종류마다 번호를 저장해서, 번호에 따라 처리해야 할 코드가 위치한 부분을 포인터로 가리키는 자료구조를 말함.
- 실제 처리해야 할 내용은
인터럽트 서비스 루틴
이라는 다른 곳에 정의됨.
- 인터럽트 처리 후 되돌아갈 위치를 알아야 하므로 인터럽트 처리 전에 수행중이던 작업이 무엇이었는지 반드시 저장해야 함.
- 이러한 정보를 저장하기 위한 장소를 운영 체제는 별도로 가지고 있는데 통상적으로
스택
이란 곳에 함수의 실행중이던 위칠로 돌아가기 위한 복귀 주소를 저장함.
인터럽트 핸들링
- 인터럽트 핸들링이란 인터럽트가 발생한 경우에 처리해야 할 일의 절차를 의미함.
- 인터럽트도 함수 호출과 유사한 매커니즘으로 처리됨.
- ex) 프로그램 a가 수행 중 → 인터럽트 발생 → a의 현재 상태 저장 (CPU는 임시 기억 장치인 레지스터에 데이터를 읽어오거나 쓰면서 작업을 수행하는데 인터럽트가 발생하면 기존의 레지스터 값이 지워지게 되므로 레지스터 값 등 CPU 내의 하드웨어 상태를 저장해두어야 함) → 인터럽트 처리
- 운영 체제 커널 영역에는 현재 시스템 내에서 수행되는 프로그램들을 관리하기 위한 자료 구조인
프로세스 제어 블록(PCB)
를 두고 있음.
- 그 자료 구조 중 일부분은 인터럽트가 발생했을 때 프로그램 어느 부분이 수행되던 중이었는지를 저장하기 위한 자료 구조로 사용됨.
- 수행 중이던 메모리 주소, 레지스터 값, 하드웨어 상태 등 저장.
- 인터럽트 처리 중 또 다른 인터럽트가 발생할 경우
- 원칙적으론 허용하지 않지만 인터럽트마다 중요도가 다르기 때문에 상대적으로 낮은 중요도를 가진 인터럽트 작업 수행중에 중요도가 더 높은 인터럽트가 발생하는 것을 허락할 필요가 있음.
- 이럴 경우 현재 처리중이던 인터럽트 코드의 수행 지점을 커널 스택에 저장하고 우선순위가 높은 인터럽트를 처리함.
- 우선 순위가 높은 인터럽트 처리가 끝나면 커널 스택에 저장된 주소로 복귀해 이전에 수행하던 인터럽트 처리 코드를 마저 수행함.
- 통상적으로 인터럽트라 하면 하드웨어 인터럽트를 의미하고, 소프트웨어 인터럽트는
트랩(trap)
이라는 용어로 불림. - ex) 예외 상황 (프로세스가 0으로 나누는 연산 등 불가능한 작업을 시도하거나 자신의 메모리 영역 바깥을 접근하려는 시도를 할 때 발생시키는 인터럽트), 시스템 콜 (ex. 화면에 정보를 출력하는 printf()함수를 호출하면 라이브러리 함수인 printf()는 일종의 인터럽트 메커니즘인 wrtie() 시스템 콜을 통해 커널에 입출력 명력을 대신 수행하도록 요청함.)
- 소프트웨어 인터럽트는 하드웨어 인터럽트처럼 컨트롤러가 발생시키는 인터럽트가 아니라 프로그램 수행 도중 직접 CPU에 인터럽트 라인을 세팅하여 발생시킴.
- 인터럽트가 발생할 때에만 운영 체제 코드 부분으로 CPU가 이양되어 인터럽트 처리를 수행함.
- 결론적으로 운영 체제가 직접 CPU를 점유하는 경우는 인터럽트에 의하지 않고는 발생하지 않음.
입출력 구조
p.76