---
# System prepended metadata

title: Chapter 03-1：Privilege Level Switching

---

Chapter 03-1：Privilege Level Switching
===

:::info 

GDT 遠比我們想的更加複雜，為了能更加深刻理解 GDT 的運作，我們另外設計測試程式來幫助我們更好理解 GDT 的運作。
&emsp; 1. GDT Basic。
&emsp; 2. Ring 0 to Ring 3: retf。
&emsp; 3. Call Gate。
&emsp; 4. Ring 3 to Ring 0: Call Gate and TSS。
:::
>[time=Tue, Sep 2, 2025 5:43 PM]
---

https://youtu.be/zVd-MjakdEI
<iframe width="560" height="315" src="https://www.youtube.com/embed/zVd-MjakdEI?si=UEEnLkdblOv7rluZ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

>Reference: [利用Call Gate與TSS (Task-State Segment)實現特權等級的轉換](https://jasonblog.github.io/note/os/1417.html)
>這個參考文件寫得相當好，而且也有搭配清晰的圖作為輔助。

# GDT Basic

>Reference:[Segment-Level Protection](https://pdos.csail.mit.edu/6.828/2004/readings/i386/s06_03.htm)

主要會做以下保護以及確認：
* Type checking：Code segment or data segment。
* Limit checking
* Privilege Levels
    * Accessing Data in Data Segments
    ![截圖 2025-09-06 凌晨1.30.47](https://hackmd.io/_uploads/rkvDAqdqll.png)
    * Restricting Control Transfers
    ![截圖 2025-09-06 凌晨1.33.23](https://hackmd.io/_uploads/S1GWyjdcxg.png)

:::warning
CPL: 特指 CS 當前的特權級。
RPL: Selector 裡面 RPL 欄位的特權級。
DPL: 在 GDT descriptor 裡面描述 segment 的特權級。
:::

>[!Note] Memory Layout
>![截圖 2025-09-06 凌晨1.20.11](https://hackmd.io/_uploads/BJlZhqOclg.png)

>[!Note] Code Flow
>![截圖 2025-09-06 凌晨1.24.58](https://hackmd.io/_uploads/BJ176cO9gx.png)

## Source Code

https://github.com/srhuang/a-os/commit/c548634472f9af6958f309103a59d263809ba580

## Compile

```sh
nasm boot/loader.s -I boot/ -o out/loader.bin 
```

## Put on hard disk

```sh
dd if=../code/out/loader.bin of=./60mb.img bs=512 count=4 seek=1 conv=notrunc
```

## Checkpoint

![截圖 2025-09-04 凌晨1.18.11](https://hackmd.io/_uploads/BkGOOgIcee.png)
![截圖 2025-09-04 凌晨4.42.00](https://hackmd.io/_uploads/HyjnOQ8ceg.png)

# Ring 0 to Ring 3


>[!Caution] CPU 原生設計是不允許高特權往低特權跳轉，唯一的方式就是使用 retf 的方式跳轉。

在 x86 的 inter-privilege-level far return (retf 但 RPL ≠ CPL) 的情況下，處理器會從 堆疊中依序 pop 這些東西：
* IP / EIP → return address (指令指標)
* CS → return code segment
* SP / ESP → 呼叫者的 stack pointer
* SS → 呼叫者的 stack segment

👉 所以會 pop 4 個項目（IP、CS、SP、SS），而不是一般情況下的 2 個（IP、CS）。

```asm=171
push SELECTOR_B_STACK   ; stack segment
push B_STACK_TOP        ; top of stack
push SELECTOR_B_CODE    ; code segment
push 0                  ; EIP
retf
```

>[!Note] Memory Layout
>![截圖 2025-09-06 凌晨1.11.48](https://hackmd.io/_uploads/r1mG99d5le.png)

>[!Note] Code Flow
>![截圖 2025-09-06 凌晨1.16.08](https://hackmd.io/_uploads/HJDli5_5lx.png)

## Source Code

https://github.com/srhuang/a-os/commit/a4d7ff54c13b819f533eff0a51c376d5511f57db

## Compile

```sh
nasm boot/loader.s -I boot/ -o out/loader.bin 
```

## Put on hard disk

```sh
dd if=../code/out/loader.bin of=./60mb.img bs=512 count=4 seek=1 conv=notrunc
```

## Checkpoint

![截圖 2025-09-04 晚上10.26.52](https://hackmd.io/_uploads/rkRpZQD5gx.png)
![截圖 2025-09-04 晚上10.31.47](https://hackmd.io/_uploads/S14iXQvqxg.png)

# Call Gate

>[!Tip] 這邊展示的是沒有特權級轉換的 call gate，下部分才會展示有特權級轉換的 call gate。

>[!Note] Call Gate Descriptor
>![截圖 2025-09-05 凌晨2.20.27](https://hackmd.io/_uploads/SyqKOIv5gg.png)
>DWORD COUNT: This field specifies the number of doublewords (DWORDs) to copy from the caller's stack to the new stack associated with the higher privilege level. 
>在特權等級轉換的情況下，主要是用做參數的傳遞。

>[!Note] Memory Layout
>![截圖 2025-09-06 凌晨12.58.08](https://hackmd.io/_uploads/SygaL9_9gl.png)

>[!Note] Code Flow
>![截圖 2025-09-06 凌晨1.01.25](https://hackmd.io/_uploads/BkqFPc_5xx.png)


## Source Code

https://github.com/srhuang/a-os/commit/4ad72ddab1af6db2d6b421406c4407565a33b66c

## Compile

```sh
nasm boot/loader.s -I boot/ -o out/loader.bin 
```

## Put on hard disk

```sh
dd if=../code/out/loader.bin of=./60mb.img bs=512 count=4 seek=1 conv=notrunc
```

## Checkpoint

![截圖 2025-09-05 凌晨2.24.24](https://hackmd.io/_uploads/SJhtYLvqeg.png)
![截圖 2025-09-05 凌晨2.28.30](https://hackmd.io/_uploads/S1XZiIPcgg.png)

# Ring 3 to Ring 0

>[!Tip] 我們會使用 call gate 來進行低特權往高特權跳轉，低特權跳轉高特權還需要 TSS 的協助。

>Reference: 
>[利用Call Gate與TSS (Task-State Segment)實現特權等級的轉換](https://jasonblog.github.io/note/os/1417.html)
>[Task State Segment](https://pdos.csail.mit.edu/6.828/2004/readings/i386/s07_01.htm)

>[!Note] TSS data structure
>![截圖 2025-09-05 凌晨4.09.22](https://hackmd.io/_uploads/rk1Qz_v9gl.png)

>[!Note] TSS Descriptor
>![截圖 2025-09-05 凌晨4.27.09](https://hackmd.io/_uploads/Hy3EU_D9ee.png)

>[!Note] LTR: load Task Register
>![截圖 2025-09-06 下午5.03.16](https://hackmd.io/_uploads/HkKZF_tceg.png)

>[!Note] Memory Layout
>![截圖 2025-09-06 凌晨12.17.43](https://hackmd.io/_uploads/ByuHpK_9el.png)

>[!Note] Code Flow
>![截圖 2025-09-06 下午5.01.12](https://hackmd.io/_uploads/SJ29__F9xx.png)

## Source Code

https://github.com/srhuang/a-os/commit/461fe96aaa305dd2707922cd39dd45f7fb3fca97

## Compile

```sh
nasm boot/loader.s -I boot/ -o out/loader.bin 
```

## Put on hard disk

```sh
dd if=../code/out/loader.bin of=./60mb.img bs=512 count=4 seek=1 conv=notrunc
```

## Checkpoint

![截圖 2025-09-05 下午4.39.15](https://hackmd.io/_uploads/rk7AWmO9xg.png)
![截圖 2025-09-05 下午4.34.00](https://hackmd.io/_uploads/SJp8b7Ocle.png)

觀察 stack pointer(SP) 的變化。
![截圖 2025-09-15 下午3.09.59](https://hackmd.io/_uploads/rJmZhVBjll.png)


