02. 운영체제 동작 구조적 원리

Junha Kim·2021년 4월 18일
0

운영체제

목록 보기
2/2

  • 현재 OS는 Time sharing, Multi Programming

I/O

I/O Operation

  • I/O 디바이스와 CPU는 병행적으로 작동 가능
  • 물리적 디바이스와 컨트롤러 버퍼 사이 데이터 전달
  • 각 디바이스는 로컬 버퍼와 레지스터를 가지고 잇음
  • 디바이스 컨트롤러를 위한 디바이스 드라이버가 필요 → 컨트롤러에게 필요한 명령어를 제공해주는 모듈

Accessing I/O Devices

  • Memory Mapped I/O → 더 자주 쓰임
    • 주소를 이용해 접근
    • I/O 디바이스가 CPU 메모리와 똑같이 동작
    • 일반적인 load, store 동작 → 사용하는 명령어 인터페이스가 같음
  • Special(isolated) I/O
    • Channel I/O라고도 부름 → 특수한 명령어가 필요하다
    • CPU가 I/O 디바이스를 위한 별도의 버스를 가지고 있음

Polling I/O

  • Programmed I/O라고도 불림
  • CPU가 I/O 디바이스를 지속적으로 확인 → 시간 낭비 ⇒ 이를 해결하기 위해 interrupt가 등장
  • 각 디바이스는
    • Data-in, Data-out 레지스터
    • Status 레지스터
    • Control, Command 레지스터 존재
  • 디바이스에 데이터 write 과정
    1. CPU가 Status 레지스터의 busy bit가 빌때까지 확인
    2. CPU는 Command 레지스터에 write하겠다는 bit를 쓰고 Data-out 레지스터에 output 값을 write
    3. CPU가 Control 레지스터에 command-ready bit를 씀
    4. 디바이스 컨트롤러는 이 bit를 보고 Status 레지스터에 busy bit를 씀
    5. 디바이스 컨트롤러가 command 레지스터를 읽고 write bit를 보고 Data-out 레지스터를 읽고 I/O 수행
    6. 디바이스 컨트롤러는 command-ready bit와 error bit, bust bit를 지움
  • 문제점
    • CPU가 polling에 너무 많은 시간을 할애 → 프로세스 대기 버퍼 메모리 오버플로우 위험
  • 이를 해결하기 위해 interrupt를 사용

Interrupt

  • CPU는 IRQ(Interrupt-request line)으로 interrupt 확인
  • interrupt 시그널을 받으면 해당 프로세스 레지스터 내용(context)들을 메모리에 저장
  • 디바이스 컨트롤러가 interrupt raise → CPU가 확인 → interrupt handler가 dispatch하여 처리

  • OS는 interrupt-driven
    • 하드웨어 : 버스로 트리거(interrupt)
    • 소프트웨어 : system call(trap)

Interrupt Handling

  • CPU에 현제 프로세스 context를 system stack에 저장
  • 어떤 종류의 interrupt인지 확인하는 방법
    • Polling : 모든 interrupt를 확인하여 어느 interrupt가 일으켰는지 확인
    • Vectored interrupt system : interrupt를 보낼 때 vector 번호를 함께 보내 누가 보냈는지 알 수 있게 함
  • 제어권을 ISR(Interrupt Service Routine)이나 Interrupt Handler에게 넘김

Direct Memory Access

  • 특정 하드웨어 시스템이 CPU와 독립적으로 메인메모리에 접근할 수 있게 해주는 방식
  • 디바이스들의 로컬버퍼에서 메모리로 데이터 이동이 완료되었다는 인터럽트만 발생시킨다.
    • 많은 데이터를 디스크로 전달하기 위해서 programmed I/O(PIO)를 사용한다면 CPU가 다른 프로세스를 처리하기 위해 사용될 수 있는 시간들이 허비.
    • byte단위로 인터럽트를 주지 않고 블럭단위(예를 들면 512Byte)로 전송이 완료될 때마다 인터럽트

  1. 프로그램 수행 도중 CPU가 입/출력 명령을 만남.
  2. CPU는 DMA에게 입/출력 명령(기억장치내의 데이터의 위치, 개수, I/O 명령의 종류 등이 전달).
  3. CPU와 독립적으로 DMA는 기억장치의 데이터를 직접 입/출력. CPU는 입/출력 명령을 내린 후 다른 프로그램을 수행.
  4. 주기억 장치와 주변장치 사이에 실제의 데이터 전송.
  5. DMA는 입/출력 완료 시 CPU에게 인터럽트로 완료 사실을 보고

Modern Interrupt Handling

  • 다단계 interrupt 운선순위를 적용하여 선점형 처리
  • Maskable interrupt
    • Interrupt Mask가 가능한 인터럽트
    • Interrupt Mask : 인터럽트가 발생하였을 때 요구를 받아들일지 말지 지정하는 것.
  • NMI(non-maskable interrupt)
    • Interrupt Mask 가 불가능한 인터럽트.
    • 무시될 수 없는 interrupt == 매우 중요한 interrupt
  • interrupt는 interrupt vector를 포함하여 전송 → 벡터 크기보다 더 많은 디바이스가 있을 경우 연결 리스트로 해결

Traps and Exceptions

  • 소프트웨어가 발생시키는 인터럽트
  • Exception
    • 프로그래밍 에러 시 발생 ex) div by 0, memory access violation
  • Trap
    • 프로그램이 OS 서비스가 필요할 때 발생(system call)
    • 소프트웨어 인터럽트라고도 함
    • OS kernel로 들어가기 위함

Protection

  • 프로그램 및 OS를 보호하기 위함.

Protecting Memory

  • 다른 프로그램의 데이터 침범을 막음
  • 유저 프로그램으로부터 OS 보호
  • Base/Limit register : OS가 프로그램 주소를 관리 및 체크
  • 가상 메모리 및 segmentation도 같은 맥락

CPU Control

  • 협력적인 방안 → 프로그램들이 주기적 system call(yield())로 CPU 제어권을 OS에게 넘김
    • OS가 프로그램들을 신뢰할 수 있을 경우에만 사용 가능
  • Timer Hardware
    • 무한 루프 혹은 독점을 막기 위한 방안 → 협력 X
    • 시간 quantum timer를 정해 interrupt 발생
    • OS가 CPU 제어권을 확실하게 가질 수 있음
    • 시간 quantum을 정하는 것이 바로 protected(privileged) operation → OS만이 할 수 있음

Privileged Instructions

  • User mode에서는 실행할 수 없는 명령
    • 하드웨어 자원에 직접적인 접근
    • 메모리 관리 상태 명령어
    • 시스템 레지스터 접근
    • 명령어 중지
    • CPU mode bit 변경
      • User mode : 유저 프로세스 영역
      • Kernel Mode : OS 관리 영역
        • system call 발생 시 kernel 모드로 전환
        • 해당 작업 마치고 RTI(Return From Interrupt) 명령어로 User 모드로 전환

System Calls

  • OS에 의해 제공되는 프로그래밍 인터페이스 서비스
  • 부적절한 요청들을 막음으로써 OS 보호
  • 특정한 자원 할당에 이용함으로써 자원 공유 공정성 확보
  • Protected Procedure Call : 오직 kernel 모드에서만 실행됨
    • 유저 모드에서 open()으로 system call 호출 → Library function(API)
    • sys open → 실제 open에 해당하는 일은 kernel mode에서 실행

  • count = read(fd, buffer, nbytes)); 실행 과정

    1. stack에 각 파라미터 저장 및 함수 호출

    2. 레지스터에 read함수 실행을 위한 코드(syscall) 저장

    3. kernel에게 trap

    4. interrupt handler가 dispath 및 해당 syscall handler에게 배분 후 처리

    5. trap이 불려졌던 곳으로 복귀

    6. 스택 포인터 증가(스택에 있던 값 삭제)

  • 빈번한 System call → Overhead

    • User mode에서 system functionality 제공
      • 결과 캐싱 및 buffering ops(fopen, fread, write) : 함수 안에 버퍼가 있어, 한번 읽은 데이터는 다시 syscall하지 않아도 됨
    • 오버헤드를 감수하고도 나눈 이유 → OS-User 분리 ⇒ Protection 달성

운영체제 구조

  • 운영체제도 CPU에서 돌아가는 프로세스 중 하나이다.
  • Event Driven
  • 싱글 thread가 아닌 이벤트가 발생할 때마다 thread가 생성된다.
  • 컴퓨터를 켜면, CPU는 BIOS에서 pre-loaded → small OS(Master Boot record) 읽어들인다. → 전체 OS를 실행
    • OS로 바로 분기를 안하고 왜 small OS를 먼저 읽는가?
      • OS마다 file system이 다르기에 그것을 먼저 이해하는게 필요하다.
      • 즉, MBR이 file system을 이해하는 역할

OS가 하는 것

  • 프로그램들을 실행, 없으면 idle loop → Event Driven이기 때문

Monolithic Structure

  • 모든 기능들이 커널 모드에 들어이음
  • 어느 한 부분이 문제 생기면 전체가 망가지는 위험성이 존재

Layered Structure

  • 각 인접 계층끼리만 interface함
  • 안정적으로 개발이 가능하며, 확장성이 좋다
  • 하지만 계층간 오버헤드가 존재

Microkernel Structure

  • 커널 모드에 있던 기능들 몇개를 유저 모드에 옮겨놓음
  • 유저 모드에 있는 모듈들은 message passing으로 communication
  • 확장성 및 이식성이 좋음
  • 커널 모드에서 실행되는 모듈들이 적어 신뢰성이 더 높아짐
  • 하지만 유저 모드에서 서로 간의 message passing은 커널 모드를 통해야함오버헤드

유닉스 운영체제 구조

Virtual Machine

  • Hypervisor가 만들어낸 가상 공간(객체)
    • Hypervisor : visualization으로 논리적 공간을 지원해주는 소프트웨어
  • 시스템 환경 구성 및 Protection에 유용

0개의 댓글