我的 Linux Kernel 學習之路

也算是半個文組翻身吧

Guan
工人智慧
6 min readJul 21, 2024

--

你可以先看看我的課程筆記 Linux Kernel Internals 2024 Spring Collections,如果覺得符合期待再往下閱讀。

背景

我的背景是統計系畢業,實習時接觸了 Computer Vision,當時是 2018 年左右,也幾乎是那個時候才有比較高強度的 Python 的練習;由於我不是本科系,對於 C/C++ 幾乎是僅勉強能讀懂,或是需要花時間慢慢查閱範例和文檔才能夠撰寫能夠運作的 C/C++ 程式等。

我記得在我的第二份正職工作,為了要防止模型被客戶取出,特意寫了一隻用 SHA256 把開機時從 Gitlab 下載的 Public Key 解出 root 密碼的 C++ 程式,那是我僅有能夠記起的 C/C++ 經驗,由於我的兩份正職工作都和 DL 強烈相關,故大多數時間還是寫 Python,一些協助後端開發的經驗也是以 Python 為主,可以說 2022 年以前, Python 是我用於接觸 CS 相關知識的母語,雖然也陸續搞過 C# 和 Go,但反正跟 C/C++ 不熟。

回成大唸碩

回到成大讀碩後也不是本科系,是運算學院的人工智慧機器人學位學程,碩論也是延續我第二份正職遺留的問題,使用 DL 解決點雲分割問題。

But, 回到成大後有意識的開始往更底層的 CS 知識走;首先是靠數位 IC 設計理解了 verilog 和電路設計的相關知識,再來是 jserv 開的計算機結構,最後是 jserv 開的 Linux Kernel。

我還記得在計結的第一份作業,應該是 RISCV 搭配 Ripes 分析一隻簡單的 C 程式;突然就理解到透過電位高低形成的二進制和 32 個 ports 就可以產生任意的 asm 指令,然後就可以驅動 CPU pipeline。

大概就是那一刻我對於現代計算機是如何運作的有一份初步的認識,也對我後來 Linux Kernel 的學習理解有很大的幫助,所以如果要我推薦這個方向修課的最小組合,就會是 Digital IC Design 相關 + 計組計結相關 + OS 相關。

其中計組一定要上強度,因為它負責將最底層的 IC 和上層的 OS 連結,學得好對於後來 OS 的學習會事半功倍。

「神課」Linux Kernel

碩二下的時候我才選到傳說中成大電資必定要修的這門神課,第一個的建議是越早修越好,越早修後續在其他相關課程的成長幅度越大;第二個建議是由於這門課的課程設計,你砸的時間和你的收穫高度相關,所以記得盡量把時間空出來,花越多時間你越強(這件事是難能可貴的,相信看過很多爛課的你深有體會)。

選擇你的「主修」Subsystem

從歷年課程的 Term Project 中,會發現每年一定會有的是 CPU 相關,我認為這是因為比起記憶體和檔案系統,它是相對好上手的 subsystem,你可以參考 Linux Kernel map,並選擇你的「主修」;所謂主修是如 “I/O”, “CPU”, “memory”, “storage”, “network” 等 subsystem,並從其中重要的部件起手,如 CPU 中最重要的函式是如 schedule(), context_switch(), pick_next_task() 等,最重要的結構是 task_struct 和 sched_entity 等,越有邏輯流程的部件就越適合看 code 起手,像上述提到的部件都是在 CPU 當中的 Scheduler。

從 Linux Kernel map 當中你也可以觀察到,相鄰的 subsystem 有強烈相關,像是討論 CPU 不可能不討論 I/O 和 memory 帶來的影響。選擇一個主修的 subsystem 只是方便你有個開始,最終你還是要逐個熟悉每一個 subsystem 的。

題外話,不嚴謹地說,每一個「主修」似乎恰好對應一線廠的業務,如聯發科以 CPU 為主、瑞昱以 I/O 為主、群聯和SMI以 storage 為主,當然不是那麼絕對,像群聯SMI擅長的 PCIE 介面就屬於 I/O,瑞昱的網通事業群也與 network 強烈相關,只是一個就業的參考 (也可能是我以管窺豹了)。

不要「舉燭」

這一點也被 jserv 強調許多次,這是因為很多同學(包括我)寫筆記寫到走火入魔,很多時候看不懂為什麼是這樣實作的,就開始幻想,有些時候甚至連實作都沒看就開始幻想,這是不對的。

首先,直接讀程式碼是必要的,再來是讀 Patch,有些程式碼是被改了又改、改了又改的,不讀 Patch 了解前因後果有時候根本不可能看懂。

最後,做實驗眼見為憑;把 qemu 和相關 toolchain 搞定,直接用 gdb 追蹤是最笨最沒有效率但也最具體的方法,對初學者有巨大幫助。

然而上述也不一定完全有效,據現役發哥 CAI E8 工程師(我弟),有時候他也看不懂在幹嘛,做了實驗還是搞不懂,最好的方法之一是跳過,因為你可能遺漏了某些關鍵,先去別的地方看看,晚點回來也許就看得懂了。然後,有時候還是需要有一些想像力的。

讀課程材料

我知道很多課程的材料都很古老,或是知識含量比例低,但不論是 CSAPP 或是 CMU 的 CA 教學影片都非常緊湊且通篇無廢話,絕對就是非本科學生需要的,我認為都很值得一讀。

當然 jserv 的文章一定要讀,你不一定要滾瓜爛熟,但讀一遍總是要的,有個印象哪些東西被提到,想到還可以回來找。

後期你也需要 《Demystifying the Linux CPU Scheduler》和 每位程式開發者都該有的記憶體知識 ,拜託一定要讀,讀完之後要反覆驗證邏輯,你的推敲和反芻才是精華所在。

使用好工具和好材料

當我碩二下修這門課的時候,ChatGPT 已經非常成熟,在修課過程中透過 VSCode 搭配讀核心程式碼是非常有用的,絕對推薦。它的「幻想」能力有時候也有出其不意的效果。

善用 lkml,找到幾個你主修 subsystem 的重點改動,結合其他資料整理出為什麼當前的程式碼會被接受、現在的實作是為了什麼等等。

最後是去讀前人的筆記;這門課已經開了很久,而且 Linux Kernel 的更新通常是以數年為單位,就算是 2020 的筆記其中某一段體悟都可能可以協助解決你想破頭的問題,你只需要搜尋 「Linux 核心」+ 你的問題就可以找到相關筆記了。

結語

寫下我的心得是因為我顯然只是一個普通人,甚至可以說只是處在本科學生的及格線邊緣,但靠著在這堂課的努力也算是踏入 OS 和嵌入式的領域了。

也是因為這門課,我也幾乎把所有一線都面完了 (SMI 沒找我哭),其他一些軟體和系統廠也都面過,最後也找到嵌入式相關的職位,多位面試官也都認可我在 Linux 的能力和技能符合他們的要求,我想我應該符合 jserv 對於「翻身」的期待吧。

jserv 寫的書,我也在書中 EEVDF 一章有貢獻

--

--