[운영체제및실습] 10주차 2회차: I/O제어 : 폴링

2025. 5. 10. 17:18·운영체제및실습

지금부터 운영체제가 디바이스 드라이버를 통해 장치를 제어하는 방법들을 알아봅니다. 

 

1. I/O Control

운영체제가 장치의 상태를 체크하면서 장치를 제어하는 데에는 크게 3가지 방법이 있습니다.

1-1) Polling

먼저 폴링에 대해서 설명하겠습니다. 

사용자 프로그램에서 출력문이 있다고 합시다. 예를 들어 printf문이 사용자 코드에 있어서 컴파일 되면서 출력이 되는 시스템 콜로 바뀝니다. 사용자 프로그램에서 장치를 직접 제어할 권한이 없어서 권한을 가진 os가 그 일을 대신해주도록 시스템 콜로 바뀌어서 요청하는 것입니다. 

시스템콜을 부른 사용자 프로셋는 유저 모드에서 커널 스페이스로 모드 체인지를 해서 커널로 들어갑니다. 이제부터는 사용자 프로세스가 아니라 커널이 운영체제가 실행되는 것입니다. 입출력 요청했던 사용자 프로그램이 커널로 바뀌어서 운영체제 기능을 하는 것입니다. 

시스템콜을 받으면, os가 처리하는 기능이 무엇인지 따져보고 입출력에 관한 것인지 알고, I/O Management(=kernel I/O subsystem)으로 전달이 됩니다. 그러면 커널 입출력 관리가 실제로 입출력 담당 출력장치가 무엇인지 알아내고, 모니터라면, 모니터 스크린에 디바이스 드라이버에게 출력을 지시합니다. 디바이스 드라이버 인터페이스에 해당되는 함수를 부르는 것입니다. 그러면, cpu는 커널 I/O Subsystem에서 Device Driver로 옮겨옵니다. 그래서 Device driver안의 코드를 실행합니다. 커널 아이오 매니지먼트가 디바이스 드라이버의 출력 함수를 부르면서 출력할 데이터나 기타 정보를 커널 스택에 저장하기 때문에 디바이스 드라이버 출력 함수는 모니터 하드웨어를 제어해가며 출력할 수 있게 됩니다.

디바이스 드라이버는 장치를 만든 회사에서 구현한 함수이므로, 출력 장치의 하드웨어를 잘 알고 있어서 모니터의 컨트롤러 하드웨어를 어떻게 제어해야지 하드웨어가 동작하는지 알고 있습니다. 그래서 컨트롤 레지스터 해당 비트를 1로 설정해 출력 명령을 내립니다. 출력 명령을 내리기 전에 장치의 상태를 확인해보고, 장치가 사용 가능할 떄 명령을 내리게 됩니다.

 

이전 절에서 하드웨어는 입출력 장치는 왼쪽의 기계적인 부분과, 컨트롤러(어댑터)라는 부분과 결합되어 있다고 했습니다. 그래서 전자장치 안에는 컨트롤러 레지스터도 있고, 상태 레지스터도 있고, 입출력될 데이터가 잠시 저장되는 데이터 버퍼가 있다고 했습니다.

 

1. 그래서 어떤 출력장치의 정보를 출력한다고 가정해봅시다. 그러면 디바이스 드라이버는 먼저 그 장치의 컨트롤러 내부에 있는 상태 레지스터에서 장치가 일을 하는 상태인지, 다른 일로 바쁜 상태인지 확인하기 위해 busy bit를 읽습니다. 만약 1이면, 장치가 다른 작업을 하고 있어서 바쁜 것이고, 이 일이 끝날 때까지 기다립니다. 또, 반복적으로 확인합니다. 0으로 바뀌면, 새로운 출력 명령을 내릴 수 있습니다.

2. 그래서 운영체제는 컨트롤 레지스터의 쓰기 비트를 1로 세팅합니다. 쓸 내용을 데이터 버퍼인 data-out register라고 출력될 내용이 들어가는 버퍼에 출력될 내용을 써줍니다.

3. 그리고 새로운 command가 내려졌음을 장치에 알리기 위해서 컨트롤 레지스터의 command-ready bit를 1로 설정합니다.

4. 그러면 컨트롤러 하드웨어는 command-ready bit가 1임을 읽게 되고 상태 레지스터의 busy bit를 1로 설정합니다. 그니까 새로운 명령을 실행하기 위해 바쁜 상황이라는 것을 알리기 위함입니다.

5. 그리고 컨트롤러가 컨트롤 레지스터를 읽어서 write 명령임을 알게 됩니다. 출력될 내용이 들어가 있는 data-out register에 있는 내용을 출력합니다.

6. 출력이 끝나면, 컨트롤러는 command-ready bit를 0으로 바꾸고, busy bit도 0으로 바꿉니다. (한가한 상태)

 

디바이스 드라이버 소프트웨어는 프린트 컨트롤러에게 명령을 내린 다음에 프린트 출력이 끝났는지 상태를 확인해야 합니다. 

명령을 내린 다음 컨트롤러와 디바이스가 동작을 다 한 후, 일이 끝났는지를 디바이스 드라이버는 status 레지스터를 읽어가면서 busy bit가 0으로 바뀌었는지 계속 주기적으로 상태를 읽어봅니다. 출력이 진행되는 경우라면, busy bit가 1로 남아있다는 것을 값을 읽어서 볼 것이고, 잠시 뒤에 또 읽고 1이면 또 일정한 시간을 기다린 다음에 또 체크를 합니다. 마치 프린터랑 모니터에게 출력 다했니라고 물어보고 안했으면 주기적으로 계속 물어보는 방법입니다. 상태를 물어보는 것을 poll한다라고 합니다. 그래서 이 방법을 polling이라고 합니다.

device driver가 반복하는 동안에, device driver라는 소프트웨어가 실행되는 것입니다. 결국 cpu가 디바이스 드라이버의 인스트럭션을 반복적으로 실행을 함으로써 이 일들이 일어납니다. 폴링방법을 프로그램 실행함으로써 입출력상태를 확인한다고 해서 프로그램 기반 아이오라고 부릅니다. 

poll을 반복하다가 언젠가 출력이 끝나면, 컨트롤러의 busy bit가 0으로 바뀔 것이고, 이 사실을 알게 된 device driver는 그제서야 다시 위로 올라가서 I/O Management로 돌아갑니다. 입출력 완료 되서야 다시 돌아가는 것입니다. 일을 마친 후에 커널이 요청한 사용자 프로그램에게 돌아가는데 바로 돌아가는 것이 아니라 커널에 들어와서 유저로 돌아가기 전에 운영체제로서 해야 하는 시스템 관리 역할을 수행을 하고 나서 사용자 프로그램으로 되돌아 갑니다.

 

우체국 예에서 입출력 처리 방법을 설명했었습니다. 바로 고객이 와서 우체국 직원이 고객을 서비스 한 후, 신청서 작성을 해야 할때,(입출력) 직원은 그대로 바라보면서 기다리지 않고 옆 고객으로 넘어가서 서비스를 시작을 합니다. 그런 입출력 방법이 polling과 같은 방법인가요? 

아닙니다. 지금 말한 폴링의 경우는 우체국 직원을 예로 들었을 때 옆고객으로 넘어가서 다른 일을 하는 것이 아니라 방금 서비스하던 고객에게 남아서 입출력이 끝날때까지(직원이 신청서를 주기적으로 다썼는지 물어보고 기다리다가 일정한 시간 후에 또 물어보고 반복해서) 고객 상태를 확인하는 방법입니다. 

우체국 직원이 cpu이고 os입니다. 폴링하는 디바이스 드라이버 코드를 실행하는 것은 cpu지만, cpu를 그렇게 시킨 것은 os입니다. os가 cpu라는 하드웨어에게 device driver code를 실행시키도록 명령을 한 것입니다. 사용자 프로그램이 유저 모드에서 실행되다가 모드 체인지를 해서 커널 모드로 갔고, 입출력 관리를 거쳐서 디바이스 드라이버로 갔는데, 디바이스 드라이버를 실행하는 주체는 누구일까요?

커널의 전신은 누구입니까?

바로 사용자 프로그램입니다. 즉, 사용자 프로그램이 커널로 변신해서 입출력 장치를 명령을 내리고, 입출력 장치의 상태를 끝날때까지 확인하는 것입니다. A고객을 서비스 하다가 B라는 고객으로 바뀐 것이 아니라 A라는 고객을 계속 실행하는 환경에서 바뀐 것입니다. 즉, context switch, process switch가 일어나지 않았습니다!

 

폴링 방법은 입출력이 끝날 때까지 계속 cpu를 잡으면서 물어보면서 기다리게 됩니다. 이것을 busy waiting이라고 했습니다. 인스트럭션을 실행하지만, 기다리는 목적입니다. busy-waiting을 하는 동안, 실제로 다른 일을 하지 않고, 기다려서 만약에 기계가 입출력이 빨리 끝나는 장치의 경우에는 오래 기다리지 않고 몇 번만 물어보고 입출력 끝나서 돌아갈 수 있어 나쁘지 않지만, 입출력이 매우 느린 장치인 경우(키보드)에는 사람이 천천히 입력한다거나 잠시 자리를 비우거나 하면 cpu가 오랜시간동안 기다리면서 인스트럭션을 실행해서 유용한 일을 하지 않고 기다리는 반복문만 실행하게 되어 cpu의 효율이 안 좋아 지게 됩니다.

그래서 polling은 디바이스의 상태를 체크를 하는데, 디바이스가 빨리 끝나는 경우가 아니면, busy-waiting을 오래 해야 해서 비효율적입니다. 반대의 경우에는 폴링의 방법은 효율적입니다. 

 

이상으로 폴링에 대해서 알아봤습니다.

1-2) Interrupt-driven I/O(인터럽트 기반 입출력)

1-3) Direct Memory Access(DMA)

 

 

'운영체제및실습' 카테고리의 다른 글

[운영체제및실습] 10주차 4회차: 디스크 스케줄링  (0) 2025.05.25
[운영체제및실습] 10주차 3회차 : I/O제어 : 인터럽트 I/O, DMA  (0) 2025.05.12
[운영체제및실습]10주차 1회차: 인터럽트 처리  (0) 2025.05.10
[운영체제및실습] 9주차 3회차 : 입출력관리 개요  (0) 2025.05.07
[운영체제및실습] 9주차 2회차: 파일 시스템 사례  (0) 2025.05.06
'운영체제및실습' 카테고리의 다른 글
  • [운영체제및실습] 10주차 4회차: 디스크 스케줄링
  • [운영체제및실습] 10주차 3회차 : I/O제어 : 인터럽트 I/O, DMA
  • [운영체제및실습]10주차 1회차: 인터럽트 처리
  • [운영체제및실습] 9주차 3회차 : 입출력관리 개요
soyun5
soyun5
개발블로그
  • soyun5
    soyun5
    soyun5
  • 전체
    오늘
    어제
    • 분류 전체보기 (67) N
      • 운영체제및실습 (14)
      • 프로그래밍언어개론 (1)
      • 데이터베이스 (0)
      • 클라우드 (0)
        • 2025 AWS Cloud 초급특강 (0)
      • 스터디 (23)
        • 2024하계모각코 (10)
        • 2024동계모각코 (13)
      • 웹개발 (0)
        • HTML, CSS, 자바스크립트 (0)
      • PS (0)
        • 백준 (0)
        • 프로그래머스 (0)
      • 앱개발 (0)
        • flutter (0)
      • C (0)
      • java (0)
        • 자료구조 (0)
        • 알고리즘 (0)
      • 깃허브 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Directory
    운영체제
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
soyun5
[운영체제및실습] 10주차 2회차: I/O제어 : 폴링
상단으로

티스토리툴바