--- title: 看漫畫學 Linux image: https://i.imgur.com/jJhfAiH.png description: 本共藉由 {turnoff.us} 的一幅漫畫,介紹 Linux 核心加上關鍵應用程式的組合 tags: LINUX KERNEL, LKI --- # 看漫畫學 Linux > 導讀: [jserv](http://wiki.csie.ncku.edu.tw/User/jserv) Daniel Stori 經營的網站 [{turnoff.us}](https://turnoff.us/) 提供一系列關於資訊技術的漫畫,其中 [inside the linux kernel](https://turnoff.us/geek/inside-the-linux-kernel/) 生動地展現 Linux 核心的部分機制和相關的套件。本文嘗試解說這幅漫畫,全貌如下: (原網站提供解析度更高的圖片) ![](https://i.imgur.com/vxRz2zK.png) 漫畫以房屋的側面剖面視角,以房屋為載體,小企鵝、小狗、小丑等成員組為大家庭,各自分工,藉此展現 Linux。由於漫畫針對 Linux 核心的比重不算高,本文標題變更為通用的 Linux 系統,即核心加上關鍵應用程式的組合。 小企鵝的名字是 Tux - [(T)orvalds (U)ni(X)](http://lkml.iu.edu/hypermail/linux/kernel/9606.1/0175.html),它是 Linux 的吉祥物。會選小企鵝當作 Linux 核心的吉祥物,只是[因為 Linus Torvalds 喜歡企鵝](http://lkml.iu.edu/hypermail/linux/kernel/9605.1/0457.html),而非企鵝具有特殊或象徵其他意義。 > 延伸閱讀: [The Story Behind Tux the Penguin](https://www.wired.com/2001/03/the-story-behind-tux-the-penguin/) ![](https://i.imgur.com/H7faFH5.jpg) > Linus Torvalds 與他辦公室內滿滿的企鵝娃娃。 > 圖片來源: [Linus Torvalds Guided Tour of His Home Office](https://youtu.be/SOXeXauRAm0) 以下術語標注於漫畫中: * file system (檔案系統) * process table (行程表) * httpd process (httpd 行程,即網頁伺服器行程) * watchdog process (看門狗行程) * ssh daemon (ssh 伺服器) * cron (執行週期性任務 [cron](https://man7.org/linux/man-pages/man8/cron.8.html) 的背景程式) * wine process (執行 [Wine](https://www.winehq.org/) 的行程) * pipe (即 [UNIX Pipeline](https://en.wikipedia.org/wiki/Pipeline_(Unix))) * terminals and terminal processes (終端機和其行程) ## 地下室 地下室擺放著一排又一排的檔案櫃,檔案櫃裡放置著檔案 (file),由此隱喻檔案系統對於 Linux 核心,乃至於泛 UNIX 作業系統的重要性 —— 檔案系統是 UNIX 風格的作業系統的基底。 ![](https://i.imgur.com/hAGrv56.png) 左上角,有隻胸前掛著牌號為 `421` 的小企鵝,它表示著 PID ([Process ID](https://en.wikipedia.org/wiki/Process_identifier),行程 ID) 為 `421` 的行程,它正在查看檔案系統裡頭某個檔案,換言之,系統中有個行程正在存取檔案系統。 右下角有隻小狗,它有敏銳的嗅覺,對應到監控 Linux 檔案系統和一系列服務的 [watchdog](https://linux.die.net/man/8/watchdog)。 ### 通往檔案系統 剖面圖的左上角 (最裡頭的區域),也就是中央大廳和地下室交界處,出現標注 `FS` 的向下樓梯 ![](https://i.imgur.com/SIasbUL.png) `FS` 是 file system 的簡稱,這表示行程可藉由該樓梯,存取到檔案系統的資源 (即檔案和檔案系統的資訊)。 延伸閱讀: * [Linux 核心設計: 檔案系統概念及實作手法](https://hackmd.io/@sysprog/linux-file-system) ## 中央大廳層 中央大廳相當熱鬧,除了一群小企鵝,尚可見到小丑和小狗: ![](https://i.imgur.com/hrgUafy.png) 我們從右下側 (即靠近讀者的一側),以順時鐘方向,逐一介紹中央大廳的成員和其寓意。 ### 行程表 中央大廳最醒目的區域,就是一塊地毯上,眾多小企鵝在圍著桌子坐著,這區域是行程表 (process table)。 ![](https://i.imgur.com/RMucOyv.png) > 英語的「表格」和「桌子」是同一個字,漫畫藉此展現行程管理 左上角有個站立的小企鵝,是其他小企鵝的長輩,照顧著狀態不一的小企鵝,這個慈母企鵝 (也可以是祖母、曾祖母等身份) 表示 PID 為 1 的行程,即 [init](https://en.wikipedia.org/wiki/Init) 或 [systemd](https://en.wikipedia.org/wiki/Systemd),所有使用者層級的行程都由其產生 (藉由 [fork](https://man7.org/linux/man-pages/man2/fork.2.html) 或 [clone](https://man7.org/linux/man-pages/man2/clone.2.html) 系統呼叫)。示意如下圖: ![](https://i.imgur.com/IIwuZcj.png) 圍繞在桌子的小企鵝們處於打盹 (sleep)、發呆 (stop),也有跟慈母企鵝互動的活躍 (running) 等狀態,對應到 Linux 核心對於行程的狀態及生命週期規範: ![](https://i.imgur.com/149kGC2.png) 一旦慈母企鵝對著 PID 為 `171`、背對慈母的小企鵝說:「孩子,現在輪到你發言」,就相當於排程器 (scheduler) 挑選出下一個要執行的任務。 延伸閱讀: * [Linux 核心設計: 不僅是個執行單元的 Process](https://hackmd.io/@sysprog/linux-process) * [Linux 核心設計: 不只挑選任務的排程器](https://hackmd.io/@sysprog/linux-scheduler) ### 看門狗 行程表兩測各有一隻小狗,它們監控著小企鵝的狀態: ![](https://i.imgur.com/8uuP4rz.png) 當小企鵝不聽話時,它們就會吠叫,不見得是 Linux 行程出錯,也可能因為裝置驅動程式或核心內部狀態陷入無法復原,這也是 "watchdog" 一詞的引申意義。實務上,Linux 伺服器系統在出現致命錯誤,需要遠端進行重新啟動,就可搭配 watchdog,藉由後者監控系統資料,判斷是否在系統出現異常時,自動重新啟動系統。 延伸閱讀: * [Linux Watchdog Support](https://www.kernel.org/doc/html/latest/watchdog/) ### httpd 行程 大廳對外的門戶,由一隻胸前標註 `1341` 的小企鵝所看守,它頭上插著一只羽毛,門上寫着 `80`,說明這個 PID 爲 `1341` 的 Linux 行程負責接待埠號 (port) `80`,後者也就是 HTTP 常見的連接埠。 ![](https://i.imgur.com/NDv9L6S.png) > [中文詞彙地區差異比較——#16「端口」與「埠」](https://byvoid.com/zht/blog/region-phrases-comparison-port/) 小企鵝頭上的一只羽毛大有來歷,它是著名的 [Apache HTTP 伺服器](https://httpd.apache.org/) 的識別圖樣: ![](https://i.imgur.com/eOeTajR.png) 網頁伺服器 ([web server](https://en.wikipedia.org/wiki/Web_server)) 也稱 HTTP server 或 HTTP daemon,可簡稱 `httpd`,後者的 "[daemon](https://en.wikipedia.org/wiki/Daemon_(computing))" 原為「惡魔」之意,在 UNIX 的世界中引申爲常駐程式或背景服務。 Linux 核心在 2.4 版的年代,當時 Linux 的效能不夠好,且無法有效利用多處理器的優勢、執行緒的實作仍很拙劣,但 Linux 卻恰好滿足 Intel x86 架構和個人電腦物美價廉的特性,廣泛採納為網際網路服務的基礎,因此當時 Linux 開發者有鑑於 [Apache 伺服器](https://httpd.apache.org/)多半在 Linux 上運作,網頁伺服器又是如此普遍且重要,就在 Linux 核心提供名為 `khttpd` 的網頁伺服器 (in-kernel httpd) 作為加速,後來演化為 [TUX](https://en.wikipedia.org/wiki/TUX_web_server) —— 用 Linux 的吉祥物來命名 in-kernel web server。 不過後來 Linux 核心開發者就不維護 `khttpd` 或 `TUX`,而是提供 [sendfile](https://man7.org/linux/man-pages/man2/sendfile.2.html), [epoll](https://man7.org/linux/man-pages/man7/epoll.7.html), [splice](https://man7.org/linux/man-pages/man2/splice.2.html) 等系統呼叫,搭配 scalability 更好的 CPU 排程器 (CFS),因為他們從多年的實踐,總結這樣的策略:「沒必要透過特化需求去克服局部的效能瓶頸」。 延伸閱讀: * [Linux 核心設計: 發展動態回顧](https://hackmd.io/@sysprog/linux-dev-review) * [高效 Web 伺服器開發](https://hackmd.io/@sysprog/fast-web-server) * [以 sendfile 和 splice 系統呼叫達到 Zero-Copy](https://hackmd.io/@sysprog/linux2020-zerocopy) * [Linux 核心設計: Scalability 議題](https://hackmd.io/@sysprog/linux-scalability) ### cron 任務 在這一層中,有一個身上寫着 `217` 的小企鵝,他正滿頭大汗地反覆查看自己的手錶,深怕沒趕上預定的時間安排: ![](https://i.imgur.com/Ht6WwBP.png) 這隻小企鵝就是 [cron](https://en.wikipedia.org/wiki/Cron),作用是例行性工作排程,按時執行週期性任務,或判斷是否要執行某個工作。 延伸閱讀: * [例行性工作排程 (crontab)](http://linux.vbird.org/linux_basic/0430cron.php) ### 管線 有兩個小企鵝扛着管線 ([PipeLine](https://en.wikipedia.org/wiki/Pipeline_(Unix)),可簡稱為 [pipe](https://man7.org/linux/man-pages/man7/pipe.7.html)) 在行走,一隻小企鵝可以把自己手上的東西通過這個管線,傳遞給後面的小企鵝。 ![](https://i.imgur.com/PfbQZ7L.png) [pipe](https://en.wikipedia.org/wiki/Pipeline_(Unix)) 是 UNIX 的重要發明,慣用的 `|` 符號,就像一根管子,將左右兩邊命令的輸出和輸入連接起來。左側命令的輸出,會當作右側命令的輸入。在 pipe 機制出現之前,使用者只能將一個命令或程式執行的結果,暫時保存於檔案中,再執行另一個程式,將暫存檔內的資料,提供給第二個指令作為它的輸入,而 pipe 機制在程式設計上具有高度的彈性,也是 UNIX 獲得廣泛採納的重要因素:一個又一個 UNIX 工具、大小規模不一的程式,以及使用者轉寫的腳本 (script) 程式,以接力方式串接起來,共同完成任務,就像用不同孔徑的篩子,將原始資料逐步轉化為最終的形式。 ![](https://i.imgur.com/vt9xV33.png) > 出處: [Pipes, Forks, & Dups: Understanding Command Execution and Input/Output Data Flow](http://www.rozmichelle.com/pipes-forks-dups/) Linux 核心為了實作 pipe,內部實作 pipe buffer,隨後甚至出現 [splice](https://man7.org/linux/man-pages/man2/splice.2.html) 系統呼叫。 延伸閱讀: * [Mastering UNIX pipes, Part 1](https://www.moritz.systems/blog/mastering-unix-pipes-part-1/) * [Mastering UNIX pipes, Part 2](https://www.moritz.systems/blog/mastering-unix-pipes-part-2/) ### 無人看守的 FTP 行程 除了上述的埠號 `80`,大廳另有個門戶,上方寫 `21`,但實在年久失修,連門牌都快脫落: ![](https://i.imgur.com/9mF21Ig.png) 這個埠號 `21` 就是 [File Transfer Protocol](https://en.wikipedia.org/wiki/File_Transfer_Protocol),簡稱 FTP,一度廣泛採用,但現在大部分人已改用 SSH 和 [SSH File Transfer Protocol](https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol) (簡稱 `sftp`) 或 [rsync](https://en.wikipedia.org/wiki/Rsync)。 ### 戒備森嚴的 SSH 伺服器 大廳最後一道門戶,由一位配戴墨鏡和警徽的冷酷企鵝守護著。門上標注 `22`,表示埠號 `22` 的 [SSH 服務](https://en.wikipedia.org/wiki/Secure_Shell_Protocol)。 ![](https://i.imgur.com/GXRRrh0.png) 這隻冷酷企鵝顯然比其他的企鵝嚴肅,臉上彷彿寫著「生人勿進」四字,因為 SSH 通訊協定背後涉及身份識別、加密,和遠端登入等操作,伺服器需要仔細盤查和核對。 延伸閱讀: * [遠端連線伺服器 SSH](http://linux.vbird.org/linux_server/0310telnetssh.php) ### [Wine](https://www.winehq.org/) 行程 這位端著紅酒,略帶醉意、胸前標注 PID `411` 就是 [Wine](https://www.winehq.org/) 行程: ![](https://i.imgur.com/64h2oPx.png) [Wine](https://www.winehq.org/) 這項開放原始碼專案最初以 "Wine Is Not an Emulator" 的遞迴式縮寫命名,致敬 [GNU](https://www.gnu.org/) 為 GNU's Not Unix,英文的 "wine" 是紅酒的意思,[Wine](https://www.winehq.org/) 專案的圖樣正是紅酒: ![](https://i.imgur.com/kzm9IuO.png) 有了 Wine,我們即可在 Linux 執行原本針對 Microsoft Windows 的應用程式,該專案背後的推手是 [CodeWeavers](https://www.codeweavers.com/) 公司,長期貢獻程式碼到 [Wine](https://www.winehq.org/) 專案,近期另一間以開放原始碼技術為訴求的 [Collabora](https://www.collabora.com/) 公司也強化 [Wine](https://www.winehq.org/) 的圖形處理,這二間公司以 WINE 為基礎,合作開發 [Proton](https://github.com/ValveSoftware/Proton),允許 MS-Windows 遊戲在 Linux 作業系統上順暢執行。 小企鵝喝紅酒,微醺地走著,好似自己是 Microsoft Windows 並提供執行應用程式所需的 API 相容層。值得留意的是,為了更好地執行 Wine,Linux 核心陸續加入新的修改,可參見以下: * [Linux Kernel: Syscall User Dispatch](https://www.kernel.org/doc/html/latest/admin-guide/syscall-user-dispatch.html) * [FUTEX2 Spun Up A Fifth Time For This Linux Interface To Help Windows Games](https://www.phoronix.com/scan.php?page=news_item&px=FUTEX2-v5) ### GNOME 這位活蹦亂跳的小丑是誰? ![](https://i.imgur.com/5SSoSxR.png) 是大名鼎鼎的 [GNOME 桌面環境](https://www.gnome.org/),推出時間稍晚於 [KDE 桌面環境](https://kde.org/)。既然定位是桌面環境,就不會只有一隻程式,因此對應到 Linux 的行程來說,[GNOME 桌面環境](https://www.gnome.org/) 啟動後,會建立一系列 Linux 行程且相互溝通。 ## 最上方的介面 接著來看樓中樓上方區域,也是最接近使用者的一層。 ![](https://i.imgur.com/1srRryc.png) 兩隻小企鵝忙碌地工作:一隻企鵝在控制台前操作,另一隻仔細端詳程式輸出結果,我們可見 `tty` 字樣標註在個別螢幕上,例如 `tty4` 上面輸入 `fre` 字樣 (可能是準備執行 [free](https://man7.org/linux/man-pages/man1/free.1.html) 工具程式或內建命令)、`tty3` 有 `awk` 字樣 (準備執行 [awk](https://man7.org/linux/man-pages/man1/awk.1p.html) 腳本)、`tty2` 是執行 `ls` 命令的輸出 (可見 `/dev`, `/etc`, `/usr`, `/bin`, `/sbin` 等目錄),至於 `tty7` 就有意思了,是視窗圖形介面,由 [X Window System](https://www.x.org/) 提供基礎建設,可能執行上述提到的 [GNOME 桌面環境](https://www.gnome.org/)。 > 延伸閱讀: [第二十三章、X Window 設定介紹](http://linux.vbird.org/linux_basic/0590xwindow.php) 至於 `tty` 到底是什麼,要從一段故事談起。 ![](https://i.imgur.com/PTCaukY.png) > ticker tape, 1918 1869,股票自動報價機 ([stock ticker machine](https://en.wikipedia.org/wiki/Ticker_tape)) 問世,其組成包含以下: * 用於長距離即時傳遞股票價格的電子/機械設備 * 打字機 (typewriter) * 一對長電纜 * 一個報價用的磁帶印表機 (tape printer) 後來演變為速度更快、以 ASCII 編碼為基礎的的電傳打字機 ([teletyper](https://en.wikipedia.org/wiki/Teleprinter)),後者甚至可用電纜串接,用來傳遞商業電報,但彼時尚未有電子計算機。 第二次世界大戰刺激電子計算機的發展,在 1940 年代末期,John von Neumann 博士和他所屬的洛斯阿拉莫斯國家實驗室深入運用 [ENIAC](https://en.wikipedia.org/wiki/ENIAC) 電子計算機,計算氫彈相關資料,輸出資料量高達 100 萬張卡片。 後來電腦融入 [CTSS](https://en.wikipedia.org/wiki/Compatible_Time-Sharing_System) 帶來的分時多工機制,得以落實多任務 (multitasking),且功能和運算速度都持續提升,電腦得以有效地和操作者互動,人們就將電傳打字機用作電腦的輸入和輸出設備,因為這些設備在市場上容易取得。 ![](https://i.imgur.com/7ZLL9pa.png) 但此時面臨的問題是:市場上已有不少的電傳打字機廠牌,所有機種之間都些微差異,因此就需要某種中間層來隱蔽 (abstract) 這些落差,於是當人們在電腦前說電傳打字機時,其實是 `tty` (電傳打字機的簡寫) 和低階操作的統稱,例如 word 長度, baud rate, flow control, parity, line editing 等功能所用的控制碼等等。 儘管電傳打字機的實體早已消聲匿跡,但 `tty` 的影響卻從 20 世紀中葉持續影響資訊科技產業,我們在 UNIX 和其後繼者 (如 Linux) 內部可見 `tty`,上述的控制碼依然存在,這也是為何有 "[terminal emulator](https://en.wikipedia.org/wiki/Terminal_emulator)" 一詞,因為包含 Linux 這樣的 21 世紀作業系統用軟體去「模擬」著 20 世紀的電傳打字機 (`tty`) 硬體和支援多種控制碼,以做到個別「模擬」出來的終端機 (terminal) 之間可以互通。 換言之,`tty` 對應的終端機是作業系統對外的操作和通訊的機制,我們熟悉的標準輸出和輸入 (即 `stdout`, `stdin`) 就可在指定的 `tty` 裝置上處理。漫畫中二隻忙碌的企鵝,正是藉由 `tty` 來處理輸入和輸出的動作。但 `tty` 並非作業系統對外溝通的唯一機制,我們可運用網路 (networking; 不必是網際網路 [internet]) 的連接埠,事先約定通訊協定和方法,進行通訊和提供服務。 延伸閱讀: * [你所不知道的C語言: Stream I/O, EOF 和例外處理](https://hackmd.io/@sysprog/c-stream-io) * [The TTY demystified](https://www.linusakesson.net/programming/tty/)