⸻
⸻
• 유저 모드 → 커널 모드 전환 시, CPU 레지스터 상태를 저장하는 구조체
• struct intr_frame 형태로 저장됨 (Pintos 등 OS에서 사용)
• 저장되는 대표적인 레지스터:
• 커널 작업이 끝나면 이 값들을 꺼내어 유저 모드 상태로 복원
⸻
iretq : interrupt return (64bit)
⸻
전환 발생 시점:
• 시스템 콜 (syscall)
• 외부 인터럽트 (타이머, 키보드 등)
작동 흐름:
1. CPU가 유저 상태의 레지스터들을 커널 스택에 저장 (intr_frame)
2. CPU 권한 수준을 Ring3 → Ring0으로 변경
3. 커널 함수(syscall_handler, interrupt_handler) 실행
4. 작업 완료 후 iretq 또는 do_iret()를 통해 유저 레지스터 복구 후 복귀
⸻
전환 발생 시점:
• 유저 프로그램 처음 실행할 때
• 인터럽트 또는 시스템 콜에서 복귀할 때
작동 흐름:
1. struct intr_frame에 미리 준비해둔 레지스터 값 사용:
• %rip: 유저 코드 시작 주소
• %rsp: 유저 스택 포인터
• %rdi, %rsi: 인자 전달
2. iretq 명령어를 실행하여:
• Ring0 → Ring3 전환 (커널 → 유저)
• %rip부터 유저 프로그램 실행 재개
⸻
• 유저/커널은 같은 CPU 레지스터 집합을 공유
• 단, 스택 포인터와 세그먼트 레지스터는 모드별로 별도 관리됨
• %cs, %ss 세그먼트 값을 통해 Ring0 vs Ring3 구분
• iretq는:
• %rip, %cs, %rflags, %rsp, %ss를 스택에서 복원
• 복원 후 Ring3으로 전환하며 유저 코드로 점프
⸻
⚙️ iretq 명령의 내부 동작 (64-bit)
스택에서 아래 순서대로 레지스터를 복구:
+----------------------------+ ← %rsp (커널 스택)
| %ss (유저 스택 세그먼트) |
| %rsp (유저 스택 포인터) |
| %rflags |
| %cs (유저 코드 세그먼트) |
| %rip (유저 명령어 주소) |
+----------------------------+
그 후:
권한 수준 Ring0 → Ring3 변경
%rip이 가리키는 유저 코드에서 실행 재개
• 이 동작은 보호 모드에서 레벨 전환을 수반하는 매우 중요한 기계어 명령어
• 커널에서 유저 모드로 안전하게 복귀할 수 있는 유일한 방법 중 하나
⸻
이건 좀 어렵네 ㅋ