: 컴퓨터 하드웨어 바로 위에 설치되는 소프트웨어 계층
=> 운영체제 개념과, 역할, 운영체제를 구성하는 각 요소 및 그 알고리즘의 핵심적인 부분에 대해 알아보자!
운영체제란?
협의의 운영체제(커널)
광의의 운영체제
=> 현대적인 방법(작업 여러개 수행될 때,, 나눠서 할당하는거)
=> 시간의 deadline 이 없음. 사람이 많으면 작업시간이 0.1초 => 1초로 늘어날 수 있음.!
=> 시분할과는 개념적으로 다름
=> 정해진 시간안에 결과가 나오는걸 보장해주는 목적이 있는 시스템
=> 영화를 보다가 끊긴다든지(soft realtime system)
=> 블랙박스(사고난 그 순간 0.5초 못찍음), 네비게이션(0.5초 있다가 우회전하라고 함): 잘 지원해야함
=> 현대적인 운영체제에서 보기 어려움 (역사 속 시스템)
=> 인터랙티브 하지 않음
=> 자료 다 ~~ 모아서 한꺼번에 처리 !
아래 4가지 용어는 비슷한 용어이지만, 어떤걸 중점적으로 바라보냐가 다름.
일반적으로, 컴퓨터에서 여러 작업을 동시에 수행하는 것을 의미한다.
Disk: 디스크 스케줄링도 중요하다. 마치 엘리베이터 시스템이랑 비슷함. 헤드의 이동을 줄여야 하는 스케줄링으로 가자! 움직임 최소화
운영체제를 설명하기에 앞서서 컴퓨터 하드웨어 동작에 대해서 설명하는 챕터 !
그림설명) CPU가 메모리에서 기계어를 읽어다가 기계어를 실행시킨다.
I/O디바이스는 INPUT/OUTPUT 디바이스. 키보드나 마우스는 INPUT 디바이스고, 프린터나 컴퓨터화면은 OUTPUT디바이스다. 하드디스크는 보조기억장치 이렇게 부르지만 실제로 컴퓨터 외부 장치로 보고, INPUT과 OUTPUT 을 모두 할 수 있는 Device다. 디스크에서 뭔가를 읽어다가 컴퓨터 내부로 데이터를 들여놓으면 input 디바이스고, 처리결과를 디스크에다가 file 형태로 저장하면 output이다.
각각의 i/o device들은 전담하는 작은 cpu가 붙어있게 된다. 그건 device controller다. disk에서 head가 어떻게 움직이는지, 어떤 데이터를 읽을지 디스크의 내부를 통제하는건 cpu가 아니고, disk controller다.
cpu의 작업공간인 memory가 필요하듯이,device controoler도 작업공간이 필요하다. local buffer라고 한다.
cpu의 운명은 메모리에서 instruction 읽어서 실행하는 걸 무한반복
cpu안에는 메모리보다 더 빠르면서 정보를 저장할 수 있는 작은 공간들이 있다. => 레지스터
cpu에서 실행되는 것이 운영체제인지, 사용자 프로그램인지 구분해주는 것 => mode bit
cpu는 항상 메모리에 있는 instruction만 실행을 하는데, 키보드의 interrupt를 알거나 디스크에서 파일 읽어와야 한다거나 이런 것들을 알기 위해 interrupt line이 있는 것임.
cpu가 디스크에서 파일을 가져와야 할 때, 직접 disk로 가서 일하는 것이 아니라, disk controller한테 파일을 가져오라고 시킨다. 그럼 controller는 읽은걸 자신의 local buffer에다가 저장한다.
cpu는 사용자 프로그램 여러개를 왔다갔다 하면서 일한다. 그런데 만약 무한루프를 도는 프로그램을 만나면??? 어떻게 하나 그럼 time sharing이 방해가 되기 때문에 컴퓨터 안에 timer라는 장치를 뒀다. 특정 프로그램이 cpu를 독점하는 것을 막는 것 ! 처음에는 운영체제가 cpu를 가지고 있다가 다른 프로그램들한테 cpu를 넘겨줄 때 timer에 어떤 값을 세팅한 후 넘겨주는 것임/
cpu는 메모리의 intruction을 실행하다가 interrupt 들어온게 있는지 interrupt line을 확인한다. 만약 timer가 인터럽트를 걸어왔으면 cpu는 하던일을 멈추고 cpu의 제어권이 사용자 프로그램으로부터 운영체제로 자동으로 넘어간다. 그럼 다른 프로그램한테 cpu를 넘겨준다. ~ 타이머에 세팅한 후 !
사용자 프로그램은 직접 i/o 장치에 접근할 수 없다. 모든 instruction은 운영체제를 통해서만 할 수 있도록 막아놨다. 보안 이유로 ! 따라서 사용자 프로그램은 스스로 운영체제한테 cpu를 넘겨주고, 운영체제가 device controller한테 일을 시키는 것 !
mode bit이 0일 때, 즉 cpu가 운영체제에서 실행중인 커널 모드 일 때는 무슨일이든 다 할 수 있게 되어있음 . i/o 접근도 가능하고 모든 instruction 가능 ! mode bit이 1이면 제한된 instruction만 가능!
제어 정보를 위한 register라는 건 cpu가 일을 시킬 때 무슨 일을 해라 ~ 라고 지시하기 위한 것 !
memory를 전담하는 controller도 있다. memory라는 것도 하나의 device이기 때문에 ~
main memory를 원칙적으로 cpu만 접근할 수 있도록 했다.
data가 local buffer에 쌓이게 되면 cpu가 거기에 있는 내용을 읽어서 자신의 작업 영역인 메모리에 복사한다.
그러다보니 cpu가 너무 interrupt를 많이 당한다. !! 효율적이지 않게 동작하게 된다.
그래서 DMA(direct memory access)controller를 하나 더 두고 있다.
직접 메모리에 접근할 수 잇는 컨트롤러다. ! 그래서 cpu랑 dma 컨트롤러가 메모리가 메모리에 동시 접근하면 문제가 생길 수 잇어서, 교통정리하는 역할을 해준다 !
즉, CPU가 인터럽트를 많이 당하는게 오버헤드가 큰 걸 막기 위해서 DMA가 BUFFER에 있는 데이터를 메모리에 올리고 CPU한테 보고도 한다~
Device controller: 각 디바이스 마다 전담을 하기 위해 작은 하드웨어 장치다!
device driver: 운영체제에 있는 코드 중에서 각 디바이스를 처리하기 위해서 디바이스 인터페이스가 있는데, 거기에 맞게 접근해주는 소프트웨어다!
결국, cpu의 숙명은 본인이 실행해야할 instruction의 메모리 주소를 레지스터 중에서 Program Counter라는 레지스터가 가지고 있거든요 매번 그걸 실행하는게 cpu의 운명 ~
instruction 중에서 i/o 장치를 접근해야 하는 상황이 되면, device driver를 통해서 그 장치한테 읽으라든지 쓰라든지 명령하는 것
사용자 프로그램을 실행하다보면 함수 호출하는 부분이 있죠 ! c언어로 프로그램을 짰으면 main 함수가 있고, a라는 함수를 만들어서 호출할 수 있고, 처음에 프로그램이 cpu에서 main 함수를 실행하다가 다른 함수 호출하면, instruction의 메모리 위치를 jump 한다. 다른 곳으로 ! (조건문이나 반복문이나 등등) 내 프로그램 안에서 호출하는 것은 이 안에서 메모리 주소를 바꾸는 것인데 , 프로그램이 실행되다가 i/o 실행을 하기 위해서 운영체제의 함수를 호출하는 것을 시스템콜이라고 한다. 그냥 메모리 주소를 바꾸는 일이 아니라 조금 더 복잡하다 ~ 어떻게 하냐면 사용자 프로그램이 직접 interrupt line을 세팅하는 instruction을 실행한다.
Trap: 소프트웨어가 인터럽트를 거는 것
일반적으로 인터럽트를 걸었다~ 했을 때는 하드웨어가 발생시킨 인터럽트를 떠올린다! ex) 타이머 인터럽트, controller가 걸어주는 인터럽트 등
시스템콜을 어떻게 거느냐?
: 사용자 프로그램이 운영체제한테 일을 해달라고 어떻게 요청하느냐?
=> 함수 호출이지만, 일반 함수 호출과는 다르게 본인이 직접 인터럽트를 걸어서 cpu가 os한테 넘어가게 하는, 다른말로 해서 trap을 사용해서 인터럽트를 건다.
=> 인터럽트를 걸어서, 즉 시스템콜을 해서 사용자 프로그램이 os한테 요청을 했는데, 아무거나 다 들어주지 않는다. 올바른 i/o 요청인지 확인해보고 과연 그 i/o device의 파일에 대한 접근권한이 있는건지등을 확인해보고 ~ 요청을 controller에게 부탁한다.
만약 i/o의 일이 끝났으면 그때는 하드웨어 인터럽트가 걸린다 ~ (device controller가 인터럽트를 건다. )
1) i/o를 하기 위해서 인터럽트가 두가지 종류가 걸린다.
처음에는 사용자 프로그램이 i/o 요청을 위해서 os한테 시스템콜을 한다. (소프트웨어 인터럽트)
2) i/o가 하던일을 끝내면 하드웨어 인터럽트가 걸린다. device controller가 하던일 끝냈다고 cpu한테 말함 ~
cpu를 특정 프로그램이 독점하는 것을 막기 위해서 timer 인터럽트라는 걸 사용한다.
현대의 운영체제는 인터럽트에 의해 구동됨: 즉, 운영체제는 cpu를 잡을 일이 없다. cpu를 사용할 일이 없고,
인터럽트가 들어올 때만 cpu가 운영체제한테 넘어가는 거지 그렇지 않으면 cpu는 사용자 프로그램이 사용하고 있는 것
사용자 프로그램이 os로의 함수호출을 하기 위해서는 interrupt line을 세팅하고 그러면, cpu 제어권이 운영체제한테 넘어가기 때문에 부탁한 일을 운영체제가 할 수 있게 되는 것이다~
인터럽트의 종류가 참 많다. 만약 keyboard controller가 interrupt를 걸어오면, keyboard buffer에 들어온 내용을 메모리로 copy하고, keyboard i/o 요청을 한 process한테는 cpu를 얻을 수 있다라는 것을 표시해야 한다.
만약, 타이머가 인터럽트를 걸었으면 cpu를 뺏어가지고 cpu를 다른 process한테 줘야 한다.
이처럼 인터럽트 종류가 있고, 각 인터럽트만 해야될 종류가 다르다. 그러면, 각각의 인터럽트마다 무슨 일 해야하는지가 운영체제 코드에 다 정의가 되어있다. 이 정의된 걸 코드로 구현한 것이 => 인터럽트 처리 루틴
1번 인터럽트가 들어왔을 때는 어떤 함수로 가야하는지의 주소, ~~ 등을 표시 => 인터럽트 벡터 (함수 주소 정의 해놓은 일종의 테이블)
i/o를 할 수 있는 방법이 2개가 있다.
2.Memory Mapped i/o에 의해: 우측에 있는 그림: i/o device에다가 메모리 주소를 매겨서 메모리 접근을 하는 instruction을 통해서 i/o를 할 수도 있음
프로그램이라는 것은 실행파일 형태로 하드디스크(file system)에 저장이 된다. 그런 실행 파일을 실행시키게 되면, 그게 메모리로 올라가서 프로세스가 된다. 근데 바로 물리적 메모리로 올라가는게 아니라 중간에 'virtual memory'를 거치게 된다.
address translation: 물리적 메모리도 아래서부터 주소가 0번으로 시작해서 주소 번호가 상승
virtual mamory의 주소는 1000번지인데, physical memory의 주소는 2000번 이런식으로 주소가 바뀌어야 한다. (logical memory => physical memory)
메모리 주소 변환을 해주는 계층이 있다 => 주소 변환 계층 (하드웨어의 지원을 받는 장치)