이번 포스팅에서는 2-1포스팅에 이어 System Structure & Program Execution 마저 진행하려고합니다.
<2-1내용 요약>
CPU, Memory를 포함하는 걸 컴퓨터라고 한다.
컴퓨터를 다른말로 호스트라고한다.
호스트컴퓨터에 붙어서 데이터를 input, output하는 디바이스들이 있다.
디바이스들을 전담하기 위한 컨트롤러들이 붙어있다. I/O 디바이스를 통해서 데이터를 읽거나 쓰거나 하면서 LOCAL buffer에 데이터를 저장한다. CPU에 뭔가를 알려주고 싶을 때는 컨트롤러가 인터럽트라는걸 걸어서 뭔가 전달할일이 있다고 알려주게 된다.
CPU는 매 순간 메모리 어디에 올라와 있는 기계어를 처리한다. CPU에서 매 순간 메모리에 있는 기계어를 읽어와서 실행한다. CPU안에 있는 레지스터 중에서 메모리 주소를 가르키고 있는 주소가 있다. PC Register이다. 이게 가르키고 있는 메모리 위치에서 CPU가 그 명령어를 실행하는 것이다!
Memory를 가르키고 있는 PC는 다음 주소를 가르키게 된다. 예를 들어 기계어가 4바이트짜리 라면 PC는 4가 증가하게 된다. 특별한 일이 없으면 CPU는 그 다음 명령어실행 → 그 다음 명령어실행한다. 하지만.. 프로그램이 항상 순차적으로 실행하는 것이 아니다.. 제어문을 통해(ex) if문 같이) 다른 메모리 주소로 점프해서 실행해야 한다. 기계어 집합 중에서는 점프를 하는 명령어가 있다. 점프하는 명령어를 만나면 점프해서 멀리 있는 기계어를 실행하기도 한다.
CPU는 빠른 일꾼이라고 생각하자!
마음대로 할 수 있는 것이 아니라 PC가 가르키는 메모리에서 기계어를 읽어서 실행한다고 생각하자!
크게 보면, 기계어 실행 → 기계어 실행이지만 사실은 그렇지 않다!
기계어를 한 줄 실행하고 인터럽트가 들어왔는지의 여부를 체크한다.
인터럽트가 들어왔다면 PC가 가르키고 있는 메모리 주소에서 실행하는게 아니라, 잠시 하던 작업을 멈추고 CPU를 누가 썼든 CPU제어권이 운영체제에게 넘어가게 된다. 운영체제는 인터럽트 마다 왜 인터럽트가 걸렸는지 상황에 맞게 처리하기 위해 운영체제 커널안에 함수로 정의가 되어 있다. → 인터럽트 벡터는 해당 인터럽트의 처리 루틴 주소를 가지고 있다.. 인터럽트 번호와 인터럽트 주소의 쌍을가지고 있다.
ex) 하드디스크 컨트롤러가 인터럽트를 걸었다. 인터럽트 라인에 3번라인이 세팅이 됐다..? 그렇다면 3번라인에 해당하는 주소가있다. 주소가 말하자면 함수의 위치를 알리고 있는 것이고 함수에 가면 디스크컨트롤러가 발생시킨 인터럽트에 대해서 CPU에서 실행해야 할 커널함수가 정의되어 있는 것이고 이 함수가 인터럽트 처리 루틴(실제 처리해야 할 일)이다. 인터럽트 종류별로 점프할 수 있게 주소를 가지고 있는 것이 인터럽트 벡터이다.
운영체제가 CPU를 가지고 있는, mode bit이 0이면 → CPU는 모든 기계어를 실행할 수 있음
사용자 프로그램이 CPU를 가지고 있는, mode bit이 1이면 → CPU는 한정된 기계어들만 실행할 수 있음(사용자 프로그램을 100% 믿을 수 없다. 남의 프로그램의 메모리 주소를 볼려고할 수 도 있고 운영체제의 커널에 가서 이상한 것을 쓸 수도 있기 때문이다.) 그래서, 자기 메모리 주소만 보고 일을 할 수 있게끔 막아놓고 있는 것이다.
I/O Device를 접근하는 건 무조건 mode bit이 0일 때만 실행할 수 있게 한다.
운영체제에 있는 함수를 사용자 프로그램이 요청하는 게 시스템 콜!
운영체제 함수를 호출할 때는 의도적으로 인터럽트 라인을 세팅하고 cpu는 인터럽트 라인을 세팅했기 때문에 하던 일을 멈추고 CPU제어권을 운영체제로 넘긴다.
예를 들어 A라는 프로그램이 CPU에서 명령어를 실행하고 있었다. 그런데 운영체제의 메모리를 접근하려는 시도를 했거나 0으로 나누는 연산을 했다?라면 (Exception) 자동적으로 막아놨다. 인터럽트 라인이 자동으로 세팅이 되고 CPU가 운영체제가 넘어간다. 보통은 프로그램을 강제로 종료시키던지 대응을 하게 된다.
타이머가 인터럽트를 걸 수도 있다!
운영체제가 CPU를 가지고 있다가 사용자 프로그램에게 CPU를 넘겨줄 때 MODE BIT을 1로 바꾸고 넘겨준다. 사용자 프로그램이 CPU를 얻어서 계속 CPU를 쓸 수가 있다. 이걸 뺏어올 방법이 없기 때문에 타이머라는 하드웨어를 줘서 운영체제가 사용자 프로그램에게 CPU를 넘겨줄 때 시간을 할당해서 넘겨주고 타이머가 끝나면 타이머가 CPU에게 인터럽트를 걸어 사용자 프로그램으로 부터 CPU를 뺏어서 운영체제가 CPU를 얻게 한다.
운영체제는 타이머 인터럽트의 도움을 받아 여러 프로그램을 번갈아 실행할 수 있게 한다.
동기식 입출력..??(Synchronous I/O)
Synchronous → 우리나라의 단어로 번역이 안된다.. 립싱크에서 싱크(서로 맞추는 것)
동기식 입출력은 I/O요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에 넘어감
- 구현방법1
- I/O가 끝날 때까지 CPU를 낭비시킴
- I/O도 마찬가지로 매시점 하나의 I/O만 일어날 수 있음(CPU도 낭비이지만, I/O장치도 낭비가 되는 것!)
- 구현방법2
- I/O요청한 작업한테는 CPU 줘봐야 일을 못하기 때문에 다른 프로세스한테 CPU를 넘긴다.
- 넘겨받은 프로그램이 또 I/O요청을 할 수가 있다. 그러면 I/O요청을 보내고 또 다른 프로세스한테 CPU를 넘긴다. → CPU가 놀지 않고 일 할 수 있고, I/O장치도 여럿이 동시에 실행될 수 있다.(구현방법1에 비해 개선해서 나온 것) 보통은 동기식으로 할 때 이런식으로 구현을 한다.
Read → 내가 I/O요청을 했으면 그 요청된 I/O 데이터를 들고와야 작업을 할 수 있는게 보통이다. I/O를 하는 동안은 기다려야 한다.
Write → 디스크에 뭔가를 쓴다던지,, 쓰고나서 확인하고 싶으면 동기식으로 구현할 수 있다.
비동기식 입출력..??(asynchronous I/O)
I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고 제어가 사용자 프로그램에 즉시 넘어감
Read → I/O요청을 했지만 결과를 보지 않고 다른일을 할 수 있고, 작업을 끝냈다고 I/O가 알려주면 그 때 부터 데이터관련한 작업을 하면 된다.
Write → 디스크에 뭔가를 쓴다던지 모니터에 출력한다던지,, 정말 출력이됐는지 확인하는 작업이 아니라서 Write는 비동기식이 조금 더 자연스럽다. 실제로 데이터를 쓰든지 말든지 그 다음 작업을 보통 할 수 있는 것
DMA(Direct Memory Access)
- 나오게 된 배경: 메모리에 접근할 수 있는 장치가 cpu밖에 없다. 그래서 I/O장치들이 CPU하고 교신을 해야 할 필요가 있을땐 인터럽트를 걸어주고 CPU가 인풋 디바이스에 요청이왔으면 로컬버퍼에 있는 데이터를 메모리에 카피를 하고 아웃풋 디바이스로부터 요청이 왔으면 메모리에 있는 내용을 로컬버퍼에 카피한다. I/O장치들은 워낙 다양하고, 키보드 하나 두들기면 1바이트OR2바이트에 대한 데이터인데 I/O컨트롤러가 CPU를 걸고 1바이트가 로컬버퍼에서 메모리에 카피를한다. 키보드 하나 또 누르면..? 또 CPU가 인터럽트가 걸리고 CPU가 인터럽트를 너무 많이 당한다!그래서 DMA라는 장치를 하나 더 붙여놓고 메모리를 접근할 수 있는게 CPU만 접근 할 수 있는게 아니라 DMA도 메모리를 직접 접근을 할 수 있게 만들어 놓는다. 키보드의 1바이트나 2바이트 같은 작은 크기의 블럭이나 페이지의 데이터가 쌓이면 모아서 한 번에 CPU에게 인터럽트를 걸어 알려준다. DMA가 로컬버퍼에 있는 데이터를 메모리에 카피를 하고 어느정도 블럭이 채워졌으면 인터럽트를 한 번 걸어서 이미 아까 요청한 작업이 메모리까지 올라왔다고 알려준다!
- → DMA를 둠으로써, CPU가 더 효율적으로 작업할 수 있게 되는 것
- → CPU가 인터럽트를 많이 당하면 CPU가 효율적으로 동작하지 않는다!
- 빠른 입출력 장치(인터럽트를 더 빈번히 거는 장치)를 메모리에 가까운 속도로 처리하기 위해 사용
- CPU의 중재 없이 device controller가 device의 buffer storage의 내용을 메모리에 block 단위로 직접 전송
- 바이트 단위가 아니라 block 단위로 인터럽트를 발생시킴
CPU가 직접 접근해서 처리할 수 있는 저장장치, Primary(Executable): Registers , Cache Memory, Main Memory
CPU가 직접 접근해서 처리할 수 없는 저장장치, Secondary: Magentic Disk(섹터단위로 접근이 가능하다), Optical Disk,
Magnetic Tape
가격이 비싸서 Register에 가깝게 모든 데이터를 올릴 수 없다. Magnetic Tape에 가까울 수록 가격이 싸다!
<프로그램의 실행>
프로그램이라는건 파일 시스템에 실행파일로 저장이 되어 있다. 그런 실행파일을 실행을 시키게 되면 Physical memory로 올라가서 프로세스가 된다. 정확하게는 Physical memory로 바로 가는게 아니라 한 단계를 거치는 데, Virtual Memory이다. 가상 메모리 단계이다.
프로그램을 실행시키게 되면 그 프로그램의 메모리 Address space(그 프로그램의 독자적인 공간, A프로그램을 실행시키면 프로세스 A의 Address space가 생기고, B프로그램을 실행시키면 프로세스 B의 Address space(code → cpu에서 실행할 기계어 코드, data → ex)변수 , stack → 함수를 호출하거나 리턴할 때 사용하는 용도)가 생긴다.)가 형성이 되는데, 이거를 물리적인 메모리에 올려서 실행을 시키는 것이다.
커널은 컴퓨터를 키게 되면 메모리에 항상 상주해서 올라가 있지만 사용자 프로그램들을 실행을 시키면 이런 주소공간이 생기다가 프로그램을 종료하면 사라진다.
하지만, Address space를 Physical Memory에 통째로 다 올려놓는 것이 아니다! → 메모리의 낭비가 될 수 있기 때문이다.
그래서, 지금 필요한 부분만 메모리에 올린다. 그렇지 않은 건 올리지 않는다. 그리고, 나중에 또 메모리에서 사용이 안되면 메모리에서 쫓아낸다. 메모리에서 쫓아낼 때 그냥 지워버리는게 아니라 보관해야 한다면, 보관해야 하는 장소가 디스크에 있는 Swap area이다.
가상 메모리는 머리 속에만 있는 주소공간이지, 실제 존재하는 공간이 아니다! → 어떤 부분은 메인메모리에와 있고, 어떤 부분은 Swap area에 있는 것!
메인메모리의 연장공간으로 하드디스크를 사용하는 공간을 Swap area라고 한다.
Swap area로 사용하고 있는 하드디스크는 전원이 나가면 의미가 없는 데이터가 된다. 메인 메모리도 전원이 나가면 사라지기 때문이다!
- Swap area: 메인메모리의 연장공간으로 사용하는 용도이다.
- File System: 비휘발성의 용도로 사용한다.
Address Translation : 예를 들어, Address space의 data영역에 변수가 100번지라면 실제 물리적인 메모리에 올라가는 데이터는 3000번지로, 실제로 저장되는 주소로 바뀌어야 한다. Address Translation은 운영체제가 하는게 아니라 하드웨어 장치가 해준다.
운영체제 커널도 하나의 프로그램이기 때문에 Kernel Address Space가 있다!
code: 커널 코드가 들어 있다
- 시스템콜, 인터럽트 처리(각각의 인터럽트 마다 무슨일을 처리해야 하는지?) 코드
- 자원 관리를 위한 코드
- 편리한 서비스 제공을 위한 코드
data: 운영체제가 사용하는 여러 자료구조들이 있다. CPU, Memory, Disk를 관리하기 위한 자료구조들이 보관되어 있다.
운영체제는 프로세스를 관리하기 때문에 각 프로그램들이 독자적인 주소공간을 가지고 있지만 이것들을 관리하기 위한 자료구조가 필요하다. cpu가 얼마나 쓰고 메모리를 얼마나 쓰는지? → PCB(Process Control Block)이라고 부른다. 프로세스마다 PCB가 하나 씩 만들어진다.
stack: 운영체제도 함수구조로 짜여져 있어서 함수를 호출하거나 리턴할 때 스택영역을 사용해야 한다. 그래서 Process A의 커널 스택, Process B의 커널 스택처럼 있다.
모든 프로그램이 함수구조이다!
- 사용자 정의 함수: 자신의 프로그램에서 정의한 함수
- 라이브러리 함수: 자신의 프로그램에서 정의하지 않고 갖다 쓴 함수, 자신의 프로그램의 실행 파일에 포함되어 있다.
- 커널 함수: 운영체제 프로그램의 함수, 커널 함수의 호출 = 시스템 콜
'Dev > OS' 카테고리의 다른 글
[OS] 운영체제 완전타파 - (2-1) (0) | 2022.06.18 |
---|---|
[OS] 운영체제 완전타파 - (1) (0) | 2022.06.17 |