---
# System prepended metadata

title: 'Chapter 06 : Interrupt'

---

Chapter 06：Interrupt
===

:::info 

作業系統本質上就是中斷驅動的大型軟體，如果沒有中斷，程式只會從頭運行到尾端，也不可能實現排程器，更別說是多工處理了。本節從最底層的 x86 硬體技術：IDT 開始介紹，接著是統一處理 external interrupt 的 8259A，最後是 internal interrupt 中最著名的 system call。
&emsp; 1. IDT
&emsp; 2. 8259A
&emsp; 3. System Call

:::
>[time=Wed, Oct 15, 2025 3:19 AM]
---
https://youtu.be/JUkbPCG6-_E

<iframe width="560" height="315" src="https://www.youtube.com/embed/JUkbPCG6-_E?si=q_Z01qPVfcqxSODQ" 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>

![截圖 2025-10-20 下午5.20.09](https://hackmd.io/_uploads/HkbxkKQRgl.png)

# IDT (Interrupt Descriptor Table)

>Reference: 
>[OSDev wiki](https://wiki.osdev.org/Interrupt_Descriptor_Table)
>[Intel 80386 Reference Programmer's Manual](https://pdos.csail.mit.edu/6.828/2005/readings/i386/s09_05.htm)

>[!Note] Interrupt Gate Descriptor
>![截圖 2025-10-17 晚上7.44.17](https://hackmd.io/_uploads/rkNN3oyCgx.png)
>![截圖 2025-10-19 下午4.41.42](https://hackmd.io/_uploads/HJmuVQGAel.png)

>[!Note] LIDT
>![截圖 2025-10-18 晚上11.37.00](https://hackmd.io/_uploads/BypN4NZ0gg.png)
>![v2-ac423456ae69f2a3af14db8a4d8ba38f_1440w](https://hackmd.io/_uploads/HJSJWr-Alx.jpg)

>[!Note] Interrupt 發生後 stack 的變化 (CPU 自動完成)
>![截圖 2025-10-17 晚上8.10.28](https://hackmd.io/_uploads/HktvM2yCxe.png)
>![截圖 2025-10-17 晚上8.10.52](https://hackmd.io/_uploads/S1gufhJ0xl.png)

>[!Note] Interrupt Vectors
>The x86 architecture defines 256 possible interrupt vectors (0-255).
>* 0x00 - 0x1F: for processor exceptions and non-maskable interrupts (NMIs).
>![截圖 2025-10-17 晚上8.47.58](https://hackmd.io/_uploads/ry5XjnkCxl.png)
>Reference: [OSDev wiki](https://wiki.osdev.org/Exceptions)
>* 0x20 - 0x2F: assigned to maskable hardware interrupts (IRQs) by the PIC/APIC.
>🔹主 8259A (Master PIC): 接收 IRQ0–IRQ7，重新對映至中斷向量 0x20–0x27
>🔹 從 8259A (Slave PIC): 接收 IRQ8–IRQ15，重新對映至中斷向量 0x28–0x2F
>![截圖 2025-10-19 凌晨1.46.48](https://hackmd.io/_uploads/H1RsfLZAxx.png)
>* 0x30 - 0xFF: used for software interrupts or additional hardware interrupts.

>[!Note] inline assembly
```c=
asm ("assembler template"
     : output operands
     : input operands
     : clobbered registers/memory);
```
>Reference: [OSDev wiki](https://wiki.osdev.org/Inline_Assembly)

| Constraint | 對應暫存器         | 範例           | 說明                |
| ---------- | ------------- | ------------ | ----------------- |
| `"a"`      | `eax` / `rax` | `"a"(value)` | 使用累加器寄存器          |
| `"b"`      | `ebx` / `rbx` | `"b"(value)` | 使用 base 寄存器       |
| `"c"`      | `ecx` / `rcx` | `"c"(value)` | 使用計數暫存器           |
| `"d"`      | `edx` / `rdx` | `"d"(value)` | 使用資料寄存器           |
| `"S"`      | `esi` / `rsi` | `"S"(src)`   | Source index      |
| `"D"`      | `edi` / `rdi` | `"D"(dest)`  | Destination index |
| `"r"`      | 任意可用暫存器       | `"r"(value)` | compiler 自動選寄存器   |
| `"m"`      | 記憶體操作數        | `"m"(var)`   | 指向變數的記憶體位置        |
| `"i"`      | 立即數常量         | `"i"(value)` | 用於固定常數            |

```c=
int a = 2, b = 3, result;
asm volatile (
    "addl %2, %1\n\t"   // 將 %2 加到 %1
    "movl %1, %0"       // 將結果放入 %0
    : "=r"(result)      // %0
    : "r"(a), "r"(b)    // %1, %2
);

```

>[!Note] page fault
>When the CPU fires a page-not-present exception the ==CR2== register is populated with the linear address that caused the exception.
>Reference: [OSDev wiki](https://wiki.osdev.org/Paging#Page_Faults)

## Source Code

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

## Compile

```
make all
```

## Put on hard disk

```
sh gen.sh
```

## Checkpoint

![截圖 2025-10-19 晚上10.31.44](https://hackmd.io/_uploads/HJE3LufAxl.png)
![截圖 2025-10-19 凌晨1.10.52](https://hackmd.io/_uploads/ByrN5S-0gl.png)
![截圖 2025-10-19 凌晨1.11.13](https://hackmd.io/_uploads/S1iBcSW0ge.png)

test page fault

![截圖 2025-10-19 晚上10.49.19](https://hackmd.io/_uploads/ry9q9dzCgl.png)

test divide zero
![截圖 2025-10-19 晚上10.50.38](https://hackmd.io/_uploads/rJWyouMRgx.png)

# 8259A (External Interrupt)

![截圖 2025-10-19 下午5.17.25](https://hackmd.io/_uploads/HyB637MRxl.png)
>Reference: [8259A data sheet](https://pdos.csail.mit.edu/6.828/2010/readings/hardware/8259A.pdf)

* INT: 發送訊號通知 CPU。
* INTA: interrupt acknowledge，接收來自 CPU ACK 訊號。

| 暫存器名稱                           | 簡述                            |
| ------------------------------------ | ------------------------------- |
| **IRR** (Interrupt Request Register) | 儲存尚未被 CPU 處理的中斷請求。 |
| **ISR** (In-Service Register)        | 儲存目前正在被 CPU 處理的中斷。 |
| **IMR** (Interrupt Mask Register)    | 指定哪些 IRQ 被遮罩 (mask)。    |
| **PR** (Priority Resolver)           | 找出優先權高的中斷。            |

>[!Note] End of Interrupt
>![99509fac-a86e-48c8-be3c-ccd4879a598f](https://hackmd.io/_uploads/SJPr9mM0lg.png)
>![截圖 2025-10-19 下午5.08.17](https://hackmd.io/_uploads/BkMi9QGCxe.png)
>![截圖 2025-10-19 下午5.09.06](https://hackmd.io/_uploads/rJkA97GRgl.png)

>[!Note] Cascade 8259A
![upload_73e6cceec9ae7fb9fda0eef5c8131f9b](https://hackmd.io/_uploads/SkjJr7f0xg.jpg)


>[!Note] 8259A Programming: Initialization Command Words (ICW)
>![截圖 2025-10-19 下午5.19.50](https://hackmd.io/_uploads/H14IpXzReg.png)
>![截圖 2025-10-19 下午5.20.32](https://hackmd.io/_uploads/H1COpmGAle.png)

| 名稱       | 功能說明                                  |
| -------- | ------------------------------------- |
| **ICW1** | 基本啟動設定（邊緣觸發 / 電平觸發、是否有 ICW4、是否有從 PIC） |
| **ICW2** | 中斷向量號碼的起始位置（中斷偏移量）                    |
| **ICW3** | 主從連線關係設定（主 PIC 哪條 IRQ 連從 PIC）         |
| **ICW4** | 進階控制（8086/8088 模式、自動 EOI、緩衝、特殊全巢狀模式）  |
>[!Caution] 寫入 ICW 有嚴格的規定，必須依序設定 ICW1, ICW2, ICW3, ICW4。

>[!Note] 8259A Programming: Operation Command Word (OCW)
>![截圖 2025-10-19 下午5.35.01](https://hackmd.io/_uploads/B1ekbNzCll.png)
>![截圖 2025-10-19 下午5.35.44](https://hackmd.io/_uploads/HyAZZEMAgg.png)

| 名稱       | 全名                       | 主要用途                     |
| -------- | ------------------------ | ------------------------ |
| **OCW1** | Operation Command Word 1 | 控制每條 IRQ 是否允許 (Mask)     |
| **OCW2** | Operation Command Word 2 | 控制中斷結束 (EOI)、優先權旋轉       |
| **OCW3** | Operation Command Word 3 | 查詢寄存器 (IRR / ISR)、設定輪詢模式 |
>[!Caution] 我們採用固定優先權，IRQ number 越低，優先權越高。

![upload_106057987cd2cdd51bb4f70ce96c2672](https://hackmd.io/_uploads/Sk-fSmGAex.png)
![截圖 2025-10-19 下午4.47.46](https://hackmd.io/_uploads/BkbABXMRgg.png)
>Reference: [Bochs' map of I/O ports to functions](https://bochs.sourceforge.io/techspec/PORTS.LST)

>[!Caution] I/O port 0x20 如何辨識 registers
>ICW1: [4:3]=b'10
>OCW2: [4:3]=b'00
>OCW3: [4:3]=b'01
>ICW2, ICW3, ICW4, OCW1: 依據寫入流程。

>[!Note] Port Operations
>![截圖 2025-10-20 晚上8.31.14](https://hackmd.io/_uploads/HJG0soQRgx.png)
>![截圖 2025-10-20 晚上8.36.51](https://hackmd.io/_uploads/r1lWTjQRex.png)
>![截圖 2025-10-20 晚上8.40.14](https://hackmd.io/_uploads/Hk5T6sQAxg.png)
>Reference: [x86 Instruction Set Reference](https://c9x.me/x86/)

>[!Note] Interrupt Flag
>![截圖 2025-10-19 晚上10.10.24](https://hackmd.io/_uploads/rJPdZ_zAlx.png)
>![截圖 2025-10-19 晚上10.11.01](https://hackmd.io/_uploads/Hya9Z_fCxg.png)
>![upload_1ad1cb15dbe0b9946a577cd963214de5](https://hackmd.io/_uploads/SkOAbOGRgg.png)


## Source Code

https://github.com/srhuang/a-os/commit/3f8c917f5646f5a6c369c2d1181f5e1492b381db

## Compile

```
make all
```

## Put on hard disk

```
sh gen.sh
```

## Checkpoint

![截圖 2025-10-19 晚上11.01.41](https://hackmd.io/_uploads/rkOuTOM0lx.png)

unmask system timer
![截圖 2025-10-19 晚上10.54.46](https://hackmd.io/_uploads/rkLk2_MRex.png)

![截圖 2025-10-19 晚上10.54.05](https://hackmd.io/_uploads/HkWnj_f0el.png)

# System Call (Internal Interrupt)

![截圖 2025-10-20 凌晨1.24.20](https://hackmd.io/_uploads/BJ-1JsGRxl.png)

## Source Code

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

>[!Warning] Bug fix
>https://github.com/srhuang/a-os/commit/786e9091f5b5f088e881406400983b8ef0b1e978

## Compile

```
make all
```

## Put on hard disk

```
sh gen.sh
```

## Checkpoint

![截圖 2025-10-20 凌晨1.13.40](https://hackmd.io/_uploads/SkHdnqz0xg.png)

