版本 540d70a7ddcabfd4d596f40498502fd64e049c35
系統軟體課程進度與開放資源
- Instructor: Jim Huang (黃敬群)
<jserv.tw@gmail.com>
- Facebook 粉絲專頁 (不要擔心提了笨問題,這專門用來和學生互動,可預約一對一討論)
- 討論區: https://www.facebook.com/groups/system.software2020/
- 課程信箱:
<embedded.master2015@gmail.com>
, 往年課程進度 - 注意: 下方課程進度表標註有
*
的項目,表示內附錄影的教材
進階電腦系統理論與實作 (Fall 2020)
- 第 1 週 (Sep 8): 誠實面對自己
- 課程簡介和注意須知 / 課程簡介和作業解說錄影
*
- 每週均安排隨堂測驗,採計其中最高分的 8 次
- 學期評分方式: 隨堂測驗 (20%) + 個人作業+分組報告 (30%) + 自我評分 (25%)
- 在 Dcard 的課程問答
- 歷屆修課學生心得: 張家榮, 陳品睿, 蕭奕凱, 方鈺學
- 分組報告示範: ARM-Linux
- GNU/Linux 開發工具共筆
*
: 務必 自主 學習 Linux 操作, Git, HackMD, LaTeX 語法 (特別是數學式), GNU make, perf, gnuplot - 透過 Computer Systems: A Programmer’s Perspective 學習系統軟體
*
: 本課程指定的教科書 (請及早購買: 天瓏書店) - 軟體缺失導致的危害
- 1970 年代推出的首款廣體民航客機波音 747 軟體由大約 40 萬行程式碼構成,而 2011 年引進的波音 787 的軟體規模則是波音 747 的 16 倍,約 650 萬行程式碼。換言之,你我的性命緊繫於一系列極為複雜的軟體系統之中,能不花點時間了解嗎?
- 軟體開發的安全性設計和測試驗證應獲得更高的重視
- 解讀計算機編碼
- 人們對數學的加減運算可輕易在腦中辨識符號並理解其結果,但電腦做任何事都受限於實體資料儲存及操作方式,換言之,電腦硬體實際只認得 0 和 1,卻不知道符號 + 和 - 在數學及應用場域的意義,於是工程人員引入「補數」以表達人們認知上的正負數
- 您有沒有想過,為何「二補數」(2’s complement) 被電腦廣泛採用呢?背後的設計考量是什麼?本文嘗試從數學觀點去解讀編碼背後的原理
- linked list 和非連續記憶體操作
*
- 安排 linked list 作為第一份作業及隨堂測驗的考量點:
- 檢驗學員對於 C 語言指標操作的熟悉程度 (附帶思考:對於 Java 程式語言來說,該如何實作 linked list 呢?)
- linked list 本質上就是對非連續記憶體的操作,乍看僅是一種單純的資料結構,但對應的演算法變化多端,像是「如何偵測 linked list 是否存在環狀結構?」和「如何對 linked list 排序並確保空間複雜度為 O(1) 呢?」
- linked list 的操作,例如走訪 (traverse) 所有節點,反映出 Locality of reference (cache 用語) 的表現和記憶體階層架構 (memory hierarchy) 高度相關,學員很容易從實驗得知系統的行為,從而思考其衝擊和效能改進方案
- 無論是作業系統核心、C 語言函式庫內部、應用程式框架,到應用程式,都不難見到 linked list 的身影,包含多種針對效能和安全議題所做的 linked list 變形,又還要考慮到應用程式的泛用性 (generic programming),是很好的進階題材
- 題目 1 + 分析
*
- 題目2 (內含作答表單) / 參考題解1, 參考題解2
- 安排 linked list 作為第一份作業及隨堂測驗的考量點:
- 作業: 9 月 20 日截止繳交
- 第 1 週隨堂測驗: 題目 (內含作答表單)
- 課堂問答簡記
- 課程簡介和注意須知 / 課程簡介和作業解說錄影
- 第 2 週 (Sep 15): C 語言程式設計
- 系統軟體開發思維
- C 語言: 數值系統
*
- 儘管數值系統並非 C 語言所特有,但在 Linux 核心大量存在 u8/u16/u32/u64 這樣透過 typedef 所定義的型態,伴隨著各式 alignment 存取,若學員對數值系統的認知不夠充分,可能立即就被阻擋在探索 Linux 核心之外 —— 畢竟你完全搞不清楚,為何在 Linux 核心存取特定資料需要繞一大圈。
- C 語言: Bitwise 操作
*
- Linux 核心原始程式碼存在大量 bit(-wise) operations (簡稱 bitops),頗多乍看像是魔法的 C 程式碼就是 bitops 的組合。
- 類神經網路的 ReLU 及其常數時間複雜度實作
- 為什麼要深入學習 C 語言?
*
- C 語言發明者 Dennis M. Ritchie 說:「C 很彆扭又缺陷重重,卻異常成功。固然有歷史的巧合推波助瀾,可也的確是因為它能滿足於系統軟體實作的程式語言期待:既有相當的效率來取代組合語言,又可充分達到抽象且流暢,能用於描述在多樣環境的演算法。」
- Linux 核心作為世界上最成功的開放原始碼計畫,也是 C 語言在工程領域的瑰寶,裡頭充斥各式「藝術」,往往會嚇到初次接觸的人們,但總是能夠用 C 語言標準和開發工具提供的擴展 (主要來自 gcc 的 GNU extensions) 來解釋。
- 基於 C 語言標準研究與系統程式安全議題
- 藉由研讀漏洞程式碼及 C 語言標準,討論系統程式的安全議題
- 透過除錯器追蹤程式碼實際運行的狀況,了解其運作原理;
- 取材自 dangling pointer, CWE-416 Use After Free, CVE-2017-16943 以及 integer overflow 的議題;
- C 語言: bit-field
- bit field 是 C 語言一個很被忽略的特徵,但在 Linux 和 gcc 這類系統軟體很常出現,不僅是精準規範每個 bit 的作用,甚至用來「擴充」C 語言
- 作業: 9 月 27 日截止繳交
- Week2 隨堂測驗: 題目 (內含作答表單)
- 第 3 週 (Sep 22): C 語言程式設計
- 公告
- C 語言:記憶體管理、對齊及硬體特性
*
- 搭配閱讀: The Lost Art of Structure Packing
- 從虛擬記憶體談起,歸納出現代銀行和虛擬記憶體兩者高度相似: malloc 給出 valid pointer 不要太高興,等你要開始用的時候搞不好作業系統給個 OOM ——簡單來說就是一張支票,能不能拿來開等到兌現才知道。
- 探討 heap (動態配置產生,系統會存放在另外一塊空間)、data alignment,和 malloc 實作機制等議題。這些都是理解 Linux 核心運作的關鍵概念。
- C 語言: 未定義行為
*
: C 語言最初為了開發 UNIX 和系統軟體而生,本質是低階的程式語言,在語言規範層級存在 undefined behavior,可允許編譯器引入更多最佳化 - Greatest Common Divisor 特性和實作考量: 探討最大公因數 (GCD) 特性,考慮微處理器架構實作帶來的效能衝擊。考慮到 binary GCD 及其最佳化。
- C 語言: 前置處理器應用
*
- C 語言之所以不需要時常發佈新的語言特徵又可以保持活力,前置處理器 (preprocessor) 是很重要的因素,有心者可逕行「擴充」C 語言
- C 語言: 指標
*
- 應可體會為何走訪 linked list 節點的程式碼要這樣寫:
struct list **lpp; for (lpp = &list; *lpp != NULL; lpp = &(*lpp)->next)
- 應可體會為何走訪 linked list 節點的程式碼要這樣寫:
- 作業: 10 月 7 日截止繳交
- Week3 隨堂測驗: 題目 (內含作答表單)
- 第 4 週 (Sep 29): 浮點數 + code review
- 第 5 週 (Oct 6): Fixed-Point + Code Review + C 語言
- 浮點數運算和定點數操作
*
- C 語言: 函式呼叫
*
- 著重在計算機架構對應的支援和行為分析
- C 語言: 遞迴呼叫
*
- 或許跟你想像中不同,Linux 核心的原始程式碼裡頭也用到遞迴函式呼叫,特別在較複雜的實作,例如檔案系統,善用遞迴可大幅縮減程式碼,但這也導致追蹤程式運作的難度大增
- Linux: 作業系統術語及概念
*
- C 語言: goto 和流程控制
*
- goto 在 C 語言被某些人看做是妖魔般的存在,不過實在不用這樣看待,至少在 Linux 核心原始程式碼中,goto 是大量存在 (跟你想像中不同吧)。有時不用 goto 會寫出更可怕的程式碼
- C 語言程式設計技巧
*
- 作業: 11 月 9 日截止繳交
- Week5 隨堂測驗: 題目 (內含作答表單)
- 浮點數運算和定點數操作
- 第 6 週 (Oct 13): 編譯器和最佳化概念
- Linux-based RTOS Experimental Platform for Constructing Self-driving Vehicles
- C 編譯器原理和案例分析
*
- C 語言: 編譯器和最佳化原理
*
- 作業: 11 月 9 日截止繳交
- Week6 隨堂測驗: 題目 (內含作答表單)
- 第 7 週 (Oct 20): 效能最佳化、連結器,和執行階段函式庫
- CS:APP 第 5 章重點提示和練習
*
- CS:APP Assign 5.18
*
- C 語言: 動態連結器
*
- C 語言: 連結器和執行檔資訊
*
- C 語言: 執行階段程式庫 (CRT)
*
- Week7 隨堂測驗: 題目 (內含作答表單)
- CS:APP 第 5 章重點提示和練習
- 第 8 週 (Oct 27): ROS + Dynamic Programming + Code Review
- 建構在 ROS(Robot Operating System) 之上的自動駕駛技術
*
- Code Review: 課堂互動
- Week8 隨堂測驗: 題目 (內含作答表單)
- 建構在 ROS(Robot Operating System) 之上的自動駕駛技術
- 第 9 週 (Nov 3): 組合語言 + 微處理器 + 虛擬記憶體
- Linux: 透過 eBPF 觀察作業系統行為
*
: 動態追蹤技術(dynamic tracing)是現代軟體的進階除錯和追蹤機制,讓工程師以非常低的成本,在非常短的時間內,克服一些不是顯而易見的問題。它興起和繁榮的一個大背景是,我們正處在一個快速增長的網路互連異質運算環境,工程人員面臨著兩大方面的挑戰:- 規模:無論是使用者規模還是機房的規模、機器的數量都處於快速增長的時代;
- 複雜度:業務邏輯越來越複雜,運作的軟體也變得越來越複雜,我們知道它會分成很多很多層次,包括作業系統核心和其上各種系統軟體,像資料庫和網頁伺服器,再往上有腳本語言或者其他高階語言的虛擬機器或執行環境,更上面是應用層面的各種業務邏輯的抽象層次和很多複雜的程式邏輯。
- Linux: 不僅是個執行單元的 Process
*
: Linux 核心對於 UNIX Process 的實作相當複雜,不僅蘊含歷史意義 (幾乎每個欄位都值得講古),更是反映出資訊科技產業的變遷,核心程式碼的task_struct
結構體更是一絕,廣泛涵蓋 process 狀態、處理器、檔案系統、signal 處理、底層追蹤機制等等資訊,更甚者,還很曖昧地保存著 thread 的必要欄位,好似這兩者天生就脫不了干係- 探討 Linux 核心設計的特有思維,像是如何透過 LWP 和 NPTL 實作執行緒,又如何透過行程建立記憶體管理的一種抽象層,再者回顧行程間的 context switch 及排程機制,搭配 signal 處理
- Linux: 不只挑選任務的排程器
*
: 排程器 (scheduler) 是任何一個多工作業系統核心都具備的機制,但彼此落差極大,考量點不僅是演算法,還有當應用規模提昇時 (所謂的 scalability) 和涉及即時處理之際,會招致不可預知的狀況 (non-determinism),不僅即時系統在意,任何建構在 Linux 核心之上的大型服務都會深受衝擊。是此,Linux 核心的排程器經歷多次變革,需要留意的是,排程的難度不在於挑選下一個可執行的行程 (process),而是讓執行完的行程得以安插到合適的位置,使得 runqueue 依然依據符合預期的順序。 - in-kernel HTTP server
*
- 現代處理器設計:原理和關鍵特徵
*
- CS:APP 第 12 章
- Concurrent Programming (並行程式設計)
*
- Linux: 淺談同步機制
*
- Linux: 多核處理器和 spinlock
*
- Toward a Better Use of C11 Atomics: Part 1, Part 2
- Part 1: Mutex Locks
- Part 2: Counting Semaphores
- Part 3: Working with Mutexes And Semaphores
- Part 4: The Critical Section Problem
- Part 5: Condition Variables
- Part 6: Implementing a barrier
- Part 7: The Reader Writer Problem
- Part 8: Ring Buffer Example
- Part 9: Synchronization Across Processes
- 作業
- User-level threads / 錄影
*
- Linux: 中斷處理和現代架構考量
*
- Linux: Timer 及其管理機制
*
- Linux: Scalability 議題
*
- 高效能 Web 伺服器開發
- User-Level Thread Library / threads
- 建構 User-Mode Linux 的實驗環境
*
- 作業
- CS:APP 第 3 章重點提示和練習
*
: 閱讀 Linux 核心原始程式碼的過程,我們無可避免會面對各式硬體架構的組合語言程式碼,至少應有基本認知,本課程採用 CS:APP 第 3 章的材料 - Arm 處理器
*
: 系列講座導論, 架構和指令集, 基礎指令和開發環境, 虛擬化技術和應用- 你可曾想過,就算選修了電機資訊相關科系大部份的課程,自己仍對每天用的手機,完全沒概念,是不是很沮喪呢?裡頭運作 ARM 處理器,但你知道裡面的 CPU pipeline 如何運作?裡頭的 cache 如何運作?四核心、八核心到底又如何運作?CPU 和 GPU 之間如何通訊?
- 系列講座預計涵蓋 ARMv7-A/M, ARMv8-A/M, virtualization extension, 以及對應的系統軟體技術,像是 big.LITTLE, hypervisor, 和 TEE 的概念介紹
- 為何要掌握數學?
- 即使 Linux 核心內部也大量可見: 從 CPU cache coherence 談 Linux spinlock 可擴展能力議題
- 隱藏在字典裡的數學
- Linux: Add Policy Engine Algorithmic Bloom Filter Entries Register
- 圖解傅立葉分析
- CS:APP 第 6 章重點提示
*
- CPU caches by Ulrich Drepper
- CS:APP 第 9 章重點提示
*
- Linux: 記憶體管理
*
: 記憶體管理是 Linux 核心裡頭最複雜的部分,涉及到對計算機結構、slob/slab/slub 記憶體配置器、行程和執行檔樣貌、虛擬記憶體對應的例外處理、記憶體映射, UMA vs. NUMA 等等議題。 - Linux 核心的 /dev/mem 裝置: 整理中
- Week9 隨堂測驗: 題目 (內含作答表單)
- Linux: 透過 eBPF 觀察作業系統行為
- 第 10 週 (Nov 10): 虛擬記憶體 + I/O + 例外處理
- 第 11 週 (Nov 17): 共享記憶體 + 系統呼叫 + 資料結構
- POSIX Shared Memory: 在 Linux 中要實作出共享記憶體 (shared memory) 的機制很多,例如: 1) SysV shared memory; POSIX shared memory; 3) 以 mmap 對檔案進行記憶體映射; 4) 以 memfd_create() 實作跨越行程存取; 本文章探討 POSIX shared memory 的使用,並提供完整應用案例,最後探討相關的同步議題。
- Linux: 賦予應用程式生命的系統呼叫
*
- Linux: 記憶體管理
*
- C 語言: 物件導向程式設計
*
- An Introduction to Cache-Oblivious Data Structures
- 「自動快取資料結構」,特性是無視硬體特定的快取大小,可能達到接近最優化快取的效能;
- 在現代 CPU 多層多種大小的快取架構下,它的理論宣稱其能自動優化在所有層的快取的存儲效率。傳統上電腦科學做偏理論的不太重視實作上的效能,而做實作或硬體優化的則不太重視理論分析。這個學門卻是橫跨了相當理論的演算法分析(需要相當多的進階數學工具),以及相當低階的硬體效能理解;
- 影片: Memory Hierarchy Models
- Google Research 強者的心得: 關於變強這檔事(九)
- Skip List: 置放大量數字並進行排序的資料結構。不用樹狀結構,而改用高度不同的 List 來連接資料。資料結構在概念上可以表示成 Left Child-Right Sibling Binary Tree 的模式。是 Cache-oblivious Algorithm 的經典範例,時間複雜度與空間複雜度與 Binary Search Tree 皆相同,但是實際運作效率比 Binary Search Tree 還要好。
- Linux 核心: A kernel skiplist implementation (Part 1), Skiplists II: API and benchmarks
- Object-oriented design patterns in the kernel, part 1 / Object-oriented design patterns in the kernel, part 2
- Linux: linked list, Queues, Maps, Binary Trees: 錄影
*
/ 共筆 - Week11 隨堂測驗: 題目 (內含作答表單)
- 第 12 週 (Nov 24): 共享記憶體 + 同步機制
- 解析 Linux 共享記憶體機制
- Linux: RCU 同步機制
*
- C11 atomic variables and the kernel / Linux Documentation: Circular Buffers
- Week12 隨堂測驗: 題目 (內含作答表單)
- 第 13 週 (Dec 1): 最佳化 + 安全和正確性 + 裝置驅動程式模型
- Making C Less Dangerous in the Linux Kernel / 錄影
*
- Linux 核心中各式 C 語言程式設計的安全和正確議題
- Variable Length Arrays are bad and slow
- Explicit switch case fall-through
- Always-initialized automatic variables
- Arithmetic overflow detection
- Hope for bounds checking
- Control Flow Integrity: forward edges
- Control Flow Integrity: backward edges
- 也提供了 gcc/clang 相關的編譯參數
- 解說1, 解說2
- Linux: 裝置驅動程式介面和模型 / 錄影
*
by Greg Kroah-Hartman - How to avoid writing device drivers for embedded Linux / 錄影
*
- Linux: Device Tree / 錄影
*
- Week13 隨堂測驗: 題目 (內含作答表單)
- Making C Less Dangerous in the Linux Kernel / 錄影
- 第 14 週 (Dec 8): Linux 核心發展回顧 + 網路封包處理
- Linux: 發展動態回顧
*
- How Linux Processes Your Network Packet / 錄影
*
- Kernel packet capture technologies / 錄影
*
- PACKET_MMAP
PACKET_MMAP
在核心空間內配置一塊核心緩衝區,一旦使用者層級的應用程式呼叫 mmap 將前述緩衝區映射到使用者層級時,接收到的 skb 會直接在該核心緩衝區,從而讓應用程式得以直接捕捉封包- 若沒有啟用
PACKET_MMAP
,就只能使用低效率的AF_PACKET
,不但有緩衝區空間的限制,而且每次捕捉封包就要一次系統呼叫。反之,PACKET_MMAP
多數時候不需要呼叫系統呼叫,也能實作出 zero-copy - 圖解 Linux tcpdump
- Week14 隨堂測驗: 題目 (內含作答表單)
- Linux: 發展動態回顧
- 第 15 週 (Dec 15): FD 和 檔案系統
- 公告:
- 即日起到 6 月 30 日中午請每位學員進行 課程期末專題
- 預計 6 月 30 日 15:00,授課教師會繳交學期成績,在這之前都有補救空間
- Linux 不成文的設計哲學: “Everything is a file descriptor” - eventfd, timerfd, signalfd
- Linux: 檔案系統和虛擬檔案系統設計
*
- Drive your NAND within Linux / 錄影
*
- Flash-Friendly File System (F2FS) / 錄影
*
- Week15 隨堂測驗: 題目 (內含作答表單)
- 公告:
- 第 16 週 (Dec 22): 多核處理器架構
- Multi-Core in Linux
*
- What is NUMA?
*
- A tour of the ARM architecture and its Linux support
*
- Multiprocessor OS
- Week16 隨堂測驗: 題目 (內含作答表單)
- Multi-Core in Linux
- 第 17 週 (Dec 29): 多處理器架構
- Lock-free 程式設計議題
- Multiprocessor OS
- Linux: Scalability 議題
- Linux-Kernel Memory Ordering: Help Arrives At Last! / video
*
- Week17 隨堂測驗: 題目 (內含作答表單)
- 第 18 週 (Jan 5): 多核處理器, 時鐘管理, Real-time