전공수업

[운영체제] 부팅, 레지스터, Instruction, 인터럽트

dayeonsheep 2024. 4. 3. 00:36

 

1. 부팅

  • if 전원꺼져 있는 시스템 -> 운영체제의 전부는 디스크에 저장되어 있을 것
  • 부팅  = 전원 버튼 눌리고 커널이라고 불리는 운영체제 일부가 메모리에 올라와 실행되어, 장치들을 준비시키고 각종 레지스터 값을 초기화하고 사용자의 입력을 받을 준비를 마친 상태
  • where is 커널? how 메모리에 올라갈지 who가 알려주나? -> 부트 프로그램 or 부츠트랩로더 라는 작은 프로그램
    • 얘네는 대게 ROM에 저장
    • 부트 프로그램 -> 전원 켜지면 무조건 제일 먼저 실행되도록 / 역할 : 커널을 찾아 메모리에 올린 후 실행시켜주는 것
    • in PC와 같은 작은 시스템) ROM에 있는 부츠트랩로더가 더 단순한 기능만 가지게하고, 커널을 메모리로 올려줄 부트 프로그램은 따로 디스크에 있음
    • 부츠트랩 로더 -- 부트 프로그램을 메모리에 올려 실행 --> 부트프로그램이 -- 커널을 찾아 메모리에 올려 실행 --> 부팅 완료

 

2. 레지스터

  • CPU(Central Processing Unit)가 요청을 처리하는 데 필요한 데이터를 일시적으로 저장하는 기억장치
    • 임시적으로 저장하는 장소를 메모리(RAM)이라고 알고 있을 것이다.
      하지만, 메모리로 연산의 결과를 보내고 영구적으로 저장할 데이터를 하드디스크에 저장해야 하는 등의 명령을 처리하기 위해서는 이들에 대한 주소와 명령의 종류를 저장할 수 있는 기억 공간이 하나 더 필요하다.
      그리고 이 공간은 무리 없이 명령을 수행하기 위해 메모리보다 빨라야 한다.
      바로 이런 역할들을 하는 것이 CPU 옆에 붙어있는 레지스터! 
  • CPU는 여러 개의 레지스터 갖고 있음
  • 메모리보다 빠른 기억장치(but 크기가 작아서 시스템과 사용 목적에 따라 8-16-32비트 등 = 명령을 한 번에 처리할 수 있는 레지스터의 비트 수의 크기 가짐)

 

- 일반적으로 프로그램에서 이용 가능한 레지스터들

  • 데이터 레지스터 : 연산을 위해 사용(연산속도 = 메모리에 있는 데이터에 대한 연산 > 레지스터에 있는 데이터의 연산 => 레지스터에 있는 게 더 빠름)
  • 주소 레지스터 : 데이터나 명령어의 메모리 주소를 저장 / 계산에 사용
    • 인덱스 레지스터: 주소 지정
    • 세그먼트 포인터/스택 포인터(SP) 레지스터 : 해당 포인터의 값을 저장
      • stack pointer는 스택의 마지막 프로그램 요청 주소를 저장하는 레지스터이다. 스택의 최상단 주소를 갖고 있다고 보면 된다.

 

- 얘네랑 다른 용도로 CPU의 연산을 제어하기 위해 사용하는 레지스터들

  • MBR : 메모리 버퍼 레지스터
  • MAR : 메모리 주소 레지스터
  • IR : 명령어 레지스터
  • PC : 프로그램 카운터
    • 메모리에서 실행할 다음 명령어의 주소를 저장하는 레지스터이다. 예를 들어, 우리가 작성한 프로그램 코드가 있을 때, PC가 한줄 씩 코드를 읽어나가면서 다음 줄의 코드 주소를 PC에 저장.
  • I/O AR, I/O BR : 입출력 주소 레지스터, 입출력 버퍼 레지스터

등등 ↑ 얘네는 다 CPU 안에 있음

 

PC와 SP의 차이점?

스택 포인터는 호출 스택을 추적하는 게 목적인 CPU 레지스터이다.
반면 프로그램 카운터는 컴퓨터가 프로그램 순서 중 어디에 위치해 있는지를 나타내는 CPU 레지스터이다.

스택 포인터는 스택의 마지막 프로그램 요청 주소를 보유하는 반면, 프로그램 카운터는 실행되어야 할 다음 명령어의 주소를 보유한다.

 

 

- 프로그램 상태 워드 (Program Status Word, PSW) 레지스터

  • 모든 CPU가 현재 상태 정보를 저장하기 위해 가짐
  • 여러 가지 조건(Condition) 코드비트(인터럽트 가능/불가능 표시, 현재 실행모드를 나타내는 등)을 포함

 

 

3. 명령어 처리(Instruction)

 

- 명령어 처리하기 위해 필요한 절차

  1. 우선 메모리에 있는 명령어를 읽어 처리기에 있는 레지스터로 갖고 오기
    • 이때 연산을 제어하기 위해 사용되는 레지스터들이 동원됨 = 이 과정이 명령어 반입(Fetch)
    • 이때 다음에 실행해야 할 메모리에 있는 명령어의 주소 = PC 레지스터가 갖고 있음
  2. 연산의 종류를 파악하고 실제로 실행하는 과정 거치면 하나의 명령어 처리됨
  3. 다음 명령어도 같은 작업 반복함으로써 전체 프로그램의 실행 완료됨

 


 

 

- 컴퓨터 시스템에 존재하는 각 자원들의 현 상황을 파악할 수 있는 방법

1. 폴링

  • CPU가 일정한 시간 간격을 두고 각 자원들의 상태를 주기적으로 확인하는 방식
  • 자원들은 폴링 신호를 받은 후, 자신의 상태나 원하는 바를 CPU에게 알려주게 됨
  • = 자신의 상태를 적어놓을 수 있는 곳에 저장시키고 CPU는 폴링 때 그것을 읽어보는 방식
  • 단점
    • 폴링의 간격을 적절히 정해야 함
    • 각 자원들은 직전 폴링 이후 변화된 자신의 상태를 다음번 폴링 때까지는 알릴 수 없음
    • 아무 일이 없더라도 CPU는 폴링에 일정량의 시간을 들여야 하는 부담

 

 

2. 인터럽트

  • 각 자원들이 능동적으로 자신의 상태변화를 CPU에게 알리는 방식
  • 장점 
    • CPU는 따로 시간 들이지 않아도 됨, 자원들은 상황 발생시 즉시 알려 처리받을 수 있음
  • -> 매우 자주 발생하므로 얼마나 빨리 잘 처리하느냐가 시스템의 성능과 직결됨

 

여기서 말하는 자원?

하드웨어 자원 = 장치(Devices), 주변장치(Peripherals) 등
이 하드웨어 자원들로부터의 인터럽트 = 하드웨어 인터럽트

CPU 스스로 자신에게 인터럽트를 해야할 때가 있는데, 이건 실행 중인 명령어 때문에 생기는 일
= 소프트웨어 인터럽트 라고 부름 -> 오류를 발생시키는 명령(0으로 나눈다든가, 다른 사용자 주소를 참조할 경우 등)
= 트랩(Trap) 이라고 부름 (CPU 스스로 자신에게 인터럽트를 해야 하는 경우)

if 오류는 아니지만 입출력을 해야 하는 명령어라면, 시스템 콜을 통해 커널 모드에서 진행해야 함
= 시스템 콜도 소프트웨어 인터럽트라고 함

 

 

시스템 콜?

사용자 프로그램에서 발생되는 읽기/쓰기와 같은 디스크나 메모리를 접근(Access) 해야 하는 경우(=커널 프로그램이 할 수 밖에 없는 종류의 일) 필요한 게 시스템 콜

유저모드로 실행 중 커널 모드에서 해야 할 일이 생기면 프로그램은 시스템 콜을 하게 되고,
이후 그 일을 해줄 운영체제 프로그램이 커널 모드에서 실행된 다음, 
다시 사용자 프로그램으로 복귀되도록 함

 

 

2.1.인터럽트 언제 처리됨?

  • 하드웨어 인터럽트 -> 현재 진행 중인 명령어 실행을 마친 후 처리
  • but 트랩 -> 처리 중인 명령어에 의해 발생 (실행 중에 발생)
    • => 오류의 경우는 바로 프로그램의 종료를 가져오게 될 것
    • => 입출력과 같은 시스템 콜은 입출력이 완료 되어야 실행 중인 명령어가 완료됨, 그리고 다음 실행문으로 진행될 것

 

2.2.인터럽트 어떻게 처리됨?

 

< 인터럽트 처리 루틴 >

  1. 인터럽트 신호를 CPU에게 보냄
    • if CPU는 명령어를 실행 중이었다면, 먼저 이 명령어의 실행 완료시키고 인터럽트 신호를 확인
  2. 현재 실행 중이던 프로그램이 인터럽트 처리 후, 다시 실행될 때를 위해 현 상태의 정보를 시스템 스택에 저장
    • 이때의 정보 = PSW, PC의 레지스터의 값 등
  3. 인터럽트 처리 루틴의 시작 주소를 PC에 넣어 실행 
  4. 인터럽트 처리 루틴은 먼저 CPU에 있는 레지스터들의 값을 저장한 후 필요한 인터럽트 처리를 시작할 것
    • 처리 루틴이 실행되면서 이 값들이 훼손될 수 있어서 저장한 후 시작하는 것

 

-> 인터럽트 처리가 끝나면

  • 이전에 저장하였던 레지스터 값들을 다시 재저장(Restore)한 후, PSW와 PC 값들을 원래 자리에 다시 넣어주고 실행
  • 그러면 PC에 들어가 있는 값이, 인터럽트 이전에 실행 중이던 프로그램에서 다음에 실행할 명령어 위치
  • 그러면 자연스럽게 프로그램의 실행을 이어나갈 수 있게 됨

 

 

전체 과정 보충 설명 1) 

1. 인터럽트 요청 
2. CPU가 처리하던 프로세스 중단
3. 현재 실행 중인 프로세스 상태 PCB에 저장
4. 인터럽트 원인 판별 
5. 인터럽트 처리 루틴 (ISR=Interrupt Service Routine ) 처리 
6. 상태 복구
7. PCB에서 정보 가져오기 
8. 명령어 수행

 

보충 설명 2)

출처 : https://luv-n-interest.tistory.com/426

 

1. 프로그램이 OS에게 I/O 컨트롤러에게 정보를 보내라고 인터럽트 (Trap)

  • 왜 I/O 컨트롤러냐면 사건(event)가 발생하면 HW나 SW로부터 발생한 인터럽트에 의해 신호가 보내지는데, 이때 event는 일반적으로 I/O를 뜻함

2-3. 컨트롤러가 해당 요청을 받아서 I/O 받음 

4. I/O 끝나면 요청이 끝났기에 인터럽트 (Hardware)

5. CPU가 인터럽트를 받고 핸들러에게 전달

6-7. 해당 루틴이 끝나면 CPU가 다시 작업

 

 

보충 설명 3)

출처 : 책 OS? Oh Yes!

 

< 인터럽트 처리 과정에서 레지스터 값들의 변화 >

  • (a) : 인터럽트 직전 상황 (인터럽트 X)
    • 메인 메모리
      • 제어 스택 : 커널에 존재, PC 값과 범용 레지스터 값의 임시 저장소
      • 인터럽트 처리 루틴 : 커널에 존재
      • 사용자 프로그램 : 멀티 프로그램이라 여러 개 존재. 일단 1개로 가정함.
    • 프로그램 카운터(PC) : N+1 → N번째 명령어 실행 중
    • 범용 레지스터 : 실행 과정 중에 보관해야하는 값들, 프로그램 내에서 쓸 수 있는 CPU 내에 있는 레지스터들(abcd 4개로 가정, 실제는 더 많을 수 있음, abcd는 사용자 프로그램이 N까지 실행되어 오면서 사용한 레지스터를 담고 있는 값)
    • 스택 포인터 : T → 제어 스택의 Bottom을 가리키고, 임시 저장 전이므로 저장된 것이 없음
      • 스택 포인트 : 제어 스택의 현 포인트를 말하는 것
  • 인터럽트 처리 실행 중
    • 인트럽트 전의 레지스터 값들을 보존하기 위해 제어 스택에 하나씩 저장한다.
    • 위의 그림에서 범용 레지스터가 4개이므로, T부터 하나씩 4개를 저장하면 T-4위의 T-5를 가리키게 된다. (이는 스택 구현에 따라 다르다)
    • 프로그램 카운터에 있는 N+1 이라는 값도 넣으면, 그 다음 집어 넣을 수 있는 포인트가 T-5이므로 스택 포인터에 T-5를 넣는다.
    • PC에는 서비스 루틴의 시작 번지인 Y를 넣는다.
      • 인터럽트 처리루틴을 돌려야하는 인터럽트가 들어왔으니까 인터럽트 처리루틴을 돌려야하는 시작 주소인 Y를 넣음
      • 인터럽트 처리 루틴이 끝나면 다음 주소를 가리켜야 되니까 Y+L+1이 프로그램 카운터에 들어감
    • 서비스 루틴이 실행된다.
  • (b) : 사용자 프로그램이 다시 실행될 수 있는 환경 (복구 이후)
    • 인터럽트 처리가 완료되면, 스택 포인터 T는 T-5를 가리키고 프로그램 카운터는 Y+L+1(처리 루틴 마지막 명령어의 다음 메모리)를 가리킨다.
    • 이제 인터럽트 처리 이전으로 PC와 스택 포인터, 범용 레지스터를 복구한다.
    • 프로그램 카운터(PC) : Y+L+1 → 저장해두었던 기존 값 N+1
    • 스택 포인터 : T-5 → T (빠진만큼 조정됨)
    • 범용 레지스터 : 처리에 사용된 값들 → 저장해두었던 기존 값 abcd

 

* 커널 = 부팅될 때 시스템에 계속 올라와 있어야 하는 OS 파트 부분

 

 

https://luv-n-interest.tistory.com/426

 

Interrupt, 인터럽트란? [운영체제]

쉽게 말하자면 interrupt는 하드웨어와 OS 간의 상호작용 수단이다. 우선 사건(event)가 발생하면 하드웨어나 소프트웨어로부터 발생한 interrupt에 의해 신호가 보내진다. **event는 일반적으로 I/O를 뜻

luv-n-interest.tistory.com

 

https://velog.io/@adam2/%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8

 

[OS기초] 인터럽트 제대로 이해하기

주변장치와 입출력 장치는 CPU나 메모리와 달리 인터럽트라는 메커니즘을 통해 관리된다. 그래서 인터럽트, 왜 하는거요? 그 이유는 입출력 연산이 CPU 명령 수행속도보다 현저히 느리기 때문이

velog.io

 

 

2.3. 중첩된 인터럽트 처리는 어케함?

중첩되는 인터럽트 : 인터럽트를 처리하고 있는데 또 새로운 인터럽트가 들어오는 상황

 

1. 순차처리

  • 인터럽트를 처리하는 동안에 발생하는 인터럽트는 현재 처리가 끝난 뒤 바로 처리해주는 방식
  • 차례대로 하나씩 해준다는 의미
  • 여러 개의 인터럽트가 몰려있으면? 제어스택이 올라갔다 내려갔다

 

2. 중첩처리

  • 중첩이 가능하도록 현재 처리 중인 인터럽트를 잠시 접어두고 또 다른 인터럽트로 실행을 옮길 수 있도록 하는 방식
  • 얘는 제어스택이 또 올라가서 쌓이게 됨
    • 중첩처리를 하면 제어스택의 크기가 더 커지게 됨

 

-> 인터럽트의 중요도에 따라서 우선순위가 더 높은 경우에는 중첩을, 그렇지 않은 경우(중요도 같거나 더 낮은 경우)에는 순차적으로 구현할 수도 있음

 

 

 


 

< 참고 >