[ESSENTIAL CONCEPT] _if 구조체란? - Week9-11-team03/Pintos-User-Program GitHub Wiki

_if 구조체란?

struct intr_frame _if;유저 모드로 진입하기 위한 CPU 상태를 저장하는 구조체입니다.
이 구조체는 최종적으로 do_iret(&_if); 함수를 통해 커널 모드에서 유저 모드로 전환할 때 사용됩니다.

📦 _if 구조체에 포함된 주요 정보

항목 설명
리턴 주소 유저 모드로 전환 시 복귀할 주소
스택 포인터 유저 모드에서 사용할 스택의 위치
EFLAGS CPU 플래그 레지스터 (인터럽트 설정 등 포함)
세그먼트 레지스터 코드, 데이터 등의 세그먼트 지정 (CS, DS 등)

📦 전체 구조

/* Interrupt stack frame. */
struct gp_registers {
    uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
    uint64_t rsi, rdi, rbp, rdx, rcx, rbx, rax;
} __attribute__((packed));

struct intr_frame {
    struct gp_registers R;        // 일반 목적 레지스터
    uint16_t es;                  // 세그먼트 레지스터
    uint16_t __pad1;
    uint32_t __pad2;
    uint16_t ds;                  // 세그먼트 레지스터
    uint16_t __pad3;
    uint32_t __pad4;

    uint64_t vec_no;              // 인터럽트 벡터 번호
    uint64_t error_code;          // 예외 발생 시 오류 코드

    uintptr_t rip;                // 명령어 포인터 (재개 위치)
    uint16_t cs;                  // 코드 세그먼트
    uint16_t __pad5;
    uint32_t __pad6;
    uint64_t eflags;              // CPU 상태 플래그
    uintptr_t rsp;                // 스택 포인터
    uint16_t ss;                  // 스택 세그먼트
    uint16_t __pad7;
    uint32_t __pad8;
} __attribute__((packed));

🔍 필드별 설명

구분 필드명 설명
📦 일반 레지스터 r15 ~ rax 함수 호출, 계산 등에서 사용되는 일반 목적 레지스터
🧩 세그먼트 레지스터 es, ds, ss, cs 메모리 세그먼트를 지정 (유저/커널 모드 전환 시 중요)
🚨 인터럽트 정보 vec_no 어떤 종류의 인터럽트/예외인지 식별하는 번호
⚠️ 오류 코드 error_code 예외 발생 시 CPU가 전달하는 오류 코드 (예: 페이지 폴트)
🧭 명령어 포인터 rip 인터럽트 발생 당시 실행 중이던 명령어 주소
📌 스택 정보 rsp, ss 인터럽트 발생 당시의 스택 포인터와 해당 세그먼트
⚙️ 상태 플래그 eflags 인터럽트 플래그, 비교 연산 결과 등 CPU 상태 저장

🔁 유저 모드 진입 흐름은 다음과 같습니다:

  1. struct intr_frame _if;에 유저 모드 진입 시 필요한 값 저장
  2. do_iret(&_if); 호출
  3. iret 명령어를 통해 레지스터 값 복원 및 유저 모드로 전환

📦 세그먼트 레지스터란?

x86 및 x86-64 아키텍처에서 세그먼트 레지스터는 메모리 접근 시
어떤 **메모리 영역(세그먼트)**을 기준으로 삼을지를 정의하는 레지스터입니다.
커널에서 유저 모드로 전환할 때도 이 레지스터들이 올바르게 설정되어야 합니다.

🔍 주요 세그먼트 레지스터

레지스터 설명
cs Code Segment – 현재 실행 중인 코드가 위치한 세그먼트
ds Data Segment – 일반 데이터가 위치한 기본 세그먼트
es Extra Segment – 추가적인 데이터 세그먼트로 사용 (일부 명령어에서)
ss Stack Segment – 현재 스택이 위치한 세그먼트

💡 참고

  • x86-64에서는 세그먼트 기반 메모리 모델이 거의 사용되지 않고, 대부분의 세그먼트는 플랫(flat)하게 설정되어 있음
  • 그러나 유저 모드와 커널 모드의 구분, 그리고 iret 명령어로 전환 시에는 여전히 세그먼트 레지스터 값이 중요합니다

⚙️ struct action 구조체란?

struct action은 Pintos에서 실행할 수 있는 명령(Action) 하나를 나타내는 구조체입니다.
각 명령은 이름, 인자 수, 실제로 실행되는 함수 포인터로 구성되어 있습니다.


📦 구조체 정의

struct action {
    char *name;                       // 액션 이름 (문자열)
    int argc;                         // 인자의 개수 (name 포함)
    void (*function) (char **argv);   // 액션을 수행할 함수 포인터
};

🔍 필드별 설명

필드명 타입 설명
name char * 실행할 액션의 이름 (예: "run"이나 "exec" 등)
argc int 해당 액션에 필요한 인자의 개수 (자기 자신 포함)
function void (*)(char**) 실제로 액션을 수행하는 함수 포인터→ char **argv는 인자 목록을 의미