OS - 시스템 구조, 프로그램 처리

컴퓨터 시스템 하드웨어 구조

OS_2_1 simple

오른쪽은 Input/Output 장치들이다.

InputI/O디바이스의 data를 CPU로 가져오는것,
Output은 CPU에서 처리한 data를 I/O디바이스로 내보내는것.

CPU는 매 클럭 사이클마다 메모리에서 기계어를 읽어 실행한다.
I/O작업은 별개의 디바이스들이 임무에 따라 수행한다.

  • 키보드는 Input 장치
  • 모니터와 프린터는 Output 장치
  • 디스크는 Input & Output 장치
    Data를 읽어 메모리에 넣기도, 결과를 저장하기도 하기 때문에

좀 더 자세히 표현하면 아래와 같다.

OS_2_3 simple

각 구성장치에대해 간략히 설명하면 아래와 같다.

Device Controller

device를 전담하는 작은 CPU
disk 에서 헤드가 어떻게 움직이고 어떤 데이터를 읽을지는 Device Controller(Disk Controller)가 전담한다.
CPU는 그저 메모리에서 매 클러마다 Instruction 을 읽어 Device Controller 에 전달만 할뿐 따로 device 에 직접 명령을 내리지 않는다.

Local Buffer

device 전용 작업 공간 CPU의 작업공간인 메인 메모리가 있듯이 디바이스에도 전용 작업공간인 Local Buffer 가 존재한다.

CPU와 I/O디바이스는 속도차이가 많이 난다.
입출력 작업이 끝나면 CPU는 device 의 Local Buffer에 들어가 내용물을 메모리에 copy 해온다.

CPU Registers

CPU 의 기계어 고속연산시 필요한 빠르고 작은 저장소
Program counter, mode bit 등.

Mode bit

실행되는것이 운영체제(모니터 모드, 커널모드)인지 사용자 프로그램(사용자모드) 인지 구분해주는 것,
모드에 따라 사용할 수 있는 기계어는 제한된다.

즉 사용자 프로그램은 잘못된 수행(나쁜짓)이 가능할 수 있기에 이를 위한 보호 장치가 필요하다. 그게 Mode bit

항상 CPU는 Instruction 실행 전에 Mode bit 를 확인 후 실행 가능한지 못한지를 판별한다.

  1. 사용자 모드
    사용자 프로그램 수행, 제한된 Instruction 만 실행가능, 보안상의 목적, 메모리 접근은 가능해도 디바이스 접근은 불가능하다, 접근 가능한것도 제한이 있을 수 있다.
  2. 커널모드
    커널 프로그램 수행, 운영체제가 CPU에서 실행중일 때, 모든 명령어를 다 허용한다, 메모리 접근, I/O디바이스 접근 등의 Instruction 허용

Program counter(PC)

다음번에 실행할 명령의 주소를 가지고 있는 CPU의 레지스터

인터럽트 발생 시 인터럽트 당한 시점의 Program Counter 와 레지스터와를 별도의 공간에 Save한 후
CPU 제어를 인터럽트 처리루틴(광범위하게 말하면 OS)에게 넘긴다.

이때 PC는 OS의 주소 위치를 가르키게 된다.

Interrupt Line

CPU는 항상 메모리에 저장된 Instruction 을 지속적으로 실행하는데
그렇다면 키보드에서 뭔가 들어 왔다던가, 디스크가 일을 다 끝낸 것을 어떻게 아느냐?

바로 Interrupt Line을 검사한다.

CPU는 하나의 Instruction이 끝나면 항상 Interrupt Line 을 검사한다.

예를 들어 프로그램A 가 실행 중에 scanf 나 disk에서 데이터 I/O 작업 요청을 메모리에 집어넣어 놓으면 CPU는 이 명령을 보고 Device Controller 게 프로그램A 가 요청했던 작업을 하도록 시킨다.

일을 시켜놓으면 disk 는 요청한 데이터 I/O 결과를 로컬 버퍼에 집어넣는다.
그런데 이 작업은 굉장히 오래 걸려서 CPU가 기다리지 않고 Memory에서 바로 다음 Instruction을 꺼내 수행한다.

만약 프로그램A가 수행한 I/O 결과 없이는 다음 명령실행이 불가능 할 경우
프로그램B로 CPU제어권이 넘어가게 된다.

이후 느린 I/O 작업이 완료되면 Deviec ControllerInterrupt Line에 통지한다,

“나 일다 끝났음”

다시 CPU는 Interrupt Line 에 새로생긴 인터럽트(우리가 요청했던I/O작업완료)를 처리한다.

Timer

만약 무한루프를 도는 프로그램이라면 CPU는 어떻게 될까?

I/O도 아니고 순수 CPU작업이라 운영체제가 뺏어올 수 없고
뺏는것도 CPU가 필요한데 CPU는 그저 무한루프만 돌 뿐…..

이런 이유로 컴퓨터 안에는 Timer 라는 하드웨어를 두고 있다.

CPU 사용 할당시간을 두고 만료되면 CPU에게 인터럽트 요청 한다.

Timer 인터럽트, 하드웨어 인터럽트, I/O 인터럽트,
어쩃든 CPU가 인터럽트 되면 CPU사용권은 항상 OS로 가게 된다.

운영체제가 CPU를 얻게 되면 다시 Timer 를 설정하고
인터럽트 사유를 조사한 후 다음 프로세스에게 CPU제어권을 넘겨준다.

타이머가 만료되면 또 인터럽트가 들어오고 무한 반복이다…

Program

Program에 있는 명령은 CPU가 실행하는 것 만 있을까?

분명 가끔은 disk 에서 데이터도 읽어오고 쓰고,
키보드에서 입력받는 등의 I/O작업도 할 것 이다.

이럴 때 Timer 를 기다리지 않고 I/O 처리를 위해 OS에게 CPU제어권을 자진 반납한다

보안상의 이유로 사용자 프로세스에서 device 에 직접접근 못하고 OS를 통해서만 접근 가능하다
System Call 이라한다

OS는 CPU에게 해당 프로세스에게 I/O 작업이 필요하다고 에 알리고 다음 프로세스에게 제어권을 넘긴다.
그럼 I/O 요청을 한 프로그램은 언제 다시 CPU제어권을 얻게 되느냐?

Device Controller 에서 I/O작업이 끝나면 컨트롤러가 인터럽트를 걸 것이고
OS로 제어권이 넘어가고 OS는 인터럽트를 살펴보고 요청한 프로세스 메모리 공간에 Local Buffer를 카피 해주고 프로세스는 CPU제어권을 가질 자격을 얻는다.

바로 해당 프로세스에 제어권이 넘어가는 것이 아니라 일단 CPU가 실행 중이었던 프로세스의 할당시간이 끝날 때까지는 기다리고 제어권을 넘겨준다.

각종 인터럽트에 의해 언젠가는 I/O작업이 끝난 프로그램이 제어권을 갖게 될 것이다.

DMA(Direct Memory Access) Controller

Device Controller 가 하는 역할을 아래와 같았다.

  • I/O장치를 전담하는 일종의 작은 CPU(device용), 펌웨어에 의해 작동됨
  • 제어 정보를 위해 Control Register, Status Register를 가짐
  • Local Buffer를 가짐

키보드를 입력하면 컨트롤러가 Local Buffer 에 저장해 놨다 CPU 인터럽트 CPU 가 모니터에 출력할 데이터를 Local Buffer 에 저장해놓고 컨트롤러에 지시를 내려 출력 CPU 가 디스크에 저장할 데이터를 Local Buffer 에 넣고 컨트롤러에 명령을 내려 디스크에 저장

근데 이렇게 I/O 디바이스마다 CPU를 인터럽트 하고 CPU 도 컨트롤러에 많은 명령을 내리는데
CPU가 너무 혹사당하느것 같다고 생각하지 않나?

그래서 사용하는게 DMA Controller(Direct Memory Access) 이다.

원래 메모리에 접근가능한건 CPU 뿐이였는데 DMA 도 메모리를 접근하게 하는것이다.

그림을 보면 Memory Controller 도 있는데 이는 DMA와 CPU가 동시에 접근하면 충돌되니 이를 제어하는 역할을 하고있다.

즉 CPU는 Memory Controller 를 통해 메모리도 접근할 수 있고
각 디바이스의 로컬 버퍼도 접근가능하고 컨트롤러에 명령도 내린다.

키보드 한번 치면 Deviec Controller 는 인터럽트 걸어서 CPU 제어권 OS로 넘어가게 하고
OS는 로컬버퍼 접근해서 Data를 메모리로 이동시켜주고
I/O요청을 했던 프로세스의 것이라면 프로세스 상태도 Ready로 바꿔주고

복잡한 작업들이 DMA가 생기면 간단하게 바뀐다.

Local Buffer 에 작업이 다 되서 데이터가 준비되면
인터럽트 걸지 않고 DMA 가 data를 바로 Memory 까지 이동시켜준다.

다 옮기면 보고용으로 인터럽트 하나걸고… 굉장히 효율적!!!
구성이 아래 그림처럼 바뀐다.

OS_2_3 simple

Device Driver(장치 구동기)

드라이버는 소프트웨어이다, OS가 Ddevice Controller에게 부탁하는 방법이 적혀있는 코드가 Device Driver라 보면 된다
OS 커널의 가장 아랫단에 존재한다.

device 에 접근하기 위해 device 별로 다른 디바이스 인터페이스가 있는데
그거에 맞게해 접근할수 있게 해주는 소프트웨어 모듈 이다.

그렇다고 Device Driver가 디스크 헤드를 움직이는 코드는 아니다.
디스크 컨트롤러가 CPU명령에 맞춰 disk 안 펌웨어라는놈을 실행하는데 이놈이 헤드를 움직이는 코드이다.

System call

I/O device 에 접근하는 것은 모두 커널모드에서 수행 된다.

즉 I/O device 는 커널모드 수행이 가능한 OS 만 접근 가능하단 뜻이고
사용자 프로그램도 OS 에 I/O 수행을 대신해서 수행할 수 있도록 부탁해야 한다.

사용자 프로그램이 OS에게 하는 부탁을 System call 이라한다.

지금까지 Deviec Controller 에서 CPU를 인터럽트 하는 걸 배웠는데
프로세스도 이런 식으로 System Call을 처리한다.
프로세서에서 직접 Interrupt Line 을 설정하는 Instruction을 실행한다.

이 명령이 실행되면 Mode bit는 0이되고 운영체제에게 제어권이 넘어가고 운영체제는 System Call을 받았기에 입출력을 대신 수행한다.

과정은 아래와 같다.

  1. 프로세스가 System Call을 통해 I/O를 OS에게 요청(인터럽트 발생)
  2. OS는 Device Driver 를 통해 일을 시킨다
  3. OS는 CPU 제어권을 다른 프로세스에게 넘긴다(I/O요청은 오래 걸리니까)
  4. 다른 프로세스 수행 중 Deviec Controller 가 I/O작업을 끝내면 인터럽트 신호를 보낸다(인터럽트 발생)

즉 프로세스가 I/O요청을 하게 되면 CPU는 두 번 인터럽트 된다.

Interrupt

인터럽트는 2가지로 나뉜다.

  • Hadware Interrupt(하드웨어가 발생시킨 인터럽트)
  • Trap(소프트웨어가 발생시킨 인터럽트)

Hadware InterruptTimer Interrupt가 있고
트랩은 소프트웨어(프로세스)가 발생시킨 오류? 혹은 요청 이다.

System CallTrap 이라 부를 수 도 있겠다.

참고로 Device Controller가 I/O작업이 끝나서 Interrupt하는 것은 하드웨어 인터럽트다.

Trap의 종류

  • Exception: 0으로 나누기, 잘못된 메모리접근
  • System Call: 프로그램이 커널 함수를 호출하는 경우(I/O 요청같은)

인터럽트 백터

해당 인터럽트의 처리 루틴 주소를 가지고 있는 테이블.
인터럽트 종류마다 어느함수를 실행해야 하는지 테이블 형식으로 함수의 주소를 갖고 있다.

인터럽트 처리 루틴(Interrupt Service Routine)

인터럽트 핸들러 라고도 함. 해당 인터럽트를 처리하는 커널 함수.

이걸 보면 현대의 운영체제는 인터럽트 위에서 구동된다고 볼 수 있다.

운영체제는 일반적으로 CPU제어권을 가질 일이 없다, 그저 인터럽트에 의해 어쩔 수 없이 갖게 되는 경우가 대부분이다.

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

한국어로 번역된 이상한 말이지만 이해해보자. 싱크란 여럿이 같이 무언가를 함에 있어 조율을 통해 시간이 딱딱 맞아 떨어지도록 되는것이다.

사용자 프로그램이 CPU를 통해 IO요청을 하면서 싱크를 하냐 안하냐 차이이다.

동기식 입출력

사용자 프로그램이 CPU에게 I/O요청을 한후 I/O작업이 완료되고 다시 사용자 프로그램에 제어가 넘어가 차례차레 진행되는 방식이다.

비동기식 입출력

사용자 프로그램이 CPU에게 I/O요청을 한후 결과와 상관없이 바로 다음 일을 진행하는 형식, 아래 그림과 같은 차이가 있다.

일반적으론 동기식 작업 방식이 당연하다고 생각 되겠지만 아닌경우도 더러 있다.
예로 ‘파일에 무언가를 써라’ 같은 명령이 있을시에는 쓰라는 I/O요청만 해놓고 작업 완료 결과 상관 없이 바로 다음 작업으로 넘어 갈 수 도 있지 않나? 꼭 확인하나 안하나 차이이다.

물론 동기식 입출력도 Waiting하는 시간동안 CPU가 노는게 아니라 다른 사용자 프로세스나 인터럽트를 처리할 것이다.

OS_2_4 simple

서로다른 입출력 기계어

OS_2_4 simple

I/O를 수행하는 기계어는 2가지 종류가 있다.

I/O 전담 기계어가 있는 경우와 그런 거 없는 경우.

왼쪽 그림은 CPU에서 디스크에서 무엇을 읽어 와라라는 기계어를 실행할 때 메모리에 접근하는 기계어종류, 디바이스에 접근하는 기계어 종류가 따로 나뉘어 있다.

오른쪽 그림은 메모리 접근하는 기계어로 디바이스까지 접근하는 그림이다. 그냥 알아만 두자.

OS_2_4 simple

캐싱이란 말 들어봤을 것이다. 위로 갈수록 비싸고 작기 때문에 데이터 보관은 아래쪽에 한다.

하지만 항상 아래 찍고 위로 오기엔 시간이 많이 걸리니 자주 쓰는 데이터는 위쪽에 저장해 놓고 운 좋게 위쪽에서 다시 쓸 수 있게 되는 것 을 Caching이라 한다.