• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            jake1036

            linux內(nèi)核學(xué)習(xí)之八 內(nèi)核體系結(jié)構(gòu)

                                                                                                 linux內(nèi)核體系結(jié)構(gòu)
                   1 操作系統(tǒng)整體架構(gòu)
                      分為四個(gè)部分: 用戶(hù)應(yīng)用程序 , 操作系統(tǒng)服務(wù)部分 , 操作系統(tǒng)內(nèi)核部分, 硬件系統(tǒng)部分。
                   2  linux內(nèi)核模式
                       應(yīng)用程序使用指定的參數(shù)值執(zhí)行系統(tǒng)調(diào)用(int x80) ,使CPU從用戶(hù)態(tài)切換到核心態(tài),然后操作系統(tǒng)根據(jù)具體的參數(shù)值調(diào)用特定的系統(tǒng)調(diào)用服務(wù)程序,
                       這些服務(wù)程序則根據(jù)需要再調(diào)用底層的一些支持函數(shù)以完成特定的功能。
                      在完成了應(yīng)用程序所要求的服務(wù)程序之后,操作系統(tǒng)從核心態(tài)回到了用戶(hù)態(tài),返回到應(yīng)用程序中執(zhí)行后面的指令。
                      

            3 內(nèi)核體系結(jié)構(gòu)
              內(nèi)核體系結(jié)構(gòu)主要由5部分組成 :
               (1) 進(jìn)程調(diào)度 (2) 內(nèi)存管理 (3) 進(jìn)程間通信 (4) 文件系統(tǒng) (5) 網(wǎng)絡(luò)接口
             





            下圖為 物理內(nèi)存使用的功能分布圖 
                       

            內(nèi)核模塊占用了 物理內(nèi)存的最開(kāi)始的位置,緊接著是 高速緩沖區(qū) ,系統(tǒng)從外部讀取數(shù)據(jù)的時(shí)候,先把數(shù)據(jù)讀取到高速緩沖區(qū)中,然后再?gòu)母咚倬彌_區(qū)中
             將數(shù)據(jù)移動(dòng)到主內(nèi)存區(qū)中。

               4  內(nèi)存地址的概念
                   存在以下三種不同的地址需要予以區(qū)別:
                   (1) 程序的虛擬地址 
                        是指由段選擇符和段內(nèi)偏移地址兩個(gè)部分組成的地址。這兩部分組成的地址并沒(méi)有直接用來(lái)訪問(wèn)內(nèi)存地址,而是通過(guò)分段機(jī)制地址變化處理和映射之后,才能找到對(duì)應(yīng)的物理內(nèi)存中。虛擬地址空間由GDT映射的全局地址空間和LDT映射成的局部地址空間組成。 

                  (2) 線性地址 是虛擬地址到物理地址變換之間的中間層,是處理器可以尋址的內(nèi)存空間中的地址。段中的偏移地址再加上相應(yīng)段的基址,就生成了一個(gè)物理地址。

                  (3)物理地址 是指出現(xiàn)在CPU外部地址上的尋址內(nèi)存的地址信號(hào),是地址變換的最終結(jié)果地址。
             
               5 虛擬地址 線性地址 和 物理地址 之間的關(guān)系 
                 
                  5.1內(nèi)核代碼和數(shù)據(jù)的地址
                       對(duì)于linux0.11內(nèi)核來(lái)說(shuō),在head.s中已經(jīng)把內(nèi)核代碼段和數(shù)據(jù)段設(shè)置為長(zhǎng)度為16MB的段,在線性地址空間中,這兩個(gè)段的范圍重疊,都是從線性地址空間0開(kāi)始到地址0xFFFFFF共16MB地址范圍。      在該范圍中含有內(nèi)核所有的代碼,內(nèi)核段表(GDT , IDT , TSS) ,頁(yè)目錄表和內(nèi)核的二級(jí)頁(yè)表,內(nèi)核局部數(shù)據(jù)以及內(nèi)核臨時(shí)堆棧。(該臨時(shí)堆棧將被用作第一個(gè)任務(wù)即任務(wù)0 的用戶(hù)堆棧) ,  所以?xún)?nèi)核代碼段和數(shù)據(jù)段在三種地址空間上的關(guān)系。
                                  


               通過(guò)上述分析得到 :
                    (1)內(nèi)核代碼段和數(shù)據(jù)段區(qū)域 在線性地址空間和物理地址空間中是一樣的。
                    (2)GDT和IDT在內(nèi)核數(shù)據(jù)段中,因此它們的線性地址空間也同樣等同于它們的物理地址地址。
                    (3) 除任務(wù)0以外,所有的其他任務(wù)所需要的物理內(nèi)存頁(yè)面與線性地址中的不同或部分不同,因此內(nèi)核 需要?jiǎng)討B(tài)地在主內(nèi)存區(qū)中為它們作映射操作,
                          動(dòng)態(tài)地建立頁(yè)目錄項(xiàng)和頁(yè)表項(xiàng)。


                5.2任務(wù)0的地址對(duì)應(yīng)關(guān)系
            任務(wù)0是系統(tǒng)中一個(gè)人工啟動(dòng)的第一個(gè)任務(wù),它的代碼段和數(shù)據(jù)段長(zhǎng)度被設(shè)置為640kb ,該任務(wù)的代碼和數(shù)據(jù)直接包含在內(nèi)核代碼和數(shù)據(jù)段中,是從線性地址0開(kāi)始的640kb內(nèi)容,因此它可以使用內(nèi)核代碼已經(jīng)設(shè)置好的頁(yè)目錄和頁(yè)表進(jìn)行分頁(yè)地址變換。同樣它的代碼段和數(shù)據(jù)段在內(nèi)存中也是重疊的。





             5.3  任務(wù)1的地址對(duì)應(yīng)關(guān)系
                     任務(wù)1 也是一個(gè)特殊的任務(wù)。它的代碼也在內(nèi)核代碼區(qū)域中。與任務(wù)0不同的是在線性地址空間中,系統(tǒng)在使用fork 創(chuàng)建任務(wù)時(shí),為存放任務(wù)1 的二級(jí)頁(yè)表而在主內(nèi)存區(qū)申請(qǐng)了一頁(yè)內(nèi)存來(lái)存放,并復(fù)制了任務(wù)0 的頁(yè)目錄和二級(jí)頁(yè)表項(xiàng)。



             5.4其他任務(wù)的地址對(duì)應(yīng)關(guān)系
                   
                 對(duì)于從任務(wù)2開(kāi)始的進(jìn)程來(lái)說(shuō),它們的父進(jìn)程都是init進(jìn)程(任務(wù)1) 。從任務(wù)2開(kāi)始,如果任務(wù)號(hào)以nr來(lái)表示,那么任務(wù)nr在線性地址空間中的起始位置將是 nr * 64MB 。
                  

            5.4 用戶(hù)申請(qǐng)內(nèi)存的動(dòng)態(tài)分配
                  當(dāng)用C函數(shù)庫(kù)中的malloc函數(shù)進(jìn)行內(nèi)存動(dòng)態(tài)分配的時(shí)候,內(nèi)核并不會(huì)插手管理,因?yàn)槊總€(gè)進(jìn)程的擁有64MB的內(nèi)存空間。但是內(nèi)核會(huì)為進(jìn)程使用的代碼和數(shù)據(jù)維護(hù)一個(gè)
            當(dāng)前位置值brk ,這個(gè)值保存在每個(gè)進(jìn)程的數(shù)據(jù)結(jié)構(gòu)中。它指出了進(jìn)程代碼和數(shù)據(jù)在進(jìn)程地址空間中的末端位置,當(dāng)malloc 函數(shù)為程序分配內(nèi)存時(shí),它會(huì)通過(guò)系統(tǒng)調(diào)用
            brk() 把程序要求新增加的空間長(zhǎng)度通知內(nèi)核,內(nèi)核代碼可以根據(jù)malloc()函數(shù)所提供的信息來(lái)更新brk的值。但是此時(shí)并不會(huì)為新申請(qǐng)的空間映射物理內(nèi)存頁(yè)面。只有當(dāng)程序?qū)ぶ返侥硞€(gè)不存在對(duì)應(yīng)的物理頁(yè)面的時(shí)候,內(nèi)核才會(huì)進(jìn)行物理內(nèi)存頁(yè)面的映射操作。
             

            6  Linux 系統(tǒng)的中斷系統(tǒng)

                       CPU根據(jù)中斷號(hào)獲取中斷向量值,即對(duì)應(yīng)中斷服務(wù)程序的入口地址值。為了讓CPU由中斷號(hào)查到對(duì)應(yīng)的中斷向量,就需要在內(nèi)存中建立一張查詢(xún)表。
                 即中斷向量表(32位模式下稱(chēng)為中斷描述符表), 80x86支持256個(gè)中斷,對(duì)應(yīng)每個(gè)中斷要安排一個(gè)中斷服務(wù)程序。對(duì)應(yīng)一個(gè)中斷號(hào),它的中斷服務(wù)程序的入口地址就在
                 保存在0x0000:N x 4 處。

                    對(duì)于Linux 系統(tǒng),在剛開(kāi)始啟動(dòng)的時(shí)候,它會(huì)使用BIOS提供的顯示和磁盤(pán)讀取中斷功能。 在內(nèi)核正常運(yùn)行之前則會(huì)在setup.s程序中重新初始化8259A芯片在head.s程序中重新設(shè)置的一張中斷向量表。
                
             7 linux 系統(tǒng)調(diào)用
                  系統(tǒng)調(diào)用是linux內(nèi)核與上層應(yīng)用程序進(jìn)行交互通信的唯一接口。
                  用戶(hù)通過(guò)直接或者間接地調(diào)用中斷int 0x80 ,并在eax寄存器中指定系統(tǒng)調(diào)用功能號(hào),即可以使用內(nèi)核資源,包括系統(tǒng)硬件資源。 
                 在Linux 內(nèi)核中,每個(gè)系統(tǒng)調(diào)用都具有唯一的一個(gè)系統(tǒng)調(diào)用功能號(hào)。 這些功能號(hào) 實(shí)際上對(duì)應(yīng)于 系統(tǒng)調(diào)用處理程序指針數(shù)組表 sys_call_table[] 中的項(xiàng)的索引值。 
                 
              7.1系統(tǒng)調(diào)用處理過(guò)程
                  當(dāng)應(yīng)用程序經(jīng)過(guò)庫(kù)函數(shù)向內(nèi)核發(fā)出一個(gè)中斷可調(diào)用int 0x80時(shí) ,就可以執(zhí)行一個(gè)系統(tǒng)調(diào)用。
                  其中寄存器eax中存儲(chǔ)著中斷調(diào)用號(hào) ,而寄存器中攜帶的參數(shù)可以依次存放在ebx  , ecx , edx中。因此Linux 0.11中最多可以向內(nèi)核中傳遞三個(gè)參數(shù)。


              8 Linux進(jìn)程控制 
                  對(duì)于0.11來(lái)說(shuō),系統(tǒng)最多同時(shí)運(yùn)行64個(gè)進(jìn)程。處理第一個(gè)進(jìn)程使用“手工”創(chuàng)建以外,其余的進(jìn)程都是通過(guò)fork系統(tǒng)調(diào)用產(chǎn)生。內(nèi)核使用進(jìn)程標(biāo)識(shí)號(hào)來(lái)標(biāo)識(shí)進(jìn)程。
                   進(jìn)程由可執(zhí)行的指令代碼 數(shù)據(jù) 和堆棧區(qū)組成。進(jìn)程中的代碼和數(shù)據(jù)部分 分別對(duì)應(yīng)一個(gè)執(zhí)行文件中的代碼段、數(shù)據(jù)段。每個(gè)進(jìn)程只能訪問(wèn)自己的代碼,數(shù)據(jù)和堆棧。
                   linux 系統(tǒng)中一個(gè)進(jìn)程可以在內(nèi)核態(tài)或者是在用戶(hù)態(tài)下執(zhí)行,并且分別使用各自獨(dú)立的內(nèi)核態(tài)堆棧 和 用戶(hù)態(tài)堆棧。  用戶(hù)堆棧用于進(jìn)程在用戶(hù)態(tài)下臨時(shí)保存調(diào)用函
            數(shù)的參數(shù)、局部變量等數(shù)據(jù)。內(nèi)核堆棧則含有內(nèi)核程序執(zhí)行函數(shù)調(diào)用時(shí)的信息。

                 在linux內(nèi)核中,進(jìn)程通常叫做任務(wù),而把運(yùn)行在用戶(hù)空間的程序稱(chēng)作 進(jìn)程。
                 

               8.1   任務(wù)數(shù)據(jù)結(jié)構(gòu) 
                         內(nèi)核程序通過(guò)使用進(jìn)程表對(duì)進(jìn)程進(jìn)行管理,每個(gè)進(jìn)程在進(jìn)程表中占有一項(xiàng)。 在Linux系統(tǒng)中,進(jìn)程表項(xiàng)是一個(gè)task_struct 任務(wù)結(jié)構(gòu)指針。或者叫做進(jìn)程控制塊,
                   其中保存著控制和管理進(jìn)程的所有信息。
                        
               8.2  進(jìn)程初始化
                       系統(tǒng)進(jìn)入保護(hù)模式之后,就開(kāi)始執(zhí)行系統(tǒng)初始化程序init/main.c 。該程序首先確定如何分配使用系統(tǒng)物理內(nèi)存,然后調(diào)用內(nèi)核各個(gè)部分的初始化函數(shù),
                   分別對(duì)內(nèi)存管理、中斷處理、塊設(shè)備和字符設(shè)備、進(jìn)程管理以及硬盤(pán)和軟盤(pán)進(jìn)行初始化處理。此后程序把自己“手工”移動(dòng)到任務(wù)0中運(yùn)行,并使用fork系統(tǒng)調(diào)用首先創(chuàng)建出進(jìn)程1 。 在進(jìn)程1中將繼續(xù)執(zhí)行應(yīng)用環(huán)境的初始化并執(zhí)行shell登錄程序。而原進(jìn)程則會(huì)在系統(tǒng)空閑的時(shí)候被調(diào)度執(zhí)行,此時(shí)任務(wù)0 僅執(zhí)行pause()系統(tǒng)調(diào)用,其中又回去執(zhí)行調(diào)度函數(shù)。
              
              8.3 CPU允許低級(jí)別的代碼通過(guò)調(diào)用門(mén)或者中斷、陷阱門(mén)來(lái)調(diào)用和轉(zhuǎn)移到高級(jí)別的代碼中去。 但是 ,反之則不行。所以?xún)?nèi)核采用這種中斷返回指令iret來(lái)實(shí)現(xiàn),
                    由高級(jí)別到低級(jí)別的跳轉(zhuǎn)。

              9 創(chuàng)建新進(jìn)程
                 linux系統(tǒng)中創(chuàng)建新進(jìn)程都是使用fork() 系統(tǒng)調(diào)用。所有的進(jìn)程都是通過(guò)復(fù)制進(jìn)程0而得到的,都是進(jìn)程0的子進(jìn)程。
                  隨后對(duì)復(fù)制的任務(wù)數(shù)據(jù)結(jié)構(gòu),進(jìn)行修改。把當(dāng)前進(jìn)程設(shè)置為新進(jìn)程的父進(jìn)程,清除信號(hào)位圖,并復(fù)位新進(jìn)程的各統(tǒng)計(jì)值。
                 接著根據(jù)當(dāng)前進(jìn)程設(shè)置任務(wù)狀態(tài)段(TSS)中各個(gè)寄存器的值。
                 
                 此后系統(tǒng)設(shè)置新任務(wù)的代碼和數(shù)據(jù)段基地址、限長(zhǎng)、并復(fù)制當(dāng)前進(jìn)程內(nèi)存分頁(yè)管理的頁(yè)表。此時(shí),系統(tǒng)并不為新的進(jìn)程分配實(shí)際的物理內(nèi)存頁(yè)面,
                 而是讓它共享父進(jìn)程的內(nèi)存頁(yè)面。只有當(dāng)父進(jìn)程或新進(jìn)程中任意的一個(gè)有寫(xiě)內(nèi)存的操作時(shí),系統(tǒng)才會(huì)為執(zhí)行寫(xiě)操作的進(jìn)程分配相關(guān)的獨(dú)自使用的內(nèi)存頁(yè)面。
                 這種處理方式叫做 寫(xiě)實(shí)復(fù)制技術(shù)。

                 創(chuàng)建一個(gè)新的進(jìn)程和加載一個(gè)執(zhí)行程序文件時(shí)兩個(gè)不同的概念。當(dāng)創(chuàng)建子進(jìn)程的時(shí)候,它完全復(fù)制了父進(jìn)程的代碼和數(shù)據(jù)區(qū),并會(huì)在其中執(zhí)行子進(jìn)程部分的代碼。
                    
                 9.1進(jìn)程調(diào)度
                      調(diào)度程序可以看在所有處于運(yùn)行狀態(tài)的進(jìn)程之間分配CPU運(yùn)行時(shí)間的管理代碼。
                      linux的進(jìn)程是搶占式的,但是被搶占的進(jìn)程仍然處于TASK_RUNNING 狀態(tài),只是暫時(shí)沒(méi)有被CPU運(yùn)行。進(jìn)程的搶占發(fā)生在進(jìn)程處于用戶(hù)態(tài)執(zhí)行階段,
                      在內(nèi)核態(tài)執(zhí)行時(shí)是不能被搶占的。
                       
                 9.2 調(diào)度程序
                       schedule()函數(shù)首先掃描任務(wù)數(shù)組。通過(guò)比較每個(gè)就緒態(tài)(TASK_RUNNING)的運(yùn)行時(shí)間遞減滴答計(jì)數(shù)counter 的值來(lái) 確定當(dāng)前哪個(gè)進(jìn)程運(yùn)行的時(shí)間最少。
                       哪一個(gè)值越大,就表示運(yùn)行時(shí)間還不長(zhǎng),于是就選擇該進(jìn)程,并使用任務(wù)切換宏函數(shù)切換到該進(jìn)程執(zhí)行。
                        
                        如果沒(méi)有其他進(jìn)程執(zhí)行,系統(tǒng)就會(huì)選擇進(jìn)程0運(yùn)行,進(jìn)程0會(huì)調(diào)用pause()函數(shù)把自己置位可中斷的睡眠狀態(tài),并再次使用schedule()函數(shù)。只要系統(tǒng)空閑就
                       調(diào)用進(jìn)程0運(yùn)行。 
                      
                  9.3進(jìn)程切換
                        每當(dāng)選擇出一個(gè)新的可以運(yùn)行的進(jìn)程時(shí),schedule()函數(shù)就會(huì)調(diào)用定義在include/asm/system.h中的switch_to()宏執(zhí)行實(shí)際進(jìn)程切換操作。該宏會(huì)把CPU的當(dāng)前進(jìn)程狀態(tài)
                        替換為新進(jìn)程的狀態(tài)。.
             
                  9.4 終止進(jìn)程
                        當(dāng)一個(gè)進(jìn)程結(jié)束了運(yùn)行或在半途中終止了運(yùn)行,那么內(nèi)核就需要釋放該進(jìn)程所占用的系統(tǒng)資源。這包括進(jìn)程運(yùn)行時(shí)打開(kāi)的文件、申請(qǐng)的內(nèi)存等。
                      









                       
                           








                    









                 




             

                    


                


              



























            posted on 2010-10-08 19:49 kahn 閱讀(1504) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国色天香久久久久久久小说| 久久丝袜精品中文字幕| 无码日韩人妻精品久久蜜桃| 久久精品国产亚洲AV久| 久久99精品久久久久久动态图| 国产精品成人99久久久久91gav| 亚洲中文字幕伊人久久无码| 日韩人妻无码一区二区三区久久 | 国产精品永久久久久久久久久| 久久久久国产亚洲AV麻豆| 亚洲精品无码久久久久去q| 久久96国产精品久久久| 18禁黄久久久AAA片| 伊人色综合久久天天| 久久综合香蕉国产蜜臀AV| 久久青青草原精品国产不卡| 99久久人妻无码精品系列| 精品久久久久久国产| 欧美精品福利视频一区二区三区久久久精品 | 国产精品嫩草影院久久| 久久婷婷成人综合色综合| 亚洲一区精品伊人久久伊人 | A狠狠久久蜜臀婷色中文网| 亚洲精品美女久久久久99小说 | 久久久久一级精品亚洲国产成人综合AV区| 久久久国产打桩机| 欧美日韩成人精品久久久免费看| 精品久久久久久综合日本| 午夜人妻久久久久久久久| 久久精品免费全国观看国产| 久久久久久亚洲精品无码| 婷婷久久综合九色综合98| 97久久精品无码一区二区 | 精品久久亚洲中文无码| 久久精品国产亚洲一区二区三区| 久久国产影院| 一级女性全黄久久生活片免费| 久久久精品久久久久特色影视| 精品久久久久久无码人妻热| 久久97久久97精品免视看| 久久久久国产一区二区三区|