본문 바로가기

Information Technology/OS

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

CPU 내부에는 레지스터 중에서 메모리의 주소를 가리키는 레지스터가 존재.

CPU는 이 프로그램 카운터 레지스터가 가리키는 메모리의 위치에서 인스트럭션을 읽어와서 그 기계어를 실행. 인스트럭션 하나가 4바이트 정도. CPU가 인스트럭션 하나를 실행하면 카운터가 4가 증가(인스트럭션 하나의 크기). 특별한 일이 없으면 메모리에 있는 다음 인스트럭션을 순차적으로 실행. 하지만 어떤 호출에 의해 점프를 통해 다른 명령을 실행할 수도 있음.

 

CPU는 인스트럭션을 처리하고 다음 인스트럭션을 처리하기 전에 꼭 인터럽트가 들어온 게 있는지 확인함.

인터럽트가 있다면 작업을 멈추고 CPU 제어권이 운영체제에게 넘어감. 그럼 운영체제 속의 커널 함수에 인터럽트를 파악하는 기능 저장. 인터럽트 벡터에 인터럽트 분류 번호와 주소가 쌍으로 저장. 인터럽트 라인마다 어떤 인터럽트인지 저장이 되어있음. 인터럽트 벡터에 예를 들면 3번 인터럽트에 해당하는 주소(함수의 위치) 저장. 실제 인터럽트를 처리하는 일이 인터럽트 처리 루틴.

 

CPU 속에 mode bit 존재. 0이면 모든 기계어 집합 실행 가능. I/O디바이스 접근 등등. I/O 디바이스에 접근하는 모든 인스트럭션은 오직 mode bit이 0일 때만. 즉, 운영체제가 CPU를 제어할 때만. 

1일 때는 한정된 인스트럭션만 실행 가능. 사용자 프로그램 자신만의 주소를 보고 실행. 보안 문제. 때문에 사용자 프로그램이 운영체제에 특정 작업을 요청할 때에는 시스템 콜 발생. 의도적으로 인터럽트 라인을 세팅. 그러면 CPU가 인터럽트를 확인하고 제어권을 운영체제에게 넘김. 

 

I/O기기가 날리는 인터럽트는 하드웨어 인터럽트. 사용자 프로그램이 날리는 인터럽트는 소프트웨어 인터럽트(Trap).

Trap에도 종류가 있음.

- exception: 예를 들면 divide by zero와 같이 허용이 안 되는 연산을 진행하려고 하면 exception 발생. 또는 사용자 프로그램에서 운영체제에 접근하는 등의 이상한 일을 하면 인터럽트 라인이 자동으로 세팅. 그럼 CPU가 운영체제에게 넘어감.

 

타이머도 인터럽트를 걸 수 있음. 사용자 모드가 모드 빗 1로 계속 CPu를 잡고 있는 걸 방지. 타이머에 할당된 시간이 끝나면 인터럽트를 걸어줌. 그럼 CPU가 인스트럭션을 실행하다 인터럽트로 빠져나와서 CPU 제어권을 운영체제에게.


동기식 입출력과 비동기식 입출력

- 동기식(Synchronous I/O): 시간적으로 맞추는 것

I/O장치까지 1) 직접 가서 2) 읽어와서 3) 결과를 보고 오는 것. 

쓰라고 한 다음에 쓰는 걸 확인하고 와서 작업을 하면 synchronous write

I/O는 시간이 오래 걸리는 작업. 때문에 요청을 한 다음에 다른 프로세스에게 cpu를 넘겨줌.

구현 방법 2 -> 여러 개의 I/O 프로그램에 일을 시킬 수 있음. 다른 IO 요청에게 계속 전달

 

- 비동기식(Asynchronous I/O)

I/O 작업 요청만 하고 CPU 제어권을 바로 얻어서 다른 작업을 진행. IO와 무관한 일을 계속 진행. I/O 작업이 끝났다는 걸 인터럽트를 통해 알림. 누가? IO D/C가 알림.


메모리에 접근할 수 있는 장치

원래는 CPU만 메모리와 접근 가능. 인터럽트를 읽고 CPU가 메모리에 값을 복사해서 저장. 그런데 IO장치들이 워낙 다양함. 다양한 IO장치들이 CPU에 계속 인터럽트를 걸면 CPU에 인터럽트가 너무 많이 걸림. 상당한 오버헤드. CPU가 효율적으로 동작하지 못함.

때문에 DMA 등장. DMA도 메모리에 직접 접근 가능. I/O 기기의 로컬 버퍼에 기준 이상(블록)의 데이터가 쌓이면 그때 작업이 끝났다고 CPU에게 한 번만 인터럽트를 보냄. 자잘한 내용은 DMA가 메모리에 전달.


메모리에 접근하는 인스트럭션과, I/O 디바이스에 접근하는 인스트럭션이 별도로 정의되어 있음. IO 디바이스에도 주소가 있음. IO디바이스에 메모리 주소를 매겨서(메인 메모리 주소의 연장) IO디바이스에 접근하는 방법도 존재(Memory mapped I/O).


CPU 속에 레지스터 존재. 그 아래 캐시 메모리 존재. 그 아래 DRAM으로 구성된 메인 메모리. 

그 아래 하드 디스크 등등. 위로 갈수록 속도가 빠른 매체 사용. 단위 공간당 가격이 비싸서 용량이 작음.

Secondary는 비휘발성. Primary는 휘발성. 

캐싱:(caching) 재사용을 목적. 한 번 위로 읽어놓은 건 두 번째 요청에서 캐시 메모리에서 바로 읽어서 처리

 

CPU가 직접 접근할 수 있는 게 Primary. 바이트 단위 접근 가능 매체. DRAM 같은 경우는 바이트 단위로 주소가 매겨지기 때문에 CPU가 읽은 자리에서 그대로 수행 가능(executable)

Secondary는 직접 접근 불가. 하드 디스크는 섹터 단위로 접근.


프로그램은 실행 파일 형태로 하드 디스크에 저장. 이게 실행을 시키면 물리적인 메모리에 올라가서 프로세스가 됨. 

중간에 virtual memory단계를 거침.

프로그램만의 독자적인 저장 공간이 (0번지로 시작하는) 만들어짐.

 

커널은 부팅과 동시에 메모리에 항상 상주. 사용자 프로그램은 종료되면 주소 공간이 삭제. 프로그램의 모든 코드를 메모리에 다 올리지 않고 필요한 코드만 물리적 메모리에 올려서 사용. 그렇지 않은 부분은 디스크에 잠시 내려둠(Swap area). 프로그램의 메모리는 하나로 존재하지 않고 쪼개져서 어떤 부분은 메모리에 다른 부분은 디스크에.

virtual memory -> 스왑 area가 메인 메모리의 연장 영역. 또는 각 프로그램마다 독자적으로 가지고 있는 주소 공간도 virtual memory.

Swap area는 전원이 나가면 의미 없는 데이터.  메모리의 연장 공간 용도.

 

하드웨어의 지원을 받아서 가상 메모리에 존재하는 주소를 물리적 메모리로 전달.


코드는 영역은 기계어 코드, 데이터 영역은 전역 변수, 스택 영역은 함수를 호출하거나 리턴할 때 데이터를 쌓고 꺼내는 용도. 이걸 물리적인 메모리에 올려서 실행. 

운영체제의 역할: 자원을 효율적으로 관리.

운영체제는 인터럽트가 있을 때 CPU 제어권을 넘겨받음. 

- 하드웨어를 관리하기 위한 자료 구조를 각각의 하드웨어들이 가지고 있음.

- 운영체제는 프로세스들을 관리. 현재 실행중인 프로그램. 각 프로그램들이 가지고 있는 각각의 주소를 관리하기 위한 자료구조. 프로그램마다 PCB(Process Control Block)가 만들어져서 프로세스를 관리함. 

- 운영체제도 함수 구조로 이뤄져있기 때문에 코드/데이터/스택으로 구성.


프로그램은 결국 함수. 기계어에 가까운 Low-level 언어 단으로 내려가더라도 함수 구조가 유지가 됨.

main 함수와 main 함수가 호출하는 다른 함수(사용자 정의 함수), 미리 정의된 라이브러리 함수.

- 커널 함수: 프로그램 내에서 시스템 콜을 통해 사용. 하지만 사용자 프로그램에 내장된 코드가 아님. 사용자 프로그램에는 커널에 대한 정의가 없고 오직 호출만 가능함.

1. 프로그램이 CPU를 잡고 있음(user mode)

2. 시스템 콜을 통해 운영체제 커널의 주소 공간에 있는 코드 실행

3. 시스템 콜이 끝나면 다시 사용자 프로그램에 CPU 제어권 넘어옴. 라이브러리 함수를 호출해도 자신의 주소 공간에 있는 함수

4. 반복