OS는 할껀데 핵심만 합니다. 1편 개요와 컴퓨터 구조

8

OS

목록 보기
1/17

운영체제

1. 운영체제 필요성과 목표

  1. 자원 관리(효율성)

    1. 응용 프로그램에게 키보드 ,네트워크 카드, 사운드 카드, 메모리등의 자원을 할당해준다.
    2. 또한, 적절한 시점에 자원을 회수하고, 적당한 순서로 자원을 배분한다.
  2. 자원보호(안정성)

    1. 악의적인 사용자에 대해서 컴퓨터의 자원을 보호한다.
    2. 비정상적인 작업으로부터 컴퓨터의 자원을 보호하는 것이다.
    3. 만약 문제가 발생하면 이전으로 복구하는 fault tolerant 한 기능을 수행해야 한다.
  3. 하드웨어 인터페이스 제공(확장성)

    1. cpu, 메모리, 키보드, 마우스 등과 같은 다양한 하드웨어를 일관된 방법으로 사용할 수 있도록 지원한다.
    2. os가 이들을 위한 하드웨어 인터페이스를 지원하기 때문이다.
    3. 하드웨어 인터페이스 지원은 드라이버를 컴퓨터에 설치해야 가능하고, 운영체제가 자동으로 설치되게 함으로서 하드웨어의 종류와 상관없이 사용할 수 있게 해준다.
    4. 꼳으면 바로 실행 가능한 plug&play 기능을 제공해야 한다.
  4. 사용자 인터페이스 제공(편리성)

    1. 하드웨어 인터페이스는 다양한 하드웨어를 OS에서 제어할 수 있는 것을 말하고, 사용자 인터페이스는 유저가 OS를 편리하게 사용할 수 있도록 지원하는 것이다.
    2. 대표적으로 윈도우의 GUI 등이 있으며, 터미널 , CMD 도 마찬가지이다.

위의 운영체제의 필요성은 운영체제의 목표와 결부된다.

  1. 자원 관리 --> 효율성
  2. 자원 보호 --> 안정성
  3. 하드웨어 인터페이스 제공 --> 확장성
  4. 사용자 인터페이스 제공 --> 편리성

2. 운영체제의 구조

2.1 커널과 인터페이스

  1. 커널 : 프로세스 관리, 메모리 관리, 저장장치 관리와 같은 운영체제 핵심적인 기능을 모아놓은 곳이다. 커널의 성능이 곧 운영체제의 성능이다.

  2. 인터페이스 : 커널에 사용자 명령어를 전달하고, 실행결과는 사용자에게 알려주는 역할을 한다.

커널과 인터페이스를 분리하였기 때문에, 같은 커널 다른 인터페이스가 가능하다. 가령, 유닉스의 인터페이스는 shell이지만 유닉스의 커널을 가져와 인터페이스만 달리하여 GUI를 만들 수 있다.

2.2 시스템 호출과 디바이스 드라이버

  1. 시스템 호출(system call) : 커널이 자신을 보호하기 위해 만든 함수의 집합인 인터페이스로 사용자나 응용 프로그램으로부터 컴퓨터 자원을 보호하기 위해 자원에 직접 접근하는 것을 차단한다. 따라서, 자원을 이용하려면 시스템 호출이라는 커널 인터페이스를 이용해야 한다.

  2. 드라이버 : 커널과 하드웨어의 인터페이스로, 커널은 단순한 입출력 기능만 제공한다. 이외의 하드웨어 특화된 소프트웨어들은 하드웨어 제작자에게 받아 실행하도록 하는데, 이 소프트웨어를 드라이버라고 부른다.

3. 커널의 구성

커널은 운영체제의 핵심으로, 프로세스 관리, 메모리 관리, 파일 시스템 관리, 입출력 관리, 프로세스 간의 통신(IPC) 관리 등을 한다.

핵심 기능설명
프로세스 관리프로세스에 CPU를 배분하고 작업에 필요한 제반 환경을 제공한다.
메모리 관리프로세스에 작업 공간을 배치하고 실제 메모리보다 큰 가상 공간을 제공한다.
파일 시스팀 관리데이터를 저장하고 접근할 수 있는 인터페이스를 제공한다.
입출력 관리필요한 입력과 출력 서비스를 제공한다.
프로세스 간 통신 관리공동 작업을 위한 각 프로세스 간 통신 환경을 지원한다.

3.1 커널의 종류

  1. 단일형 구조 커널

하나의 커널에 모든 기능들을 다 넣어놓은 것으로, 성능은 좋지만 하나의 시스템에서 발생한 문제가 전체 시스템에 영향을 미치고, 개발이 어렵다는 단점이 있다. 또한, 수정이 어렵다.

즉, c언어의 main에 모든 function들을 다 담아 놓은 것이다.

  1. 계층형 구조 커널

계층형 구조 커널은 비슷한 기능을 가진 모듈을 묶어서 하나의 계층으로 만들고, 계층 간의 통신을 통해 운영체제를 구현하는 방식이다.

비슷한 기능을 모아 모듈화했기 때문에 버그나 오류를 쉽게 처리할 수 있다. 대부분의 OS가 이 구조로 이루어져 있다.

  1. 마이크로 구조 커널

계층형 구조에서 코드가 점점 무거워져 커널 소스가 방대해짐에 따라 오류를 처리하기 어려워졌고, 이를 해결하기위해 만들어진 커널이 바로 마이크로 구조 커널이다.

마이크로 구조 커널은 프로세스 관리, 메모리 관리, 프로세스 간 통신 등 가장 기본적인 기능만을 제공한다. 파일시스템, 프로세스 관리, 하드웨어 관리 등 많은 부분들이 사용자 영역에 구현되어있다.

대표적으로 마하가 OS X와 IOS 커널로 사용되어 유명해졌다.

4. 기본적인 컴퓨터 구조

오늘날의 컴퓨터는 대부분 폰노이만 구조를 따른다. 폰노이만 구조는 CPU, 메모리, 입출력장치, 저장장치가 버스로 연결되어 있는 구조를 말한다.

이 구조가 등장하기 이전에는 하드와이어링 형태로 전선 연결을 계속바꾸는 형태였다.

https://semiengineering.com/knowledge_centers/compute-architectures/von-neumann-architecture/

이러한 문제를 해결하기 위해 폰노이만은 메모리를 이용하여 프로그래밍이 가능한 컴퓨터 구조, 즉 하드웨어는 그대로 둔 채 작업을 위한 프로그램만 교체하여 메모리에 올리는 방식을 고안했다.

폰노이만 구조의 가장 큰 핵심은 모든 프로그램은 메모리에 올라와야 실행할 수 있다는 것이다.

4.1 CPU의 구성

CPU는 크게 3가지 구성으로 이루어져있는데 산술논리 연산장치, 제어장치, 레지스터 이다.

  1. 산술논리 연산장치
    CPU가 데이터를 연산하는 장치로, 덧셈 , 뺄셈, 곱셈, 나눗셈과 같은 산술 연산과 AND, OR와 같은 논리 연산도 수행한다.

  2. 제어장치
    cpu에서 작업을 지시하는 부분을 제어장치라고 한다.

  3. 레지스터
    cpu내의 데이터를 임시로 보관하는 곳으로 레지스터라고 한다. 저장 장치의 속도 순서로 레지스터 > 메모리 > 하드디스크 지만, 용량은 정반대이다.

4.2 CPU 명령어 처리 과정

산술논리 연산장치, 제어장치, 레지스터를 이용해 어떻게 컴퓨터가 명령어를 처리하는 지 알아보자

int sum;
int a = 2, b =3;
sum = a + b;

위 코드를 어셈블러로 변환한 다음, 기계어로 바뀌어야 기계가 인식할 수 있다.

LOAD mem(100), register 2;
LOAD mem(120), register 3;
ADD register 5, register 2, register 3;
MOVE register 5, mem(160);

LOAD로 메모리 100 번지에 있는 값을 레지스터 2로 가져온다는 의미이다. 메모리 100번지에는 변수 a의 값인 2가 있다고 하고 120번지에는 변수 b의 값인 3이 있다고 하자
ADD를 통해 register 2 ,3의 값을 더하고 register 5에 저장한다.
MOVE 명령어를 통해 register 5의 값을 메모리 160번지(sum)로 옮긴다.

cpu가 연산을 하려면 필요한 데이터를 CPU로 가져와 임시로 보관해야한다. 이때 사용하는 장소가 레지스터이다.

제어장치는 명령어를 해석하여 제어 신호를 보내고 CPU 내의 데이터 흐름을 조절하는 역할을 한다. 위 예제에서 제어장치는 메모리에서 데이터를 가져와라, 덧셈을 실행하라, 덧셈한 결과를 메모리로 옮겨놔라 라고 명령 신호룰 보낸다.

즉, 다음과 같이, 메모리에서 100, 120번지를 읽어 레지스터로 보내는 것이 1,2 로드이다. 더하기 연산 명령어를 읽고 제어장치는 레지스터에서 2와 3번지에 있는 값을 산술 논리 연산장치에 넣고 연산하도록 한다.

연산결과는 레지스터 5번에 저장되고, MOVE 명령어를 읽고 4, 이동 화살표처럼 레지스터에게 5번 레지스터 값을 메모리 160번지에 저장하라고 지시한다.

4.3 레지스터 종류

CPU는 레지스터에 메모리에서 가져온 정보와 산술 논리 연산장치 결과의 정보를 저장한다.

이때 사용되는 레지스터는 데이터 레지스터와 주소 레지스터이다.

  • 데이터 레지스터(DR) : 메모리에서 가져온 데이터를 임시로 보관한다. CPU 내의 대부분의 레지스터가 데이터 레지스터이기 때문에 범용 레지스터, 일반 레지스터라고 불린다.

  • 주소 레지스터(AR) : 데이터 또는 명령어가 저장된 메모리의 주소는 주소 레지스터에 저장된다.

이외의 특수 레지스터는 다음과 같다. 참고로 특수 레지스터는 사용자가 임의로 변경할 수 없기 때문에 사용자 불가 레지스터라고 불린다.

  • 프로그램 카운터(PC) : 프로그램 카운터는 다음에 실행할 명령어의 주소를 기억하고 있다가 제어장치에게 알려준다.

  • 명령어 레지스터(IR) : 명령어 레지스터는 현재 실행 중인 명령어를 저장한다. 제어 장치는 명령어 레지스터에 있는 명령을 해석한 후 외부 장치에 적절한 제어 신호를 보낸다.

  • 메모리 주소 레지스터(MAR) : 메모리 주소 레지스터는 메모리에서 데이터를 가져오거나 반대로 메모리로 데이터를 보낼 때 주소를 지정하기 위해 사요ㅕㅇ한다.

  • 메모리 버퍼 레지스터(MBR) : 메모리 버퍼 레지스터는 메모리에서 가져온 데이터나 메모리로 옮겨 갈 데이터를 임시로 저장한다. 메모리 버퍼 레지스터는 항상 메모리 주소 레지스터와 함께 동작한다.

명령어 LOAD mem(100) , register 2;의 실행 과정을 통해 특수 레지스터의 살펴보자.

  1. 프로그램 카운터에는 실행 중인 코드의 행 번호(주소이지만 행번호로 대체)가 저장되고, 이 번호는 제어장치에 전송된다.

  2. 명령어 레지스터에는 명령어를 저장해야 하므로, LOAD가 탑재된다.

  3. 제어장치가 명령어 레지스터에 있는 명령어를 해석하여 메모리에 있는 데이터(mem(100))을 가져오라는 제어 신호를 보낸다.

  4. 메모리 주소 레지스터에는 100( 메모리 주소 )가 저장되고, 메모리 관리자는 메모리 100번지에 저장된 값을 메모리 버퍼 레지스터로 가져온다.

  5. 제어장치는 메모리 버퍼 레지스터에 저장된 값을 레지스터 2로 옮긴다.

위에서 언급한 레지스터 말고도 CPU에사 사용하는 레지스터들이 아주 많다. 프로그램 상태 레지스터(상태 레지스터)는 연산 결과(양수, 음수, 등)를 저장한다.

4.3 버스 종류

버스는 CPU, 메모리, 주변 장치 간에 데이터를 주고 받을 때 사용한다.

  1. 제어 버스
    제어 버스에서는 다음에 어떤 작업을 할지 지시하는 제어신호가 오고 간다. 제어신호는 CPU의 제어장치와 연결되어 있고, 제어장치의 제어 신호가 메모리와 주변 장치에 오고 간다. 또한, 메모리나 주변 장치에서도 제어 신호를 보낼 수 있는데, 이는 메모리나 주변 장치에서 오류가 발생할 시나 데이터가 왔다는 신호 등을 제어 버스를 통해 CPU로 전달하기 위함이다.

  2. 주소버스
    메모리의 데이터를 읽거나 쓸 때 어느 위치에서 작업할 것인지를 알려주는 위치 정보(주소)가 오고 간다. 하드 디스크나 메모리의 어떤 위치(주소)에 있는 데이터를 읽어 올지 또는 쓸지가 전달된다. 주소 버스는 단방향으로 CPU로 들어가는 정보는 없고, CPU가 메모리나 주변 장치를 읽기위해 주소를 요청할 수 있기는 때문이다.

  3. 데이터 버스
    주소 버스를 통해 어떤 주소를 읽을 지가 전달되면 반환으로 데이터가 버스에 실려 목적지 까지 이동한다. 데이터 버스는 메모리 버퍼 레지스터와 연결되어 있으며 양방향이다. 이는 메모리나 주변 장치는 CPU의 레지스터나 주소에 접근할 필요가 없고, 값만 주면 되기 때문에 값을 주는 방향은 양방향이다.

4.4 메모리 보호

메모리에는 프로세스들이 적재되어 실행되기 때문에 작업이 진행중인 메모리에 벗어나는 주소를 침범하는 것은 다른 프로세스에 접근하는 것이기 때문에 실행에 오류를 일으킨다.

따라서, OS 는 경계 레지스터와 한계 레지스터를 지정하여 메모리를 보호한다.

  1. 경계 레지스터 : 현재 진행 중인 작업의 첫번째 주소
  2. 한계 레지스터 : 현재 진행 중인 작업이 차지하고 있는 메모리 크기

다음과 같이 경계 레지스터 140와 + 한계 레지스터의 주소만 접근이 가능한 것이다. 만약, 두 레지스터의 값을 벗어난다면 메모리 오류를 일으켜 모든 작업을 중단 시킨다.

4.5 부팅

응용 프로그램은 운영체제가 메모리에 올려서 실행한다. 그럼 운영체제는 누가 메모리에 올려실행할까??

컴퓨터를 켰을 때 운영체제를 메모리에 올리는 과정을 부팅이라고 한다.

사용자가 컴퓨터의 전원을 켜면 ROM에 저장된 바이오스가 실행된다. 바이오스는 CPU, 메모리, 키보드 등과 같은 주요 하드웨어가 제대로 작동하는 지 확인한다.

이상이 없다면 하드디스크의 마스터 부트 레코드(MBR)에 저장된 작은 프로그램을 메모리로 가져와 실행한다.

마스터 부트 레코드는 하드디스크의 첫 번째 섹터를 말한다. 운영체제를 실행하기 위한 코드인 부트스트랩이 이곳에 저장되어 있다. 부트스트랩 코드는 운영제체를 메모리로 가져와 실행한다.

마스터 부트 레코드에 있는 부트스트랩이 메모리에 올라오면 하드디스크에 저장된 운영체제를 메모리로 불러온다.

5. 성능 향상 기술

5.1 버퍼

버퍼는 속도에 차이가 있는 두 장치 사이의 속도 차이를 완화하기 위해 도입되었다.

느린 입출력장치에서 데이터를 읽을 때마다 하나씩 전송하면 작업량에 비해 실제로 전송되는 데이터 양이 매우 작지만, 일정향의 데이터를 모아 한꺼번에 전송하면 적은 노력으로도 많은 양의 데이터를 옮길 수 있다. 이때 한 번에 모으는 곳이 버퍼이다.

하드디스크에는 메모리 버퍼가 있는데 통상 1TB, 7200rpm, 32MB로 쓰여있는데 32mb가 버퍼이다. 버퍼는 하드웨어적 개념뿐만 아니라, 소프트웨어적 개념으로도 자주쓰여 많이 사용된다.

5.2 스풀

버퍼와 유사하지만 스풀은 cpu와 입출력장치가 독집적으로 동작하도록 고안된 소프트웨어적 버퍼이다. 대표적으로 프린터가 스풀을 사용한다.

한글과 컴퓨터에서 글을 쓰고 인쇄를 한다고 하자, 만약 스풀을 사용하지 않으면 프린터에서 인쇄가 완료되기 전까지 아무일도 할 수 없다.

그런데, 스풀이 있다면 CPU는 스풀에게 명령을 맡기고 다른 작업을 할 수 있고, 스풀은 인쇄작업이 완료될 때 까지 인쇄를 수행한다.

5.3 캐시

캐시는 메모리와 CPU간의 속도차이를 완화하기위해 메모리의 데이터를 미리 가져와 저장해두는 임시저장소이다.

캐스는 필요한 데이터를 모아 한꺼번에 전달하는 버퍼의 일종으로 CPU가 앞으로 사용할 것으로 예상되는 데이터를 미리 가져다 놓는다. 이러한 작업을 prefetch이다.

즉, CPU는 메모리에 접근해야할 때 캐시를 먼저 방문하여 원하는 데이터가 있는 지 찾아본다. 캐시에서 원하는 데이터를 찾았다면 캐시 히트라고 한며, 캐시에 없다면 캐시 미스라고 한다.

캐시는 locality이론( 여러번 방문하는 메모리 주소는 또 방문하게 된다)에 근거하여 매우 효율적이다.

  • 즉시 쓰기
    즉시 쓰기는 캐시에 있는 데이터가 변경되면 메모리에 바로 반영하는 것이다.

  • 지연 쓰기
    캐시에 있는 데이터가 변경되면 즉시 메모리에 반영하는 것이 아닌, 주기적으로 모아 반영하는 방식이다. copy back이라고도 한다.

5.4 L1 캐시와 L2캐시

캐시의 레벨(단계)를 나눈 것으로 명령어 부분과 데이터 부분을 나눈 것으로 명령어 캐시, 데이터 캐시, 일반 캐시로 나뉜다.

명령어는 명령어대로, 데이터는 데이터대로 캐싱을 구현한 것이다.

참고로 저장 계층의 구조는 다음과 같다.


https://www.semanticscholar.org/paper/Joins-in-a-heterogeneous-memory-hierarchy%3A-memory-Pohl-Sattler/32ec6d9cda0e7ab81c908b9d4f904e2b39738ad6

이렇게 위로 갈수록 용량이 적고, 속도는 빠르다. 이렇게 함으로서 CPU와 저장장치 간의 병목 현상을 어느정도 해결할 수 있게되었다.

5.4 인터럽트

초기 컴퓨터는 CPU가 입출력장치에서 직접 데이터를 가져오거나 보냈는데, 이러한 방식은 매우 비효율적이었다. 따라서, 입출력 장치만 따로 관리해주고 CPU는 연산논리 일을 작동하도록 하는 것이 고안되었는데, 이것이 인터럽트방식이다.

동작 과정은 다음과 같다.

  1. CPU가 입출력 관리자에게 입출력 명령을 보냄
  2. 입출력 관리자는 명령받은 데이터를 메모리에 적재하거나, 메모리에서 저장장치로 옮긴다.
  3. 데이터 전송이 완료되면 입출력 관리자는 완료 신호를 CPU에 보낸다.

입출력 관리자가 CPU에 보내는 완료 신호를 인터럽트라고 한다. CPU는 입출력 관리자에게 작업 지시를 내리고 다른 일을 하다가 완료 신호를 받으면 하던 일을 중다낳고 옮겨진 데이터를 처리한다. 이처럼 하던 작업을 중단하고 처리해야 하는 신호라는 의미에서 인터럽트라고 불리게 되었다.

인터럽트는 CPU에서 어떤 작업이 끝냈는 지를 CPU에 알려주기 위해 인터럽트 번호를 보낸다. 인터럽트 번호는 장치의 고유 번호로 운영체제마다, 장치마다 이름이 다르다. 가령 키보드면 1, 마우스면 2번이다.

입출력 작업이 완료되었음을 CPU에 알려주는 인터럽트 외에도 다양한 종류의 인터럽트가 있다. 강제 종류 시에 CPU의 모든 일을 멈추고 데이터를 저장하기 위해 인터럽트가 발생하고, 메모리에서 실행 중인 작업이 자신에게 주어진 메모리 영역을 넘어서 작업을 하려거나, 0으로 나누려면 인터럽트가 발생한다.

0개의 댓글