Linux內(nèi)核分析方法談_第1頁(yè)
Linux內(nèi)核分析方法談_第2頁(yè)
Linux內(nèi)核分析方法談_第3頁(yè)
Linux內(nèi)核分析方法談_第4頁(yè)
Linux內(nèi)核分析方法談_第5頁(yè)
已閱讀5頁(yè),還剩30頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、盡管linux絕對(duì)是最流行的開(kāi)源操作系統(tǒng),但是相對(duì)于其他操作系統(tǒng)的漫 長(zhǎng)丿力史來(lái)說(shuō),linux的丿力史非常短暫。在計(jì)算機(jī)出現(xiàn)早期,程序員是使用硬件語(yǔ) 言在裸硬件上進(jìn)行開(kāi)發(fā)的。缺少操作系統(tǒng)就意味著在某個(gè)吋間只有一個(gè)應(yīng)用程序 (和一個(gè)用戶)可以使用這些龐大而又昂貴的設(shè)備。早期的操作系統(tǒng)是在20世 紀(jì)50年代開(kāi)發(fā)的,用來(lái)提供簡(jiǎn)單的開(kāi)發(fā)體驗(yàn)。包括為ibm 701開(kāi)發(fā)的 general motors operating system (gmos)和 north american aviation 為 ibm 709 開(kāi)發(fā)的 fortran monitor system (fms)。在 20 世紀(jì) 60

2、年代,mit (massachusetts institute of technology)和一些公 司為 ge-645 開(kāi)發(fā)了一個(gè)名為 multics (multiplexed information and computing service)的實(shí)驗(yàn)性的操作系統(tǒng)。這個(gè)操作系統(tǒng)的開(kāi)發(fā)者z at&t 后來(lái)退出了 multics,并在1970年開(kāi)發(fā)了自己的名為unics的操作系統(tǒng)。與 這個(gè)操作系統(tǒng)一同誕生的是c語(yǔ)言,c語(yǔ)言就是為此而開(kāi)發(fā)的,然后它們使用 c語(yǔ)言對(duì)操作系統(tǒng)進(jìn)行了重寫(xiě),使操作系統(tǒng)開(kāi)發(fā)具有可移植性。二十年后,andrewtanenbaum創(chuàng)建了一個(gè)微內(nèi)核版本的unix®

3、;,名為minix (代表minimal unix),它可以在小型的個(gè)人計(jì)算機(jī)上運(yùn)行。這個(gè)開(kāi)源操作系 統(tǒng)在20世紀(jì)90年代激發(fā)了 linus torvalds開(kāi)發(fā)linux的靈感(請(qǐng)參看圖 1所示)。linux快速?gòu)囊粋€(gè)個(gè)人項(xiàng)目進(jìn)化成為一個(gè)全球數(shù)千人參與的開(kāi)發(fā)項(xiàng)目。對(duì)于 linux來(lái)說(shuō),最為重要的決策之一是采用gpl (gnu general public license) 在gpl保護(hù)z下,linux內(nèi)核可以防止商業(yè)使用,并且它還從gnu項(xiàng)口(richard stallman開(kāi)發(fā),其源代碼要比linux內(nèi)核大得多)的用戶空間開(kāi)發(fā) 受益。這允許使用一些非常有用的應(yīng)用程序,例如gcc (gnu

4、compiler collection)和各種 shell 支持。nux的最大的好處z就是它的源碼公開(kāi)。同時(shí),公開(kāi)的核心源碼也吸引著無(wú)數(shù)的 電腦愛(ài)好者和程序員;他們把解讀和分析linux的核心源碼作為自己的最大興趣,把修 改linux源碼和改造linux系統(tǒng)作為口己對(duì)計(jì)算機(jī)技術(shù)追求的最大目標(biāo)。linux內(nèi)核源碼是很具吸引力的,特別是當(dāng)你弄懂了一個(gè)分析了好久都沒(méi)搞懂的問(wèn) 題;或者是被你修改過(guò)了的內(nèi)核,順利通過(guò)編譯,一切運(yùn)行止常的時(shí)候。那種成就感真 是油然而生!而且,對(duì)內(nèi)核的分析,除了出自對(duì)技術(shù)的狂熱追求z外,這種令人生畏的 勞動(dòng)所帶來(lái)的回報(bào)也是非常令人著迷的,這也正是它擁有眾多追隨者的主要原因:

5、首先,你可以從中學(xué)到很多的計(jì)算機(jī)的底層知識(shí),如后而將講到的系統(tǒng)的引導(dǎo) 和硬件提供的中斷機(jī)制等;其它,象虛擬存儲(chǔ)的實(shí)現(xiàn)機(jī)制,多任務(wù)機(jī)制,系統(tǒng) 保護(hù)機(jī)制等等,這些都是非都源碼不能體會(huì)的。同時(shí),你還將從操作系統(tǒng)的整體結(jié)構(gòu)中,體會(huì)整體設(shè)計(jì)在軟件設(shè)計(jì)中的份量和 作用,以及一些宏觀設(shè)計(jì)的方法和技巧:linux的內(nèi)核為上層應(yīng)用提供一個(gè)與具 體硬件不相關(guān)的平臺(tái);同時(shí)在內(nèi)核內(nèi)部,它又把代碼分為與體系結(jié)構(gòu)和碩件相 關(guān)的部分,和可移植的部分;再例如,linux雖然不是微內(nèi)核的,但他把人部分的設(shè)備駁動(dòng)處理成相對(duì)獨(dú)立的內(nèi)核模塊,這樣減小了內(nèi)核運(yùn)行的開(kāi)銷,增強(qiáng)了 內(nèi)核代碼的模塊獨(dú)立性。而r你還能從對(duì)內(nèi)核源碼的分析中,體會(huì)

6、到它在解決某個(gè)具體細(xì)節(jié)問(wèn)題時(shí),方 法的巧妙:如后面將分析到了的linux通過(guò)botoom_half機(jī)制來(lái)加快系統(tǒng)對(duì)屮 斷的處理。最璽要的是:在源碼的分析過(guò)程中,你將會(huì)被一點(diǎn)一點(diǎn)地、潛移默化地專業(yè)化。 一個(gè)專業(yè)的程序員,總是把代碼的清晰性,兼容性,可移植性放在很重要的位 置。他們總是通過(guò)定義人量的宏,來(lái)增強(qiáng)代碼的清晰度和可讀性,而乂不增加 編譯后的代碼長(zhǎng)度和代碼的運(yùn)行效率;他們總是在編碼的同時(shí),就考慮到了以 后的代碼維護(hù)和升級(jí)。甚至,只要分析百分之一的代碼后,你就會(huì)深刻地體會(huì) 到,什么樣的代碼才是一個(gè)專業(yè)的程序員寫(xiě)的,什么樣的代碼是一個(gè)業(yè)余愛(ài)好 者寫(xiě)的。而這一點(diǎn)是任何沒(méi)有真正分析過(guò)標(biāo)準(zhǔn)代碼的人都

7、無(wú)法體會(huì)到的。然而,由于內(nèi)核代碼的冗長(zhǎng),和內(nèi)核體系結(jié)構(gòu)的龐雜,所以分析內(nèi)核也是一個(gè)很艱 難,很需耍毅力的事;在缺乏指導(dǎo)和交流的悄況下,尤其如此。只有方法正確,才能事 半功倍。止是基丁這種考慮,作者希望通過(guò)此文能給人家一些借鑒和啟迪。由于本人所進(jìn)行的分析都是基于2.2.5版本的內(nèi)核;所以,如果沒(méi)有特別說(shuō)明,以 下分析都是基于i386單處理器的2.2.5版本的linux內(nèi)核。所有源文件均是相對(duì)于目錄 /usr/src/linux 的。方法之一:從何入手要分析linux內(nèi)核源碼,首先必須找到各個(gè)模塊的位置,也即要弄懂源碼的文件組 織形式。雖然對(duì)于有經(jīng)驗(yàn)的高手而言,這個(gè)不是很難;但對(duì)于很多初級(jí)的lin

8、ux愛(ài)好者, 和那些對(duì)源碼分析很有興趣但接觸不多的人來(lái)說(shuō),這還是很冇必要的。1> linux核心源程序通常都安裝在/usr/src/linux卜,而且它有一個(gè)非常簡(jiǎn)單的編號(hào) 約定:任何偶數(shù)的核心(的二個(gè)數(shù)為偶數(shù),例如2.0.30)都是一個(gè)穩(wěn)定地發(fā)行的核心, 而任何奇數(shù)的核心(例如2.1.42)都是一個(gè)開(kāi)發(fā)中的核心。2、核心源程序的文件按樹(shù)形結(jié)構(gòu)進(jìn)行組織,在源程序樹(shù)的最上層,即目錄 /usr/src/linux卜有這樣一些目錄和文件: copying: gpl版權(quán)中明。對(duì)具有g(shù)pl版權(quán)的源代碼改動(dòng)而形成的程序,或使用 gpl工具產(chǎn)生的程序,具有使用gpl發(fā)表的義務(wù),如公開(kāi)源代碼; cred

9、its:光榮榜。對(duì)linux做出過(guò)很大貢獻(xiàn)的一些人的信息; maintainers:維護(hù)人員列表,對(duì)當(dāng)前版本的內(nèi)核各部分都有誰(shuí)負(fù)責(zé); makefile:第一個(gè)makefile文件。用來(lái)組織內(nèi)核的各模塊,記錄了個(gè)模塊間的相互這 間的聯(lián)系和依托關(guān)系,編譯時(shí)使用;仔細(xì)閱讀各子目錄卜的makefile文件對(duì)弄清各個(gè)文 件這間的聯(lián)系和依托關(guān)系很有幫助; readme:核心及其編譯配置方法簡(jiǎn)單介紹; rules.make:各種makefilemake所使用的一些共同規(guī)則; reportingbugs:有關(guān)報(bào)告bug的一些內(nèi)容; arch/ : arch子目錄包括了所有和體系結(jié)構(gòu)相關(guān)的核心代碼。它的每一個(gè)子

10、目錄都代 表一種支持的體系結(jié)構(gòu),例如i386就是關(guān)于intel cpu及與z相兼容體系結(jié)構(gòu)的子口錄。pc機(jī)一般都基于此目錄; include/: include t目錄包括編譯核心所需要的大部分頭文件。與平臺(tái)無(wú)關(guān)的頭文件 在include/linux子目錄下,與intel cpu相關(guān)的頭文件在include/asm-i386子目錄下, 而include/scsi目錄則是有關(guān)scsi設(shè)備的頭文件口錄; ini”:這個(gè)目錄包含核心的初始化代碼(注:不是系統(tǒng)的引導(dǎo)代碼),包含兩個(gè)文件 main.c和version.c,這是研究核心如何工作的好的起點(diǎn)之一。 mm/:這個(gè)目錄包括所有獨(dú)立于cpu體系結(jié)構(gòu)

11、的內(nèi)存管理代碼,如頁(yè)式存儲(chǔ)管理內(nèi) 存的分配和釋放等;而和體系結(jié)構(gòu)相關(guān)的內(nèi)存管理代碼則位于arch/*/mm/,例如 arch/i386/mm/fault.c; kernel/:主要的核心代碼,此目錄下的文件實(shí)現(xiàn)了大多數(shù)linux系統(tǒng)的內(nèi)核函數(shù),其 中最巫要的文件當(dāng)屬sched.c;同樣,和體系結(jié)構(gòu)相關(guān)的代碼在arch/*/kernel中; drivers/:放置系統(tǒng)所有的設(shè)備驅(qū)動(dòng)程序;每種驅(qū)動(dòng)程序又各占用一個(gè)子h錄:如, /block下為塊設(shè)備驅(qū)動(dòng)程序,比如ide (ide.c)。如果你希望查看所有可能包含文件系 統(tǒng)的設(shè)備是如何初始化的,你可以看drivers/block/genhd.c屮的d

12、evice_setup()o它不 僅初始化碩盤(pán),也初始化網(wǎng)絡(luò),因?yàn)榘惭bnfs文件系統(tǒng)的時(shí)候需要網(wǎng)絡(luò) documentation/:文檔目錄,沒(méi)有內(nèi)核代碼,只是一套有用的文檔,可惜都是english 的,看看應(yīng)該有用的哦; fs/:所有的文件系統(tǒng)代碼和各種類型的文件操作代碼,它的每一個(gè)了目錄支持一個(gè)文 件系統(tǒng),例如fat和ext2; ipc/:這個(gè)口錄包含核心的進(jìn)程間通訊的代碼; lib/:放置核心的庫(kù)代碼; net/:核心與網(wǎng)絡(luò)相關(guān)的代碼; modules/:模塊文件日錄,是個(gè)空日錄,用于存放編譯時(shí)產(chǎn)牛的模塊日標(biāo)文件; scripts/:描述文件,腳本,用于對(duì)核心的配置;一般,在每個(gè)子目錄卞,

13、都有一個(gè)makefile和一個(gè)readme文件,仔細(xì)閱讀這兩 個(gè)文件,對(duì)內(nèi)核源碼的理解很有用。對(duì)linux內(nèi)核源碼的分析,有兒個(gè)很好的入口點(diǎn):一個(gè)就是系統(tǒng)的引導(dǎo)和初始化, 即從機(jī)器加電到系統(tǒng)核心的運(yùn)行;另外一個(gè)就是系統(tǒng)調(diào)用,系統(tǒng)調(diào)用是用戶程序或操作 調(diào)用核心所提供的功能的接口。対于那些対硬件比較熟悉的愛(ài)好者,從系統(tǒng)的引導(dǎo)入手 進(jìn)行分析,可能來(lái)的容易一些;而從系統(tǒng)調(diào)用下口,則可能更合適于那些在dos或uinx、 linux下有過(guò)c編程經(jīng)驗(yàn)的高手。這兩點(diǎn),在后面述將介紹到。方法之二:以程序流程為線索,一線串珠從表面上看,linux的源碼就象一團(tuán)扎亂無(wú)章的亂麻,其實(shí)它是一個(gè)組織得冇條冇 理的蛛網(wǎng)。耍

14、把整個(gè)結(jié)構(gòu)分析清楚,除了找岀線頭,還得理順各個(gè)部分之間的關(guān)系,有 條不紊的一點(diǎn)一點(diǎn)的分析。所謂以程序流程為線索、一線串珠,就是指根據(jù)程序的執(zhí)行流程,把程序執(zhí)行過(guò)程 所涉及到的代碼分析清楚。這種方法最典型的應(yīng)用有兩個(gè):一是系統(tǒng)的初始化過(guò)程;二 是應(yīng)用程序的執(zhí)行流程:從程序的裝載,到運(yùn)行,一直到程序的退出。為了簡(jiǎn)便起見(jiàn),遵從循序漸進(jìn)的原理,現(xiàn)就系統(tǒng)的初始化過(guò)程來(lái)具體的介紹這種方 法。系統(tǒng)的初始化流程包括:系統(tǒng)引導(dǎo),實(shí)模式下的初始化,保護(hù)模式下的初始化共三 個(gè)部分。下面將介紹。inux系統(tǒng)的常見(jiàn)引導(dǎo)方式有兩種:lilo引導(dǎo)和loadin引導(dǎo);同時(shí)linux內(nèi)核也自帶 了一個(gè)bootsectloade

15、r。由于它只能實(shí)現(xiàn)linux的引導(dǎo),不像前兩個(gè)那樣具有很大的靈 活性(lilo可實(shí)現(xiàn)多重引導(dǎo)、loadin可在dos卞引導(dǎo)linux),所以在普通應(yīng)用場(chǎng)合實(shí)際上 很少使用bootsect-loaderc當(dāng)然,bootsect-loader也具有它自己的優(yōu)點(diǎn):短小沒(méi)有多 余的代碼、附帶在內(nèi)核源碼中、是內(nèi)核源碼的有機(jī)組成部分,等等。bootsect-loader在內(nèi)和源碼中對(duì)應(yīng)的程序是/arch/i386/boot/bootsect.s。下面將 主要是針對(duì)此文件進(jìn)行的分析。1. 幾個(gè)相關(guān)文件:<1> /arch/i386/boot/bootsect.s <2> /in cl

16、ude/li nux/con fig.h<3> /in clude/asm/boot.h<4> /in clude/li nu x/autoconf.h2. 引導(dǎo)過(guò)程分析:對(duì)于intel x86 pc,開(kāi)啟電源后,機(jī)器就會(huì)開(kāi)始執(zhí)行rom bios的一系列系統(tǒng) 測(cè)試動(dòng)作,包括檢查ram, keyboard,顯示器,軟硬磁盤(pán)等等。執(zhí)行完bios 的系統(tǒng)測(cè)試z后,緊接著控制權(quán)會(huì)傳移給rom屮的啟動(dòng)程序(rom bootstrap routine);這個(gè)程序會(huì)將磁盤(pán)上的笫0軌笫0扇區(qū)(叫boot sector或mbr ,系 統(tǒng)的引導(dǎo)程序就放在此處)讀入內(nèi)存中,并放到自0x070

17、0:0x0000 始的512 個(gè)字節(jié)處;然后處理機(jī)將跳到此處開(kāi)始執(zhí)行這一引導(dǎo)程序;也即裝入mbr屮的 引導(dǎo)程序后,cs:ip = 0x0700:0x0000。加電后處理機(jī)運(yùn)行在與8086相兼容 的實(shí)模式下。如果耍用bootsect-loader進(jìn)行系統(tǒng)引導(dǎo),則必須把bootsect.s編譯連接斤對(duì)應(yīng) 的二進(jìn)制代碼置于mbr;當(dāng)rom bios把bootsect.s編譯連接后對(duì)應(yīng)的二進(jìn) 制代碼裝入內(nèi)存斤 機(jī)器的控制權(quán)就完全轉(zhuǎn)交給bootsect;也就是說(shuō),bootsect 將是第一個(gè)被讀入內(nèi)存中并執(zhí)行的程序。bootsect接管機(jī)器控制權(quán)后,將依次進(jìn)行以下一些動(dòng)作:1. 首先,bootsect將

18、它泊己”(自位置0x07c0:0x0000 始的512個(gè)字節(jié))從被 rom bios載入的地址0x0700:0x0000處搬到0x9000:0000處 這一任務(wù)山 bootsect.s的前十條指令完成;第十一條指令“jmpi go,initseg”則把機(jī)器跳轉(zhuǎn) 到“新”的 bootsect 的“jmpi go,initseg”后的那條指令“go: mov di,#0x4000-12n; 之后,繼續(xù)執(zhí)行bootsect的剩卜的代碼;在bootsect.s屮定義了幾個(gè)常量:bootseg = 0x07c0 bios載入mbr的約定位置的段址;initseg = 0x9000 bootsect.s的

19、前i 條指令將自己搬到此處(段址)setupseg =0x9020 裝入 setup.s 的段址sysseg =0x1000系統(tǒng)區(qū)段址對(duì)于這些常量可參m/include/asm/boot.h中的定義;這些常量在下面的分析屮將 會(huì)經(jīng)常用到;2. 以0x9000:0x4000-12為棧底,建立自己的棧區(qū);其中0x9000:0x4000-12 到0x9000:0x4000的一十二個(gè)字節(jié)預(yù)留作磁盤(pán)參數(shù)表區(qū);3. 在0x9000:0x4000-12到0x9000:0x4000的一二個(gè)預(yù)留字節(jié)中建立新的磁 盤(pán)參數(shù)表,之所以叫“新”的磁盤(pán)參數(shù)表,是相對(duì)于bios建立的磁盤(pán)參數(shù)表而言 的。由于設(shè)計(jì)者考慮到有些

20、老的bios不能準(zhǔn)確地識(shí)別磁盤(pán)“每個(gè)磁道的扇區(qū)數(shù)”, 從而導(dǎo)致bios建立的磁盤(pán)參數(shù)表妨礙磁盤(pán)的最高性能發(fā)揮,所以,設(shè)計(jì)者就在 bios建立的磁盤(pán)參數(shù)表的棊礎(chǔ)上通過(guò)枚舉法測(cè)試,試圖建立準(zhǔn)確的“新”的磁盤(pán)參 數(shù)表(這是在后繼步驟中完成的);并把參數(shù)表的位置由原來(lái)的0x0000:0x0078 搬到0x9000:0x4000-12;且修改老的磁盤(pán)參數(shù)表區(qū)使之指向新的磁盤(pán)參數(shù)表;4. 接下來(lái)就到了 load_setup子過(guò)程;它調(diào)用0x13中斷的第2號(hào)服務(wù);把第0 道第2扇區(qū)開(kāi)始的連續(xù)的setup_sects (為常量4)個(gè)扇區(qū)讀到緊鄰bootsect的內(nèi) 存區(qū);,即0x9000:0x0200開(kāi)始的2

21、048個(gè)字節(jié);而這四個(gè)扇區(qū)的內(nèi)容即是 /arch/i386/boot/setup.s編譯連接后對(duì)應(yīng)的二進(jìn)制代碼;也就是說(shuō),如果耍用 bootsect-loader進(jìn)行系統(tǒng)引導(dǎo),不僅必須把bootsect.s編譯連接后對(duì)應(yīng)的二進(jìn) 制代碼置于mbr,而且還得把setup.s編譯連接后對(duì)應(yīng)的二進(jìn)制代碼置于緊跟 mbr后的連續(xù)的四個(gè)扇區(qū)屮;當(dāng)然,由于setup.s對(duì)應(yīng)的可執(zhí)行碼是山bootsect 裝載的,所以,在我們的這個(gè)項(xiàng)口中可以通過(guò)修改bootsect來(lái)根據(jù)需要隨意地 放置setup.s對(duì)應(yīng)的可執(zhí)行碼;5. ioad_setup子過(guò)程的唯一出口是probejoop子過(guò)程;該過(guò)程通過(guò)枚舉法測(cè) 試磁

22、盤(pán)“每個(gè)磁道的扇區(qū)數(shù)”;6. 接下來(lái)兒個(gè)子過(guò)程比較清晰易懂:打印我們熟悉的“l(fā)oading”;讀入系統(tǒng)到 0x1000:0x0000;關(guān)掉軟駁馬達(dá);根據(jù)的5步測(cè)岀的“每個(gè)磁道的扇區(qū)數(shù)”確定磁 盤(pán)類型;最后跳轉(zhuǎn)到0x9000:0x0200,即setup.s對(duì)應(yīng)的m執(zhí)行碼的入口,將機(jī) 器控制權(quán)轉(zhuǎn)交setup.s;整個(gè)bootsect代碼運(yùn)行完畢;3. 引導(dǎo)過(guò)程執(zhí)行完后的內(nèi)存印象圖:出于簡(jiǎn)便考慮,在此分析屮,我忽略了對(duì)大內(nèi)核的處理的分析,因?yàn)閷?duì)大內(nèi)核的處 理,只是此引導(dǎo)過(guò)程屮的一個(gè)很小的部分,并不影響對(duì)整體的把握。完成了系統(tǒng)的引導(dǎo) 后,系統(tǒng)將進(jìn)入到初始化處理階段。系統(tǒng)的初始化分為實(shí)模式和保護(hù)模式兩部

23、分。 ii、實(shí)模式下的初始化實(shí)模式下的初始化,主要是指從內(nèi)核引導(dǎo)成功后,到進(jìn)入保護(hù)模式之前系統(tǒng)所做的 一些處理。在內(nèi)核源碼中對(duì)應(yīng)的程序是/arch/i386/boovsetup.s;以下部分主要是針對(duì) 此文件進(jìn)行的分析。這部分的分析主要是耍奔懂它的處理流程和initseg(9000:0000) 段參數(shù)表的建立,此參數(shù)表包含了很多碩件參數(shù),這些都是以后進(jìn)行保護(hù)模式卜初始化, 以及核心建立的基礎(chǔ)。1.幾個(gè)其它相關(guān)文件:<1> /arch/i386/boot/bootsect.s<2> /in clude/linux/config.h<3> /include/as

24、m/boot.h<4> /in elude/ asm/segme nt.h <5> /include/li nu x/version.h<6> /include/li nu x/compile.h2.實(shí)模式下的初始化過(guò)程分析:開(kāi)始復(fù)位硬盤(pán)系統(tǒng)確禍整系統(tǒng)內(nèi)核段地址到正確位苴"彩尹和沐3汕僮于setup. s 的束氐衛(wèi)確,則setup區(qū)全出 裝在 9qjq; q2jq 和 5000:9004. 何;歪則,余m和系統(tǒng)內(nèi)絃一進(jìn) 裝在 1000: 0000 之qaa55 -和 5a5a澤來(lái)的糸覘內(nèi)建段范址 a 1000芒執(zhí)的段址還 必須加二setjp余部占

25、用詢空間.將 hdo 和 hdal 的參瓠 從 0000:4*0x41 的32個(gè)字節(jié)搬到0x0x9000:0x0080linuz實(shí)模式下的初始儷程圖二將 hdal 的參數(shù)(a 0x000:0x0090 起 的10個(gè)寧節(jié))涪零檢杳m3 a bjs,將其參數(shù)貫于0x9000: oxooao檢杳ps/2鼠標(biāo)器,存在則置0x9000: 0x0iff為oxaa,否則苴其為0檢查apmbios,將其夢(mèng)皺直于0x000:0x00645'j ohpooo: oko082 m三十二個(gè)字節(jié)關(guān)申斷:并禁止nmi謹(jǐn)求以sysseg與in:tseg間的4kb作為緩沖取, 每設(shè)4k,將系統(tǒng)搬到0z0100:000

26、0處檢查自己杲否位于setup seg j(t,不存.則探至此處1 idt為空,設(shè)呻段址咖心,共256個(gè)入口,并設(shè)了一個(gè)系統(tǒng)數(shù)據(jù)和一個(gè)代解段in;el把d-51號(hào)申斷向 量用來(lái)處理異常李件,而 t8m則把碩申晰設(shè)住 dx)8-d:<df防以必須審 新編程,把硬中騎設(shè)到 dx2d-d:<2f使a20線有瓶對(duì)中斷控制器8259a-l,9259a-2重新編程t孕保護(hù)模對(duì)initseg(9000:0000)段參數(shù)表:(參見(jiàn) include/linux/tty.h)參數(shù)名偏移量(段址均為 0x9000)長(zhǎng)度byte參考文件param_cursor_pos0x00002arch/i386/bo

27、ot/video.sextended mem size0x00022arch/i386/boot/setup.sparam_video_page0x00042arch/i386/boot/video.sparam_video_mode0x00061arch/i386/boot/video.sparam_video_cols0x00071arch/i386/boot/video.s沒(méi)用0x00082include/linux/tty.hparam_video_ega_bx0x000a2arch/i386/boot/video.s沒(méi)用0x000c2include/linux/tty.hparam_

28、video_linesoxoooe1arch/i386/boot/video.sparam_have_vgaoxooof1arch/i386/boot/video.sparam_font_points0x00102arch/i386/boot/video.sparam_lfb_width0x00122arch/i386/boot/video.sparam_lfb_height0x00142arch/i386/boot/video.sparam_lfb_depth0x00162arch/i386/boot/video.sparam_lfb_base0x00184arch/i386/boot/vi

29、deo.sparam_lfb_size0x001c4arch/i386/boot/video.s暫未用0x00204include/linux/tty.hparam_lfb_linelength0x00242arch/i386/boot/video.sparam_lfb_colors0x00266arch/i386/boot/video.s暫未用0x002c2arch/i386/boot/video.sparam_vesapm_seg0x002e2arch/i386/boot/video.sparam_vesapm_off0x00302arch/i386/boot/video.sparam_l

30、fb_pages0x00322arch/i386/boot/video.s保留0x0034-0x003finclude/linux/tty.hapm bios version0x00402arch/i386/boot/setu p.sbios code segment0x00422arch/i386/boot/setup.sbios entry offset0x00444arch/i386/boot/setup.sbios 16 bit code seg0x00482arch/i386/boot/setup.sbios data segment0x004a2arch/i386/boot/set

31、up.s支持32位標(biāo)志0x004c2arch/i386/boot/setu p.sbios code seg length0x004e4arch/i386/boot/setup.sbios data seg length0x00522arch/i386/boot/setup.shdo參數(shù)0x008016arch/i386/boot/setu p. shdo參數(shù)0x009016arch/i386/boot/setup.sps/2 device 標(biāo)志0x0 iff1arch/i386/boot/setup.s* 注: include/linux/tty.h : cl_magic and cl_of

32、fset here1. include/linux/tty.h :unsigned char rsvd_size; /* 0x2c */ unsigned char rsvd_pos; /* 0x2d */ 0表示沒(méi)有apm bios 0x0002置位表示支持32位模式 0表示沒(méi)有,oxoaa表示有鼠標(biāo)器川、保護(hù)模式下的初始化保護(hù)模式下的初始化,是指處理機(jī)進(jìn)入保護(hù)模式后到運(yùn)行系統(tǒng)笫一個(gè)內(nèi)核程序過(guò)程 中系統(tǒng)所做的一些處理。保護(hù)模式卜的初始化在內(nèi)核源碼中對(duì)應(yīng)的程序是 /arch/i386/boovcompressed/head.s 和 /arch/i386/kernel/head.s ;以下部分主

33、要 是針對(duì)這兩個(gè)文件進(jìn)行的分析。1. 幾個(gè)相關(guān)文件:<1 .> /arch/i386/boot/compressed/head.s<2 > /arch/i386/kernel/head.s<3.> /arch/i386/boot/compressed/misc.c<4.> /arch/i386/boot/setup.s<5.> /inelude/ asm/segment.h<6.> /arch/i386/kernel/traps.c<7> /include/i386/desc.h<8.> /incl

34、ude/asm-i386/processor.h2. 保護(hù)模式下的初始化過(guò)程分析:一、/arch/i386/kernel/head.s 流程:逹意,從此均 為俁護(hù)虛擬 方式尋址/arch/i386/kernel/head-sgs開(kāi)始 + 用 kernel ds 初始化 ds, es, fs, gs此時(shí)頁(yè)目錄只定義了 2個(gè)頁(yè)表項(xiàng): 第0項(xiàng)和第768項(xiàng),此兩項(xiàng)都對(duì) 應(yīng)同一個(gè)頁(yè)表0x00102 »同時(shí), head.s 也0x00102000 處定義了 一個(gè)頁(yè)表民0,餞頁(yè)表對(duì)應(yīng)物理地 址的0-4m/即在0-4m/物理 地址與邏輯地址是一致的;當(dāng)然 通過(guò)頁(yè)目錄的第7住項(xiàng),也可訪 問(wèn)此段空間即3

35、g3gb-mm段 也段應(yīng)此段bssji setup. s 的代碼段? k同時(shí)參見(jiàn):/ ar ch/ i386/kernel/1 raps. c和include/i386/ desc. hinitseg段的參數(shù)參見(jiàn) “實(shí)模式下的初始化j emp后 2k將作為命令緩沖區(qū) empty_zero_page 位 于 0x105000 | 大小 4ki務(wù) cl_base_addr;cl_offset 開(kāi)始的 2k 個(gè)字節(jié)拷貝到empty zero page的后2k此時(shí)皿已經(jīng)初始化了,只需裝載到i dtr即可正常情況下,不會(huì)返 回 > 若返回,則不正 常,所以死循環(huán)的£h/i巒何則l/it仝

36、號(hào)程圖二有關(guān)cpu的信息被放在一個(gè) 命名b oot,_cpu_data的結(jié)構(gòu) cpuinfo_x86 中丿參見(jiàn) in.cludle/asm-i386/processor.h|檢查cpu類型,保存cpu信息;并根據(jù)不同類型的cpu來(lái)重新初始化cro檢查協(xié)處理器是否有救,無(wú)效則em 5位、否則復(fù) 位,同時(shí)對(duì)保存cpu信息的相應(yīng)單元迸行標(biāo)示,在進(jìn)入保護(hù)模式前,已初貽化 了一個(gè)只含兩個(gè)有效采統(tǒng)段 的gdt ;此處重新建立gdt, 新的gdt位于0x106000,共 12+2*1ir_tasks 個(gè) 項(xiàng)毎頂 8byte?設(shè)置了兩個(gè)系紜段和 兩個(gè)用戶段,都是從0并始的 4g大小還設(shè)了 4個(gè)apm段二、/a

37、rch/i386/boot/compressed/head.s 流程:|/arch/i386/boot/cc>iip:r巳 ss巳d/h巳adl s 流程圖 |1. 從流程圖中可以看到,保護(hù)模式下的初始化主耍干了這樣兒件事:1. 解壓內(nèi)核到0x100000處、2. 建立頁(yè)h錄和pgo頁(yè)表并啟動(dòng)分頁(yè)功能(即虛存管理功能)、3. 保存實(shí)模式下測(cè)到的硬件信息到empty_zero_page初始化命令 緩存區(qū)、4. 檢測(cè)cpu類型、檢查協(xié)處理器、5. 重新建立gdt全局描述符表、和屮斷描述附表idt;2. 從頁(yè)h錄和pgo頁(yè)表可以看出,0&#0; 4m物理內(nèi)存被用作系統(tǒng)區(qū),它被映射 到系

38、統(tǒng)段線性空間的0&#0; 4m和3g&#0; 3g+4m;即系統(tǒng)可以通過(guò)訪問(wèn)這兩 個(gè)段來(lái)訪問(wèn)實(shí)際的0&#0; 4m物理內(nèi)存,也就是系統(tǒng)所在的區(qū)域;3. 木來(lái)在實(shí)模式下初始化時(shí)已經(jīng)建立了全局描述符表gdt,而此處重新建立全局描 述符表gdt則主要是出于兩個(gè)原因:一個(gè)就是若內(nèi)核是大內(nèi)核bzimag,則以前 建立的gdt,可能已經(jīng)在解壓時(shí)被覆蓋掉了所以,在這個(gè)源碼文件中均只采用相 對(duì)轉(zhuǎn)移指令jxxnf或jxxnb;二是以前建立的gdt是建立在實(shí)地址方式下的,而 現(xiàn)在則是在啟用保護(hù)虛擬地址方式之后建立的,也即現(xiàn)在的gdt是建立在邏輯地 址(即線性地址)上的;4. 每次建立新的g

39、dt后和啟用保護(hù)虛擬地址方式后都必須巫新裝載系統(tǒng)棧和巫新 初始化各段寄存器:cs,ds,es,fs,gs;5. 從實(shí)模式下的初始化和保護(hù)模式下的初始化過(guò)程可以看ill, linux系統(tǒng)由實(shí)模式 進(jìn)入到保護(hù)模式的過(guò)程大致如下:實(shí)模式到386保護(hù)模式毓程圖|第一歩第二步第三步6. 由于分頁(yè)機(jī)制只能在保護(hù)模式下啟動(dòng),不能在實(shí)模式下啟動(dòng),所以第一步是必要的; 又因?yàn)樵?86保護(hù)模式下gdt和idt是建立在邏輯地址(線性地址)上的,所以第三步也 是必要的;7. 經(jīng)過(guò)實(shí)模式和保護(hù)模式下的初始后,主要系統(tǒng)數(shù)據(jù)分布如下:初始后屯要系統(tǒng)數(shù)據(jù)分布表位置系統(tǒng)數(shù)據(jù)大小0x101000頁(yè)目錄 swapper_pg_di

40、r4k0x102000頁(yè)表pgo4k0x103000empty_bad_page4k0x104000e m pty_bad_pa g e_ta b i e4k0x105000empty_zero_page4k0x105000系統(tǒng)硬件參數(shù)2k0x105800命令緩沖區(qū)2k0x106000全局描述附表gdtjable4192b從上面對(duì)linux系統(tǒng)的初始化過(guò)程的分析可以看出,以程序執(zhí)行流程為線索、一線 出珠,就是按照程序的執(zhí)行先后順序,弄懂程序執(zhí)行的各個(gè)階段所進(jìn)行的處理,及其各 階段之間的相互聯(lián)系。而流程圖應(yīng)該是這種分析方法最合適的表達(dá)工具。事實(shí)上,以程序執(zhí)行流程為線索,是分析任何源代碼都首選的方

41、法。山于操作系統(tǒng) 的特殊性,光用這種方法是遠(yuǎn)遠(yuǎn)不夠的。當(dāng)然用這種方法來(lái)分析系統(tǒng)的初始化過(guò)程或用 戶進(jìn)程的執(zhí)行流程應(yīng)該說(shuō)是很有效的。方法之三:以數(shù)據(jù)結(jié)構(gòu)為基點(diǎn),觸類旁通結(jié)構(gòu)化程序設(shè)計(jì)思想認(rèn)為:程序=數(shù)據(jù)結(jié)構(gòu)+算法。數(shù)據(jù)結(jié)構(gòu)體現(xiàn)了整個(gè)系統(tǒng) 的構(gòu)架,所以數(shù)據(jù)結(jié)構(gòu)通常都是代碼分析的很好的著手點(diǎn),對(duì)linux內(nèi)核分析尤其如此。 比如,把進(jìn)程控制塊結(jié)構(gòu)分析清楚了,就對(duì)進(jìn)程有了基本的把握;再比如,把頁(yè)目錄結(jié) 構(gòu)和頁(yè)表結(jié)構(gòu)弄懂了,兩級(jí)虛存映射和內(nèi)存管理也就掌握得差不多了。為了體現(xiàn)循序漸 進(jìn)的思想,在這我就以linux對(duì)屮斷機(jī)制的處理來(lái)介紹這種方法。首先,必須指出的是:在此處,中斷指廣義的中斷概義,它指所有通過(guò)

42、idt進(jìn)行的 控制轉(zhuǎn)移的機(jī)制和處理;它覆蓋以f兒個(gè)常用的概義:中斷、異常、可屏蔽中斷、不可 屏蔽中斷、換中斷、軟中斷 i、硬件提供的中斷機(jī)制和約定'尋址:彼件提供可供256個(gè)服務(wù)程序中斷進(jìn)入的入口,即中斷向量;中斷向量在保護(hù)模式下的實(shí)現(xiàn)機(jī)制是中斷描述符表idt, idt的位置由idtr確定,idtr 是個(gè)48位的寄存器,高32位是idt的基址,低16位為idt的界限(通常為2k=256*8);idt中包含256個(gè)中斷描述符,對(duì)應(yīng)256個(gè)中斷向量;每個(gè)中斷描述符8位,其結(jié) 構(gòu)如圖一:0-1offset (15-0)2-3selector15 >14 l3fl28,t4-5p |dp

43、l | oxoe| 0x006-7offset (3116)oj注.e. 刪磁 ?=o磁 使用則«賢異常dpu 00-11.對(duì)應(yīng)ih個(gè)特6嗽(00量高)中斷進(jìn)入過(guò)程如圖二所示。當(dāng)中斷是由低特權(quán)級(jí)轉(zhuǎn)到高特權(quán)級(jí)(即當(dāng)前特權(quán)級(jí)cpl>dpl)時(shí),將進(jìn)行堆棧的轉(zhuǎn) 移;內(nèi)層堆棧的選擇曲當(dāng)前tss的相應(yīng)字段確定,而r內(nèi)層堆棧將依次被壓入如下數(shù)據(jù): 外層ss,外層esp,eflags,外層cs,外層eip;中斷返回過(guò)程為一逆過(guò)程;圖二7中靳進(jìn)入京尋圖idt selector特性字 bffsg - 基址特性字w- pdt 或 ldt |服務(wù)程序入口二異常處理機(jī)制:intel公司保留031號(hào)中斷

44、向量用來(lái)處理異常事件:當(dāng)產(chǎn)生一個(gè)異常時(shí),處理機(jī)就會(huì)自動(dòng)把控制轉(zhuǎn)移到相應(yīng)的處理程序的入口,異常的處理程序由操作系統(tǒng)提供,中斷向量和異常事件對(duì)應(yīng)如表一:表一、中斷向量和異常事件對(duì)應(yīng)表中斷向量號(hào)異常事件linux的處理程序0除法錯(cuò)誤divide_error1調(diào)試異常debug2nmi中斷nmi3單字節(jié),int3int34溢出overflow5邊界監(jiān)測(cè)中斷bounds6無(wú)效操作碼lnvalid_op7設(shè)備不可用device_ no t_available8雙垂故障double_fault9協(xié)處理器段溢出coprocessor_segment_overrun10無(wú)效tssin calid_tss11缺段

45、中斷nsegme nt_not_prese nt12堆棧異常stack_segme nt13一般保護(hù)異常general_protection14頁(yè)異常page_fault15spurious_interrupt_bug16協(xié)處理器出錯(cuò)coprocessor_error仃對(duì)齊檢查中斷alignmen t_check三可編程中斷控制器8259a :為更好的處理外部設(shè)備,x86微機(jī)提供了兩片可編程屮斷控制器,用來(lái)輔助cpu接 受外部的中斷信號(hào);對(duì)丁中斷,cpu只提供兩個(gè)外接引線:nmi和intr;nmi只能通過(guò)端口操作來(lái)屏蔽,它通常用于:電源掉電和物理存儲(chǔ)器奇偶驗(yàn)錯(cuò);intr可通過(guò)直接設(shè)置屮斷屏蔽位

46、來(lái)屏蔽,它可用來(lái)接受外部中斷信號(hào),但只有一 個(gè)引線,不夠用;所以它通過(guò)外接兩片級(jí)鏈了的8259a,以接受更多的外部中斷信號(hào)。 8259a主要完成這樣一些任務(wù):a. 中斷優(yōu)先級(jí)排隊(duì)管理,b. 接受外部中斷請(qǐng)求c. 向cpu提供小斷類型號(hào)外部設(shè)備產(chǎn)生的屮斷信號(hào)在irq (中斷請(qǐng)求)管腳上首先由中斷控制器處理。屮斷 控制器可以響應(yīng)多個(gè)屮斷輸入,它的輸岀連接到cpu的int管腳,信號(hào)可通過(guò)int 管腳,通知處理器產(chǎn)生了中斷。如果cpu這時(shí)可以處理中斷,cpu會(huì)通過(guò)inta (中 斷確認(rèn))管腳上的信號(hào)通知屮斷控制器已接受屮斷,這時(shí),屮斷控制器可將一個(gè)8位 數(shù)據(jù)放置在數(shù)據(jù)總線上,這一 8位數(shù)據(jù)也稱為中斷向

47、量號(hào),cpu依據(jù)中斷向量號(hào)和中 斷描述符表(idt)中的信息自動(dòng)調(diào)用相應(yīng)的中斷服務(wù)程序。圖三屮,兩個(gè)屮斷控制器 級(jí)聯(lián)了起來(lái),從屬中斷控制器的輸出連接到了主中斷控制器的第3個(gè)中斷信號(hào)輸入, 這樣,該系統(tǒng)可處理的外部中斷數(shù)量最多可達(dá)15個(gè),圖的右邊是i386 pc中各中斷 輸入管腳的一般分配??赏ㄟ^(guò)對(duì)8259a的初始化,使這15個(gè)外接引腳對(duì)應(yīng)256個(gè)屮斷 向量的任何15個(gè)連續(xù)的向量;由于intel公司保留031號(hào)中斷向量用來(lái)處理異常事件(而 默認(rèn)情況下,ibm bios把碩中斷設(shè)在0x08-0x0f),所以,硬屮斷必須設(shè)在31以后,linux 則在實(shí)模式下初始化時(shí)把其設(shè)在0x200x2f,対此下而

48、還將具體說(shuō)明。圖三、i386 pc可編程中斷控制器8259a級(jí)鏈?zhǔn)疽鈭Dirq0 (時(shí)鐘)irq 1(鍵盤(pán))irq 3(tty2)irq 4( ttyl)irq5(xtwinchester)irq 6 (軟駝)irq 7 (打印機(jī))irq 8 (實(shí)時(shí)時(shí)鐘)irq 9 (重定向的irq2)irq 10irq 11irq 12irq 13( fpu 異常)irq 14( at winchester)irq 15碩件中斷機(jī)制提供了 256個(gè)入口,即idt中包含的256個(gè)中斷描述符(對(duì)應(yīng)256個(gè) 中斷向量)。ifu 0-31號(hào)中斷向量被intel公司保留用來(lái)處理異常事件,不能另作它用。對(duì)這031 號(hào)中斷

49、向量,操作系統(tǒng)只需提供界常的處理程序,當(dāng)產(chǎn)生一個(gè)異常時(shí),處理機(jī)就會(huì)口動(dòng) 把控制轉(zhuǎn)移到相應(yīng)的處理程序的入口,運(yùn)行相應(yīng)的處理程序;而事實(shí)上,對(duì)于這32個(gè) 處理異常的中斷向量,此版本(225)的linux只提供了 017號(hào)中斷向量的處理程序, 其對(duì)應(yīng)處理程序參見(jiàn)表一、中斷向量和異常事件對(duì)應(yīng)表;也就是說(shuō),17-31號(hào)中斷向量 是空著未用的。既然031號(hào)中斷向量已被保留,那么,就是« k 32-255共224個(gè)屮斷向量可用。 這224個(gè)中斷向量又是怎么分配的呢?在此版本(2.2.5)的linux中,除了 0x80 (syscall_vector)用作系統(tǒng)調(diào)用總?cè)肟谥?,其他都用在外部硬件中斷?/p>

50、上,其中 包括可編程中斷控制器8259a的15個(gè)irq:事實(shí)上,當(dāng)沒(méi)有定義config_x86_io_apic 時(shí),其他223(除0x80外)個(gè)中斷向量,只利用了從32號(hào)開(kāi)始的15個(gè),其它208個(gè)空 著未用。這些中斷服務(wù)程序入口的設(shè)置將在下而有詳細(xì)說(shuō)明。相關(guān)數(shù)據(jù)結(jié)構(gòu)a. 中斷描述符表idt:也就是中斷向量表,相當(dāng)如一個(gè)數(shù)組,保存著各中斷服務(wù) 例程的入口。(詳細(xì)描述參見(jiàn)圖一、中斷描述符格式)b. 與硬中斷相關(guān)數(shù)據(jù)結(jié)構(gòu):與硬中斷相關(guān)數(shù)據(jù)結(jié)構(gòu)主要有三個(gè):一:定義在/arch/i386/kernel/irq.h 中的struct hw_interrupt_type const char * type

51、name;void (*startup)(unsigned int irq);void (*shutdown)(unsigned int irq);void (*handle)(unsigned int irq, struct pt_regs * regs);void (*enable)(unsigned int irq);void (*disable)(unsigned int irq);二:定義在/arch/i386/kernel/irq.h 中的typedef struct unsigned int status; /* irq status - irqjnprogress, irq_d

52、isabled */ struct hw_interrupt_type *handler; /* handle/enable/disable functions */ struct irqaction *action; /* irq action list */unsigned int depth; /* disable depth for nested irq disables */ irq_desc_t;三:定義在泊clude/linux/ interrupt.h 屮的struct irqaction void (*handler)(int, void *, struct pt_regs

53、*);unsigned long flags;unsigned long mask;const char *name;void *dev_id;struct irqaction *next;;三者關(guān)系如下:圖四、與駛中斷相關(guān)的幾個(gè)數(shù)據(jù)結(jié)構(gòu)各關(guān)系各結(jié)構(gòu)成員詳述如下:a. struct irqaction結(jié)構(gòu),它包含了內(nèi)核接收到特定 irq之后應(yīng)該采取的操作,其成員如下: handler:是一指向某個(gè)隊(duì) 1數(shù)的指針。該函數(shù)就是所在結(jié)構(gòu)對(duì)相應(yīng)中斷的處理函 數(shù)。 flags:取值只有 sa_interrupt (中斷可嵌套),sa_sample_random(這個(gè)中斷是源于物理隨機(jī)性的),和sa_sh

54、irq (這個(gè)irq和英它struct irqaction 共享)。 mask:在x86或者體系結(jié)構(gòu)無(wú)關(guān)的代碼屮不會(huì)使用(除非將其設(shè)置為0);只 有在sparc64的移植版本中耍跟蹤有關(guān)軟盤(pán)的信息時(shí)才會(huì)使用它。 name:產(chǎn)生屮斷的硬件設(shè)備的名字。因?yàn)椴恢挂粋€(gè)硬件可以共享一個(gè)irq。 devjd:標(biāo)識(shí)碩件類型的一個(gè)唯一的id。linux支持的所有硬件設(shè)備的每一種 類型,都有一個(gè)由制造廠商定義的在此成員中記錄的設(shè)備ido next:如果irq是共享的,那么這就是指向隊(duì)列屮下一個(gè)struct irqaction結(jié) 構(gòu)的指針。通常情況下,irq不是共享的,因此這個(gè)成員就為空。a. struct hw

55、_interrupt_type 結(jié)構(gòu),它是一個(gè)抽象 的中斷控渝器。這包含一系列的指向函數(shù)的指針, 這些函數(shù)處理控制器特有的操作: typename:控制器的名字。 startup:允許從給定的控制器的irq所產(chǎn)生的事件。 shutdown:禁止從給定的控制器的irq所產(chǎn)牛的事件。 handle:根據(jù)提供給該函數(shù)的irq,處理唯一的中斷。 enable和disable:這兩個(gè)函數(shù)基本上和startup和shutdown相同;a.另外一個(gè)數(shù)據(jù)結(jié)構(gòu)是irq_desc_t,它具有如下成 員: status: 一個(gè)整數(shù)。代表irq的狀態(tài):irq是否被禁止了,有關(guān)irq的設(shè)備當(dāng) 前是否正被自動(dòng)檢測(cè),等等。

56、 handler:扌n|nj hw_interrupt_type 的指針。 action:指向irqaction結(jié)構(gòu)組成的隊(duì)列的頭。止常悄況下每個(gè)irq只有一個(gè)操 作,因此鏈接列表的止常長(zhǎng)度是1 (或者0)。但是,如果irq被兩個(gè)或者多個(gè) 設(shè)備所共享,那么這個(gè)隊(duì)列中就有多個(gè)操作。 depth: irq_desc_t的當(dāng)前用戶的個(gè)數(shù)。主要是用來(lái)保證在中斷處理過(guò)程中irq 不會(huì)被禁止。 irq_desc是irq_desc_t類型的數(shù)組。對(duì)于每一個(gè)irq都有一個(gè)數(shù)組入口,即 數(shù)組把每一個(gè)irq映射到和它相關(guān)的處理程序和irq_desc_t中的其它信息。a.與bottom_half相關(guān)的數(shù)據(jù)結(jié)構(gòu):圖五、底半處理數(shù)據(jù)結(jié)構(gòu)示意圖底半處理程序 bh_mask_count:計(jì)數(shù)器。對(duì)每個(gè)enable/disable請(qǐng)求嵌套對(duì)進(jìn)彳亍計(jì)數(shù)。這 些請(qǐng)求通過(guò)調(diào)用enable_bh和disable_bh實(shí)現(xiàn)。每個(gè)禁止請(qǐng)求都增加計(jì)數(shù)器;每個(gè)使能請(qǐng)求都減小計(jì)竅器。當(dāng)計(jì)數(shù)器払到0時(shí),所有未完成的禁止語(yǔ)句都已 經(jīng)被使能語(yǔ)句所匹配了,因此下半部分最終被重新使能。(定義在kernel/softirq.c 中) bh_

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論