跟蹤分析Linux內(nèi)核的啟動(dòng)過(guò)程

網(wǎng)易云課堂《Linux內(nèi)核分析》作業(yè)

實(shí)驗(yàn)?zāi)康模?br>

跟蹤分析一個(gè)簡(jiǎn)單的Linux內(nèi)核啟動(dòng)過(guò)程,理解操作系統(tǒng)是怎么啟動(dòng)的

實(shí)驗(yàn)過(guò)程:

登陸實(shí)驗(yàn)樓虛擬機(jī)http://www.shiyanlou.com/courses/195

打開(kāi)shell終端,執(zhí)行以下命令:

cd LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage-initrd rootfs.img

1

執(zhí)行完畢后會(huì)彈出QEMU窗口芹务,輸出Linux內(nèi)核啟動(dòng)信息

2

啟動(dòng)成功后界面顯示MenuOS命令提示符

3

系統(tǒng)支持三個(gè)命令:help份名、version葵擎、quit

4

使用gdb跟蹤調(diào)試內(nèi)核

打開(kāi)shell終端贯卦,執(zhí)行以下命令:

cd LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage-initrd rootfs.img -s -S

關(guān)于-s和-S選項(xiàng)的說(shuō)明:

-S freeze CPU at startup (use ’c’ to start execution) 在系統(tǒng)啟動(dòng)的時(shí)候凍結(jié)CPU,使用c鍵繼續(xù)執(zhí)行后續(xù)操作

-s shorthand for -gdb tcp::1234 打開(kāi)遠(yuǎn)程調(diào)試端口蛮放,默認(rèn)使用tcp協(xié)議1234端口,若不想使用1234端口奠宜,則可以使用-gdb tcp:xxxx來(lái)取代-s選項(xiàng)

5

打開(kāi)另外一個(gè)shell終端包颁,執(zhí)行以下命令

gdb

(gdb)filelinux-3.18.6/vmlinux # 在gdb界面中targe remote之前加載符號(hào)表

6

(gdb)target?remote:1234 #?建立gdb和gdbserver之間的連接,按c?讓qemu上的Linux繼續(xù)運(yùn)行

7

(gdb)breakstart_kernel #?斷點(diǎn)的設(shè)置可以在target?remote之前压真,也可以在之后

8

按c鍵繼續(xù)執(zhí)行到start_kernel()函數(shù)

9

輸入list命令查看start_kernel()函數(shù)代碼

10

再設(shè)置一個(gè)斷點(diǎn)rest_init

11

查看rest_init()函數(shù)代碼

12

利用break設(shè)置斷點(diǎn)娩嚼,c繼續(xù)執(zhí)行,list查看函數(shù)代碼可以方便調(diào)試Linux啟動(dòng)過(guò)程中用到的任何函數(shù)滴肿。

實(shí)驗(yàn)分析:

本文以Linux內(nèi)核官方網(wǎng)站(The Linux Kernel Archives)2015-03-06發(fā)布的穩(wěn)定版3.19.1源代碼為準(zhǔn)分析岳悟。

分析./init/main.c源碼文件start_kernel()函數(shù)

Linux內(nèi)核啟動(dòng)代碼大致分2部分:

一部分是硬件平臺(tái)相關(guān)的,存放在./arch/目錄下,以平臺(tái)區(qū)分不同目錄贵少,比如x86平臺(tái)就在./arch/x86/目錄下呵俏,由匯編語(yǔ)言編寫(xiě)而成。

另一部分是硬件平臺(tái)無(wú)關(guān)的滔灶,由C語(yǔ)言編寫(xiě)而成普碎。

./init/main.c中的start_kernel()函數(shù)即是Linux內(nèi)核啟動(dòng)過(guò)程由平臺(tái)相關(guān)轉(zhuǎn)為平臺(tái)無(wú)關(guān)代碼后第一個(gè)執(zhí)行的函數(shù),在這個(gè)函數(shù)中录平,Linux內(nèi)核開(kāi)始真正進(jìn)入初始化階段麻车。

下面簡(jiǎn)單介紹其中的幾個(gè)函數(shù)。(斜體字為源碼斗这,粗體字為解釋)

/*

* Need to run as early as possible, to initialize the

* lockdep hash:

*/

lockdep_init();

lockdep是一個(gè)內(nèi)核調(diào)試模塊动猬,用來(lái)檢查內(nèi)核互斥機(jī)制(尤其是自旋鎖)潛在的死鎖問(wèn)題。

set_task_stack_end_magic(&init_task);

手工創(chuàng)建的PCB涝影,0號(hào)進(jìn)程即最終的idle進(jìn)程枣察。

/*

* Set up the the initial canary ASAP:

*/

boot_init_stack_canary();

canary值的是用于防止棧溢出攻擊的堆棧的保護(hù)字。

trap_init();

對(duì)內(nèi)核陷阱異常進(jìn)行初始化燃逻。

mm_init();

初始化內(nèi)核內(nèi)存分配器序目。

/*

* Set up the scheduler prior starting any interrupts (such as the

* timer interrupt). Full topology setup happens at smp_init()

* time - but meanwhile we still have a functioning scheduler.

*/

sched_init();

初始化調(diào)度器數(shù)據(jù)結(jié)構(gòu),并創(chuàng)建運(yùn)行隊(duì)列伯襟。(一道作業(yè)題的答案:Linux源碼start_kernel函數(shù)中調(diào)用進(jìn)程調(diào)度初始化的是哪個(gè)函數(shù)猿涨?)

/* Do the rest non-__init'ed, we're now alive */

rest_init();

start_kernel()函數(shù)中調(diào)用的最后一個(gè)函數(shù)。

分析./init/main.c源碼文件rest_init()函數(shù)

rest_init()函數(shù)的主要功能是創(chuàng)建并啟動(dòng)內(nèi)核進(jìn)程init姆怪,即第一個(gè)用戶態(tài)進(jìn)程叛赚。

int pid;

定義pid變量存放進(jìn)程號(hào)

rcu_scheduler_starting();

RCU(Read-Copy Update)鎖機(jī)制啟動(dòng)。

參考:Linux 2.6內(nèi)核中新的鎖機(jī)制--RCU

/*

* We need to spawn init first so that it obtains pid 1, however

* the init task will end up wanting to create kthreads, which, if

* we schedule it before we create kthreadd, will OOPS.

*/

kernel_thread(kernel_init, NULL, CLONE_FS);

init進(jìn)程在此時(shí)創(chuàng)建好了稽揭,但是現(xiàn)在還不能調(diào)度它俺附。

numa_default_policy();

設(shè)定NUMA(Non-Uniform Memory Access Architecture)系統(tǒng)的內(nèi)存訪問(wèn)策略為默認(rèn)。

參考:Linux 的 NUMA 技術(shù)

pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

創(chuàng)建kthreadd內(nèi)核線程溪掀,它的作用是管理和調(diào)度其它內(nèi)核線程事镣。

rcu_read_lock();

kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);

獲取kthreadd的線程信息,獲取完成說(shuō)明kthreadd已經(jīng)創(chuàng)建成功揪胃。

rcu_read_unlock();

complete(&kthreadd_done);

通過(guò)一個(gè)complete變量(kthreadd_done)來(lái)通知kernel_init線程璃哟。

實(shí)驗(yàn)總結(jié):

當(dāng)計(jì)算機(jī)系統(tǒng)加電(Power on PC)后,BIOS代碼被調(diào)用執(zhí)行喊递,然后開(kāi)始調(diào)用執(zhí)行Linux內(nèi)核初始化代碼随闪,在平臺(tái)相關(guān)的匯編代碼執(zhí)行完畢后會(huì)跳轉(zhuǎn)到start_kernel()函數(shù),開(kāi)始真正的內(nèi)核初始化骚勘,其中init_task創(chuàng)建了0號(hào)進(jìn)程铐伴,即最終的idle進(jìn)程,隨后rest_init()函數(shù)創(chuàng)建了init進(jìn)程,即1號(hào)進(jìn)程盛杰,以及kthreadd進(jìn)程挽荡,即2號(hào)進(jìn)程,系統(tǒng)開(kāi)始正式對(duì)外工作了即供。

參考:

Linux內(nèi)核源碼分析--內(nèi)核啟動(dòng)之(3)Image內(nèi)核啟動(dòng)(C語(yǔ)言部分)(Linux-3.0 ARMv7)

Linux內(nèi)核源碼分析--內(nèi)核啟動(dòng)之(5)Image內(nèi)核啟動(dòng)(rest_init函數(shù))(Linux-3.0 ARMv7)

aapu原創(chuàng)作品轉(zhuǎn)載請(qǐng)注明出處《Linux內(nèi)核分析》MOOC課

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末定拟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逗嫡,更是在濱河造成了極大的恐慌青自,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驱证,死亡現(xiàn)場(chǎng)離奇詭異延窜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)抹锄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)逆瑞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人伙单,你說(shuō)我怎么就攤上這事获高。” “怎么了吻育?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵念秧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我布疼,道長(zhǎng)摊趾,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任游两,我火速辦了婚禮砾层,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贱案。我一直安慰自己梢为,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布轰坊。 她就那樣靜靜地躺著,像睡著了一般祟印。 火紅的嫁衣襯著肌膚如雪肴沫。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天蕴忆,我揣著相機(jī)與錄音颤芬,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛站蝠,可吹牛的內(nèi)容都是我干的汰具。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼菱魔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼留荔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起澜倦,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤聚蝶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后藻治,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體碘勉,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年桩卵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了验靡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雏节,死狀恐怖胜嗓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矾屯,我是刑警寧澤兼蕊,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站件蚕,受9級(jí)特大地震影響孙技,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜排作,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一牵啦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妄痪,春花似錦哈雏、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至罪针,卻和暖如春彭羹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泪酱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工派殷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留还最,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓毡惜,卻偏偏與公主長(zhǎng)得像拓轻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子经伙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容