我們知道,在 start_kernel() 的開機過程中,會呼叫許多初始化核心的常式。其中 fork_init() 是用來初始化 kernel 的"fork" 環境的。"fork()" 是用來產生 child process 的 system call,當 parent process 想要執行外部程式時,會先 fork child process,接著 child process 再利用 exec system call 自己的空間取代為外部程式。
從講義第 5 頁開始,我們把問題做分割,找出與 Scheduling 有關的初始化流程來做研讀,因為我們想要以 Scheduling 做為深入 Linux kernel 的第一門課。
講解 fork_init()
1. Kernel 能 fork 的 process 數是依據 physical memory 的大小來決定的,我們看到 fork_init(unsigned long mempages) 的 mempages 即是用來計算 max_threads 的參數。
2. 看到 mempages 參數,這個參數是由 start_kernel() 呼叫 fork_init() 時傳入的:
asmlinkage void __init start_kernel(void) { ... fork_init(num_physpages); ... }
3. 找一下 num_physpages,原來是 kernel 的 global symbol 啊,這個地方在 mm/memory.c:
unsigned long num_physpages; ... EXPORT_SYMBOL(num_physpages);
我們的想法是,目前還沒讀到有關 Memory Manager 與 mm 初始化的主題,所以還不如先暫時把這個地方當黑盒子,再做一次分割。因此,num_physpages 是怎麼來的就先放到「TODO」清單裡了。
4. 計算 max_threads 需要以下二個常數:
a. THREAD_SIZE:dependent on architecture
b. PAGE_SIZE:dependent on architecture
這二個常數都是平臺相依的,我把他們都標示在投影片上。這是在 processor-level 的 porting 就要處理掉的。
5. 再來,如同程式碼所述:至少要能產生 20 個 thread 系統才能開機。所以限定 max_threads 的最小值是 20。
另外,我們會發現有些與 "memory" 或 "signal" 有關的 code,目前比較好的做法是先放到「TODO」。希望我們這裡的思考邏輯與陳述方式對大家「閱讀核心」能有一點幫助。
跟上我們的腳步:請先行閱讀以下的文章,再看這篇日記! |
|
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw