Linux内核

Linux内核

計算機術語
Linux是一種開源電腦操作系統内核。它是一個用C語言寫成,符合POSIX标準的類Unix操作系統。Linux最早是由芬蘭黑客Linus Torvalds為嘗試在英特爾x86架構上提供自由免費的類Unix操作系統而開發的。該計劃開始于1991年,在計劃的早期有一些Minix黑客提供了協助,而今天全球無數程序員正在為該計劃無償提供幫助。Linux是一個一體化内核(monolithic kernel)系統。“内核”指的是一個提供硬件抽象層、磁盤及文件系統控制、多任務等功能的系統軟件。一個内核不是一套完整的操作系統。一套基于Linux内核的完整操作系統叫作Linux操作系統,或是GNU/Linux。設備驅動程序可以完全訪問硬件。Linux内的設備驅動程序可以方便地以模塊化(modularize)的形式設置,并在系統運行期間可直接裝載或卸載。
    中文名: 外文名: 所屬學科: 軟件名稱:Linux内核 軟件語言:C語言 軟件授權:免費 發明者:Linus Torvalds 使用時間:1991年

内核結構

在Richard Stevens的unix環境高級編程中這樣定義“它控制計算機硬件資源,提供程序運行環境。一般而言我們稱這種軟件為内核(kernel),它相對較小,位于環境的中心”。操作系統是一個用來和硬件打交道并為用戶程序提供一個有限服務集的低級支撐軟件。一個計算機系統是一個硬件和軟件的共生體,它們互相依賴,不可分割。計算機的硬件,含有外圍設備、處理器、内存、硬盤和其他的電子設備組成計算機的發動機。但是沒有軟件來操作和控制它,自身是不能工作的。完成這個控制工作的軟件就稱為操作系統,在Linux的術語中被稱為“内核”,也可以稱為“核心”。Linux内核的主要模塊(或組件)分以下幾個部分:存儲管理、CPU和進程管理、文件系統、設備管理和驅動、網絡通信,以及系統的初始化(引導)、系統調用等。

版本号

Linux内核使用三種不同的版本編号方式。

第一種方式用于1.0版本之前(包括1.0)。第一個版本是0.01,緊接着是0.02、0.03、0.10、0.11、0.12、0.95、0.96、0.97、0.98、0.99和之後的1.0。

第二種方式用于1.0之後到2.6,數字由三部分“A.B.C”,A代表主版本号,B代表次主版本号,C代表較小的末版本号。隻有在内核發生很大變化時(曆史上隻發生過兩次,1994年的1.0,1996年的2.0),A才變化。可以通過數字B來判斷Linux是否穩定,偶數的B代表穩定版,奇數的B代表開發版。C代表一些bug修複,安全更新,新特性和驅動的次數。以版本2.4.0為例,2代表主版本号,4代表次版本号,0代表改動較小的末版本号。在版本号中,序号的第二位為偶數的版本表明這是一個可以使用的穩定版本,如2.2.5,而序号的第二位為奇數的版本一般有一些新的東西加入,是個不一定很穩定的測試版本,如2.3.1。這樣穩定版本來源于上一個測試版升級版本号,而一個穩定版本發展到完全成熟後就不再發展。

第三種方式從2004年2.6.0版本開始,使用一種“time-based”的方式。3.0版本之前,是一種“A.B.C.D”的格式。七年裡,前兩個數字A.B即“2.6”保持不變,C随着新版本的發布而增加,D代表一些bug修複,安全更新,添加新特性和驅動的次數。3.0版本之後是“A.B.C”格式,B随着新版本的發布而增加,C代表一些bug修複,安全更新,新特性和驅動的次數。第三種方式中不再使用偶數代表穩定版,奇數代表開發版這樣的命名方式。舉個例子:3.7.0代表的不是開發版,而是穩定版!

發展曆史

Linux最早是由芬蘭人Linus Torvalds設計的。當時由于UNⅨ的

商業化,Andrew Tannebaum教授開發了Minix操作系統以便于不受AT&T許可協議的約束,為教學科研提供一個操作系統。當時發布在Internet上,免費給全世界的學生使用。Minix具有較多UNⅨ的特點,但與UNⅨ不完全兼容。1991年10月5日,Linus為了給Minix用戶設計一個比較有效的UNⅨPC版本,自己動手寫了一個“類Minix”的操作系統。整個故事從兩個在終端上打印AAAA...和BBBB...的進程開始的,當時最初的内核版本是0.02。Linus Torvalds将它發到了Minix新聞組,很快就得到了反應。

Linus Torvalds在這種簡單的任務切換機制上進行擴展,并在很多熱心支持者的幫助下開發和推出了Linux的第一個穩定的工作版本。1991年11月,Linux0.10版本推出,0.11版本随後在1991年12月推出,當時将它發布在Internet上,免費供人們使用。當Linux非常接近于一種可靠的/穩定的系統時,Linus決定将0.13版本稱為0.95版本。1994年3月,正式的Linux1.0出現了,這差不多是一種正式的獨立宣言。截至那時為止,它的用戶基數已經發展得很大,而且Linux的核心開發隊伍也建立起來了。

結構屬性

在讨論大型而複雜的系統的體系結構時,可以從很多角度來審視系統。體系結構分析的一個目标是提供一種方法更好地理解源代碼。

Linux内核實現了很多重要的體系結構屬性。在或高或低的層次上,内核被劃分為多個子系統。Linux也可以看作是一個整體,因為它會将所有這些基本服務都集成到内核中。這與微内核的體系結構不同,後者會提供一些基本的服務,例如通信、I/O、内存和進程管理,更具體的服務都是插入到微内核層中的。

随着時間的流逝,Linux内核在内存和CPU使用方面具有較高的效率,并且非常穩定。但是對于Linux來說,最為有趣的是在這種大小和複雜性的前提下,依然具有良好的可移植性。Linux編譯後可在大量處理器和具有不同體系結構約束和需求的平台上運行。一個例子是Linux可以在一個具有内存管理單元(MMU)的處理器上運行,也可以在那些不提供MMU的處理器上運行。Linux内核的uClinux移植提供了對非MMU的支持。

開發規範

核心的開發和規範一直是由Linux社區控制着,版本也是唯一的。實際上,操作系統的内核版本指的是在Linus本人領導下的開發小組開發出的系統内核的版本号。自1994年3月14日發布了第一個正式版本Linux1.0以來,每隔一段時間就有新的版本或其修訂版公布。

Linux将标準的GNU許可協議改稱Copyleft,以便與Copyright相對照。通用的公共許可(GPL)允許用戶銷售、拷貝和改變具有Copyleft的應用程序。當然這些程序也可以是Copyright的,但是你必須允許進一步的銷售、拷貝和對其代碼進行改變,同時也必須使他人可以免費得到修改後的源代碼。事實證明,GPL對于Linux的成功起到了極大的作用。它啟動了一個十分繁榮的商用Linux階段,還為編程人員提供了一種凝聚力,誘使大家加入這個充滿了慈善精神的Linux運動。

主要子系統

系統調用接口

SCI層提供了某些機制執行從用戶空間到内核的函數調用。正如前面讨論的一樣,這個接口依賴于體系結構,甚至在相同的處理器家族内也是如此。SCI實際上是一個非常有用的函數調用多路複用和多路分解服務。在/linux/kernel中您可以找到SCI的實現,并在./linux/arch中找到依賴于體系結構的部分。

進程管理

進程管理的重點是進程的執行。在内核中,這些進程稱為線程,代表了單獨的處理器虛拟化(線程代碼、數據、堆棧和CPU寄存器)。在用戶空間,通常使用進程這個術語,不過Linux實現并沒有區分這兩個概念(進程和線程)。内核通過SCI提供了一個應用程序編程接口(API)來創建一個新進程(fork、exe或Portable Operating System Interface[POSⅨ]函數),停止進程(kill、exit),并在它們之間進行通信和同步(signal或者POSⅨ機制)。

進程管理還包括處理活動進程之間共享CPU的需求。内核實現了一種新型的調度算法,不管有多少個線程在競争CPU,這種算法都可以在固定時間内進行操作。這種算法就稱為O⑴調度程序,這個名字就表示它調度多個線程所使用的時間和調度一個線程所使用的時間是相同的。O⑴調度程序也可以支持多處理器(稱為對稱多處理器或SMP)。您可以在./linux/kernel中找到進程管理的源代碼,在./linux/arch中可以找到依賴于體系結構的源代碼。

内存管理

内核所管理的另外一個重要資源是内存。為了提高效率,如果由硬

管理虛拟内存,内存是按照所謂的内存頁方式進行管理的(對于大部分體系結構來說都是4KB)。Linux包括了管理可用内存的方式,以及物理和虛拟映射所使用的硬件機制。

不過内存管理要管理的可不止4KB緩沖區。Linux提供了對4KB緩沖區的抽象,例如slab分配器。這種内存管理模式使用4KB緩沖區為基數,然後從中分配結構,并跟蹤内存頁使用情況,比如哪些内存頁是滿的,哪些頁面沒有完全使用,哪些頁面為空。這樣就允許該模式根據系統需要來動态調整内存使用。

為了支持多個用戶使用内存,有時會出現可用内存被消耗光的情況。由于這個原因,頁面可以移出内存并放入磁盤中。這個過程稱為交換,因為頁面會被從内存交換到硬盤上。内存管理的源代碼可以在./linux/mm中找到。

虛拟文件系統

虛拟文件系統(VFS)是Linux内核中非常有用的一個方面,因為它為文件系統提供了一個通用的接口抽象。VFS在SCI和内核所支持的文件系統之間提供了一個交換層。

VFS在用戶和文件系統之間提供了一個交換層

在VFS上面,是對諸如open、close、read和write之類的函數的一個通用API抽象。在VFS下面是文件系統抽象,它定義了上層函數的實現方式。它們是給定文件系統(超過50個)的插件。文件系統的源代碼可以在./linux/fs中找到。

文件系統層之下是緩沖區緩存,它為文件系統層提供了一個通用函數集(與具體文件系統無關)。這個緩存層通過将數據保留一段時間(或者随即預先讀取數據以便在需要是就可用)優化了對物理設備的訪問。緩沖區緩存之下是設備驅動程序,它實現了特定物理設備的接口。

特性

可移植性

盡管Linus Torvalds的初衷不是使Linux成為一個可移植的操作系統,今天的Linux卻是全球被最廣泛移植的操作系統内核。從掌上電腦iPad到巨型電腦IBMS/390,甚至于微軟出品的遊戲機XBOX都可以看到Linux内核的蹤迹。Linux也是IBM超級計算機BlueGene的操作系統。

Linux可以在以下結構上運行:

Acorn:Archimedes,A5000和RiscPC系列

康柏:Alpha

惠普:PA-RISC

IA64:英特爾Itanium個人電腦

IBM的S/390和AS/400

英特爾80386及之後的兼容産品:80386,80486和整個奔騰系列;AMDAthlon,Duron,Thunderbird;Cyrix系列。對英特爾8086,8088,80186,80188和80280芯片的支持正在開發中。

Mips

摩托羅拉68020及以上:新的Amigas,一些蘋果電腦

PowerPC:所有較新的蘋果電腦

SPARC和UltraSPARC:太陽微系統的工作站

HitachiSuperH:SEGADreamcast

索尼公司:PlayStation2

微軟公司:Xbox

ARM系列

網絡支持

作為一個生産操作系統和開源軟件,Linux是測試新協議及其增強的良好平台。Linux支持大量網絡協議,包括典型的TCP/IP,以及高速網絡的擴展(大于1Gigabit Ethernet [GbE]和10 GbE)。Linux也可以支持諸如流控制傳輸協議(SCTP)之類的協議,它提供了很多比TCP更高級的特性(是傳輸層協議的接替者)。

動态内核

Linux還是一個動态内核,支持動态添加或删除軟件組件。被稱為動态可加載内核模塊,它們可以在引導時根據需要(當前特定設備需要這個模塊)或在任何時候由用戶插入。

系統管理程序

Linux最新的一個增強是可以用作其他操作系統的操作系統(稱為系統管理程序)。該系統對内核進行了修改,稱為基于内核的虛拟機(KVM)。這個修改為用戶空間啟用了一個新的接口,它可以允許其他操作系統在啟用了KVM的内核之上運行。除了運行Linux的其他實例之外,Microsoft®Windows®也可以進行虛拟化。惟一的限制是底層處理器必須支持新的虛拟化指令

組成

進程管理(process management)

定時器(timer)

中斷管理(interrupt management)

内存管理(memory management)

模塊管理(module management)

虛拟文件系統接口(VFS layer)

文件系統(file system)

設備驅動程序(device driver)

進程間通信(inter-process communication)

網絡管理(network management)

系統啟動(system init)等操作系統功能的實現

發行版

Linux内核的發展過程中,我們還不得不提一下各種Linux發行版的作用,因為正是它們推動了Linux的應用,從而也讓更多的人開始關注Linux。一些組織或廠家,将Linux系統的内核與外圍實用程序(Utilities)軟件和文檔包裝起來,并提供一些系統安裝界面和系統配置、設定與管理工具,就構成了一種發行版本(distribution),Linux的發行版本其實就是Linux核心再加上外圍的實用程序組成的一個大軟件包而已。相對于Linux操作系統内核版本,發行版本的版本号随發布者的不同而不同,與Linux系統内核的版本号是相對獨立的。因此把SUSE、RedHat、Ubuntu、Slackware等直接說成是Linux是不确切的,它們是Linux的發行版本,更确切地說,應該叫做“以Linux為核心的操作系統軟件包”。根據GPL準則,這些發行版本雖然都源自一個内核,并且都有自己各自的貢獻,但都沒有自己的版權。Linux的各個發行版本(distribution),都是使用Linus主導開發并發布的同一個Linux内核,因此在内核層不存在什麼兼容性問題。每個版本都不一樣的感覺,隻是在發行版本的最外層才有所體現,而絕不是Linux本身特别是内核不統一或是不兼容。

90年代初期Linux開始出現的時候,僅僅是以源代碼形式出現,用戶需要在其他操作系統下進行編譯才能使用。後來出現了一些正式版本。目前最流行的幾個正式版本有:SUSE、RedHat、Fedora、Debian、Ubuntu、CentOS、Gentoo,等等。用戶可根據自己的經驗和喜好選用合适的Linux發行版。

原先Linus Torvalds将Linux置于一個禁止任何商業行為的條例之下,但之後改用GNU通用公共許可證第二版。該協議允許任何人對軟件進行修改或發行,包括商業行為,隻要其遵守該協議,所有基于Linux的軟件也必須以該協議的形式發表,并提供源代碼。

Linus Torvalds曾經公開聲稱将Linux置于GNU通用公共許可證之下是他一生中所做的“最好的決定”。

常量定義

初始定義

宏phys定義了你的機器上的地址轉換__virt_to_phys()。這個宏用于把虛拟地址轉換為一個物理地址。通常情況下:

phys=virt-PAGE_OFFSET PHYS_OFFSET

解壓縮符号

解壓縮器的地址地址。由于當你調用解壓縮器代碼時,通常關閉MMU,因此這裡并不讨論虛拟地址和物理地址的問題。通常你在這個地址處調用内核,開始引導内核。它不需要在RAM中,隻需要位于FLASH或其他隻讀或讀/寫的可尋址的存儲設備中。

lZBSSADDR

解壓縮器的初始化為0的工作區的起始地址。必須位于RAM中,解壓縮器會替你把它初始化為0,此外,需要關閉MMU。

lZRELADDR

解壓縮内核将被寫入的地址和最終的執行地址。必須滿足:

__virt_to_phys(TEXTADDR)==ZRELADDR

内核的開始部分被編碼為與位置無關的代碼。

lNITRD_PHYS

放置初始RAM盤的物理地址。僅當你使用bootpImage時相關(這是一種非常老的param_struct結構)

lINITRD_ⅥRT

初始RAM盤的虛拟地址。必須滿足:

__virt_to_phys(INITRD_ⅥRT)==INITRD_PHYS

lPARAMS_PHYS

param_struct結構體或taglis的物理地址,用于給定内核執行環境下的不同參數。

内核符号

RAM第一個BANK的物理地址地址。

lPAGE_OFFSET

RAM第一個BANK的虛拟地址地址。在内核引導階段,虛拟地址PAGE_OFFSE将被映射為物理地址PHYS_OFFSET,它應該與TASK_SIZE具有相同的值。

lTASK_SIZE

一個用戶進程的最大值,單位為byte。用戶空間的堆棧從這個地址處向下增長。

任何一個低于TASK_SIZE的虛拟地址對用戶進程來說都是不可見的,因此,内核通過進程偏移對每個進行進行動态的管理。我把這叫做用戶段。任何高于TASK_SIZE的對所有進程都是相同的,稱之為内核段。(換句話說,你不能把IO映射放在低于TASK_SIZE和PAGE_OFFSET的位置處。)

lTEXTADDR

内核的虛拟起始地址,通常為PAGE_OFFSET0x8000。内核映射必須在此結束。

lDATAADDR

内核數據段的虛拟地址,不能在使用解壓縮器的情況下定義。

lVMALLOC_START

lVMALLOC_END

用于限制vmalloc()區域的虛拟地址。此地址必須位于内核段。通常,vmalloc()區域在最後的虛拟RAM地址以上開始VMALLOC_OFFSET字節。

lVMALLOC_OFFSET

Offset normally incorporated into VMALLOC_START to provide a hole between virtual RAM and the vmalloc area. We do this to allow out of bounds memory accesses (eg,something writing off the end of the mapped memory map) to be caught. Normally set to 8MB.

構架宏

pram——指定了RAM起始的物理地址,必須始終存在,并應等于PHYS_OFFSET。

pio——是供arch/arm/kernel/debug-armv.S中的調試宏使用的,包含IO的8MB區域的物理地址。

vio——是8MB調試區域的虛拟地址。

這個調試區域将被位于代碼中(通過MAPIO函數)的随後的構架相關代碼再次進行初始化。

lBOOT_PARAMS

參見PARAMS_PHYS.

lFⅨUP(func)

機器相關的修正,在存儲子系統被初始化前運行。

lMAPIO(func)

機器相關的函數,用于IO區域的映射(包括上面的調試區)。

lINITIRQ(func)

用于初始化中斷的機器相關的函數。

相關詞條

相關搜索

其它詞條