Chapter 06:Interrupt
===
:::info
作業系統本質上就是中斷驅動的大型軟體,如果沒有中斷,程式只會從頭運行到尾端,也不可能實現排程器,更別說是多工處理了。本節從最底層的 x86 硬體技術:IDT 開始介紹,接著是統一處理 external interrupt 的 8259A,最後是 internal interrupt 中最著名的 system call。
  1. IDT
  2. 8259A
  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>

# 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
>
>
>[!Note] LIDT
>
>
>[!Note] Interrupt 發生後 stack 的變化 (CPU 自動完成)
>
>
>[!Note] Interrupt Vectors
>The x86 architecture defines 256 possible interrupt vectors (0-255).
>* 0x00 - 0x1F: for processor exceptions and non-maskable interrupts (NMIs).
>
>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
>
>* 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



test page fault

test divide zero

# 8259A (External Interrupt)

>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
>
>
>
>[!Note] Cascade 8259A

>[!Note] 8259A Programming: Initialization Command Words (ICW)
>
>
| 名稱 | 功能說明 |
| -------- | ------------------------------------- |
| **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)
>
>
| 名稱 | 全名 | 主要用途 |
| -------- | ------------------------ | ------------------------ |
| **OCW1** | Operation Command Word 1 | 控制每條 IRQ 是否允許 (Mask) |
| **OCW2** | Operation Command Word 2 | 控制中斷結束 (EOI)、優先權旋轉 |
| **OCW3** | Operation Command Word 3 | 查詢寄存器 (IRR / ISR)、設定輪詢模式 |
>[!Caution] 我們採用固定優先權,IRQ number 越低,優先權越高。


>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
>
>
>
>Reference: [x86 Instruction Set Reference](https://c9x.me/x86/)
>[!Note] Interrupt Flag
>
>
>
## Source Code
https://github.com/srhuang/a-os/commit/3f8c917f5646f5a6c369c2d1181f5e1492b381db
## Compile
```
make all
```
## Put on hard disk
```
sh gen.sh
```
## Checkpoint

unmask system timer


# System Call (Internal Interrupt)

## 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
