본문 바로가기

프로그래밍/운영체제

[운영체제] System Structure & Program Execution 2

전 시간에 본 걸 잠시 복습해보자

 

CPU 와 메모리를 합쳐서 컴퓨터라 부르고 다른말로 호스트라 한다.

 

I/O 디바이스는 컴퓨터에 입력을 하거나 출력을 하는 도구고, 

필요한 데이터는 로컬 버퍼에 저장을 한다.

CPU 에 알릴때는 디바이스 컨트롤러를 통해 Interrupt 를 걸게 된다.

 

CPU는 매순간 메모리의 어떤 위치에 있는 기계어를 불러와 사용을 하는데

어떤 기계어를 가져오냐면 CPU 레지스터에 메모리 주소를 가리키는 PC(프로그램 카운터)라는 친구가있다.

여기서 다음 명령어를 가리키고 있고, CPU 는 이걸 가져와서 사용한다.

* CPU 는 항상 PC 가 가리키는 메모리 주소에서 인스터럭션을 읽어 와서 사용하는 일만 한다.

 

근데 인스트럭션을 읽기전에 하는 일이 인터룹트 라인에 들어온게 있는지 확인하는 일이다.

들어온게 있다면 제어권을 운영체제에 넘기게된다.

 

 

- modebit 이 0일 때는 모든 인스트럭션을 사용가능하다.

1일때는 한정적인 인스트럭션만 사용가능. 

사용자 프로그램이 I/O 작업을 하고 싶다면 modebit이 1이여서 못하기 때문에

시스템콜을 날려서 interrupt line 에 세팅을 하게 되고 , CPU 는 하던 일을 멈추고 제어권을 운영체제에 넘기게 된다.

 

 

- device controller 들이 인터룹트를 걸 수 도 있지만,

timer 라는 라드웨어가 걸 수 도 있다.

무한루프를 도는 프로그램에 제어를 걸 수 있다.

 

 

여기까지 복습을 했다.

 

 

 

동기식 입출력 : I/O 에 요청을 하고 요청이 올때까지 기다린 후 작업을 진행한다.

비동기식 입출력 : 요청을 보내고 바로 사용자 프로그램이 사용된다.

 

동기식 입출력의 구현 방법은 , CPU 를 낭비시키지 않게 구현 할 수 있는 방법이다.

I/O 요청을 하고 다른 프로그램에 CPU 를 넘기는 방식.

 

 

I/O 는 커널을 통해서만 할 수 있다.

사용자 프로그램이 I/O요청을 커널에 하게되면

I/O 요청에 맞는 디바이스 드라이버를 거치게 되고 , 하드웨어를 통해 읽거나 쓰는 작업을 한다.

근데 I/O 작업은 오래 걸리는 작업..

동기식은 이 작업을 기다리고 있다가 진행을 하는 방식이다.

 

비동기는 이걸 기다리지 않고 요청만하고 CPU 제어권을 얻어서 다른 작업을 하는 것.

끝났다는건 Interrupt 를 통해서 알게된다.

 

두 방법 모두 I/O 완료는 입터럽트로 알려주게 된다.

 

 

DMA 는 CPU가 아님에도 메모리에 접근 할 수 있는 장치다.

원래는 , CPU 가 Input 디바이스 결과물을 메모리에 저장하거나 Output에 출력을 하는데,

만약 키보드가 쳐지면 1바이트... 수준의 아주 작은 I/O에도 CPU가 인터럽트가 걸려서 

copy 를 해오고 해야 될텐데... 

이러면 인터럽트가 너무 많이 당한다.

이 오버헤드를 막아 주는게 DMA. 

 

작은 일들은

버퍼에 특정 크기. 블록이나 페이지 정도의 데이터가 쌓일때까지 기다리고,

그거를 CPU에 1번 인터럽트를 걸어서 알려주는데, 이게 어떻게 동작하냐면

 

블록이나 페이지 정도의 데이터가 쌓이기 전에 DMA가 메모리에 먼저 copy를 하고 ,  

블록 크기로 쌓이게 되면 CPU에 메모리에 올려놨다고 알려준다.

 

 

 

맨 위에 CPU 가 있을 것.

CPU 안에 레지스터가 있고, 캐시 메모리도 CPU 안에 있기도 한다.

메인 메모리 가 있고 그 밑에 디스크들이 있다.

 

위로 갈 수록 속도가 빠르지만 비싸다(용량이 작다).

디스크는 비 휘발성이고 위에 있는것들은 휘발성이다.

 

CPU가 매 클럭 마다 인스트럭션을 처리하게 되는데 메인 메모리를 처리하려면 

적게는 10~100 클럭이 걸리기때문에 이 속도 차이를 완충하기 위해 

캐시 메모리나 레지스터를 두는것

 

프로그램이 어떻게 컴퓨터에서 실행이 되나?

프로그램은 하드 디스크에 저장이 되어있다.

실행을 시키게 되면 메모리에 올라가고 프로세스가 된다.

정확하게는 물리적인 메모리에 바로 올라가는건 아니고 , Virtual memory에 올라간다.

 

프로그램을 실행하게 되면 Address space(메모리 주소공간)가 생성이 되게 된다.

0번지부터 시작하는 그 프로그램의 독자적인 주소 공간이 생성된다.

 

code, data , stack 으로 구분된다.

code - CPU 에서 사용할 기계어 코드

data - 변수, 전역변수 같은 프로그램이 사용할 자료구조를 담고있고,

stack - code  가 함수 구조로 되어있기 때문에 함수를 호출할때 데이터를 쌓았다가 꺼내가고 하는 용도로 사용하는 공간.

 

이 독자적인 공간을 메모리에 올려서 실행을 하는 것.

물리적인 메모리에 커널은 항상 상주해있지만 , 사용자 프로그램은 실행했다가 종료되면 사라진다.

 

근데 이 프로그램의 address space 를 물리적 메모리 공간에 다 올리는 건 아니다.

당장 필요한 부분, a 라는 함수를 실행하고 있다. 하면 그 부분만 물리 메모리에 넣어두고,

사용하지 않는곳은 올려두지 않는다.

나머지 부분은 Swap area 에 올려둔다.

 

운영체제 커널의 주소 공간.

 

자원을 효율적으로 관리하는 코드가 있을것.

운영체제가 언제 CPU를 얻게 되냐면 인터럽트를 걸렸을때!

각 인터럽트를 어떻게 처리할지에 대한 코드가 있다.

 

데이터에는 운영체제가 사용하는 자료구조 들이 있다.

하드웨어 종류마다 자료구조를 만들어서 쓰고 있다.

 

또 사용자 프로그램들을 관리 하는데, 관리하기 위한 PCB 자료구조가 있다.

프로세스 컨트롤 블록이라 한다.

 

모든 프로그램이 다 함수로 만들어져 있다.

컴파일이 되서 기계어가 되어도 함수 형태가 저장되어있다.

 

프로그램언어로 함수를 작성하게 되면 , 사용자 정의 함수라 함.

라이브러리는 외부에서 가져온 함수.

 

커널 함수를 실행 하기 위해서는 시스템 콜을 발생시켜야 한다.