這幾天身體不太好,進(jìn)展不快.有時(shí)候突然發(fā)現(xiàn)在拼命的讀代碼的間隙里,停一會(huì)想一想,收獲會(huì)更大.特別是對(duì)于這種非常龐大的系統(tǒng)來(lái)說(shuō).把握整體的意義尤其重要.隨著對(duì)linux整體的拆解,我對(duì)于整個(gè)系統(tǒng),已經(jīng)不想開始是那么模糊.好像已經(jīng)度過(guò)了那個(gè)極點(diǎn).不過(guò)我也應(yīng)做好準(zhǔn)備,因?yàn)橐坏覍?duì)整個(gè)細(xì)節(jié)解讀時(shí),肯定也會(huì)有同樣的經(jīng)歷.
整個(gè)linux內(nèi)核之所以這樣艱澀,難懂就在于它的整體性.想我們這樣很少寫萬(wàn)行以上程序的人來(lái)說(shuō),它就好像一個(gè)龐大的肉球.讓你不知道如何下嘴.不過(guò)一但咬破.就非常香美了.畢竟,讀這么優(yōu)秀的代碼也是一種享受.
我個(gè)人認(rèn)為linux 的內(nèi)核難在這幾點(diǎn):1,系統(tǒng)龐大,太多的變量,結(jié)構(gòu), 以及typedef定義的東西不容易找到.2,作為操作系統(tǒng),它的函數(shù)調(diào)用時(shí)動(dòng)態(tài)的,讀不懂大量的makefile 你根本就不知道這50 M的東西是怎么組織起來(lái)的,況且,你絕對(duì)不可以像跟蹤程序一樣用debug走一下.3, 龐大的數(shù)據(jù)結(jié)構(gòu),可能是比較簡(jiǎn)單的運(yùn)算變得不容易讀.
因此在讀核的初級(jí)階段.我們應(yīng)該善于想象,善于將不容易理解的部分用偽碼的理解方式走過(guò),當(dāng)我們對(duì)大局把握好了,將整個(gè)結(jié)構(gòu)拆解清楚了,在讀不遲.況且,雖內(nèi)核本身來(lái)說(shuō),它所涉及到的運(yùn)算,結(jié)構(gòu). 本質(zhì)上和課本上的沒(méi)有差別.(可惜我不是計(jì)算機(jī)系畢業(yè)的).只不過(guò)是內(nèi)容多了一些罷了.
比如說(shuō)進(jìn)程調(diào)度這一部分,說(shuō)白了,就是在調(diào)用fork()的時(shí)候,就產(chǎn)生一task_strut 類型的指針,它包含進(jìn)程調(diào)度所用到的一切信息.然后將這個(gè)指針插到隊(duì)列中去就行了,然后cpu 一次總隊(duì)類中取出指針,分配給他們時(shí)間片.
而這個(gè)指針如何插入呢?說(shuō)白了就是看它的weight,weight 的計(jì)算方法,有根據(jù)進(jìn)程類型的不同由不同的算法(實(shí)時(shí)進(jìn)程,內(nèi)核進(jìn)程,普通進(jìn)程).好了,這樣我們想一下<<數(shù)據(jù)結(jié)構(gòu)中>>關(guān)于隊(duì)列的操作,插入,刪除,插到隊(duì)頭,置于隊(duì)尾.再想一下,這些操作如何同操作系統(tǒng)的應(yīng)用結(jié)合在一塊.例如;好隊(duì)進(jìn)程正在運(yùn)行,突然,由于一硬件中斷.產(chǎn)生一進(jìn)程,它必須馬上處理.系統(tǒng)應(yīng)把它插入到隊(duì)頭.
好了.你可以讀一下/usr./src/linux/kenrel/sched.c,不要過(guò)那么多全局變量,現(xiàn)在數(shù)據(jù)結(jié)構(gòu)上走過(guò)去,如下面的代碼:
static inline void move_last_runqueue(struct task_struct * p)
{
struct task_struct *next = p->next_run;
struct task_struct *PRev = p->prev_run;
/* remove from list */
next->prev_run = prev;
prev->next_run = next;
/* add back to list */
p->next_run = &init_task;
prev = init_task.prev_run;
init_task.prev_run = p;
p->prev_run = prev;
prev->next_run = p;
}
static inline void move_first_runqueue(struct task_struct * p)
{
struct task_struct *next = p->next_run;
struct task_struct *prev = p->prev_run;
/* remove from list */
next->prev_run = prev;
prev->next_run = next;
/* add back to list */
p->prev_run = &init_task;
next = init_task.next_run;
init_task.next_run = p;
p->next_run = next;
next->prev_run = p;
}
如果你還不懂,你可能要先,在c語(yǔ)言和數(shù)據(jù)結(jié)構(gòu)上下一點(diǎn)功夫.其他的模塊,我想也是大同小異, 不過(guò),也修補(bǔ)會(huì)這么簡(jiǎn)單.如內(nèi)存管理中用到了好多平衡二叉樹的排序,遍歷等等.但總的結(jié)構(gòu)時(shí)不變的.只要可以通欄全局,在不開定義的情況下,可以讀懂全局變量的意思(其實(shí),猜個(gè)八九不成問(wèn)題),看懂是不成問(wèn)題的.起碼我是信心十足.
我應(yīng)該在熟悉一下,計(jì)算機(jī)專業(yè)的軟件基礎(chǔ)課!!
新聞熱點(diǎn)
疑難解答
圖片精選