# 2025q1 Homework5 (assessment)
contributed by < `RealBigMickey` >
2025 年 4 月 3 日,目前是 Linux 核心設計的第七週,而這堂課目前給我最大的收穫是認知到自己不足,從未覺得自己是如此的渺小。大二的我退必修來這堂課的初衷是學習,但遇到的種種挫折也是源自於學習,一週一週的作業與測驗,每次面對的都是新東西新概念,一次次的被轟炸,一點一滴的慢慢學...
## 自動販賣機而延畢的那一年:
原本不打算寫這麼多的,當初覺得簡單寫幾句帶過就好,畢竟老師的個性也討厭假掰、鬼打牆、假文青似的心得,若沒有感觸就別多寫了吧。但這文很特別,幾個少年好高騖遠的故事,還沒學著跑就想要飛,伸手抓住天上的星星,跌倒再起的故事。
時不時我也會有些天馬行空的發想,雖然不切實際,但還是會想去嘗試去實踐,雖然這可能是幫自己找藉口,但往往自己會因為得顧課業、找不到志同道合的人、其他事物或壓力而壓下這些想法。不知道何時開始,自己開始去羨慕那些可以被熱誠吞噬,可以為理想把自己燃燒殆盡的人,有一天,我是不是也能這樣?
有時我不經意的想,有一天?為什麼要等到有一天?
說到底缺的就是缺了個野心,還沒有遇到一件足以讓我死心塌地,可以不顧一切去做的事,還沒一個理想讓我願意付出一切心力。
哪一天會遇到?或許明年、或許明天,也有可能這輩子都不會遇見,星空中不一定看得到流星,但若低著頭則沒機會遇見它。
目前的我雖然嚮往但還沒有想飛,我的雙腳踩在地面上,視線還不穩定,腳踏實地的慢慢往前。
## 我可以怎麼對 Linux 核心做出貢獻?
深知自己的能力還很有限,因此若要做就想先從 Linux 核心中比較小眾、比較微不足道的地方出發,去找一些就算是我也能貢獻的地方。
**優化方向:**
- 善用 SIMD, SWAR
- 善用 ```__builtin_expect(!!(x), 1)```進一步優化編譯過程
- 善用各種 `__builtin` 函式
- 盡可能的去使用 [bitops](https://hackmd.io/@sysprog/c-bitwise) 去操作
- 多使用 tenary 運算子
- 必要的話用 asm inline 組合語言 (真的要很必要)
目前自己想的方向大概才這幾個,某一週的 quiz 提到 SIMD+SWAR ,當時研究了一天,覺得還蠻酷的,而且還算有趣。`__builtin_expect` 也是某一週的 quiz 出現的東西,看到時就覺得 「wow原來還可以這樣的。」
至於寫組合語言這點,最大的難點是兼容性。Linux 核心在上億的裝置上執行,支援各種不同架構與裝置,而組合語言很容易直接將它寫死。先不論 RISC-V, x86 等指令集上就有的巨大差異的架構,光是 x86 與 x86_64 (amd64) 位元上的差異就會導致不同的語法與寫法。amd64 是支援 x86 的指令集但這樣就沒有達到最佳優化的目的。
**目前看到或許能著手改善的地方:**
- hid-playstation.c
- xpad
- hid-nintendo

沒錯就是熟悉的遊戲三巨頭,Linux 核心內建就有支援三大廠商的搖桿,我的想法是這些 .c 檔或許沒有甚麼人在關注/維護,畢竟影響的人真的不多,而且就算搖桿的程式沒有優化到最好那又如何,根本對日常使用完全沒差。
沒關係!```A man's trash is another man's treasure.``` 人家不屑做的我來就好!
> 這當然只是非常初步的想法,會繼續去看並學習,找到自己能貢獻的地方
## switch_to()
Nomally I don't really document myself researching concepts I don't get (cause if I did there would be WAY too much to write down😅). But, I found switch_to quite interesting so I'm writing this down.
One of the questions in the Google Form for submitting HW5 asked which standard C library function the ```switch_to``` macro corresponds to, ignoring performance considerations.
### What does it do?
In the Linux kernel, switch_to used to context switch between two processes
e.g.
```c
struct task_struct *last;
switch_to(prev, next, last);
```
- Saves context of prev
- Switches CPU to next
- Stores the previous task in last
How it's defined in the source code:
```c
#define switch_to(prev, next, last) \
do { \
((last) = __switch_to_asm((prev), (next))); \
} while (0)
```
Cool, it's a macro that calls **__switch_to_asm** which is assembly.
*Looking at the assembly code for __switch_to_asm: (amd64 for example)*
:::spoiler
```clike
SYM_FUNC_START(__switch_to_asm)
/*
* Save callee-saved registers
* This must match the order in inactive_task_frame
*/
pushq %rbp
pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
/* switch stack */
movq %rsp, TASK_threadsp(%rdi)
movq TASK_threadsp(%rsi), %rsp
#ifdef CONFIG_STACKPROTECTOR
movq TASK_stack_canary(%rsi), %rbx
movq %rbx, PER_CPU_VAR(fixed_percpu_data + FIXED_stack_canary)
#endif
/*
* When switching from a shallower to a deeper call stack
* the RSB may either underflow or use entries populated
* with userspace addresses. On CPUs where those concerns
* exist, overwrite the RSB with entries which capture
* speculative execution to prevent attack.
*/
FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW
/* restore callee-saved registers */
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbx
popq %rbp
jmp __switch_to
SYM_FUNC_END(__switch_to_asm)
```
The called function must save/restore callee-saved registers. The six lines of pushq and popq do just that, so not really important to the meat of the function.
:::
This is interesting because this is an instance of assembly being used in Linux kernal.
But how does Linux know what assembly code to run? Biggest problem with assembly is it's compatibility, it's architecture bound.

[Officially Supported Architectures in the Linux Kernel](https://www.kernel.org/doc/html/v6.3/arch.html)
At the root of the kernel source tree, you can see folders for every architecture that's supported. But upon building only 1 folder is used and compiled!
SO, The specific architecture is chosen even before **buildtime** of the Linux kernel.
### Why use assembly?
Because we're changing tasks by changing the **Stack Pointer**, which is represented as the register **'%rsp'**. C provides no easy way to change the stack pointer.
## 期末專案討論
這部分是目前最沒方向的,連一些很初步的架構都沒有,只有些許零碎的想法,不只是還不清楚自己想做甚麼,更多是不知道自己到底有沒有能力去實踐這些專案。從 0 開始設計 RISC-V 處理器並在上面執行 Linux 聽起超酷的好嗎,即便是用 qemu 模擬出來的結果還是讓我讚嘆不已。但回到我自己,才剛學過很初階的 Verilog,作業系統、編譯系統都還沒上,甚至正在上計算機組織,有沒有辦法在這學期期末前搞出這麼大的專案?
雖然我沒什麼能力但自信心還是有的,我認為若真的投入 100% 心血與力氣或許有辦法真的搞出來,可惜日子沒有那麼好過,我沒辦法把幾個月的時間都獻給一科的一個專案。好高騖遠心理也要有個底,不希望放掉其他科目。
**那你還想做這種大專案嗎?**
想,當然想。雖然想法上跟老師有些背道而馳,但我認為大學的路還走不到一半,只要心還在、沒有忘記,等一會兒都還來的及。就算現在做不到,過了一學期、一年,一次 Linux 核心設計的洗禮,做了專題、修完課後,大四再捲土重來還算遲嗎?
好像有些扯遠了,回到專案的想法。對自己設計處理器並執行 Linux 有興趣,但現階段自認能力不足。我記得有個專案叫 Simplefs 是個簡略的檔案系統,這個東西也覺得很酷,當時作業 0 觀看時就有做下以下筆記:
>Idea: Create a simple and intuitive File system with the goal of streamlining files through the web and locally, using a simple set of commands and instructions to communicate and use said system.
升上大二時曾做過一個很大便的小專案,一句話就是```"利用 Discord 訊息中的附檔來實現無限大雲端硬碟系統"```。整個專案用 python 寫,程式碼宛如義大利麵,自己都快看不懂。扯到 socket、html、資料庫、discord bot 等東西,整個就是一團亂但至少結果是能用的。可以算是向 discord 那邊偷了儲存空間來用,而且上傳下載速度意外還行。
> 
> 當時做的簡單示意圖
所以這個期末專案的想法是寫個簡單檔案系統,而它只支援一些非常簡略的功能,目的是簡略且快速。可以利用些簡單的指令操控,而這些指令可以透過網路執行使用,傳輸資料,簡單的實用性使其可融入其他已存在的系統中。
:::warning
參見 [Cloud Storage FUSE](https://cloud.google.com/storage/docs/cloud-storage-fuse/overview)
:::
若真的要融入其他系統,我會希望能融入大一暑假寫的那個大便雲端系統試試看,實測它的便利性與 'Compatibility'。
> Apr 3, 2025
### 更:
我記得某一次的表單中提過個專案,Jserv 老師的 [mini-arm-os](https://github.com/jserv/mini-arm-os) ([介紹的簡報](https://wiki.csie.ncku.edu.tw/embedded/summer2015/mini-arm-os.pdf))
也有看到其他同學做的學習筆記/紀錄 -> [連結](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/rkJtpGdAT)
我覺得這個專案很有趣,在大學畢業前自己設計處理器與作業系統算是我的小夢想,目前不管是 C 、組合語言還是 Verilog 能力都還遠遠不足,但心中還是有想嘗試的心。
設計處理器目前真的是不可能,Verilog 能力還停留在 pong 就極限了(Atari 那個遊戲),太多東西要補。因此期末要做我會選擇一個相對簡單、文獻較多且為開源的 RISC-V 來寫簡易作業系統...
先暫定名為 tiny-RISCV-os
(得與老師談談,得衡量一下可行性)
結論,目前可能的題目:
- 雲端檔案系統
- tiny-RISCV-os
> Apr 22, 2025