Linux內核
1特性
架構
Linux是一個一體化
內核(monolithic kernel)系統。
設備驅動程序能夠徹底訪問硬件。Linux內的
設備驅動程序能夠方便地以
模塊化(modularize)的形式設置,並在系統運行期間可直接裝載或
卸載。
可移植性
儘管Linus Torvalds的初衷不是使
Linux成爲一個可移植的操做系統,今天的
Linux倒是全球被最普遍移植的
操做系統內核。從掌上電腦iPad到巨型電腦IBM S/390,甚至於
微軟出品的遊戲機XBOX均可以看到
Linux內核的蹤影。Linux也是IBM
超級計算機Blue Gene的操做系統。
Linux能夠在如下結構上運行:
Acorn:Archimedes,A5000和RiscPC系列
康柏:Alpha
惠普:
PA-RISC
IA64:英特爾Itanium我的電腦
IBM的S/390和AS/400
英特爾80386及以後的兼容產品:80386,80486和整個奔騰系列;AMD Athlon,Duron,Thunderbird; Cyrix系列。對英特爾8086,8088,80186,80188和80280芯片的支持正在開發中。
Mips
摩托羅拉68020及以上: 新的Amigas,一些蘋果電腦
PowerPC:全部較新的蘋果電腦
SPARC和UltraSPARC:太陽微系統的
工做站
Hitachi SuperH: SEGA Dreamcast
索尼公司: PlayStation 2
微軟公司: Xbox
ARM系列
發表形式
原先Linus Torvalds將Linux置於一個禁止任何商業行爲的條例之下,但以後改用
GNU通用公共許可證第二版。該協議容許任何人對
軟件進行修改或發行,包括商業行爲,只要其遵照該協議,全部基於Linux的軟件也必須以該協議的形式發表,並提供
源代碼。
Linus Torvalds曾經公開聲稱將Linux置於GNU通用公共許可證之下是他一輩子中所作的「最好的決定」。
2組成
進程管理(process management)、 1
定時器(timer)、 2
中斷管理(interrupt management)、 3
內存管理(memory management)、 4
模塊管理(module management)、 5
虛擬文件系統接口(VFS layer)、 6
文件系統(file system)、 7
設備驅動程序(device driver)、 8
網絡管理(network management)、 10
系統啓動(system init)等操做系統功能的實現。11
3內核
概念
[1]
操做系統是一個用來和硬件打交道併爲
用戶程序提供一個有限服務集的低級
支撐軟件。一個
計算機系統是一個硬件和
軟件的共生體,它們互相依賴,不可分割。計算機的硬件,含有外圍設備、處理器、
內存、硬盤和其餘的
電子設備組成計算機的發動機。可是沒有
軟件來操做和控制它,自身是不能工做的。完成這個控制工做的
軟件就稱爲操做系統,在Linux的術語中被稱爲「內核」,也能夠稱爲「核心」。Linux內核的主要模塊(或組件)分如下幾個部分:存儲管理、CPU和
進程管理、文件系統、設備管理和驅動、網絡
通訊,以及系統的初始化(引導)、系統調用等。
版本號
Linux內核使用三種不一樣的版本編號方式。 第一種方式用於1.0版本以前(包括1.0)。第一個版本是0.01,緊接着是0.0二、0.0三、0.十、0.十一、0.十二、0.9五、0.9六、0.9七、0.9八、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月,正式的Linux 1.0出現了,這差很少是一種正式的獨立宣言。截至那時爲止,它的用戶基數已經發展得很大,並且Linux的核心開發隊伍也創建起來了。
體系結構屬性
Linux 內核實現了不少重要的
體系結構屬性。在或高或低的層次上,內核被劃分爲多個子系統。Linux 也能夠看做是一個總體,由於它會將全部這些基本服務都集成到內核中。這與
微內核的
體系結構不一樣,後者會提供一些基本的服務,例如
通訊、
I/O、
內存和
進程管理,更具體的服務都是插入到微內核層中的。
隨着時間的流逝,Linux 內核在
內存和 CPU 使用方面具備較高的效率,而且很是穩定。可是對於 Linux 來講,最爲有趣的是在這種大小和複雜性的前提下,依然具備良好的
可移植性。Linux 編譯後可在大量處理器和具備不一樣
體系結構約束和需求的平臺上運行。一個例子是 Linux 能夠在一個具備
內存管理單元(MMU)的處理器上運行,也能夠在那些不提供
MMU的處理器上運行。Linux 內核的
uClinux移植提供了對非 MMU 的支持。
開發和規範
核心的開發和規範一直是由Linux社區控制着,版本也是惟一的。實際上,操做系統的
內核版本指的是在Linux本人領導下的開發小組開發出的系統內核的版本號。自1994年3月14日發佈了第一個正式版本Linux 1.0以來,每隔一段時間就有新的版本或其修訂版公佈。
Linux將標準的GNU許可協議改稱Copyleft,以便與Copyright相對照。通用的公共許可(GPL)容許用戶銷售、拷貝和改變具備Copyleft的
應用程序。固然這些程序也能夠是Copyright的,可是你必須容許進一步的銷售、拷貝和對其代碼進行改變,同時也必須使他人能夠免費獲得修改後的
源代碼。事實證實,GPL對於Linux的成功起到了極大的做用。它啓動了一個十分繁榮的商用Linux階段,還爲
編程人員提供了一種凝聚力,誘使你們加入這個充滿了慈善精神的Linux運動。
主要子系統
系統調用接口:SCI 層提供了某些機制執行從
用戶空間到內核的
函數調用。正如前面討論的同樣,這個接口依賴於
體系結構,甚至在相同的處理器家族內也是如此。SCI 其實是一個很是有用的
函數調用多路複用和多路分解服務。在 ./
linux/kernel 中您能夠找到 SCI 的實現,並在 ./
linux/arch 中找到依賴於
體系結構的部分。
進程管理:進程管理的重點是進程的執行。在內核中,這些進程稱爲線程,表明了單獨的處理器虛擬化(線程代碼、數據、
堆棧和 CPU
寄存器)。在
用戶空間,一般使用進程 這個術語,不過 Linux 實現並無區分這兩個概念(進程和線程)。內核經過 SCI 提供了一個
應用程序編程接口(
API)來建立一個新進程(fork、exec 或 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 中找到。
文件系統層之下是
緩衝區緩存,它爲文件系統層提供了一個通用函數集(與具體文件系統無關)。這個緩存層經過將數據保留一段時間(或者隨即預先讀取數據以便在須要是就可用)優化了對
物理設備的訪問。
緩衝區緩存之下是
設備驅動程序,它實現了特定
物理設備的接口。
特性
若是 Linux 內核的
可移植性和效率還不夠好,Linux 還提供了其餘一些特性,它們沒法劃分到上面的分類中。
做爲一個生產操做系統和
開源軟件,Linux 是測試新協議及其加強的良好平臺。Linux 支持大量
網絡協議,包括典型的 TCP/IP,以及高速網絡的擴展(大於 1 Gigabit Ethernet [GbE] 和 10 GbE)。Linux 也能夠支持諸如
流控制傳輸協議(SCTP)之類的協議,它提供了不少比 TCP 更高級的特性(是傳輸層協議的接替者)。
Linux 仍是一個動態內核,支持動態添加或刪除
軟件組件。被稱爲動態可加載內核模塊,它們能夠在引導時根據須要(當前特定設備須要這個模塊)或在任什麼時候候由用戶插入。
Linux 最新的一個加強是能夠用做其餘操做系統的操做系統(稱爲
系統管理程序)。該系統對內核進行了修改,稱爲基於內核的
虛擬機(KVM)。這個修改成
用戶空間啓用了一個新的接口,它能夠容許其餘操做系統在啓用了 KVM 的內核之上運行。除了運行 Linux 的其餘實例以外, Microsoft® Windows® 也能夠進行虛擬化。唯一的限制是底層處理器必須支持新的虛擬化指令
4發行版
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發行版。
5常量定義
初始定義
宏phys定義了你的機器上的地址轉換__virt_to_phys()。這個宏用於把虛擬地址轉換爲一個
物理地址。一般狀況下:
phys = virt - PAGE_OFFSET PHYS_OFFSET
解壓縮符號
解壓縮器的地址地址。因爲當你調用解壓縮器代碼時,一般關閉MMU,所以這裏並不討論
虛擬地址和物理地址的問題。一般你在這個地址處調用內核,開始引導內核。它不須要在RAM中,只須要位於FLASH或其餘只讀或讀/寫的可尋址的存儲設備中。
l ZBSSADDR
解壓縮器的初始化爲0的工做區的起始地址。必須位於RAM中,解壓縮器會替你把它初始化爲0,此外,須要關閉MMU。
l ZRELADDR
解壓縮內核將被寫入的地址和最終的執行地址。必須知足:
__virt_to_phys(TEXTADDR) == ZRELADDR
內核的開始部分被編碼爲與位置無關的代碼。
l INITRD_PHYS
放置初始RAM盤的
物理地址。僅當你使用bootpImage時相關(這是一種很是老的param_struct結構)
l INITRD_ⅥRT
初始RAM盤的虛擬地址。必須知足:
__virt_to_phys(INITRD_ⅥRT) == INITRD_PHYS
l PARAMS_PHYS
param_struct 結構體或tag lis的物理地址,用於給定內核執行環境下的不一樣參數。
內核符號
RAM第一個BANK的物理地址地址。
l PAGE_OFFSET
RAM第一個BANK的虛擬地址地址。在內核引導階段,虛擬地址PAGE_OFFSE將被映射爲物理地址PHYS_OFFSET,它應該與TASK_SIZE具備相同的值。
l TASK_SIZE
任何一個低於TASK_SIZE的虛擬地址對用戶進程來講都是不可見的,所以,內核經過進程偏移對每一個進行進行動態的管理。我把這叫作用戶段。任何高於TASK_SIZE的對全部進程都是相同的,稱之爲內核段。(換句話說,你不能把IO映射放在低於TASK_SIZE和PAGE_OFFSET的位置處。)
l TEXTADDR
內核的虛擬起始地址,一般爲PAGE_OFFSET 0x8000。內核映射必須在此結束。
l DATAADDR
內核數據段的虛擬地址,不能在使用解壓縮器的狀況下定義。
l VMALLOC_START
l VMALLOC_END
用於限制vmalloc()區域的虛擬地址。此地址必須位於內核段。一般,vmalloc()區域在最後的虛擬RAM地址以上開始VMALLOC_OFFSET字節。
l VMALLOC_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的8 MB區域的物理地址。
vio——是8MB調試區域的虛擬地址。
這個調試區域將被位於代碼中(經過MAPIO函數)的隨後的構架相關代碼再次進行初始化。
l BOOT_PARAMS
參見 PARAMS_PHYS.
l FⅨUP(func)
機器相關的修正,在存儲子系統被初始化前運行。
l MAPIO(func)
機器相關的函數,用於IO區域的映射(包括上面的調試區)。
l INITIRQ(func)
用於初始化中斷的機器相關的函數
[4] 。