Lab 4 Background Knowledge

Memory Layout

因為每個 task 的記憶體是獨立分開的,所以需要為每個 task 分配屬於自己的 user stack 及 kernel stack。目前因為沒有 Dynamic Allocator,所以記憶體都是使用靜態宣告。

我是參考 TA 的 Reference Design

+------------------+
| Arm Peripherals  |
+------------------+ <- 0x40000000
| GPU Peripherals  |
+------------------+ <- 0x3f000000
|        .         |
+------------------+
|   User stack[n]  |
+------------------+
|        .         |
|        .         |
+------------------+
|   User stack[0]  |
+------------------+
|  Kernel stack[n] |
+------------------+
|        .         |
|        .         |
+------------------+
|  Kernel stack[0] |
+------------------+
|  Interrupt stack |
+------------------+
|  kernel/user bss |
+------------------+
| kernel/user data |
+------------------+
| kernel/user text |
+------------------+ <- kernel_base (0x80000)

Interrupt stack 會在第一次 IRQ 觸發時,從 kernel stack 切換過去,好處是可以將一些不屬於任意 task 的操作 (e.g. Timer Interrupt) 所使用的記憶體不要去占用到 kernel stack,會比較乾淨一點。

也有另外一種設計是把 Interrupt stack 不獨立出來,放在 kernel stack 上

Privilege tasks & User tasks

Privilege tasks:

  • 只跑在 kernel mode
  • 跑一些需要 kernel mode 權限的程式 (e.g. zombie reaper, idle task)

User tasks:

  • 大部分時間都跑在 user mode
  • 發生 exception 時切換到 kernel mode
  • 當進入/離開 kernel 時,需要保存/復原 context

In common:

  • 都有 kernel stack
  • 在 kernel mode 時會被 context switch
  • 跑在相同的 runqueue

Runtime state

圖片來自 Lab 4 Spec

在實驗中,將狀態區分成 5 種:

  1. Task in User Mode (發生 exception 時到狀態 2)
  2. Task at entry/exit of kernel routine (保存/復原 context)
  3. Task runs a kernel routine (使用自己的 kernel stack 跑 kernel code)
  4. Task in interrupt context (interrupt 可能發生在 user mode 或是 kernel mode,interrupt context 不屬於任何 task,使用 interrupt stack)
  5. Context switch state (Voluntary context switch / Involuntary context switch)

Scheduler 是一個 Process 嗎?

老師上課很常提到一件事:「kernel 是死的,是存在記憶體的一段 code,process 才是活的。」

Scheduler 其實只是一段 kernel 的 code,用來決定下一個 process 該是誰要跑,由此可知 scheduler 自己其實不是一個 process。

comments powered by Disqus