今天開始我的讀核罹難記.第一次讀內(nèi)核,整整上學(xué)時(shí)的考試前.胡里胡涂的就過去了,沒甚收獲.這次我發(fā)誓要徹底讀一次.
面對近50 m 的源碼,困惑是難免的所以我決定先從大面上把握,再在某一些具體的點(diǎn)上切入.這樣一來linux 的啟動(dòng)過程便十分重要,因此我先用dmesg命令察看一下linux啟動(dòng)時(shí)打出的消息.(我想源文件應(yīng)在/usr/src/linux/init/main.c中)
內(nèi)核的啟動(dòng)最后是到 start_kernel ( in /init/main.c )也就是說啟動(dòng)的過程是從 head.S ( arch/i386/boot/ ) 一直運(yùn)行到 main.c(start_kernel) .它的作用是完成開機(jī)后的設(shè)置與內(nèi)核的初始化,然后,系統(tǒng)究竟入一個(gè)無限的循環(huán)中等待用戶的輸入,調(diào)用fork來產(chǎn)生子進(jìn)程.從而達(dá)到交互式操作系統(tǒng)的設(shè)計(jì)要求.
第一部分 : 內(nèi)核初始化以及啟動(dòng).
.啟動(dòng)系統(tǒng).當(dāng)PC機(jī)加電開始啟動(dòng)時(shí),80X86的處理器(CPU)在實(shí)模式下自檢,開始執(zhí)行物理地址0xFFFF0即ROM-BIOS的起始地址處的代碼。PC機(jī)的BIOS進(jìn)行系統(tǒng)自檢,初始化中斷向量表到物理地址0x0。然后把引導(dǎo)設(shè)備的第一個(gè)扇區(qū)加載到地址0x7C00,執(zhí)行此處的指令。到這里與linux無關(guān),x86系列的硬件設(shè)置如此.
linux的內(nèi)核本身是不能自舉的,所以lilo和loadlin的作用就是加載系統(tǒng)內(nèi)核.有關(guān)lilo的原理可以參考lilo的readme.從加電到內(nèi)核加載的過程是:加電->執(zhí)行BIOS->加載第一扇區(qū)->lilo->加載內(nèi)核
Linux內(nèi)核的最初部分代碼是用匯編語言寫的(文件是boot/bootsect.s)。(我的匯編水平有限,暫且不看),它首先把自身這部分代碼移到絕對地址0x90000,把下面的2K代碼從引導(dǎo)設(shè)備加載到地址0x90200上,內(nèi)核的其余部分加載到地址0x10000處。在加載系統(tǒng)時(shí)顯示“l(fā)oading...”. 然后,程序控制權(quán)交給另一個(gè)實(shí)模式匯編程序(boot/Setup.S)。接下來,此程序把整個(gè)系統(tǒng)從地址0x10000移到地址0x1000,進(jìn)入保護(hù)模式。程序控制轉(zhuǎn)給系統(tǒng)的其余部分即地址0x1000。
下一個(gè)步驟是系統(tǒng)內(nèi)核的解壓過程,這部分代碼在地址0x1000(文件/Boot/head.S),該段程序初始化寄存器,然后執(zhí)行decomPRess_kernel(),這個(gè)函數(shù)源于zBoot/inflate.c、zBoot/unzip.c和zBoot/misc.c三個(gè)文件
Loading ....[ bootsect.S ]
uncompress .....[ decompress_kernel() ]
main.c ---> start_kernel() 開始.
開始 printk(banner);
Linux version 2.2.6 (root@lance) (gcc version 2.7.2.3) (檢查一下GCC 的版本號, 在/init/main.c 中如果gcc 的版本號不夠,時(shí)不允許編譯內(nèi)核的)
#40 Sun Apr 18 17:44:20 CST 1999
調(diào)用init_time()打印出以下內(nèi)容:
Detected 199908264 Hz processor.
然后運(yùn)行 console_init() --> drivers/char/tty_io.c */
Console: colour VGA+ 80x25
運(yùn)行一個(gè)循環(huán),測量一下 MIPS – 據(jù)說是要用一個(gè)確定的機(jī)器指令周期來實(shí)現(xiàn)實(shí)時(shí)的延遲.
Calibrating delay loop... 199.48 BogoMIPS
初始化內(nèi)存/* init_mem */
Memory: 63396k/65536k available (848k kernel code, 408k reserved, 856k data
, 28k
/** dquote_init() **/
VFS: Diskquotas version dquot_6.4.0 initialized
察看cpu 的類型(在2.2.14 以后聽說增加了對多種cpu 的支持, 以后我可得用心看看,if I can find a bug of intel then ……)
CPU: Intel Pentium Pro stepping 09
初始或處理器與協(xié)處理器,對于比較老的處理器, linux 會(huì)用軟件模擬協(xié)處理器?
Checking 386/387 coupling... OK, FPU using exception 16 error reporting.
檢查治理的合法性
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
此后調(diào)用 linux_thread(init ,..,..,)(arch/i386/kernel/process.c)
創(chuàng)建一個(gè)運(yùn)行 init 的進(jìn)程.
進(jìn)入了第二階段用戶模式 ( user_mode )End of start_kerne最后進(jìn)入cpu_idle ( arch/i386/kernel/process.c )
第二部分 設(shè)備的初始化
對設(shè)備的初始化調(diào)用. init()--->do_basic_init()--+
pci_init() 對pci 設(shè)備的初始化( 在main.c文件中有這樣一段 ifdef PCI …..需要看一下)下面打印出結(jié)果:
PCI: PCI BIOS revision 2.10 entry at 0xfd8d1
PCI: Using configuration type 1
PCI: Probing PCI hardware
對Socket的初始化,socket_init() (這里也許就是linux 的網(wǎng)絡(luò)秘密所在吧,以后我的注意) -Linux NET4.0 for Linux 2.2
Based upon Swansea University Computer Society NET3.039
NET4: Unix domain sockets 1.0 for Linux NET4.0.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
Starting kswapd v 1.5 kswapd_setup()
調(diào)用 device_setup()
Detected PS/2 Mouse Port.
初始化 聲卡
Sound initialization started
Sound initialization complete
初始化 軟驅(qū)
Floppy drive(s): fd0 is 1.44M
FDC 0 is a National Semiconductor PC87306
SCSI 設(shè)備的初始化
(scsi0) <Adaptec AIC-7880 Ultra SCSI host adapter> found at PCI 13/0
(scsi0) Wide Channel, SCSI ID=7, 16/255 SCBs
(scsi0) Downloading sequencer code... 419 instructions downloaded
scsi0 : Adaptec AHA274x/284x/294x (EISA/VLB/PCI-Fast SCSI) 5.1.10/3.2.4
<Adaptec AIC-7880 Ultra SCSI host adapter>
scsi : 1 host.
Vendor: SEAGATE Model: ST32155W Rev: 0596
ype: Direct-access ANSI SCSI revision: 02
Detected scsi disk sda at scsi0, channel 0, id 0, lun 0
Vendor: SEAGATE Model: ST32155W Rev: 0596
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sdb at scsi0, channel 0, id 1, lun 0
scsi : detected 2 SCSI disks total.
(scsi0:0:0:0) Synchronous at 40.0 Mbyte/sec, offset 8.
SCSI device sda: hdwr sector= 512 bytes. Sectors= 4197405 [2049 MB] [2.0 GB ](scsi0:0:1:0) Synchronous at 40.0 Mbyte/sec, offset 8.
SCSI device sdb: hdwr sector= 512 bytes. Sectors= 4197405 [2049 MB] [2.0 GB]Partition check: sda: sda1 |
sdb: sdb1 sdb2 < sdb5 sdb6 > |
安裝 文件系統(tǒng) filesystem_setup()
安裝設(shè)備驅(qū)動(dòng)程序 mount_root()
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 28k freed
Adding Swap: 66540k swap-space (priority -1)
Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996
SB 3.01 detected OK (220)
<ESS ES1688 AudioDrive (rev 11) (3.01)> at 0x220 irq 5 dma 1
YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1
996<Yamaha OPL3> at 0x388
NET4: AppleTalk 0.18 for Linux NET4.0
eth0: Intel EtherExpress Pro 10/100 at 0xf800, 00:A0:C9:49:2F:FF, IRQ 9.
Board assembly 645520-034, Physical connectors present: RJ45
Primary interface chip DP83840 PHY #1.
DP83840 specific setup, setting register 23 to 8462.
General self-test: passed.
Serial sub-system self-test: passed.
Internal registers self-test: passed.
ROM checksum self-test: passed (0x49caa8d6).
Receiver lock-up workaround activated.
NET4: AppleTalk 0.18 for Linux NET4.0
結(jié)束 do_basic_setup()
open("/dev/console", O_RDWR, 0)
開始執(zhí)行 /sbin/init ( execv(...) )
內(nèi)核就此啟動(dòng)完畢...
這樣一來系統(tǒng)在啟動(dòng)時(shí)需要的文件一目了然了.要讀啟動(dòng)這方面的源碼,大概也就可以這樣行動(dòng)即:
Boot/head.S
decompress_kernel(),然后按照個(gè)功能塊來讀取相應(yīng)的函數(shù).
其實(shí)對于整個(gè)kernel 來說,還應(yīng)該解讀一下makefile ,說實(shí)話在編程來講我是很愛寫 makefile ,然而解讀內(nèi)核,她就是工作十分難以進(jìn)行.好在有了souce insight 可以讓我們輕松的找到,函數(shù)和常量的定義, 方便不少.
打開main.c (其實(shí)我是將2.2.14解到了windows 下).發(fā)現(xiàn)有n 個(gè)函數(shù)與2n 個(gè)常量的定義,只有幾個(gè) init 函數(shù)在.對于其他的外部函數(shù)也定義了不少.這里卻沒有主函數(shù)—我現(xiàn)在懷疑linux 程序是否和vc 一樣不知道從哪里開始進(jìn)行:__).不過馬上明白了, 整個(gè)內(nèi)核事變在一塊的. 還包括.存儲管理, 處理機(jī)管理, 內(nèi)存管理等許多模塊, 她該不會(huì)啟動(dòng)以后就沒有時(shí)刻干了吧
好了, 一口吃不成胖子.我還是先從啟動(dòng)讀起.不過我開始對是否要加中文祝時(shí)產(chǎn)生懷疑, 寫那些代碼的本身都是高手, 他們應(yīng)知道怎樣是最好的注釋. 難道讀代碼的人連這點(diǎn)e 文也看不了?
新聞熱點(diǎn)
疑難解答
圖片精選