System 구조 및 실행 절차
CPU와 다른 I/O device들 간에는 bus를 통해 데이터를 주고받습니다. 이번에는 전반적인 system 구조와 실행 절차를 정리했습니다.
1. 기본적인 구조
- Memory는 CPU의 작업 공간, 프로그램이 올라가는 공간
- CPU는 클럭을 기준으로 계속 매 클럭마다 명령어를 가져온다.
2. CPU 동작
- A라는 사용자 응용프로그램을 실행하고 있다 생각해보자.
- CPU의 처리속도와 I/O device의 처리속도는 많은 차이가 있다.
- (CPU가 효율적으로 일하기 위해서는 Memory랑만 서로 소통하면 된다.)
- CPU의 제어권은 A에게 있는 상태에서 키보드와 같은 외부 I/O devices 장치들을 이용하고 싶은 상태이다.
- (물론 사용자 응용프로그램은 외부 장치에 접근을 못하지만 이는 후에 보도록 한다.)
- 키보드 입력같은 장치를 이용하게 된다면 처리속도가 다르기 때문에 한 클럭에 한 명령이 실행되더라도 입력받은 값을 바로 못 받으며, 사실 언제 입력될지도 모르기 때문에 계속 기다리게 된다면 CPU는 다른 일을 못하게 된다.
- 따라서 CPU는 명령어를 보내면 해당 명령어를 받아들여 따로 관리해줄 존재가 필요 ( = Device Controller )
- 자 이제, CPU는 장치가 가지고 있는 Device Controller에 명령어를 보내고 다시 자기 할 일을 하면 됩니다.
- 그럼 다시 받기 위해서는? => Device Controller가 다시 신호를 보내야 알 수 있다. ( = Hardware Interrupt )
- 하드웨어 인터럽트를 CPU에서 받기 위해서는 인터럽트를 받는 장소가 있어야한다 ( = Interrupt-request line )
*Device Controller
- I/O device를 관리하는 일종의 작은 CPU
- Hardware이다.
- 제어 Register
- Control register, Status register
- local buffer (Data register) : 데이터를 담는 공간
- Interrupt(Hardware Interrupt)로 끝남을 알린다.
*Device driver
- Software이다, 운영체제에 설치
- 각 디바이스에 맞는 인터페이스 제공 및 디바이스에 접근 가능하게 해준다.
- 이때 Device Controller는 명령어를 받게 되며 다 끝나게 되면, 끝났음을 알리기 위해 인터럽트를 보내게 됩니다.
- 그럼 어디에 입력받은 값을 저장할까? => 이를 위해 Local buffer가 존재
- 즉 local buffer = device controller가 작업하는 공간
- 또한 CPU는 메모리보다 더 빠르면서 정보를 저장할 수 있는 공간이 있는데 cpu register이다.
여기까지 이제 입력을 받아올 수 있게 되었다. 그런데 만약 사용자 응용프로그램 A가 무한 루프를 가지고 있다 생각해보자.
그렇게 되면 하나의 응용프로그램만 사용 가능하고 다른 프로그램을 아예 사용하지 못하게 된다.
즉 하나의 프로그램이 끝나기 전까지 다른 프로그램을 사용하지 못하는 상태이다.
- 하나의 프로그램이 CPU를 독점한 상태
- 범용 컴퓨터의 경우 time sharing이 되어야 하는데 못하고 있다.
이를 해결하기 위해 Timer라는 하드웨어가 존재, CPU의 독점을 막는 역할을 한다.
3. Timer 동작 과정
- 처음에는 운영체제가 CPU를 가지고 있다가 사용자 응용 프로그램이 실행되게 되면 Timer로 값을 설정 후 넘겨준다.
- 그렇게 되면 CPU는 '명령어를 확인하고 실행'과 'interrupt-request line을 확인'하는 과정을 반복하고
- (CPU는 항상 똑같이 실행된다.)
- interrupt-request line을 통해 interrupt가 들어온 것을 확인하면 CPU는 하던 일을 멈추고
- CPU 제어권을 사용자에서 운영체제에 넘겨준다. ( 왜 why? 운영체제만 I/O device에 접근 가능하기 때문에)
- 운영체제는 해당 인터럽트를 확인하여 입력받은 값을 요청했던 응용프로그램의 메모리 공간에 카피해준다.
- Timer가 남아있다면, 기존 실행되고 있던 응용 프로그램에게 다시 CPU의 제어권을 넘겨준다.
- 그 후 Timer가 다 되면 Interrupt-request line에 interrupt를 보내게 되고 CPU는 이를 감지하여 다시 운영체제에게 CPU 제어권을 준 후 요청을 보냈던 응용프로그램에게 CPU 제어권을 넘김
그럼 여기서 생기는 의문은 과연 ' 실행 중인 프로그램이 운영체제인지 사용자 응용프로그램인지 어떻게 확인하는가? '
이는 mode bit를 통해 확인할 수 있다입니다.
Mode bit: 실행 중인 프로그램이 어떤 모드인지 확인 가능
- 0( Kernel mode ) : 모든 메모리 접근 가능
- 1( User mode ) : 제한된 명령어만 실행 가능
- 결국 장치에 대한 접근에 대한 명령 또한 메모리에 있다.
이제 모든 인터럽트에 대한 처리를 CPU가 감당하며 프로그램을 실행할 수 있습니다. 다만 여기서 문제는 모든 인터럽트를 CPU가 처리한다는 것입니다. 이렇게 되면 비효율적이게 된다. 따라서 I/O에 대한 인터럽트를 대신 받아서 해줘야 하는데 이를 DMA Controller라고 합니다.
DMA Controller ( Direct Memory Access Controller)
- I/O device 들에 대한 인터럽트를 대신 받아 메모리에 올려준다.
- 일을 다 하게 되면 CPU에 interrupt를 보내게 된다.
하지만 이렇게 되면 생기는 문제가 있는데, 동시 접근이다.
즉 CPU가 특정 주소에 접근하고 있는데 DMA가 device controller를 통해 받아온 값으로 동일한 주소에 접근하게 되면
충돌이 발생한다. 따라서 이를 막기 위해 Memory Contrroller가 존재한다.
*Memory Controller
- CPU와 DMA Controller 가 동시에 특정 영역에 접근하는 것을 막기 위해 중재하는 역할
4. 사용자 응용 프로그램이 I/O Device에 접근 방법
- System call : 운영체제 커널을 호출
- 사용자 응용 프로그램의 경우 직접 해당 주소로 점프를 못한다.
- Interrupt-request line에 mode bit 값을 변경하는 명령어 실행
- CPU는 명령어 실행 후 Interrupt-request line 확인하므로, 해당 명령어 실행 후 바로 Interrupt-request line 확인
- Trap : Software가 인터럽트를 거는 행위
- Interrupt vector:
- interrupt vector의 특정 위치로 이동
- 해당 인터럽트 벡터가 가리키는 interrupt service routine으로 이동
- 올바른 요청 확인 및 실행 (register & pc 저장)
- device controller에게 명령어를 요청
- CPU는 사용자 프로그램의 다른 일 수행
- Device:
- 해당 명령어를 수행하고 완료 시 인터럽트 송신 (Hardware Interrupt)
- 인터럽트 수신 후 운영체제가 CPU의 제어권 받고 해당 명령 실행 후
- 다시 기존 프로그램의 Timer가 존재하면, 기존 프로그램에게 CPU 제어권 넘기고
- 끝난 후 요청한 프로그램이 실행
*Interrupt vector:
- 인터럽트 처리 루틴 주소를 가지고 있다.
- 인터럽트가 오면 어느 주소로 가야 하는지 알려주는 집합
*Interrupt Service rountine:
- 인터럽트를 처리하는 커널 함수
- 처리할 때의 실제 동작 코드
'운영체제' 카테고리의 다른 글
운영체제 - Thread (0) | 2022.08.06 |
---|---|
운영체제 - 프로세스 (0) | 2022.08.06 |
운영체제 - I/O 구조 (0) | 2022.08.03 |
운영체제 - 저장소 (0) | 2022.08.03 |
운영체제 - 인터럽트 (0) | 2022.08.03 |