• <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)核學習之八 內(nèi)核體系結(jié)構(gòu)

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

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





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

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

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

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

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


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


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





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



             5.4其他任務的地址對應關(guān)系
                   
                 對于從任務2開始的進程來說,它們的父進程都是init進程(任務1) 。從任務2開始,如果任務號以nr來表示,那么任務nr在線性地址空間中的起始位置將是 nr * 64MB 。
                  

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

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

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

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


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

                 在linux內(nèi)核中,進程通常叫做任務,而把運行在用戶空間的程序稱作 進程。
                 

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

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

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









                       
                           








                    









                 




             

                    


                


              



























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

            久久久亚洲裙底偷窥综合 | 国产午夜精品理论片久久影视| 久久久久久久亚洲精品| 免费国产99久久久香蕉| 精品久久久久中文字幕日本| 亚洲国产另类久久久精品黑人 | 久久精品国产一区二区三区日韩| 亚洲中文字幕无码久久2017| 久久精品国产免费观看三人同眠| 伊人久久大香线蕉无码麻豆| 日本五月天婷久久网站| 伊人色综合久久天天人手人婷| 精品伊人久久大线蕉色首页| 亚洲欧美伊人久久综合一区二区 | 2021国产精品久久精品| 日韩精品久久久久久久电影| 久久精品成人欧美大片| 国产成人久久精品一区二区三区| 久久久久久免费一区二区三区| 51久久夜色精品国产| 久久久久久国产a免费观看不卡| 色综合久久中文字幕综合网| 婷婷久久香蕉五月综合加勒比| 国产精品99久久精品| 久久精品亚洲乱码伦伦中文| 久久精品国产日本波多野结衣| 77777亚洲午夜久久多喷| 久久99热这里只有精品国产| 国内精品久久国产| 久久免费美女视频| 久久久久久国产精品无码下载| 国产午夜免费高清久久影院 | 中文字幕亚洲综合久久菠萝蜜| 亚洲第一极品精品无码久久| 中文精品久久久久国产网址| 亚洲色欲久久久久综合网| 久久99精品国产99久久6男男| 久久91精品国产91久久户| 精品国产乱码久久久久久人妻| 99久久99久久久精品齐齐| 久久夜色精品国产www|