인터럽트가 들어올때만 운영체제 CPU를 사용하고 아닐때는 전부 사용자 프로그램이 CPU를 쓰고 있다.
(모든 전체적인 통제는 운영체제가 한다.)
Interrupt | 하드웨어 인터럽트 |
Trap | 소프트웨어 인터럽트 |
Interrupt
- 하드웨어가 발생시킨 인터럽트
Trap
- Exception: 프로그램이 오류를 범한 경우
- System call: 프로그램이 커널 함수를 호출하는 경우
System call
운영체제에 I/O를 하기위해서는 modebit이 커널모드로 변경되어야 한다.
- 사용자 프로그램에서 입출력 장치를 사용하기 위해서 system call이라는 Trap을 걸어준다.
- CPU가 하나의 인스트럭션 수행하고 interrupt line을 체크하기 때문에 소프트웨어적으로 인터럽트를 걸었기 때문에 cpu제어권이 운영체제로 넘어가면서 mode bit이 kernel mode로 변경한다.
- 이러면 운영체제가 어떤 사용자 프로그램에서 I/O 디바이스를 사용하기 위해 system call을 했다 운영체제가 cpu를 가지고 있기 때문에 device controller 한테 그것을 읽어오라고 부탁을 할 수 있다.
추가 정리
- Trap을 걸었다고 아무거나 다 처리해주면 안된다.(permission bit, PCB등 확인하겠지요) os는 항상 올바른 요청인지 권한이 있는지 확인을 해주고 올바르다면 I/O 요청을 device controller가 요청한 일을 할 것이다.
- I/O 를 하기위해서 필요한 인터럽트는 하드웨어 인터럽트냐 소프트웨어 인터럽트냐고 물어보면 요청을 할때는 소프트웨어 인터럽트I/O가 다끝났으면 하드웨어 인터럽트를 통해 끝났다는걸 알려주기 때문에 둘다 필요하다.
- I/O 사용할때만 system call 을 사용하는게 아니고 뭔가 운영체제한테 부탁할 일들이 있을 때 사용된다. (sleep(),printf(),exit()등)
Exception
divide by 0(0으로 나누는 연산은 허용이 안되는데 내프로그램이 실수로 그런 연산을 할 경우) 혹은 운영체제 메모리를 접근하려고 했다거나 프로그램이 실행이 되다가 하면 안되는 일을 하게 될 때
- 인스트럭션 셋에서 자동적으로 못하도록 막아둔다.
- 인터럽트 라인이 자동으로 셋팅이 되기 때문에 그 프로그램으로 부터 자동적으로 cpu권한이 운영체제로 넘어가게 된다.
- cpu권한이 운영체제로 넘어가면 보통은 운영체제에서 프로그램을 강제로 종료시킨다.
인터럽트 처리 루틴 (Interrupt Service Routine, interrupt handler)
해당 인터럽트를 처리하는 커널 함수
- 하드웨어 적으로 볼 때 타이머, 키보드 , 디스크 등등 각각의 인터럽트 종류마다 운영체제가 해야되는 일이 다르기 때문에 각각의 인터럽트 종류마다 무슨일을 해야되는지 운영체제 코드에 실제 인터럽트 처리하는 부분들이 각각 정의가 되어있다.
interrupt vector
해당 인터럽트의 처리 루틴 주소를 가지고 있다.
- 각각의 인터럽트가 들어오면 어떤 함수로 가야되는지(table) 표시를 해주어야 되는데 이런것을 인터럽트 벡터라는 곳에 표시를 해준다. 각인터럽트 종류마다 그 인터럽트가 생겼을 때 어디있는 함수를 실행해야 되는지 함수의 주소들을(운영체제 코드) 정의해논 테이블을 말한다.
동기식 입출력과 비동기식 입출력
I/O는 오래걸리는 작업이다 보니까 오래걸리는 작업동안에 사용자 프로그램이 CPU를 가지고 있으면서 아무것도 안하고 기다리면 매 시점에 하나의 I/O만 일어날 수 있다. (즉 CPU , I/O장치 두개 다 낭비 가된다.)
Synchronous
사용자 프로그램이 I/O 요청을 커널한테 하면 그 I/O에 맞는 device driver 를 거치고 실제 하드웨어를 통해서 I/O를 읽거나 쓰는 작업을 한다. I/O을 하는건 오래걸리는 작업이다 보니까 시간이 흘러야 I/O가 끝난것이 도착하고 도착한것을 보고서 사용자가 다음작업을 한다 라는게 Synchronous I/O이다.
- 보통은 Synchronous I/O 요청을 한다음에 이 프로그램은 CPU를 줘봐야 아무것도 못하고 낭비되니까 다른 프로세스한테 넘겨주게 된다. (이때 넘겨준 프로세스도 I/O 작업을 하면 또 넘겨주니까 CPU도 낭비안되고 I/O 장치도 낭비 안된다.)
Asynchronous
사용자 프로그램이 I/O 요청을 커널한테 하면 실제로 I/O작업이 진행되는데 그걸 기다리지 않고 I/O요청만 해놓고 바로 CPU제어권을 얻어서 뭔가 다른 작업들을 하는게 Asynchronous I/O 를 말한다.
- I/O 요청만 보내놓고 그 프로세스한테 곧바로 CPU를 넘겨주면 I/O가 진행이 되고 있든 말든 그 프로세스는 I/O하고 무관한 일은 계속 실행하는 입출력 방식
I/O 하는데 시간이 걸릴 것이고 끝났으면 끝났다고 알려주게 되는데 두경우 모두 I/O의 완료는 인터럽트로 알려준다.
(I/O 장치의 컨트롤러가 buffer에다가 저장할 텐데 block 이나 page라고 말하는데 특정 사이즈의 데이터가 쌓이게 되면 DMA가 memory에다가 local buffer에 데이터를 카피하고 인터럽트 걸어준다. )
두 개의 I/O가 실제로 가지는 의미
read write둘다 구현하기 나름 보통은 read Synchronous, write Asynchronous 인거 같다.
Read
- 예를 들어 내가 하나의 프로그램을 짰는데 디스크에서 뭘 읽어와야 될 때 보통은 디스크에서 읽어온 다음에 결과를 보고 그 다음 작업을 하게 프로그램을 짤텐데 read의 경우 I/O 하는동안 기다려야 되기 때문에 Synchronous I/O
- I/O요청을 해서 디스크에서 읽어오라고 했지만 읽어오는거와 상관없이 결과나오는걸 보지 않고 그냥 할 수 있는 작업들이 있을텐데 그동안은 그작업을 하도록 프로그램을 짤 수 있다.
- I/O가 작업 다했다고 인터럽트로 알려주면 그것을 보고 읽어온 데이터가 있어야 할 수 있는 동작들을 이때부터 하면 되는거다. 그런식으로 read 인데도 Asynchronous하게 할 수 있다.
Write
- 디스크에 써라 혹은 화면에 출력해라의 경우 확인해야지만 다음작업을 할 수 있는건 아니다 보통은 write는 Asynchronous하게 하는게 자연스럽다. 하지만 이때도 정말 잘써저 있는지 확인해야지 내프로그램이 돌아가게 하고 싶을때는 Synchronous write를 하면된다.
I/O작업 추가 정리 (2가지 경우)
- 우리가 CPU를 통해서 수행하는 인스트럭션은 메모리만(Load/store architecture) 접근해야되는 인스트럭션과 I/O를 작업하는 인스트럭션이 존재한다. (Load/store architecture 말고 다른 I/O접근하는 인스트럭션) 메모리도 주소가 있듯이 I/O device도 주소가 있다.
- I/O device 에다가 메모리 주소를 매겨서 메모리 접근하는 인스트럭션을 통해서 I/O 접근을 할 수 있는데 이것을 Memory mepped I/O라고 부른다. 메모리 주소의 연장 주소를 I/O device에 매긴다 예를 들어 모든 메모리주소가 0 ~ 100번지이면 101 번지주소 부터는 I/O 접근 관련 주소를 통해서 메모리 접근하는거 처럼 I/O를 접근하는 방법 Memory mepped I/O
Reference
'CS > 운영체제' 카테고리의 다른 글
DeadLock(교착 상태) (2) | 2024.01.22 |
---|---|
운영체제(OS, Operating System)(1) (0) | 2022.12.28 |