PintOS PJT2 - interrupt frame

김수환·2024년 11월 17일

PintOS

목록 보기
10/15
struct intr_frame {
    /* intr-stubs.S의 intr_entry에 의해 푸시됨.
       중단된 작업의 저장된 레지스터입니다. */
    struct gp_registers R;  // 정수 레지스터 구간
    uint16_t es;            // Extra Segment - Extra Data 영역
    uint16_t __pad1;
    uint32_t __pad2;
    uint16_t ds;  // Data Segment - 데이터 영역
    uint16_t __pad3;
    uint32_t __pad4;
    /* intr-stubs.S의 intrNN_stub에 의해 푸시됨. */
    uint64_t vec_no; /* Interrupt vector number. */
                     /* 때로는 CPU에 의해 푸시되고, 그렇지 않으면 일관성을 위해 intrNN_stub에 의해 0으로 푸시됩니다.
                        CPU는 이를 'EIP' (Extended) Instruction Pointer 바로 아래에 두지만 우리는 여기로 옮깁니다. */
    uint64_t error_code;
    /* CPU에 의해 푸시됨.
       중단된 작업의 저장된 레지스터입니다.. */
    uintptr_t rip;  // Instruction Pointer = Program Counter 다음에 실행될 명령의 주소
    uint16_t cs;    // Code Segment - 명령어 영역
    uint16_t __pad5;
    uint32_t __pad6;
    uint64_t eflags;  // Extended Flags - 상태, 제어, 시스템 플래그 -> 레지스터가 어떤 일을 수행하는 지
    uintptr_t rsp;    // Stack Pointer - 스택 포인터
    uint16_t ss;      // Stack Segment - 임시 Stack 영역
    uint16_t __pad7;
    uint32_t __pad8;
} __attribute__((packed));

struct intr_frame 구조체 해석

이 구조체는 인터럽트가 발생하거나 트랩(예: 시스템 호출)이 처리되는 동안 중단된 작업의 상태를 저장하는 데 사용됩니다. 인터럽트 처리기가 실행되면 CPU 상태(레지스터, 스택 포인터 등)를 저장하고 인터럽트 처리가 끝나면 복원합니다.


구조체 멤버 설명

1. struct gp_registers R

  • 정수 레지스터 상태를 저장합니다. intr-stubs.Sintr_entry에 의해 푸시됩니다.
  • 사용자 모드에서 실행 중이던 작업의 정수 레지스터 상태를 보존합니다.

2. 세그먼트 레지스터 (es, ds)

  • 세그먼트 레지스터는 메모리 세그먼트를 정의하며, 데이터와 명령어의 위치를 결정합니다.
  • es (Extra Segment): 추가 데이터 세그먼트
  • ds (Data Segment): 데이터 세그먼트
  • __pad1 ~ __pad4: 메모리 정렬을 위해 추가된 패딩입니다.

3. vec_no (Interrupt Vector Number)

  • 인터럽트 번호를 저장합니다.
  • CPU 또는 인터럽트 처리 코드에서 설정되며, 어떤 인터럽트가 발생했는지 식별하는 데 사용됩니다.
  • 예를 들어:
    • 0x0D: 일반적인 보호 오류
    • 0x80: 시스템 호출

4. error_code

  • 특정 인터럽트(예: 페이지 폴트)에서 발생한 오류의 상세 정보를 저장합니다.
  • 이 값은 인터럽트 처리기가 발생 원인을 진단하는 데 사용됩니다.

5. CPU에 의해 저장된 레지스터

(1) rip (Instruction Pointer)

  • 현재 실행 중인 명령어의 주소를 저장합니다.
  • 인터럽트가 발생한 위치를 나타냅니다. 인터럽트 처리 후 원래 실행 중이던 코드로 복귀할 때 사용됩니다.

(2) cs (Code Segment)

  • 명령어가 위치한 세그먼트를 가리킵니다.

(3) eflags (Extended Flags)

  • CPU 상태를 나타내는 플래그 레지스터입니다.
  • 각 플래그 비트는 특정 상태(예: 캐리 플래그, 인터럽트 활성화 여부)를 나타냅니다.

(4) rsp (Stack Pointer)

  • 스택의 최상위 주소를 가리킵니다.
  • 인터럽트 처리기가 호출되면 CPU는 이 값을 사용해 현재 실행 상태를 스택에 저장합니다.

(5) ss (Stack Segment)

  • 스택이 위치한 세그먼트를 가리킵니다.

구조체의 역할

  1. 인터럽트 처리:
    • CPU는 인터럽트가 발생하면 현재 실행 중인 프로그램의 상태(레지스터 값 등)를 스택에 저장합니다.
    • 이후 struct intr_frame에 이 정보를 복사해 둡니다.
    • 처리 후, 저장된 값을 복원하여 원래 실행 중이던 상태로 복귀합니다.
  2. 시스템 호출 처리:
    • rip 레지스터와 eflags 플래그를 확인해 인터럽트가 발생한 위치와 상태를 분석합니다.
    • 레지스터 값을 사용해 시스템 호출의 매개변수를 전달하고, 반환 값을 저장합니다.

구조체에 포함된 패딩의 역할

__pad1 ~ __pad8는 메모리 정렬을 보장하기 위한 패딩입니다. 메모리 정렬은 성능 최적화 및 하드웨어 호환성을 위해 필수적입니다.


결론

struct intr_frame인터럽트와 트랩 처리 중 작업 상태를 저장하고 복원하는 데 사용됩니다. 이를 통해 커널은 사용자 모드에서 실행 중이던 작업을 중단하고 인터럽트를 처리한 후, 다시 원래 작업을 계속할 수 있습니다.

profile
juniorDev

0개의 댓글