--- 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) * [Linux 核心設計: 針對事件驅動的 I/O 模型演化](https://hackmd.io/@sysprog/linux-io-model/) * [Linux 核心設計: Scalability 議題](https://hackmd.io/@sysprog/linux-scalability) * [Effective System Call Aggregation (ESCA)](https://eecheng87.github.io/ESCA/) ### 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)。 近期 Google Chrome 網頁瀏覽器[移除對 FTP 的支援](https://chromestatus.com/feature/6246151319715840): > The current FTP implementation in Google Chrome has no support for encrypted connections (FTPS), nor proxies. Usage of FTP in the browser is sufficiently low that it is no longer viable to invest in improving the existing FTP client. In addition more capable FTP clients are available on all affected platforms. ### 戒備森嚴的 SSH 伺服器 大廳最後一道門戶,由一位配戴墨鏡和警徽的冷酷企鵝守護著。門上標注 `22`,表示埠號 `22` 的 [SSH 服務](https://en.wikipedia.org/wiki/Secure_Shell_Protocol)。 ![](https://i.imgur.com/GXRRrh0.png) 這隻冷酷企鵝顯然比其他的企鵝嚴肅,臉上彷彿寫著「生人勿進」四字,因為 SSH 通訊協定背後涉及身份識別、加密,和遠端登入等操作,伺服器需要仔細盤查和核對。 延伸閱讀: * [遠端連線伺服器 SSH](https://linux.vbird.org/linux_server/centos6/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 行程且相互溝通。 [GNOME 桌面環境](https://www.gnome.org/) 的吉祥物是花園地精 (Garden Gnome),在歐洲相當普遍,誕生於 16 世紀的義大利,陸續由各地手工藝精湛的師傅們賦予他們多種樣貌,於是電影和家具店中都可其身影。GNOME 最初是 GNU Network Object Model Environment 的簡稱,不過這個 Network Object Model 可能跟許多人想的不同,這個 "network" 是指 GNOME 專案創立初期使用 [Common Object Request Broker Architecture](https://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture) (CORBA) 這個分散式運算架構並包裝為 [Bonobo](https://en.wikipedia.org/wiki/Bonobo_(GNOME)),後來開發者體會到,在桌面環境使用 CORBA 實在是「殺雞用牛刀」,也比照 KDE 專案,改用 [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/) 來處理個元件乃至應用程式開發框架之間的通訊議題。 ## 最上方的介面 接著來看樓中樓上方區域,也是最接近使用者的一層。 ![](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 設定介紹](https://linux.vbird.org/linux_basic/centos7/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 等功能所用的控制碼等等。 > Microsoft 共同創辦人 Paul Allen 及 Bill Gates 展示 teletype 的使用 > ![](https://hackmd.io/_uploads/S1rmuKnsj.png) > [出處](https://twitter.com/BillGates/status/1145696067285114881) 儘管電傳打字機的實體早已消聲匿跡,但 `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/) * [TTY 到底是什麼?](https://www.kawabangga.com/posts/4515) ## Linux 究竟包含哪些部分? 當我們重新檢視 [inside the linux kernel](https://turnoff.us/geek/inside-the-linux-kernel/) 漫畫,不難發現其實只有一部分是真正存在於 Linux 核心,例如 process table, file system, scheduler, 和 tty 底層的實作,至於漫畫中大廳出現的大部分角色則隸屬於使用者層級 (user-level,或 userland)。