16bit Real Mode와 32bit Protected Mode의 차이점 중 하나는 보호 기능이다.
Protected Mode에서 여러 유저 프로그램이 같이 동작하게 되는데 이 때 규약에 맞는 명령만 실행한다.
이때 다음과 같은 것들을 확인한다.
1. Limit 체크
2. Type 체크
3. 특권 레벨 체크
4. 명령 세트 체크
CPU의 체크 포인트
Limit 체크
세그먼트 디스크립터의 크기를 정하는 limit는 세그먼트 영역을 넘어서 오프셋으로 지정하지 못하게 한다.
오프셋으로 넘어서면 overwrite가 될 위험이 있다.
Limit는 GDT, IDT, TSS 모두 있다.
TSS는 TR 레지스터의 6바이트 중 2바이트를 limit로 사용한다.
Type 체크
용도를 체크하는 역할을 한다. 권한체크가 아니다.
예를 들면, 칼을 음식을 써는데 사용하는 것이 아닌 밥을 퍼 먹는데 사용했을 때 에러가 난다.
특권 레벨
CPL
현재 실행되고 있는 태스크의 특권 레벨을 뜻한다.
CS 레지스터의 0, 1번째 비트에 위치한다.
DPL
스크립터에 기재된 권한을 뜻한다. P비트 다음에 있는 그 권한이다.
디스크립트를 통한 세그먼트 영역으로의 모든 접근에서 항상 CPL과 DPL의 관계를 체크한다.
RPL
특권 레벨 3인 프로세스가 콜게이트를 통해 특권 레벨 0인 루틴을 실행할 때 일시적으로 특권 레벨이 0으로 상승한다.
이 점이 악용되는 것을 막기 위해 RPL이 존재한다.
콜게이트
콜게이트는 권한이 낮은 유저가 권한이 높은 커널의 함수를 호출할 수 있도록 CPU에서 제공하는 것을 의미한다.
위에서 말한 낮은 특권 레벨의 프로그램이 실행 도중 높은 특권 레벨로 변경되는 경우는 주로 인터럽트, 예외, 콜게이트가 있다.
PIC와 예외에서는 프로그램에 권한 상승에 대한 코드 없이 권한 상승이 이루어진다.
반면 소프트웨어 인터럽트와 콜게이트는 권한 상승 코드에 의해 잠깐 동안 권한 상승이 이루어진다.
콜게이트 또한 GDT 테이블에 디스크립터로서 포함된다.
콜게이트의 디스크립터 구조는 다음과 같다.

코드와 데이터의 특권 레벨 관계
특권 레벨 간 JMP 명령은 불가하나 콜게이트를 이용해서는 가능하다.
CALL 같은 경우는 특권 레벨 간 이동이 가능한데, 낮은 특권 레벨에서 높은 특권 레벨로 이동이 가능하다.
RET 같은 경우 높은 특권 레벨에서 낮은 특권 레벨로 이동이 가능하다.
CALL을 사용하여 level 3 → level 1으로 이동 시 CS 레지스터의 0, 1번째 비트에 00이 들어가고 CPL도 0이다.
RET 하여 level1 → level3로 이동 시 CS 레지스터의 0, 1번째 비트에 이진수 11(3)이 들어가고 CPL도 3이 된다.
특권 레벨이 0일 경우에는 모든 특권 레벨의 데이터 세그먼트에 접근이 가능하다.
낮으면 접근이 불가한데, 이때 CALL 명령을 통해 특권 레벨을 상승시키는 방법 밖에 없다.
특권 레벨 변동 시의 스택의 변화
특권 레벨을 상승시킨다는 건 곧 유저 모드에서 커널 모드로 실행이 된다는 것이다.
특권 레벨이 변환될 때 스택에 돌아올 주소 등을 넣고 다시 돌아오면 스택에 넣어둔 값들을 사용한다.
이는 태스크 스위칭이 아니다.
CALL 명령이 내려졌을 때의 스택
커널 모드로 변환 시 잠깐의 권한 상승을 위해 스택에 데이터를 저장하게 된다.
1. CPU가 TSS를 참조하여 커널 모드 스택 주소인 SS0, ESP0을 읽어온다.
2. 커널 모드 스택에 현재 유저 태스크의 SS, ESP, CS, EIP를 PUSH한다,
3. CPU의 SS, ESP 레지스터에 SS0, ESP0 값으로 변경한다.
4. RET 명령을 만나면 커널 스택에 저장된 SS, ESP, CS, EIP를 PIP하여 CPU 레지스터에 다시 넣어 유저 모드로 돌아간다.
호출 구문에 인수가 있을 경우
만약 유저가 유저 스택에 인수 2개를 등록하고 위 과정을 진행하게 되면, 커널 모드에서 유저 모드로 복귀할 때 인수 2개의 값을 찾지 못한다.
이러한 경우 CPU가 콜게이트 디스크립터의 인수 개수 칸을 참고하여 인수를 커널 스택으로 자동 복사한다.
인터럽트 예외가 발생하였을 때 스택
특권 레벨 0에서 인터럽트 발생 시에는 스택 변경이 일어나지 않는다.
콜게이트때와 다르게 현재 유저 태스크의 레지스터 값을 스택에 복사할 때 EFLAGS를 추가하여 PUSH한다.
그리고 커널 모드에 있는 인터럽트 핸들러 루틴으로 점프하여 수행한 뒤 IRET 명령을 통해 유저 모드로 복귀하면서 스택에 넣은 값들을 POP한다.
유저 모드에서 인터럽트가 발생하던, 커널 모드에서 인터럽트가 발생하던, 인터럽트 발생 시 스택에 EFLAG를 추가하여 PUSH한다.
'OS > 만들면서 배우는 OS 커널의 구조와 원리' 카테고리의 다른 글
| 8-1. 페이징 - A20 게이트 (0) | 2026.04.21 |
|---|---|
| 7. 유저모드 Task Switching (0) | 2026.04.19 |
| 5. 태스크 스위칭, 문맥 교환 (0) | 2026.04.13 |
| 4. 인터럽트와 예외 (0) | 2026.04.10 |
| 3. Protected Mode로 변환 (1) | 2026.04.08 |