3장 컴퓨터 시스템의 동작 원리

미정·2022년 9월 24일
0
post-thumbnail

1. 컴퓨터 시스템의 구조

컴퓨터 시스템의 구조는

  • 내부장치 인 CPU, 메모리와
  • 외부장치 인 디스크, 키보드, 마우스, 모니터, 네트워크 장치 등으로 구성된다.(입출력장치 라고도 한다)

컴퓨터는 1) 외부장치에서 내부장치로 데이터를 읽어와 2) 각종 연산을 수행한 후, 3) 그 결과를 외부장치로 다시 내보내는 방식으로 업무를 처리한다.

이 때, 컴퓨터 내부로 데이터가 들어오는 것은 입력(input), 컴퓨터 외부로 데이터가 나가는 것을 출력(output)이라고 한다.

헷갈리기 쉬운 부분! 디스크도 컴퓨터의 '외부장치'

따라서, 디스크에서 내용을 읽어 컴퓨터 내부에서 어떤 연산을 한 후 디스크에 데이터를 저장했다면 컴퓨터 입장에서는 입력과 출력이 일어난 것이다.

  • 컨트롤러(controller)
    메모리 및 입출력 장치 등의 각 하드웨어 장치에는 컨트롤러가 붙어있다. 컨트롤러를 일종의 작은 CPU 로서, 각 하드웨어 장치마다 존재하면서 이들을 제어한다. ex) XX를 제어하는 컨트롤러 -> XX컨트롤러

2. CPU연산과 I/O연산

컴퓨터에서 연산을 한다 == CPU가 무언가 일을 한다 이다.
입출력 장치들의 I/O 연산은 입출력 컨트롤러가 담당하고, 컴퓨터 내에서 수행되는 연산은 메인 CPU가 담당한다.

  • 이 때, 입출력 장치와 메인 CPU는 동시 수행이 가능하다.

한편, 각 장치를 제어하기 위해 설치된 장치 컨트롤러는, 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리, 로컬버퍼(local buffer) 를 가지고 있다.

예를 들어, 프로그램B가 수행 중에 디스크에서 데이터를 읽어오라는 명령을 내리면, 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 이를 로컬버퍼 에 저장한다. 작업이 끝나면, 디스크 컨트롤러는 interrupt 를 발생시켜 CPU에 보고한다.

3. 인터럽트의 일반적 기능

인터럽트에는 하드웨어 인터럽트와 소프트웨어 인터럽트가 있다.
CPU의 서비스가 필요한 경우, CPU 옆에 있는 인터럽트 라인 에 신호를 보내서 인터럽트가 발생했음을 알려주는 방식은 둘다 동일하다.

  • 하드웨어 인터럽트 는 컨트롤러 등 하드웨어 장치가 CPU의 인터럽트 라인을 세팅하고,
  • 소프트웨어 인터럽트 는 소프트웨어가 그 일을 수행한다.
통상적으로 '인터럽트'라고 하면 하드웨어 인터럽트를 의미하고,
소프트웨어 인터럽트는 '트랩(trap)'이라는 용어로 주로 불린다.

발생한 인터럽트의 종류와는 상관없이, 일단 인터럽트가 발생하면 CPU는 하던 일을 멈추고, 운영체제 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾게 된다. 운영체제는 할 일을 쉽게 찾아가기 위한 인터럽트 벡터를 가지고 있다.

  • 인터럽트 벡터
    인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야 할 코드가 위치한 부분을 가리키고 있는 자료구조를 말한다. 실제 처리해야 할 코드는 '인터럽트 처리루틴' 또는 '인터럽트 핸들러' 라고 불리는 다른 곳에 정의된다.
  • 인터럽트 처리루틴(Interrupt Service Routine : ISR)
    해당 인터럽트를 처리하는 커널함수. 운영체제 커널 내에 있는 인터럽트 처리루틴은 다양한 인터럽트에 대해 각각 처리해야 할 업무들을 정의하고 있다.
예시) 디스크 컨트롤러가 인터럽트를 발생시킨 경우!
  -> 해당 인터럽트가 발생했을 때 수행하도록 정의된 코드를 찾아 수행한다. 

디스크의 로컬버퍼에 있는 내용을 사용자 프로그램의 메모리로 전달하고,
해당 프로그램이 CPU를 할당받을 경우 다음 명령을 수행할 수 있음을 표시해두는 일'을 수행한다.

소프트웨어 인터럽트(trap)에 대해서 자세히 살펴보자 : 예외상황(exception)과 시스템콜(system call)

  • 예외상황(exception) - 프로그램이 오류를 범한 경우
    사용자 프로그램이 0으로 나누는 연산 등 비정상적인 작업을 시도하거나, 자신의 메모리 영역 바깥에 접근하려는 시도 등 권한이 없는 작업을 시도할 때 이에 대한 처리를 위해 발생시키는 인터럽트이다.

  • 시스템 콜(system call) - 커널함수 호출
    사용자 프로그램이 운영체제 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청(커널함수 호출)하는 방법이라고 볼 수 있다.

4. 인터럽트 핸들링

인터럽트 핸들링이란, 인터럽트가 발생한 경우에 처리해야 할 일의 절차를 의미한다.

프로그램 A가 실행되고 있을 때, 인터럽트가 발생하면 실행 중이던 A의 현재 상태(프로그램이 실행 중이던 코드의 메모리 주소와 레지스터값, 하드웨어 상태 등)를 먼저 저장한다.

CPU에서 명령이 실행될 때에는 CPU 내부에 있는 임시 기억장치인 레지스터(register)에 데이터를 읽거나 쓰면서 작업을 하는데, 이때 인터럽트가 발생해 새로운 명령을 실행하면 기존의 레지스터값들이 지워지게 되므로 CPU 내의 이러한 상태를 저장해두어야 한다.

운영체제는 현재 시스템 내에서 실행되는 프로그램들을 관리하기 위해 프로세스 제어블록(Process Control Block : PCB) 이라는 자료구조를 둔다. PCB는 각각의 프로그램마다 하나씩 존재한다.

정리하자면,

=> 프로그램 A 실행 중 인터럽트 발생 -> 프로그램 A의 실행 상태를 PCB에 저장 
-> CPU의 제어권이 인터럽트 처리루틴으로 넘어가 인터럽트 처리
-> 인터럽트 처리가 끝나면 저장된 상태를 PCB로부터 CPU상에 복원, 
   해당 상태부터 실행이 이어진다. 

5. 입출력 구조

6. DMA

원칙적으로 메모리는 CPU에 의해서만 접근할 수 있는 장치다. 따라서 CPU 외의 장치가 메모리의 데이터에 접근하기 위해서는 CPU에게 인터럽트를 발생시켜 CPU가 이를 대행하는 식으로만 가능하다.

한편, 모든 메모리 접근 연산이 CPU에 의해서만 이루어질 경우 입출력 장치가 메모리 접근을 원할 때마다 인터럽트에 의해 CPU의 업무가 방해를 받게 되어 CPU 사용의 효율성이 저하되는 문제가 발생한다.

이러한 비효율성을 극복하기 위해 CPU 이외에 메모리 접근이 가능한 장치를 하나 더 두는 경우가 많은데, 이와 같은 장치를 DMA(Direct Memory Access)라고 부른다.

  • DMA
    DMA는 일종의 컨트롤러로서, CPU가 입출력 장치들의 메모리 접근 요청에 의해 자주 인터럽트 당하는 것을 막아주는 역할을 한다.

DMA를 사용하게 되면, 로컬버퍼에서 메모리를 읽어오는 작업을 CPU가 담당하는 것이 아니라 DMA가 대행 한다.

DMA는 바이트(byte) 단위가 아니라 블록(block)이라는 큰 단위로 정보를 메모리로 읽어온 후에 CPU에게 인터럽트를 발생시켜서 해당 작업의 완료를 알려준다.

결과적으로, DMA를 통해 CPU에 발생하는 인터럽트 발생 빈도를 줄여 CPU의 효율적인 관리와 빠른 입출력 연산 수행을 달성할 수 있다.

7. 저장장치의 구조

컴퓨터 시스템을 구성하는 저장장치는 주기억장치보조기억장치 로 나누어볼 수 있다.

  • 주기억장치(메모리)
    전원이 나가면 저장되었던 내용이 모두 사라져버리는 휘발성(volatile)의 RAM을 매체로 사용하는 경우가 대부분이다.

  • 보조기억장치
    전원이 나가도 저장된 내용을 기억할 수 있는 비휘발성(nonvolatile)의 마그네틱 디스크를 주로 사용한다. + 플래시 메모리, CD, 마그네틱 테이프 등이 사용되기도 한다.

보조기억장치의 용도는 (1) 파일시스템용(2) 메모리 연장공간(스왑영역)용 두 가지로 나뉜다.

(1) 파일시스템 용
전원이 나가도 유지해야 할 정보가 있으면 그것을 '파일 형태'로 보조기억장치에 저장하게 된다.

(2) 메모리 연장공간(스왑 영역 : swap area) 용
다수의 프로그램이 메모리에 올라가 동시에 수행되는 다중 프로그래밍 환경에서는 메모리 공간이 부족한 경우가 흔히 발생하게 된다. 운영체제는 프로그램 수행에 당장 필요한 부분만 메모리에 올려놓고 그렇지 않은 부분은 디스크의 스왑 영역에 내려놓게 된다. -> 스왑 아웃(swap out)
(스왑 아웃된 부분이 다시 필요할 때에는 다시 메모리 영역으로 올리게 된다)

이러한 스왑영역은 프로그램이 실행될 때 내용을 저장했다가 프로그램이 종료될 때 삭제하는 '메모리의 연장 공간'으로서의 역할을 담당하므로 파일 시스템처럼 비휘발성 용도로 사용되는 것과는 역할이 구분된다.

8. 저장장치의 계층 구조

컴퓨터 시스템을 구성하는 저장장치는 빠른 저장장치부터 느린 저장장치까지 단계적인 계층 구조로 이루어진다. 빠른 저장장치는 단위 공간당 가격이 높기 때문에 적은 용량을 사용하며, 느린 저장장치는 가격이 저렴해 대용량을 사용하는 반면 접근 속도가 느리다는 약점이 있다. -> *캐싱기법으로 속도 차이 완충

  • 레지스터(in CPU), 캐시메모리, 메인메모리 : 휘발성
  • 메인메모리보다 아랫부분을 구성하는 저장장치계층(마그네틱 디스크, 광디스크, 마그네틱 테이프) : 휘발성

캐싱 기법(caching)

캐싱기법 이란, 상대적으로 용량이 적은 빠른 저장장치를 이용해 느린 저장장치의 성능을 향상시키는 총체적 기법을 일컫는다.

빠른 저장장치에 빈번히 사용될 정보를 저장하면, 필요한 정보를 빠른 저장장치에서 곧바로 찾을 수 있는 경우가 많아져 전체적인 성능이 향상된다.

캐싱 기법이 적은 용량으로도 효과를 거둘 수 있는 것은 컴퓨터 내의 데이터나 프로그램을 구성하는 모든 부분이
균일하게 사용되는 것이 아니라 일부분만이 집중적으로 사용되고 특정 부분은 거의 사용되지 않기 때문이다.

이러한 캐싱 기법을 컴퓨터 시스템 내의 다양한 저장장치 계층에서 활용함으로써 적은 용량의 상위 저장장치만으로도 대부분의 경우 빠른 수행 속도의 성능을 얻어낼 수 있게 된다.

9. 하드웨어의 보안

보통 우리가 사용하는 운영체제는 여러 프로그램이 동시에 실행될 수 있는 다중 프로그래밍 환경에서 동작한다. 따라서, 프로그램 간 실행 방해 및 충돌 방지를 위해 하드웨어에 대한 각종 보안 기법이 필요하다.

하드웨어적인 보안을 유지하기 위해 운영체제는 기본적으로 두가지 모드를 지원한다.
=> 커널모드(kernel mode)사용자 모드(user mode)

  • 커널모드(kernel mode)
    - 운영체제가 CPU 제어권을 가지고 운영체제 코드를 실행하는 모드
    - 모든 종류의 명령을 다 실행할 수 있다.

  • 사용자모드(user mode)
    - 일반 사용자 프로그램이 실행된다.
    - 제한적인 명령만을 수행할 수 있다.


(문제) 중요한 연산을 운영체제만이 수행할 수 있도록 정의하더라도, 사용자 프로그램이 프로그램 내에서 그런 종류의 연산을 수행해버리면 제어가 아무 소용이 없다. 사용자 프로그램이 CPU를 가지고 있는 동안에는 운영체제가 자신의 코드를 실행하지 못하기 때문에 사용자 프로그램을 감시할 방법이 없다..!!


따라서, 하드웨어적인 지원이 필요하다. 컴퓨터 시스템은 CPU 내부에 모드비트(mode bit) 를 두어 사용자 프로그램을 감시하게 된다.

mode bit(모드 비트)

CPU 를 운영체제가 가지고 있는지, 사용자 프로그램이 가지고 있는지 표시해줌

  • 1 사용자 모드 : 사용자 프로그램 수행
  • 0 모니터 모드 : OS 코드 수행 (모니터모드 = 커널모드, 시스템모드)

보안을 해칠 수 있는 중요한 명령어는 커널 모드[0] 에서만 수행 가능한 '특권명령' 으로 규정. 예컨대, 모든 입출력 명령특권명령 으로 규정해서 사용자 프로그램이 직접 입출력을 하는 것을 차단한다.

CPU는 보안과 관련된 명령을 수행하기 전에는, 항상 모드비트를 조사해 그 값이 [0] 으로 세팅된 경우에만 그 명령을 수행한다. 운영체제가 CPU를 점유해 자신의 코드를 수행하다가 사용자 프로그램에게 CPU의 제어권을 넘길 때, 모드비트를 [1] 로 세팅해 넘기게 된다.

모든 입출력 명령은 커널모드[0] 에서만 수행 가능한 '특권명령'이기 때문에 사용자 프로그램은 운영체제를 통해서만 I/O 장치에 접근이 가능하다는 것을 염두에 두고, 다음 과정을 이해해보자!!

▶ 시스템콜(system call) : 사용자 프로그램은 운영체제에게 I/O 요청 (커널 함수 호출)
 - 일반적인 함수 호출과는  사용자 프로그램이 직접 interrupt(trap) 를 걸어서 CPU가 운영체제에게 넘어가게 함

▶ 제어권이 interrupt vector가 가리키는 interrupt service routine으로 이동
  이 때, 인터럽트 하드웨어에 의해 모드비트가 [0]으로 세팅됨 (=> 입출력이 가능한 커널모드) 

▶ 운영체제는 올바른 I/O 요청인지 확인 후 I/O 수행

▶ I/O 완료시(-> device controller에 의해 하드웨어 interrupt가 걸림) 제어권을 시스템콜 다음의 명령으로 옮김

10. 메모리 보안

여러 프로그램이 메모리에 동시에 올라가서 실행되기 때문에 하나의 사용자 프로그램이 다른 사용자 프로그램이나 운영체제가 위치한 메모리 영역을 침범하는 문제가 발생할 수 있다.

기준 레지스터와 한계 레지스터를 이용한 메모리 보안

2개의 레지스터를 사용해서 프로그램이 접근하려는 메모리 부분이 합법적인지 체크함으로써 메모리를 보호할 수 있다.

  • 기준 레지스터 (base register)
    - 어떤 프로그램이 수행되는 동안 해당 프로그램이 합법적으로 접근할 수 있는 메모리상의 가장 작은 주소를 보관하고 있다.

  • 한계 레지스터 (limit register)
    - 해당 프로그램이 기준 레지스터값부터 접근할 수 있는 메모리의 범위를 보관하고 있다.

즉, 어떤 프로그램이 실제 메모리에 올라가 있는 부분의 시작 주소와 그 프로그램의 길이를 각각 기준 레지스터와 한계 레지스터에 보관해 메모리 접근 연산이 있을 때마다 하드웨어적으로 '현재 접근하려는 위치가 합법적인 범위에 있는지' 체크하게 된다.
(단, 기준 레지스터와 한계 레지스터를 통한 메모리 보호 기법은 하나의 프로그램이 메모리의 한 영역에 연속적으로 위치하는 단순화된 메모리 관리 기법을 사용하는 경우에 한정된 설명이다. 7장에서 더 다양한 기법들을 알아볼 예정 ^~^)

	i ) 합법적인 범위 안에 있음 -> 메모리 접근 가능
    
    ii) 범위 안에 없음! -> 예외상황 발생 
    	CPU 제어권이 운영체제로 넘어가고, 운영체제는 예외상황을 발생시킨 프로그램을 강제 종료!!

여기서 오해하지 말아야 할 것! : 메모리 접근 연산은 특권명령이 아니다!
메모리 접근 연산은 사용자 프로그램이 CPU를 가지고 있는 동안 수행할 수 있는 연산이므로 특권명령은 아니다. 단지 사용자 프로그램이 메모리에 접근하기 전에 하드웨어적으로 그 접근이 합법적인지를 체크하여 메모리를 보호하게 된다.
(기준 레지스터와 한계 레지스터의 값을 세팅하는 연산은 특권명령으로 규정하여 사용자 프로그램이 임의로 값을 변경할 수 없게 해야한다)

커널 모드에서는 메모리에 무제한으로 접근하는 것이 가능하다!

11. CPU 보호

보통 컴퓨터 시스템에 하나밖에 없는 CPU. 특정 프로그램이 CPU의 사용 권한을 독점하는 것을 막기 위해 운영체제는 타이머(timer) 라는 하드웨어를 사용한다.

  • 타이머(timer)
    - 정해진 시간이 지나면 인터럽트를 발생시켜 운영체제가 CPU 제어권을 획득할 수 있도록 하는 역할을 수행
    - 타이머는 일정한 시간단위로 세팅될 수 있으며, 매 클럭틱(clock tick)때마다 1씩 감소한다.
    - 타이머가 0이 되는 순간 인터럽트가 발생하게 된다.

타이머의 값을 세팅하는 명령을 로드 타이머 (load timer) 라고 하며, 이는 특권명령에 속한다.

+ ) 타이머는 여러 프로그램이 CPU의 시간을 조금씩 나누어 사용하는 시스템을 의미하는 시분할(time-sharing) 시스템에서 현재 시간을 계산하기 위해서도 사용된다.

0개의 댓글