태스크 스테이트 세그먼트
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
태스크 스테이트 세그먼트(TSS)는 x86 아키텍처에서 태스크의 상태 정보를 저장하는 메모리 영역이다. TSS는 메모리 어디에든 위치할 수 있으며, 전역 디스크립터 테이블(GDT)에 TSS 디스크립터를 생성하고 태스크 레지스터(TR)에 세그먼트 선택자를 로드하여 사용한다. TSS는 레지스터 값, 스택 포인터, I/O 포트 권한 비트맵 등 다양한 정보를 저장하며, 특히 특권 레벨 변경 시 스택 포인터를 지정하는 데 사용된다. x86-64 환경에서는 하드웨어 태스크 전환 기능이 폐지되었지만, 스택 포인터 및 I/O 권한 비트맵을 위해 TSS가 여전히 사용된다. 리눅스 커널은 각 CPU당 하나의 TSS를 사용하여 I/O 포트 권한 비트맵과 내부 스택 기능을 활용하며, TSS 접근에 문제가 발생하면 유효하지 않은 TSS 예외가 발생한다.
TSS는 메모리의 어느 곳에나 위치할 수 있다. TR이라고 하는 세그먼트 레지스터는 세그먼트 선택자를 가지며, 이는 GDT에 있는 유효한 TSS 세그먼트 디스크립터를 가리킨다. TSS 디스크립터는 GDT에 위치한다.
2. TSS의 위치 및 구조
보안을 위해 TSS는 커널만 접근할 수 있는 메모리에 배치해야 한다.
TSS는 16비트, 32비트, 64비트의 세 가지 종류가 있으며, 각각 다른 구조를 가진다.
| 15 - 0 |
|---|
| 태스크의 LDT 선택자 |
| DS |
| SS |
| CS |
| ES |
| DI |
| SI |
| BP |
| SP |
| BX |
| DX |
| CX |
| AX |
| FLAGS |
| IP |
| SS (특권 레벨 2) |
| SP (특권 레벨 2) |
| SS (특권 레벨 1) |
| SP (특권 레벨 1) |
| SS (특권 레벨 0) |
| SP (특권 레벨 0) |
| 백 링크 선택자 |
- 32비트 TSS 구조
| 31 - 16 | 15 - 1 | 0 |
|---|---|---|
| I/O 허가 비트맵 영역 | ||
| 인터럽트 리다이렉션 비트맵 | ||
| OS 사용 가능 영역 | ||
| I/O 허가 비트맵 오프셋 | 0 | T |
| 0 | 태스크의 LDT 선택자 | |
| 0 | GS | |
| 0 | FS | |
| 0 | DS | |
| 0 | SS | |
| 0 | CS | |
| 0 | ES | |
| EDI | ||
| ESI | ||
| EBP | ||
| ESP | ||
| EBX | ||
| EDX | ||
| ECX | ||
| EAX | ||
| EFLAGS | ||
| EIP | ||
| CR3 | ||
| 0 | SS (특권 레벨 2) | |
| ESP (특권 레벨 2) | ||
| 0 | SS (특권 레벨 1) | |
| ESP (특권 레벨 1) | ||
| 0 | SS (특권 레벨 0) | |
| ESP (특권 레벨 0) | ||
| 0 | 백 링크 선택자 |
- 64비트 TSS 구조
| 63 - 48 | 47 - 32 | 31 - 16 | 15 - 0 |
|---|---|---|---|
| I/O 허가 비트맵 영역 | |||
| OS 사용 가능 영역 | |||
| I/O 허가 비트맵 오프셋 | 예약됨 | ||
| 예약됨 | |||
| IST 7 | |||
| IST 6 | |||
| IST 5 | |||
| IST 4 | |||
| IST 3 | |||
| IST 2 | |||
| IST 1 | |||
| 예약됨 | |||
| RSP (특권 레벨 2) | |||
| RSP (특권 레벨 1) | |||
| RSP (특권 레벨 0) | |||
| 예약됨 |
2. 1. 태스크 레지스터 (Task Register, TR)
TR(태스크 레지스터)은 TSS의 세그먼트 선택자를 저장하는 16비트 레지스터이다. TR은 LTR 명령을 통해 로드될 수 있는데, LTR은 특권 명령이며 다른 세그먼트 레지스터 로드와 유사하게 작동한다. 태스크 레지스터는 프로그래머가 보고 접근할 수 있는 부분과 TSS 디스크립터에서 자동으로 로드되는 숨겨진 부분으로 구성된다.[1] LTR 명령을 실행해도 초기 태스크의 TSS를 지정할 뿐, 하드웨어 태스크 스위치는 일어나지 않는다.[1]2. 2. 레지스터 정보
TSS는 x86 레지스터의 값을 저장할 수 있으며, 이는 태스크 전환에 사용된다. CPU는 세그먼트 셀렉터에 TSS의 셀렉터 또는 태스크 게이트의 셀렉터를 지정한 FAR CALL/FAR JUMP 실행, 또는 NT 플래그가 설정된 상태에서의 IRET 명령에 의한 하드웨어 태스크 스위칭 실행 시, 현재 태스크의 레지스터 정보를 TSS에 저장하고, 새로운 태스크의 TSS에서 레지스터 정보를 레지스터로 로드한다. 그러나 Windows 및 리눅스[1]와 같은 현대적인 운영체제는 x86이 가진 하드웨어 태스크 스위칭 기능을 사용하지 않으며, 레지스터 정보, TSS의 백 링크 셀렉터, LDT 셀렉터 필드는 사용되지 않는다.[4]x64에서는 하드웨어 태스크 스위칭 기능이 폐지되었으며, 레지스터 정보의 위치에는 IST (Interrupt Stack Table, 인터럽트 스택 테이블)의 정보를 설정한다.
하드웨어 태스크 전환 중에는 읽기/쓰기 필드와 읽기 전용 필드가 나뉜다.
- '''읽기/쓰기 필드'''는 하드웨어 태스크 전환 중에 읽고 쓰여진다.
- 모든 범용 레지스터(
EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP) - 모든 세그먼트 레지스터(
CS,DS,ES,FS,GS,SS) - 현재 실행 상태(
EIP,EFlags) - 태스크 전환이
JMP가 아닌CALL또는INT로 인해 발생한 경우 ''새'' TSS의Link필드 - '''읽기 전용 필드'''는 필요에 따라 읽기 전용으로 사용된다.
- 제어 레지스터 3(
CR3), 페이지 디렉터 기본 레지스터(PDBR)라고도 함. - 로컬 디스크립터 테이블 레지스터(
LDTR) - 세 개의 권한 수준 스택 쌍(
SS0:ESP0,SS1:ESP1,SS2:ESP2) - IO 포트 비트맵 포인터(
IOPB) 및 I/O 포트 비트맵 자체
16비트, 32비트, 64비트 TSS의 레지스터 정보는 다음과 같다.
- 16비트 TSS
| 15 - 0 |
|---|
| 태스크의 LDT 선택자 |
| DS |
| SS |
| CS |
| ES |
| DI |
| SI |
| BP |
| SP |
| BX |
| DX |
| CX |
| AX |
| FLAGS |
| IP |
| SS(특권 레벨 2) |
| SP(특권 레벨 2) |
| SS(특권 레벨 1) |
| SP(특권 레벨 1) |
| SS(특권 레벨 0) |
| SP(특권 레벨 0) |
| 백 링크 선택자 |
- 32비트 TSS
| 31 - 16 | 15 - 1 | 0 |
|---|---|---|
| 0 | 태스크의 LDT 선택자 | |
| 0 | GS | |
| 0 | FS | |
| 0 | DS | |
| 0 | SS | |
| 0 | CS | |
| 0 | ES | |
| EDI | ||
| ESI | ||
| EBP | ||
| ESP | ||
| EBX | ||
| EDX | ||
| ECX | ||
| EAX | ||
| EFLAGS | ||
| EIP | ||
| CR3 | ||
| 0 | SS(특권 레벨 2) | |
| ESP(특권 레벨 2) | ||
| 0 | SS(특권 레벨 1) | |
| ESP(특권 레벨 1) | ||
| 0 | SS(특권 레벨 0) | |
| ESP(특권 레벨 0) | ||
| 0 | 백 링크 선택자 | |
- 64비트 TSS
| 63 - 48 | 47 - 32 | 31 - 16 | 15 - 0 |
|---|---|---|---|
| 예약됨 | |||
| IST 7 | |||
| IST 6 | |||
| IST 5 | |||
| IST 4 | |||
| IST 3 | |||
| IST 2 | |||
| IST 1 | |||
| 예약됨 | |||
| RSP(특권 레벨 2) | |||
| RSP(특권 레벨 1) | |||
| RSP(특권 레벨 0) | |||
| 예약됨 | |||
2. 3. I/O 포트 권한 비트맵 (I/O Permission Bitmap)
TSS는 현재 태스크의 I/O 포트 권한 비트맵에 대한 16비트 포인터를 포함한다. 이 비트맵은 보통 태스크가 시작될 때 운영 체제에 의해 설정되며, 프로그램이 접근할 수 있는 개별 포트를 지정한다. I/O 비트맵은 포트 접근 권한의 비트 배열이다. 프로그램이 포트에 접근할 수 있는 권한이 있으면 해당 비트 인덱스에 "0"이 저장되고, 권한이 없으면 "1"이 저장된다. TSS의 세그먼트 제한이 전체 비트맵보다 작으면 누락된 모든 비트는 "1"로 간주된다.[1]프로그램이 IN 또는 OUT 같은 x86 I/O 포트 명령을 실행하면(x86 명령어 목록 참조 - 바이트, 워드 및 더블 워드 길이 버전이 있음), 하드웨어는 프로그램이 모든 I/O 포트에 접근할 수 있는지 확인하기 위해 I/O 권한 레벨(IOPL) 검사를 수행한다. 프로그램의 현재 권한 레벨(CPL)이 I/O 권한 레벨(IOPL)보다 수치적으로 크면(프로그램이 IOPL이 지정하는 것보다 권한이 적음) 프로그램은 모든 포트에 대한 I/O 포트 접근 권한이 없다. 그러면 하드웨어는 TSS의 I/O 권한 비트맵을 확인하여 해당 프로그램이 IN 또는 OUT 명령의 특정 포트에 접근할 수 있는지 확인한다. I/O 포트 권한 비트맵의 (모든) 관련 비트가 지워져 있으면 프로그램은 포트에 대한 접근이 허용되고 명령이 실행될 수 있다. (모든) 관련 비트가 설정되어 있거나 비트가 TSS의 세그먼트 제한을 초과하는 경우 프로그램은 접근 권한이 없으며 프로세서는 일반 보호 오류를 생성한다. 이 기능을 통해 운영 체제는 사용자 프로그램에 선택적인 포트 액세스를 허용할 수 있다.[1]
80286 이후의 CPU에서는 태스크가 I/O 포트 접근 명령(IN, OUT 등)을 실행했을 때, CPU는 플래그 레지스터의 IOPL(I/O 특권 레벨)과 태스크의 특권 레벨인 CPL(현재 특권 레벨)을 비교한다. CPL 쪽이 특권이 높거나 같으면 모든 I/O 포트 접근이 허가된다. CPL이 IOPL보다 특권이 낮은 경우에는 모든 I/O 포트 접근이 허가되지 않는다.[1]
80386 이후에는 TSS가 확장되어 I/O 허가 비트맵이 TSS에 추가되었다. 이 비트맵은 운영 체제에 의해 설정되며, 어떤 I/O 포트에 접근 가능한지를 지정한다. CPL 쪽이 IOPL보다 특권이 높거나 같으면 모든 I/O 포트 접근이 허가된다. CPL이 IOPL보다 특권이 낮은 경우, CPU는 I/O 허가 비트맵을 체크하여 접근하려는 I/O 포트의 비트가 0이면 해당 I/O 포트에 대한 접근이 허가된다. 비트가 1이면 해당 포트에 대한 접근은 불가능하며, 일반 보호 예외가 발생한다. 이 기능을 통해 운영 체제는 태스크에 대해 I/O 포트마다 접근 권한을 제한할 수 있다.[1]
2. 4. 특권 레벨 스택 포인터
TSS(태스크 상태 세그먼트)는 권한 레벨 변경이 발생할 때 새로운 스택 포인터를 지정하기 위한 필드들을 포함한다. 예를 들어, 보호 모드(32비트)에서 인터럽트가 발생하면 x86 CPU는 TSS에서 SS0과 ESP0을 찾아 해당 값을 각각 SS와 ESP에 로드한다. 이를 통해 커널은 사용자 프로그램과 다른 스택을 사용할 수 있으며, 각 사용자 프로그램에 대해 이 스택이 고유하게 된다.AMD64 확장 기능에 도입된 인터럽트 스택 테이블(IST)은 TSS에 위치하며 논리적(세그먼트+오프셋) 스택 포인터를 포함한다. 인터럽트 디스크립터 테이블이 사용할 IST 항목을 지정하는 경우(7개가 있음) 프로세서는 IST에서 새 스택을 로드한다. 이를 통해 심각한 오류가 발생할 경우(NMI 또는 더블 폴트 등) 알려진 정상 스택을 사용할 수 있다.
TSS는 특권 레벨 0, 1, 2의 스택 포인터 초기값을 저장한다. 특권 레벨 전환이 발생한 경우, CPU는 TSS로부터 스택 포인터를 자동으로 로드하여 특권 레벨마다 다른 스택을 사용한다.
16비트 TSS의 경우, 특권 레벨 0, 1, 2에 대한 SS(스택 세그먼트)와 SP(스택 포인터) 값이 TSS의 특정 위치에 저장된다.
| 15 - 0 |
|---|
| SS (특권 레벨 2) |
| SP (특권 레벨 2) |
| SS (특권 레벨 1) |
| SP (특권 레벨 1) |
| SS (특권 레벨 0) |
| SP (특권 레벨 0) |
32비트 TSS의 경우, 특권 레벨 0, 1, 2에 대한 SS(스택 세그먼트)와 ESP(확장 스택 포인터) 값이 TSS의 특정 위치에 저장된다.
| 31 - 16 | 15 - 1 | 0 |
|---|---|---|
| 0 | SS (특권 레벨 2) | |
| ESP (특권 레벨 2) | ||
| 0 | SS (특권 레벨 1) | |
| ESP (특권 레벨 1) | ||
| 0 | SS (특권 레벨 0) | |
| ESP (특권 레벨 0) | ||
64비트 TSS의 경우, 특권 레벨 0, 1, 2에 대한 RSP(확장 스택 포인터) 값이 TSS의 특정 위치에 저장되며, 추가적으로 인터럽트 스택 테이블(IST)을 위한 공간이 할당되어 있다.
| 63 - 48 | 47 - 32 | 31 - 16 | 15 - 0 |
|---|---|---|---|
| IST 7 | |||
| IST 6 | |||
| IST 5 | |||
| IST 4 | |||
| IST 3 | |||
| IST 2 | |||
| IST 1 | |||
| RSP (특권 레벨 2) | |||
| RSP (특권 레벨 1) | |||
| RSP (특권 레벨 0) | |||
2. 5. 인터럽트 스택 테이블 (Interrupt Stack Table, IST)
AMD64 확장 기능에 도입된 새로운 기능은 인터럽트 스택 테이블(Interrupt Stack Table, IST)이며, TSS에 위치하며 논리적(세그먼트+오프셋) 스택 포인터를 포함한다. 인터럽트 디스크립터 테이블이 사용할 IST 항목을 지정하는 경우(7개가 있음) 프로세서는 IST에서 새 스택을 로드한다. 이를 통해 심각한 오류가 발생할 경우(NMI 또는 더블 폴트 등) 알려진 정상 스택을 사용할 수 있다. 이전에는 IDT의 예외 또는 인터럽트 항목이 태스크 게이트를 가리켜 프로세서가 태스크 게이트가 가리키는 태스크로 전환하도록 했다. 원래 레지스터 값은 인터럽트 또는 예외가 발생한 시점의 TSS에 저장되었다. 그런 다음 프로세서는 SS:ESP를 포함한 레지스터를 TSS에 지정된 알려진 값으로 설정하고 이전 TSS에 대한 선택자를 저장했다. 여기서 문제는 하드웨어 태스크 전환이 AMD64에서 지원되지 않는다는 것이다.[1]x64에서는 하드웨어 태스크 스위치 기능이 폐지되었지만, TSS 자체는 계승되어 특권 레벨 0, 1, 2에서의 스택 포인터, IST(Interrupt Stack Table, 인터럽트 스택 테이블), I/O 허가 비트맵과 같은 정보가 저장된다.[1]
태스크 레지스터(Task Register, TR)는 64비트의 주소를 저장할 수 있도록 확장되었다.[1]
64비트 TSS의 구조는 다음과 같다.[1]
| 63 - 48 | 47 - 32 | 31 - 16 | 15 - 0 |
|---|---|---|---|
| I/O 허가 비트맵 영역 | |||
| OS 사용 가능 영역 | |||
| I/O 허가 비트맵 오프셋 | 예약됨 | ||
| 예약됨 | |||
| IST 7 | |||
| IST 6 | |||
| IST 5 | |||
| IST 4 | |||
| IST 3 | |||
| IST 2 | |||
| IST 1 | |||
| 예약됨 | |||
| RSP(특권 레벨 2) | |||
| RSP(특권 레벨 1) | |||
| RSP(특권 레벨 0) | |||
| 예약됨 | |||
2. 6. 이전 TSS 링크 (Previous TSS Link)
이전 TSS 링크는 이전 TSS와 연결할 수 있게 해주는 16비트 선택자이다. 이는 하드웨어 태스크 전환에만 사용된다. 자세한 내용은 IA-32 매뉴얼을 참조하면 된다. IRET 명령으로 이전 태스크로 하드웨어 태스크 스위치를 사용하여 복귀할 때 사용된다.[1]16비트 및 32비트 TSS의 백 링크 선택자는 다음과 같다.
| 아키텍처 | 내용 |
|---|---|
| 16비트 TSS | 15 - 0: 백 링크 선택자 |
| 32비트 TSS | 31 - 16: 0, 15 - 0: 백 링크 선택자 |
x86-64 아키텍처는 하드웨어 태스크 전환을 지원하지 않지만, TSS는 64비트 확장 모드에서 실행되는 시스템에서 여전히 사용된다. 이 모드에서 TSS는 다음과 같은 정보를 담고 있어 유용하다.
3. x86-64 (64비트) 환경에서의 TSS
x64에서는 하드웨어 태스크 스위치 기능이 없어졌지만, TSS 자체는 유지되어 다음과 같은 정보가 저장된다.
태스크 레지스터(TR)는 64비트 주소를 저장할 수 있도록 확장되었다.
4. 리눅스에서의 TSS 활용
리눅스 커널은 각 CPU마다 하나의 TSS만 생성하여 모든 태스크에 사용한다. 이 방식은 다른 아키텍처로의 이식성을 쉽게 제공하고(예: AMD64 아키텍처는 하드웨어 태스크 전환을 지원하지 않음), 성능과 유연성을 향상시키기 위해 선택되었다. 리눅스는 TSS의 I/O 포트 권한 비트맵과 내부 스택 기능만 사용하며, 다른 기능은 리눅스 커널에서 사용하지 않는 하드웨어 태스크 전환에만 필요하다.[2]
5. TSS 관련 예외
x86 예외 벡터 10은 유효하지 않은 TSS 예외(#TS)라고 불린다. TSS 접근에 문제가 발생할 때마다 프로세서에 의해 발생한다. 예를 들어 CPL=3에서 인터럽트가 발생하여 CPL=0으로 제어가 전송되는 경우, 스택 전환을 위해 TSS를 사용하여 SS0과 ESP0/RSP0를 추출한다. 태스크 레지스터가 잘못된 TSS 선택자를 가지고 있으면 #TS 오류가 발생한다. 유효하지 않은 TSS 예외는 정상적인 운영 체제 작동 중에는 발생해서는 안 되며, 항상 커널 버그 또는 하드웨어 오류와 관련이 있다.[3]
TSS 예외에 대한 자세한 내용은 IA-32 매뉴얼의 3a권 6장을 참조하면 된다.[3]
참조
[1]
서적
Understanding the Linux Kernel, Third Edition
https://books.google[...]
O'Reilly Media
2009-11-23
[2]
서적
Understanding the Linux Kernel
https://books.google[...]
O'Reilly
2014-02-25
[3]
서적
Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3a
http://www.intel.com[...]
2012-05-21
[4]
서적
Understanding the Linux Kernel, Third Edition
https://books.google[...]
O'Reilly Media
2009-11-23
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com