[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 상태 저장 |
🔁 유저 모드 진입 흐름은 다음과 같습니다:
struct intr_frame _if;
에 유저 모드 진입 시 필요한 값 저장do_iret(&_if);
호출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는 인자 목록을 의미 |