3跟蹤分析Linux內(nèi)核的啟動過程

安大大 + 原創(chuàng)作品轉(zhuǎn)載請注明出處 + 《Linux操作系統(tǒng)分析》MOOC課程


實驗

  • 使用自己的Linux系統(tǒng)環(huán)境搭建MenuOS的過程
# 下載內(nèi)核源代碼編譯內(nèi)核
cd ~/LinuxKernel/
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
xz -d linux-3.18.6.tar.xz
tar -xvf linux-3.18.6.tar
cd linux-3.18.6
make i386_defconfig
make # 一般要編譯很長時間蓝纲,少則20分鐘多則數(shù)小時
 
# 制作根文件系統(tǒng)
cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git  # 如果被墻鹃共,可以使用附件menu.zip 
cd menu
gcc -o init linktable.c menu.c test.c -m32 -static –lpthread #init是系統(tǒng)啟動后默認(rèn)啟動1號進(jìn)程遭贸,init是第一個用戶態(tài)進(jìn)程师坎,第一個用戶態(tài)進(jìn)程是1號進(jìn)程
cd ../rootfs
cp ../menu/init ./ #把init拷貝到rootfs目錄下邊
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img #使用cpio方式把當(dāng)前rootfs目錄下所有的文件打包成rootfs.img一個鏡像文件
#至此一個最簡單的根文件系統(tǒng)鏡像制作完畢
 
# 啟動MenuOS系統(tǒng)
cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
  • 重新配置編譯Linux使之?dāng)y帶調(diào)試信息
1.在原來配置的基礎(chǔ)上似袁,make menuconfig選中如下選項重新配置Linux,使之?dāng)y帶調(diào)試信息
2.1 kernel hacking—>
2.2 [*] compile the kernel with debug info #把debug信息打開
          #使得跟蹤調(diào)試時可以邊跟蹤邊看跟蹤到某一點(diǎn)的某一行代碼時上下那一段的源代碼
3.make重新編譯(時間較長)
  • 內(nèi)核啟動完成后進(jìn)入menu程序:
menu編譯好的init文件放在rootfs里

把menu編譯好的init文件放在rootfs里殴胧,然后把rootfs做成rootfs.img荚坞。根文件系統(tǒng)是rootfs.img,內(nèi)核啟動完后加載根文件系統(tǒng)澡谭,根文件系統(tǒng)里的init可執(zhí)行文件就被執(zhí)行起來了

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

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 關(guān)于-s和-S選項的說明:
 -S freeze CPU at startup (use ’c’ to start execution)  CPU初始化之前凍結(jié)起來
 -s shorthand for -gdb tcp::1234 在這個端口上創(chuàng)建了一個gdb server愿题,若不想使用1234端口损俭,則可以使用-gdb tcp:xxxx來取代-s選項

另開一個shell窗口:

gdb
(gdb)file linux-3.18.6/vmlinux # 把一個帶有符號表的內(nèi)核鏡像加載進(jìn)來,在gdb界面中targe remote之前加載符號表
(gdb)target remote:1234 # 建立gdb和gdbserver之間的連接,按c 讓qemu上的Linux繼續(xù)運(yùn)行
(gdb)break start_kernel # 設(shè)置斷點(diǎn)潘酗,跟蹤內(nèi)核杆兵,斷點(diǎn)的設(shè)置可以在target remote之前,也可以在之后
被凍結(jié)的linux系統(tǒng)
把帶有debug信息(符號表)的內(nèi)核加載進(jìn)來
建立gdb和gdbserver之間的連接
設(shè)置start_kernel斷點(diǎn)
按c回車,系統(tǒng)開始執(zhí)行,啟動到start_kernel的位置
使用list命令就能查看到start_kernel上下的這段代碼
設(shè)置rest_init斷點(diǎn)
查看rest_init處的代碼,它是在start_kernel函數(shù)的尾部調(diào)用的

全局變量init_task即手工創(chuàng)建的PCB在這里初始化,0號進(jìn)程即最終的idle進(jìn)程仔夺。
不管分析內(nèi)核的哪一部分都會涉及到start_kernel,因為要通過start_kernel進(jìn)行初始化琐脏。

trap_init();初始化一些中斷向量
mm_init();內(nèi)存管理模塊初始化
sched_init();調(diào)度模塊初始化
等等
start_kernel的最后一句rest_init();

當(dāng)系統(tǒng)沒有進(jìn)程需要執(zhí)行時就調(diào)度到idle進(jìn)程

Linux內(nèi)核啟動過程相關(guān)的參考資料
計算機(jī)的啟動過程概述

x86 CPU啟動的第一個動作CS:EIP=FFFF:0000H(換算為物理地址為000FFFF0H,因為16位CPU有20根地址線)缸兔,即BIOS程序的位置日裙。http://wenku.baidu.com/view/4e5c49eb172ded630b1cb699.html

BIOS例行程序檢測完硬件并完成相應(yīng)的初始化之后就會尋找可引導(dǎo)介質(zhì),找到后把引導(dǎo)程序加載到指定內(nèi)存區(qū)域后惰蜜,就把控制權(quán)交給了引導(dǎo)程序昂拂。這里一般是把硬盤的第一個扇區(qū)MBR和活動分區(qū)的引導(dǎo)程序加載到內(nèi)存(即加載BootLoader),加載完整后把控制權(quán)交給BootLoader抛猖。

引導(dǎo)程序BootLoader開始負(fù)責(zé)操作系統(tǒng)初始化格侯,然后起動操作系統(tǒng)。啟動操作系統(tǒng)時一般會指定kernel财著、initrd和root所在的分區(qū)和目錄联四,比如root (hd0,0),kernel (hd0,0)/bzImage root=/dev/ram init=/bin/ash撑教,initrd (hd0,0)/myinitrd4M.img

內(nèi)核啟動過程包括start_kernel之前和之后朝墩,之前全部是做初始化的匯編指令,之后開始C代碼的操作系統(tǒng)初始化伟姐,最后執(zhí)行第一個用戶態(tài)進(jìn)程init收苏。

一般分兩階段啟動,先是利用initrd的內(nèi)存文件系統(tǒng)玫镐,然后切換到硬盤文件系統(tǒng)繼續(xù)啟動倒戏。initrd文件的功能主要有兩個:1、提供開機(jī)必需的但kernel文件(即vmlinuz)沒有提供的驅(qū)動模塊(modules) 2恐似、負(fù)責(zé)加載硬盤上的根文件系統(tǒng)并執(zhí)行其中的/sbin/init程序進(jìn)而將開機(jī)過程持續(xù)下去

init進(jìn)程詳解

Linux內(nèi)核中的init_task進(jìn)程和idle進(jìn)程

道生一(start_kernel....cpu_idle)杜跷,一生二(kernel_init和kthreadd),二生三(即前面0矫夷、1和2三個進(jìn)程)葛闷,三生萬物(1號進(jìn)程是所有用戶態(tài)進(jìn)程的祖先,2號進(jìn)程是所有內(nèi)核線程的祖先)双藕,新內(nèi)核的核心代碼已經(jīng)優(yōu)化的相當(dāng)干凈淑趾,都符合中國傳統(tǒng)文化精神了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末忧陪,一起剝皮案震驚了整個濱河市扣泊,隨后出現(xiàn)的幾起案子近范,更是在濱河造成了極大的恐慌,老刑警劉巖延蟹,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件评矩,死亡現(xiàn)場離奇詭異,居然都是意外死亡阱飘,警方通過查閱死者的電腦和手機(jī)斥杜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沥匈,“玉大人蔗喂,你說我怎么就攤上這事「咛” “怎么了缰儿?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長散址。 經(jīng)常有香客問我返弹,道長,這世上最難降的妖魔是什么爪飘? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮拉背,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己秋冰,他們只是感情好偿凭,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著两疚,像睡著了一般床估。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诱渤,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天丐巫,我揣著相機(jī)與錄音,去河邊找鬼勺美。 笑死递胧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赡茸。 我是一名探鬼主播缎脾,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼占卧!你這毒婦竟也來了遗菠?” 一聲冷哼從身側(cè)響起联喘,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辙纬,沒想到半個月后豁遭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牲平,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年堤框,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纵柿。...
    茶點(diǎn)故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜈抓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出昂儒,到底是詐尸還是另有隱情沟使,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布渊跋,位于F島的核電站腊嗡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拾酝。R本人自食惡果不足惜燕少,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒿囤。 院中可真熱鬧客们,春花似錦、人聲如沸材诽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脸侥。三九已至建邓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間睁枕,已是汗流浹背官边。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留譬重,地道東北人拒逮。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像臀规,于是被迫代替她去往敵國和親滩援。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評論 2 361

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