contributed by < jimmylu890303
>
人生就是一連串的選擇。每一次的選擇都像是一場賭注,而在每個選擇中,應當付出百分之百的努力,才能取得成功。如果因為害怕失敗而不敢踏出第一步,就永遠無法品嘗成功的滋味。即使遇到失敗,也能從中獲得寶貴的經驗。最重要的是,在過程中能夠領悟到其中的意義。
人不付出犧牲,就得不到任何回報。如果要得到什麼,就必須付出同等的代價,這就是鍊金術的基本原則,等價交換。當時我們深信著,這就是這世界的真理。–––《鋼之鍊金術師》
與作者一樣,我們都是平凡的人,並非天才。然而,與我最大的區別在於他敢於付出。他為了一個突發奇想的想法,願意花費長達14個月的時間去實現它。雖然我們可能不懂硬體也不懂機械,但只要我們願意坦誠面對困難並積極解決,就能克服一切障礙。因此,我認為持之以恆、堅持不懈的心態是最重要的。只要擁有這樣的心態,所有的困難都可以迎刃而解。
我們將秤冰塊的機構固定好後,將其傾斜,希望落入的冰塊會從尾端開始堆積。另外擋板可以避免冰塊超出支點,接下來,由我負責檢驗該設計下冰塊和荷重元產生的訊號是否有正比關係,誤差是否在可接受的範圍內。
於是我便重複「加冰塊、倒冰塊、測量訊號、紀錄」,做了超過480次
在實踐的過程中,我不斷嘗試,就像學習一樣。一開始可能會感到困惑,但經過多次的嘗試,總能找到解決的辦法。我希望能學習像作者一樣的心態,專注投入地完成每一件事情。
你不能現在就放棄,要是現在就放棄的話,你這輩子日後遇到這種等級的困難,就只會想逃避而已。
最後,我對上述的話感觸很深。我在遇到困難時常常感到想要逃避,而不是勇敢地正視它。因此,我希望能夠將這句話銘記在心裡。
在這幾周學習 Linux 核心實作的感受是我一直努力跟上每周的課程進度和作業,並從教材中學到了許多知識。雖然其中很多的部分屬於基礎知識,但或許是因為大學時基礎不夠扎實,所以整體閱讀教材時感到有些吃力。雖然進度稍微落後,但我覺得自己獲益良多。
在作業方面,我經常在趕作業的截止期限,交出去的作業品質都不夠好,雖然都能夠運作,但明顯缺乏細節。尤其是看到課堂上許多同學的作業表現,感覺他們非常厲害,與我有著天壤之別。他們甚至能夠在極短的時間內交付一個品質很好的作品。但透過觀察這些同學,我也希望有朝一日能夠追上他們的腳步。
整體來說,修這堂課非常的挑戰性,我需要補足的知識也非常地多,但是就如上述所說 人不付出犧牲,就得不到任何回報。如果要得到什麼,就必須付出同等的代價
,所以即使很困難,也不要放棄,堅持下去後我相信我也會獲益良多。
在閱讀 CS:APP 第二章時,講述著數值系統的重要性,裡面介紹各個型態的轉換,資安漏洞就是常常會由不同型態的數值的轉換導致。
我以為數值轉換及運算是一個很微小簡單的事情,但是魔鬼確會藏在這些小細節之中。
書中提及一個知名的例子, maxlen
被定義成 int 型態,而 KSIZE
為 unsigned
的型態,當在執行 KSIZE < maxlen
的操作時, maxlen 會被轉換成 unsigned
,而這個隱性轉換大多數的工程師都不會注意到細節卻可以被駭客當作一個入侵的入口。
當今天有心人士將 maxlen = 負數
傳入這個函數時, mxalen 會被轉換成 unsigned
(一個非常大的無號數), 透過 memcpy(user_dest, kbuf, len)
就能夠存取到一些非法區域(如 kernel 中的敏感資訊)。
並且因為底層系統使用 Binary 運作,所以書中也有提及一些編譯器的優化。
以乘以常數為例 :
原先乘法可以被 (x<<3) + (x<<2) + (x<<1)
取代,並且乘法及除法所耗費的成本也比較多,所以使用位移指令可以達到增加程式的效率。
還有一個比較特別的技巧是 Dividing by a Powers of 2 (Rounding up)
(x + (1 << k) - 1) >> k
起初看到這個表達式會想說為何要加上 (1 << k) - 1
這個bias?
後來看著它的推導後才比較明白
考慮
假設 where
當 r=0 時, ,當 r > 0 時,,所以這樣就可以進行向上取整得操作。
所以考慮 情況,則為 (x + (1 << k) - 1) >> k
信號是在軟體層次上對中斷機制的一種模擬,在原理上,一個進程收到一個信號與處理器收到一個插斷要求可以說是一樣的。信號是非同步的,一個進程不必通過任何操作來等待信號的到達,事實上,進程也不知道信號到底什麼時候到達。
不可靠信號 | 可靠信號 | |
---|---|---|
支援排隊 | No | Yes |
可附加資訊 | No | Yes |
https://man7.org/linux/man-pages/man7/signal.7.html
https://man7.org/linux/man-pages/man2/sigaction.2.html (注意 process vs. thread)
為何後續 linux 的維護者不將不可靠信號
改成可靠信號
?
額外分成非即時信號及即時信號的必要性?
非即時信號及即時信號是網路上中文來源不明的教材,在參造 signal 的文件中,沒提及到不可靠信號及非即時信號的內容。
SIGKILL
及 SIGSTOP
參閱老師的 coro.c 課程教材,可以發現在作任務的切換是使用 setjmp
和 longjmp
去做跳躍的動作( nonlocal goto )
當在一開始 A 呼叫 setjmp
時, setjmp
會將 stack pointer, instruction pointer, the values of other registers, the signal mask 存在 jmp_buf 的 buffer 內 longjmp
作使用。但在執行 setjmp
時, pc 會指向 line 8 的位置。
當 B 使用 longjmp
時會恢復 Buf 內的資訊,那應該會執行printf("A setjmp address\n");
一次,但是真實的作用是會觸發 setjmp(Buf) != 0
行為則執行 else 內的行為。
ip 會儲存在 line 7 的位置,所以在 B 使用
longjmp
時會恢復 Buf 內的資訊,觸發setjmp(Buf) != 0
行為則執行 else 內的行為。
在 /dev/ 下的裝置有 major number 和 minor number,在對 /dev/下的裝置作操作時, linux kernel 會透過 major number 去找到對應的 module , 但是若有多個 device 對應到同個 major number,也是會找相同的 module,但是要如何透過不同的 minor number 去控制不同的驅動行為 ?
多個裝置對應相同的 major number: 如果有多個裝置使用相同的 major number(例如同一類型的硬體裝置),每個裝置會有不同的 minor number。這些 minor number 可以在同一驅動程式模組中被不同的函式或處理邏輯所區分和處理。
TODO: 將 semu 的部分 VirtIO 成果整合到 kvm-host
TODO: 研讀 KVM: Linux 虛擬化基礎建設, 打造以 KVM 為基礎的精簡虛擬機器管理程式, 2022 年報告 和 2023 年報告,以理解 KVM 和 VirtIO 原理,針對電腦網路和 2D 裝置模擬提出方案