Linux操作系統與應用 第一章_第1頁
Linux操作系統與應用 第一章_第2頁
Linux操作系統與應用 第一章_第3頁
Linux操作系統與應用 第一章_第4頁
Linux操作系統與應用 第一章_第5頁
已閱讀5頁,還剩49頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第一章操作系統概述認識操作系統操作系統的發展開放源代碼的Unix/Linux操作系統Linux內核Linux內核源代碼

Linux

內核模塊編程入門Linux

內核中鏈表的實現及應用不同角度看到的操作系統操作系統整體看操作系統設計者使用者普通開發者認識操作系統打開計算機,首先跳入眼簾的是什么?要拷貝一個文件,具體的拷貝操作是誰完成的?你需要知道文件存放在何處嗎?柱面、磁道、扇區描述什么?數據的搬動過程怎樣進行繁瑣留給自己,簡單留給用戶

操作系統穿上華麗的外衣-圖形界面操作系統穿上樸素的外衣-字符界面<>認識操作系統-從使用者的角度看拷貝命令的C語言實現片斷<>inf=open(“/floppy/TEST”,O_RDONLY,0);out=open(“/mydir/test”,O_WRONLY,0600);do{l=read(inf,buf,4096);write(outf,buf,l);}while(l);close(outf);close(inf);認識操作系統-從程序開發者的角度看

<>瀏覽器信息管理文件管理系統游戲

編譯程序編輯程序命令解釋程序

操作系統

CPU、內存、I/O接口硬件內核認識操作系統-從所處位置看操作系統是其它所有用戶程序運行的基礎。

<>#include<stdio.h>main(){printf(“Helloworld\n”)}用戶告訴操作系統執行test程序操作系統通過文件名找到該程序檢查其類型,檢查程序首部,找出代碼和數據存放的地址文件系統找到第一個磁盤塊操作系統建立程序的執行環境操作系統把程序從磁盤裝入內存,并跳到程序開始處執行該程序的執行過程簡述如下:操作系統檢查字符串的位置是否正確操作系統找到字符串被送往的設備操作系統將字符串送往輸出設備窗口系統確定這是一個合法的操作,然后將字符串轉換成像素窗口系統將像素寫入存儲映像區視頻硬件將像素表示轉換成一組模擬信號控制顯示器(重畫屏幕)顯示器發射電子束。你在屏幕上看到Helloworld。從中看到什么認識操作系統-從程序執行看從操作系統設計者的角度看操作系統的設計目標是什么?盡可能地方便用戶使用計算機讓各種軟件資源和硬件資源高效而協調地運轉起來。計算機的硬件資源和軟件資源各指什么?假設在一臺計算機上有三道程序同時運行,并試圖在一臺打印機上輸出運算結果,必須考慮哪些問題?從操作系統設計者的角度考慮,一個操作系統必須包含以下幾部分操作系統接口CPU管理內存管理設備管理文件管理<>認識操作系統-從設計者角度看操作系統是計算機系統中的一個系統軟件,是一些程序模塊的集合——它們能以盡量有效、合理的方式組織和管理計算機的軟硬件資源,合理的組織計算機的工作流程,控制程序的執行并向用戶提供各種服務功能,使得用戶能夠靈活、方便、有效的使用計算機,使整個計算機系統能高效、順暢地運行。<>認識操作系統-定義<>操作系統的組成(1)

通常意義上的操作系統被認為是整個系統中負責完成最基本的功能和系統管理的部分。除了內核,這些部分還應該包括啟動引導程序、命令行shell或者其他種類的用戶界面、基本的文件管理工具和系統工具等。實際上,人們在得到操作系統的同時,更需要的是構架于其上的應用軟件,從而完成所需的實際功能。為此,操作系統一般要和應用軟件綁定發行和出售。這樣的軟件包在linux領域被稱作發布版。

<>操作系統的組成(2)

從開發者的角度看,操作系統本質上是大型軟件包,因此結構組織不會與其它大型軟件迥異:操作系統的設計采用分層結構,越向上層抽象程度越高,越接近用戶;越向下層,越靠近硬件,抽象也越接近硬件。上層軟件依靠下層軟件提供的服務,而且上層軟件自身還提供附加服務。因此,操作系統的結構整體總體呈現倒金字塔形。用一組簡單的公式描述操作系統的組成要素:操作系統=內核+系統程序系統程序=編譯環境+API(應用程序接口)+AUI(用戶接口)編譯環境=編譯程序+鏈接程序+裝載程序API=shell+系統服務例程+應用程序對于整個軟件系統:軟件系統=操作系統+AUI操作系統的演變單道批處理系統

串行執行預先組織好的一組任務

提高了系統效率。多道批處理系統可以交錯運行多個程序再次提高系統效率。分時系統將處理器的運行時間分成數片,均分或依照一定權重派發給系統中的用戶使用

快速響應

<>操作系統的發展硬件角度下的操作系發展軌跡年

特點

操作系統特點

機械計算機時代17世紀~20世紀初

1)純機械結構,低速

2)只能進行簡單的數學運算

純手工操作

從計算尺至差分機到分析機發展了數百年第一代計算機

1946年~50年代末電子管計算機

1)體積大、能耗高、故障多、價格貴

2)難以普及應用

無操作系統

(程序按機器碼編寫,載體從插件板到卡片與紙帶)

1906年發明電子管

1946ENIAC研制成功

(第一臺電子管計算機)年

特點

操作系統特點

第二代計算機

50年代末~60年代中期

晶體管計算機

1)采用印刷電路

2)穩定性與可靠性大大提高

3)批量生產成為可能

4)進入實際應用領域但數量有限1)單道批處理系統

2)操作系統以監督軟件形式出現

3)任務按順序方式處理

1947年發明晶體管

第三代計算機

60年代中期~70年代初

集成電路計算機

1)體積減小,性價比迅速提高

2)小型計算機發展迅速

3)進入商業應用

4)尚不適合家庭應用的需求1)涌現大批操作系統

多道批處理系統、分時系統和實時系統

2)奠定了現代操作系統的基本框架

1958年發明集成電路

1971年INTEL發明微處理器

硬件角度下的操作系統發展軌跡分析在硬件的性價比較低的時候,操作系統設計追求什么?

在硬件性價比越來越高后,操作系統的設計開始追求的目標是什么?計算機開始普及后,操作系統的設計開始追求?從第三代到第四代計算機,操作系統的發展逐漸擺脫追隨硬件發展的狀況,形成自己的理論體系進入第四代系統后,分布式系統和多處理器系統雖然極大的擴充了操作系統理論,但系統結構并沒有變化,只是各功能模塊得以進一步完善。<>操作系統的發展硬件角度下操作系統發展的分析<>主流操作系統

系統特點

計算機語言背

手工操作

無編程語言直接使用機器代碼

1936年圖靈提出圖靈機

單道批處理系統

作業運行的監督程序

編程語言雛形期

1957年FORTRAN語言開發成功多道批處理

分時系統

實時系統

多處理系統

操作系統結構確立,分為處理機管理、內存管理、設備管理、文件管理等模塊

1)編程語言大量涌現

2)結構化程序設計

3)C語言逐漸

60年代的軟件危機導致軟件工程的發展

1969年Unix誕生

1972年C語言推出

主流操作系統

系統特點

計算機語言背

類Unix系列

WINDOWS系列

人機交互成為主題

1)可視化界面

2)多媒體技

面向對象語言成為主流

80年代中期開始面向對象技術逐步發展網絡操作系統

分布式操作系統微內核技術興起

1)JAVA語言

2)腳本語言興起1995年JAVA推出

嵌入式系統

單內核與微內核競爭激烈編程工具向跨平臺方向發

1991年免費的操作系統Linux發布

軟件角度下的操作系統發展軌跡

分析程序設計理論約束著操作系統設計。操作系統的發展滯后于計算機語言的發展,從結構化設計到對象化設計,操作系統總是最后應用新編程理論的軟件之一。至今操作系統對于是否需要徹底對象化(即微內核化),還處于徘徊時期,仍在探索單內核與微內核的最佳結合方式。人機交互技術主要是為用戶考慮,這是對操作系統設計進行的變革。以Linux為代表的開源軟件的出現,打破了帶有神秘色彩的傳統的封閉式開發模式。<>軟件角度下的操作系統發展軌跡分析

<>講究效率的單模塊操作系統進程管理內存管理設備管理文件管理模塊之間可以互相調用的單模塊結構<>講究效率的單模塊操作系統模塊之間直接調用函數,除了函數調用的開銷外,沒有額外開銷。龐大的操作系統有數以千計的函數復雜的調用關系勢必導致操作系統維護的困難<>追求簡潔的微內核操作系統客戶進程進程服務器內存服務器文件服務器…微內核<>追求簡潔的微內核操作系統內核與各個服務器之間通過通信機制進行交互,這使得微內核結構的效率大大折扣。內核發出請求,服務器做出應答為各個服務器模塊的相對獨立性,使得其維護相對容易<>歷史悠久的Unix在MULTICS(1969)的肩上制研制者KenThompson和DennisM.Ritchie

Unix的誕生還伴有C語言呱呱落地Unix是現代操作系統的代表:安全、可靠、強大的計算能力Unix的商業化是一把雙刃劍

<>自由而奔放的黑馬-Linux誕生于學生之手成長于Internet壯大于自由而開放的文化<>Linux之父-LinusTorvalds芬蘭、赫爾辛基大學、1990起始于寫兩個進程然后寫驅動程序、文件系統、任務切換程序,從而形成一個操作系統鄒形<>Linux得以流行的原因之一

-遵循POSIX標準POSIX表示可移植操作系統接口(PortableOperatingSystemInterface)

POSIX是在Unix標準化過程中出現的產物。

POSIX1003.1標準定義了一個最小的Unix操作系統接口

任何操作系統只有符合這一標準,才有可能運行Unix程序

<>Linux的肥沃土壤-GNUGNU是GNUIsNotUnix的遞歸縮寫,是自由軟件基金會的一個項目

GNU項目產品包括emacs編輯器、著名的GNUC和Gcc編譯器等,這些軟件叫做GNU軟件。GNU軟件和派生工作均適用GNU通用公共許可證,即GPL(GeneralPublicLicense

)Linux的開發使用了眾多的GUN工具<>GPL-開源軟件的法律GPL允許軟件作者擁有軟件版權但GPL規定授予其他任何人以合法復制、發行和修改軟件的權利。<>Linux系統或發布版

符合POSIX標準的操作系統內核、Shell和外圍工具。C語言編譯器和其他開發工具及函數庫XWindow窗口系統各種應用軟件,包括字處理軟件、圖象處理軟件等。<>開放與協作的開發模式

世界各地軟件愛好者集體智慧的結晶提供源代碼,遵守GPL。經歷了各種各樣的測試與考驗,軟件的穩定性好。開發人員憑興趣去開發,熱情高,具有創造性。<>Linux內核

Linus領導下的開發小組開發出的系統內核

是所有Linux發布版本的核心

內核開發人員一般在百人以上,任何自由程序員都可以提交自己的修改工作。

采用郵件列表來進行項目管理、交流、錯誤報告有大量的用戶進行測試,正式發布的代碼質量高

<>Linux內核的技術特點

linux內核被設計成單內核結構,這是相對微內核而言的

2.6版本以前的linux內核是單線程結構,是非搶占式的內核結構linux內核支持動態加載內核模塊

Linux內核被動地提供服務linux內核采用了虛擬內存技術,使得內存空間達到4GBlinux文件系統實現了一種UNIX風格的抽象文件模型——虛擬文件系統(VirtualFilesystermSwitch,VFS)linux提供了一套很有效的延遲機制——下半部分、軟中斷tasklet和2.6版本新引進的工作隊列等。<>整個系統的核心-內核

硬件系統調用接口應用程序進程1應用程序進程2應用程序進程3Linux內核用戶進程

內核子系統系統調用<>整個系統的核心-內核

用戶進程—運行在Linux內核之上的一個龐大軟件集合。系統調用—內核的出口,用戶程序通過它使用內核提供的功能。

Linux內核—操作系統的靈魂,負責管理磁盤上的文件、內存,負責啟動并運行程序,負責從網絡上接收和發送數據包等等。硬件—包括了Linux安裝時需要的所有可能的物理設備。例如,CPU、內存、硬盤、網絡硬件等等。<>內核子系統<>內核子系統進程調度-控制著進程對CPU的訪問。內存管理-允許多個進程安全地共享主內存區域虛擬文件系統-隱藏各種不同硬件的具體細節,為所有設備提供統一的接口。網絡-提供了對各種網絡標準協議的存取和各種網絡硬件的支持。進程間通信(IPC)-支持進程間各種通信機制,包括共享內存、消息隊列及管道等。Linux內核版本樹

0.01

Linux(第一版)

0.13版

|

產品化版本

實驗版本

1.0.0

1.1.0(1.0.0的拷貝)

1.0.X(修改)

1.1.X(增加新功能,進行測試)

1.1.95(成為1.2.0)內核源代碼結構Linux內核源代碼分析工具

Linux超文本交叉代碼檢索工具

http://lxr.linux.no/

Windows平臺下的源代碼閱讀工具SourceInsightLinux內核模塊編程入門

認識內核模塊

內核模塊是linux內核向外部提供的一個插口,是內核的一部分,但是并沒有被編譯到內核里面去,其全稱為動態可加載內核模塊(LoadableKernelModule,LKM),簡稱模塊。為什么要使用模塊?

linux內核之所以提供模塊機制,是因為它本身是一個單內核。而單內核的最大優點就是效率高,因為所有的內容都集成在一起,但其缺點是可擴展性和可維護性相對較差,模塊機制就是為了彌補這一缺陷。Linux內核模塊編程入門

模塊的定義

模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。它在運行時被鏈接到內核作為內核的一部分在內核空間運行,這與運行在用戶空間的進程是不同的。模塊通常由一組函數和數據結構組成,用來實現一種文件系統、一個驅動程序或者其他內核上層的功能。編寫簡單的內核模塊

模塊和內核都在內核空間運行,模塊編程在一定意義上說就是內核編程。一個內核模塊應該至少有兩個函數,第一個為module_init(),是模塊加載函數,當模塊被插入到內核時調用它;第二個為module_exit(),是模塊卸載函數,當模塊從內核移走時調用它。Linux內核模塊編程入門

簡單的內核模塊實例:

任何模塊都要包含的三個頭文件:#include<linux/module.h>#include<linux/kernel.h>#incldue<linux/init.h>說明:module.h頭文件包含了對模塊的版本控制;kernel.h包含了常用的內核函數;init.h包含了宏__init和__exit,宏__init告訴編譯程序相關的函數和變量僅用于初始化,編譯程序將標有__init的所有代碼存儲到特殊的內存段中,初始化結束就釋放這段內存。在此使用了printk()函數,該函數是由內核定義的,功能和C庫中的printf()類似,它把要打印的日志輸出到終端或系統日志。字符串中的<1>是輸出的級別,表示立即在終端輸出。Linux內核模塊編程入門

內核模塊的Makefile文件

內核模塊不是獨立的可執行文件,但在運行時其目標文件被鏈接到內核中。只有超級用戶才能加載和卸載模塊。給前面的程序起名叫module_example.c,那么其對應的Makefile文件的基本內容如下:obj-m:=這個賦值語句的含義是說明要使用目標文件module_example.o建立一個模塊,最后生成的模塊名為module_example.ko。.o文件是經過編譯和匯編,而沒有經過鏈接的中間文件。注:makefile文件中,若某一行是命令,則它必須以一個Tab鍵開頭。Linux內核模塊編程入門

運行代碼當編譯好模塊,就可以用insmod命令將新的模塊插入到內核中,如:

insmodmodule_example.ko然后,可以用lsmod命令查看模塊是否正確地插入到了內核中。模塊的輸出由printk()產生。該函數默認打印系統文件/var/log/messages的內容。卸載模塊時,使用rmmod命令加上在insmod中看到的模塊名,就可以從內核中移除該模塊:

rmmodmodule_exampleLinux內核模塊編程入門

應用程序與內核模塊的比較

C語言應用程序內核模塊程序使用函數Libc庫內核函數運行空間用戶空間內核空間運行權限普通用戶超級用戶入口函數main()module_init()出口函數exit()module_cleanup()編譯gcc–cmake連接gccinsmod運行直接運行insmod調試gdbkdbug,kdb,kgdb等Linux內核中鏈表的實現及應用為什么要用鏈表?①與數組相比,鏈表中可以動態插入或刪除元素,在編譯時不必知道要創建的元素個數。②在內存無需占用連續的內存單元。③每個元素都包含一個指向下一個元素的指針,當有元素加入鏈表或者從鏈表中刪除元素時,只需要調整下一個節點的指針就可以了。Linux內核中鏈表的實現及應用通過前趨(prev)和后繼(next)兩個指針域,就可以從兩個方向遍歷雙鏈表,這使得遍歷鏈表的代價減少。鏈表的演化

在C語言中,一個基本的雙向鏈表定義如下:structmy_list{ void*mydata; structmy_list*next; structmy_list*prev; };Linux內核中鏈表的實現及應用鏈表的定義linux內核對鏈表的實現方式與眾不同,不是在鏈表中包含數據,而是在數據結構中包含鏈表。其具體的定義如下:

structlist_head{

structlist_head*next,*prev;

};這個不含數據結構的通用雙向鏈表可以嵌入到任何結構中。說明:1.list域隱藏了鏈表的指針特性2.structlist_head可以位于結構的任何位置,可以給其起任何名字3.在一個結構中可以有多個list域

以structlist_head為基本對象,可以對鏈表進行插入、刪除、合并以及遍歷等各種操作。

Linux內核中鏈表的實現及應用鏈表的聲明和初始化structlist_head只定義了鏈表節點,并沒有專門定義鏈表頭,那么一個鏈表結構是如何建立起來的?內核代碼list.h中定義了兩個宏:#defineLIST_HEAD_INIT(name){&(name),&(name)}/*僅初始化*/#defineLIST_HEAD(name)structlist_headname= LIST_HEAD_INIT(name)

/*聲明并初始化*/

當我們調用LIST_HEAD(name)聲明一個名為name的鏈表頭時,它的next和prev指針都初始化指向自己。這樣,我們就有了一個空鏈表,因為linux用頭指針的next是否指向自己來判斷鏈表是否為空:staticinlineintlist_empty(conststructlist_head*head){

returnhead->next==head;}Linux內核中鏈表的實現及應用在鏈表中增加一個節點在include/linux/list.h中增加結點的函數為:

staticinlinevoidlist_add();staticinlinevoidlist_add_tail();

在內核代碼中,函數名前加兩個下劃線表示內部函數。list_add()和list_add_tail()均調用__list_add()真正實現頭插和尾插。staticinlinevoid__list_add(structlist_head*new,structlist_head*prev,structlist_head*next){next->prev=new;new->next=next;new->prev=prev;prev->next=new;}staticinlinevoidlist_add(structlist_head*new,

structlist_head*head){__list_add(new,head,head->next);}該函數向指定鏈表的head結點后插入new結點。因為是循環鏈表,而且通常沒有首尾結點的概念,所以可以將任何結點傳給head。若傳最后一個元素給head,該函數就可以實現一個棧。Linux內核中鏈表的實現及應用

list_add_tail()的內核實現:

staticinlinevoidlist_add_tail(structlist_head*new,structlist_head*head){__list_add(new,head->prev,head);}

list_add_tail()函數向指定鏈表的head結點前插入new結點。說明:關于staticinline關鍵字。

“static”加在函數前,表示這個函數是靜態函數,所謂靜態函數,實際上是對函數作用域的限制,指該函數的作用域僅局限于本文件。所以說,static具有信息隱藏的作用。而關鍵字"inline“加在函數前,說明這個函數對編譯程序是可見的,也就是說編譯程序在調用這個函數時就立即展開該函數。Linux內核中鏈表的實現及應用

鏈表的遍歷

這種鏈表只是找到了一個個結點在鏈表中的偏移位置pos,如下圖(a)。那么如何通過pos獲得結點的起始地址,從而可以引用結點中的域呢?(a)(b)list.h中定義了晦澀難懂的list_entry()宏:#definelist_entry(ptr,type,member)\

((type*)(

溫馨提示

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

評論

0/150

提交評論