컴퓨터 시스템의 동작원리

wave·2021년 2월 14일
1

컴퓨터 시스템의 구조

키보드로부터 입력을받아서 컴퓨터가 어떤 연산을 한 후 그 결과를 모니터에 출력하는 경우를 대표적인 입출력(I/O)이라고 말할 수 있다. 따라서 컴퓨터 외부장치를 입출력 장치라고도 부른다.

우리가 생각하는 운영체제는 여러 프로그램이 동시에 수행되는 시스템을 위한 운영체제이다. 프로그램이 수행되려면 그 프로그램이 메모리에 올라가 있어야 한다. 운영체제는 컴퓨터가 부팅 되었을 때 부터 항상 수행되면서 각종 자원들을 관리해야 하므로 항상 메모리에 올라가 있다. 하지만 운영체제의 모든 코드를 다 메모리에 상주시키면 메모리의 낭비가 발생하게 된다. 따라서 운영체제 중 항상 메모리에 올라가 있는 부분은 전체 운영체제 중 핵심적인 부분에 한정되며, 이 부분을 커널 이라고 부른다.


CPU 연산과 I/O 연산

컴퓨터가 연산을 한다는 것은 CPU가 무언가 일을 한다는 뜻이다.

  • 입출력 장치들의 I/O 연산: 입출력 컨트롤러가 담당
  • 컴퓨터 내에서 수행되는 연산: 메인 CPU가 담당

로컬버퍼(local buffer)

장치 컨트롤러는 장치로부터 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리를 가지고 있다.

  1. 프로그램A가 디스크에서 데이터를 읽어오라는 명령 발생
  2. 디스크 컨트롤러가 물리적인 디스크에서 내용을 읽어 이를 로컬 버퍼에 저장한다.
  3. 다 읽으면 다음 일을 수행

이때 메인 CPU가 지속적으로 체크하는 것이 아니고 장치에 있는 컨트롤러가 인터럽트를 발생시켜 CPU에 보고.

CPU는 매 시점 메모리에서 명령을 하나씩 읽어와서 수행한다. 이때 CPU옆에는 인터럽트 라인이 있어서

  1. CPU가 자신의 작업을 하던 중간에 인터럽트 라인에 신호가 들어오면
  2. 하던 일을 멈추고 인터럽트와 관련된 일을 처리

CPU는 명령 하나를 수행할 때 마다 인터럽트가 발생했는지 확인한다. 인터럽트가 발생했으면 다음 명령을 수행하기 전에 인터럽트를 처리하게 되고, 그렇지 않으면 다음 명령을 계속 수행한다.


인터럽트의 일반적인 기능

  • 운영체제 커널에는 인터럽트가 들어왔을 때 해야 할 일이 미리 다 프로그래밍 되어 그 코드가 보관돼 있다.
  • 운영체제는 각종 하드웨어 및 소프트웨어 자원 뿐 아니라 사용자 프로그램에 필요한 서비스도 제공한다.

인터럽트 처리루틴

다양한 인터럽트에 대해 각각 처리해야할 업무들을 정의하고 있다.

하드웨어 인터럽트

  • 컨트롤러 등 하드웨어 장치가 CPU의 인터럽트 라인을 세팅한다.

CPU 어딘가 인터럽트를 받아들일 공간이 필요하다.

소프트웨어 인터럽트

  • 소프트웨어가 그 일을 수행한다.

CPU 옆에 있는 인터럽트 라인에 신호를 보내서 인터럽트가 발생했음을 알려주는 방식은 둘 다 동일하다.

위에서 계속 언급했던 것 처럼 인터럽트가 발생하면 CPU는 하던 일을 멈추고 운영체제 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾게 된다. 운영체제는 할 일을 쉽게 찾아가기 위해 인터럽트 벡터(Interrupt Vector)를 가지고 있다.

인터럽트 벡터

인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야 할 코드가 위치한 부분을 가리키고 있는 자료구조를 말한다.

실제 처리해야할 코드는 인터럽트 처리루틴 또는 인터럽트 핸들러라고 불리는 다른 곳에 정의된다.

소프트웨어 인터럽트 = Trap

  • 인터럽트 = 하드웨어 인터럽트
  • 트랩(trap) = 소프트웨어 인터럽트
  1. 예외상황(Exception)

    비정상적인 작업을 시도하거나, 자신의 메모리 영역 바깥에 접근하려는 시도 등 권한이 없는 작업을 시도할 때 이에 대한 처리를 위해 발생시키는 인터럽트를 말한다.

  2. 시스템 콜(System call)

    사용자 프로그램이 운영체제 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청하는 방법

    운영체제 커널에 있는 코드를 사용자 프로그램이 실행하고자 할 때에는 인터럽트 라인 세팅을 통해 CPU 제어권을 운영체제로 넘겨 실행하게 되는 것이다.

    예를 들어 화면의 입출력이 필요한 경우 이미 존재하는 커널의 코드를 호출해서 처리한다.

예외상황과 시스템 콜 둘다 CPU의 제어권이 운영체제로 이양된다는 공통점이 있다.

질문1) 하드웨어 인터럽트와 소프트웨어 인터럽트 하는일 이해가 안감, 라인셋팅이 무엇인가요?

질문2) 그럼 이양 안될때는 언제인가요?

  • 프로그램이 제어를 하면 안되는 것들 다른 프로그램을 컨트롤 하기 위해 그거 빼고는 프로그램이 CPU의 제어권을 가지고 있다.

인터럽트 핸들링

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

프로그램 A가 실행되고 있을 때 인터럽트가 발생하면 A의 현재 상태를 먼저 저장한다.

(현재상태: cpu에서 실행중인 명령의 메모리 주소를 포함하해 몇 가지 부가적인 정보들을 의미한다. )

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

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

PCB

PCB는 각각의 프로그램마다 하나씩 존재하며 해당 프로그램의 어느 부분이 실행 중이었는지를 저장하고 있다.

프로그램 실행 중, 인터럽트가 발생하게 되면

  1. 프로그램이 실행중이던 코드의 메모리 주소와 레지스터 값, 하드웨어 상태 등이 저장 = PCB에
  2. CPU의 제어권이 인터럽트 처리루틴으로 넘어감
  3. 인터럽트 처리가 끝나면 저장된 상태를 PCB로부터 CPU상에 복원에 인터럽트 당하기 직전의 위치부터 실행이 이어지게 된다.

입출력 구조

동기식 입출력(Synchronous I/O)

어떤 프로그램이 입출력요청을 했을 때 입출력 작업이 완료된 후에야 그 프로그램이 후속 작업을 수행할 수 있는 방식을 말한다.

  • CPU는 입출력 연산이 끝날 때 까지 인터럽트를 기다리며 자원을 낭비하게 된다.
  • CPU를 다른 프로그램에게 이양해 CPU가 계속 쉬지 않고 일할 수 있도록 관리한다.

프로그램 A가 가 cpu를 할당받고 명령을 수행하다가 다른 곳에서 입출력 요청이 온다면 B에게 다시 할당한다. 그러면 B는 cpu를 할당받아 일을 하게 되고 자원을 낭비하지 않는다. 프로그램 A의 입출력이 완료될 때 까지 a에게는 cpu를 다시 할당하지 않는다. 어차피 다시 할당하더라도 입출력속도가 상대적으로 느려 명령을 수행하지 못하기 때문이다. a는 "봉쇄상태(Blocked state)"

  • 하지만 입출력이 수행중일 때 다른 프로그램과 같은 곳에서 연산이 겹치게 된다면 의도하지 않은 결과를 초래한다.
  • 이를 막기 위해 동기식 입출력에서는 입출력의 요청의 동기화를 위해 장치별로 큐를 두어 요청한대로 처리할 수 있도록 한다.

동기성을 보장하기 위해 장치마다 큐를 두어 요청된 순서대로 처리할 수 있도록 한다.

비동기식 입출력

CPU의 제어권을 입출력 연산을 호출한 그 프로그램에게 곧바로 다시 부여하는 방식

어떤 프로그램 데이터를 디스크에서 읽어오라는 요청을 했을 때 보통은 읽어온 결과를 이용해서 다음 연산을 수행하지만 경우에 따라서는 그 데이터와 관련 없이 수행할 수 있다. 비동기식 입출력에서는 그러한 작업을 먼저 수행하고, 읽어오는 데이터가 반드시 있어야 수행할 수 있는 일들은 입출력이 완료된 후에 수행하게 된다.

동기식 입출력과 비동기식 입출력의 비교

프로그램 A가 실행중 : 디스크에서 어떤 데이터를 읽어오는 명령

  1. 시스템 콜을 통해 CPU에게 일종의 소프트웨어 인터럽트를 발생
  2. CPU는 지금까지 포로그램 A의 코드를 실행하던 일을 멈추고 현재의 상태를 저장한 후(PCB) 인터럽트에 의해 처리해야 할 커널의 루틴으로 이동한다(인터럽트 처리루틴)
  3. 처리루틴으로 이동하면 CPU는 컨트롤러에게 입출력 연산을 요청한다.
  4. 컨트롤러는 A가 요청한 데이터를 디스크로부터 자신의 로컬버퍼로 읽어온다. 읽어오는 동안에 프로그램 A는 CPU를 다시 할당 받지 못하게 된다.
  5. 운영체제는 A를 봉쇄상태로 표시
  6. CPU를 다른 프로그램 B에게 할당해 계속 CPU까 일할 수 있도록 한다.
  7. 원하는 정보가 로컬버퍼로 다 들어오면 컨트롤러는 CPU에게 입출력이 완료되었다는 사실을 인터럽트를 발생시켜 알린다.
  8. 프로그램 B를 수행중이던 CPU는 수행하던 지점 몇 상태를 저장해놓고 인터럽트를 처리하게 된다.
  9. 인터럽트 처리루틴은 로컬버퍼에 있는 A가 요청한 데이터를 A의 메모리 영역으로 읽어오고 A의 봉쇄 상태를 해제시켜 A에게 다시 CPU를 할당해도 됨을 표시한다.

질문3) 소프트웨어 인터럽트는 무조건 시스템콜, 예외상황 밖에 없는건가요 ?

  • 비동기식 입출력은 현대에 중요하지 않고, 입출력자체는 별로 안중요함

DMA(Direct Memory Access)

메모리에 접근할 수 있는 방법

  1. CPU에 의해서만 접근 가능

    • 인터럽트 발생시키기: cpu는 컨트롤러의 로컬버퍼와 메모리 사이에서 데이터를 옮기는 일
    • 메모리 접근 연산이 CPU에 의해서만 이루어질 경우 입출력 장치가 메모리 접근을 원할 때 마다 인터럽트에 의해 CPU의 업무가 방해를 받게 되어 CPU 사용의 효율성이 떨어지는 문제점 발생
    • 이러한 비효율성을 극복하기 위해 CPU 이외의 메모리 접근이 가능한 장치를 하나 더 둔다.
  2. DMA(Direct Memory Access)

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

DMA를 사용하게 되면 로컬 버퍼에서 메모리로 읽어오는 작업을 CPU까 담당하는 것이 아니라 DMA가 대행함으로써 CPU는 원래 하던 작업을 멈추고 인터럽트를 처리할 필요가 없어지는 것이다. 우왕 굿!

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

저장장치의 구조

주기억장치

메모리라고 부르며 전원이 나가면 저장되었던 내용이 모두 사라져버리는 휘발성의 RAM을 매체로 사용

보조기억장치

전원이 나가도 저장된 내용을 기억할 수 있는 비휘발성의 마그네틱 디스크

보조기억장치의 용도

  1. 파일시스템 용

    전원이 나가도 유지해야할 정보가 있으면 그것을 파일 형태로 보조기억 장치에 저장

  2. 메모리의 연장 공간인 스왑 영역

    • 스왑 아웃: 프로그램 수행에 당장 필요한 부분만 메모리에 올려놓고 그렇지 않은 부분은 디스크의 스왑 영역에 내려놓게 된다.
    • 스왑 영역은 프로그램이 실행딜 때 내용을 저장했다가 프로그램이 종료될 때 삭제하는 메모리의 연장 공간으로서의 역할

저장장치의 계층 구조

컴퓨터 시스템은 빠른 저장장치부터 느린 저장장치까지 단계적인 계층 구조로 이루어진다.

레지스터 < 캐시메모리 < 메인메모리 < 마그네틱 디스크 < 광디스크 < 마그네틱 테이프

캐시메모리는 레지스터와 메인 메모리 사이에 존재하며 가격적인 측면에서는 메인 메모리보다 비싸다 그러나 여러가지 캐싱 기법을 이용해 적은 용량의 캐시 메모리를 사용해서도 메인 메모리와 같이 큰 용량을 가진 것 처럼 효율적으로 동작하도록 관리할 수 있다.

캐싱기법

상대적으로 적으로 용량이 적은 빠른 저장장치를 이용해 느린 저장장치의 성능을 향상시키는 총체적 기법


하드웨어의 보안

운영체제는 다중 프로그래밍 환경에서 동작한다 그래서 프로그램이 다른 프로그램의 실행을 방해하거나 충돌을 일으키는 문제를 막기 위해 보안 기법이 필요하다.

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

커널모드

운영체제가 CPU의 제어권을 가지고 운영체제 코드를 실행하는 모드

  • 중요한 정보에 접근해 위험한 상황을 초래할 수 있는 연산을 할 때
  • 근데 사용자 프로그램이 프로그램 내에서 위험한 종류의 연산을 수행해버리면 제어가 아무런 소용이 없게 된다. 사용자 프로그램이 CPU를 가지고 있는 동안에는 운영체제가 자신의 코드를 실행하지 못하므로 사용자 프로그램을 감시할 방법이 없기 때문이다.
  • 하드웨어 적인 지원이 필요하다

모드비트(Mode Bit)

컴퓨터 시스템은 CPU 내부에 모드비트를 두어 사용자 프로그램을 감시하게 된다.

  • 모드비트 0: 커널모드
  • 모드비트 1: 사용자모드

CPU는 보안과 관련된 명령(특권명령)을 수행하기 전에는 항상 모드비트를 조사해 그 값이 0으로 세팅된 경우에만 그 명령을 수행한다.

모드비트 세팅

  • 운영체제가 CPU를 점유해 자신의 코드를 수행하다가 사용자 프로그램에게 CPU의 제어권을 넘길 때 모드비트를 1로 세팅해 넘기게 된다.
  • 사용자 프로그램이 수행되다가 하드웨어 접근 등 보안이 필요한 중요한 명령을 수행해야 할 경우에는 시스템 콜을 통해 운영체제가 대신해줄 것을 요청한다.
  • 인터럽트가 발생 될 때 모드비트는 자동으로 0이 세팅된다.
  • 특권명령은 커널모드에서 운영체제에 의해서만 수행할 수 있는 것이다.

자신의 소유가 아닌 다른 사람의 파일에 접근할 수 있기 때문에 입출력 명령은 특권 명령으로 규정해 사용자 프로그램이 직접 입출력을 하는 것을 차단한다.

  1. 프로그램은 시스템 콜로 운영체제에 요청
  2. 운영체제가 CPU를 할당받음
  3. 인터럽트 벡터의 특정 위치를 통해 해당 인터럽트 처리루틴으로 이동
  4. 입출력이 완료되면 CPU의 제어권을 다시 사용자 프로그램에게 넘긴다.

질문4) 시스템 콜은 무조건 CPU 제어권이 커널 즉 운영체제 인데 비동기성에서는 어떻게 인터럽트를 발생시키나요?


메모리 보안

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

특히 인터럽트 벡터와 인터럽트 처리 루틴이 있는 곳은 각별한 보안이 필요하다.

메모리 보안 방법

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

1. 기준 레지스터 (Base Register)

어떤 프로그램이 수행되는 동안 그 프로그램이 합법적으로 접근할 수 있는 메모리상의 가장 작은 주소를 보관

2. 한계 레지스터 (Limit Register)

그 프로그램이 기준 레지스터값부터 접근할 수 있는 메모리의 범위 보관

메모리 접근 연산이 있을 때 마다 하드웨어적으로 현재 접근하려는 위치가 합법적인 범위에 있는지 체크하게 된다.

접근 하려는 주소가 이 범위 안에 없으면 불법적인 메모리 접근으로 예외상황이라는 일종의 소프트웨어적인 인터럽트가 발생하게 된다!

예외상황

  1. 운영체제에 소프트웨어 인터럽트를 발생시켜 CPU의 제어권을 운영체제로 이양
  2. 예외상황을 발생시킨 프로그램을 강제로 종료시킨다.

이 메모리 보호 기법은 하나의 프로그램이 메모리의 한 영역에 연속적으로 위치하는 단순화된 메모리 기법을 사용하는 경우에 한정된 설명이다.

하나의 프로그램이 메모리의 여러 영역에 나뉘어 위치하는 페이징 기법 등에 대해서도 살펴보게 될거다.

사용자 모드 : 기준 레지스터와 한계 레지스터를 사용해 메모리를 보호

커널 모드 : 무제한 접근 가능, 특권명령 x

하지만 레지스터의 값을 세팅하는 연산은 특권명령으로 규정한다.

질문5) 프로그램이 연산? 실행할 때 CPU가 실제 메모리에 프로그램이 떠 있는지 확인한 후 실행하는 게 맞나요?


CPU 보호

프로그램의 CPU 독점을 막기 위해 운영체제는 타이머(Timer)라는 하드웨어를 사용한다.

타이머 (Timer)

정해진 시간이 지나면 인터럽트를 발생시켜 운영체제가 CPU의 제어권을 획득할 수 있도록 하는 역할

  • 시분할 시스템에도 사용

profile
훌라도 하고 개발도 하는 사람

0개의 댓글