我的理解,虛擬文件系統其實就是 通用文件操作的統一API介面,因為LINUX支持很多文件系版統,他不可能為權每個文件系統都設計一個API介面,這樣,LINUX累,運行在LINUX上的程序更累,所以LINUX為了簡化操作,就設計的通用API介面(專業術語,就是虛擬文件系統),這樣程序不必關心,運行在LINUX上的是哪個文件系統,就對程序透明了,而具體的文件系統操作,有LINUXn內核完成就說這么多了,不懂可以再問O(∩_∩)O~
⑵ linux基本原理
計算機體系結構:運算器 控制器 存儲器 輸入設備 輸出設備
詳解:存儲即內存:編址的存儲單元。即每一個存儲單元在都有一個編址。
控制器告訴運算器加數在存儲器的哪個存儲單元。
poll:(拉的機制)CPU不停地查看誰發生的電信號
interrupt:(中斷,即硬體通知機制)敲完鍵盤:鍵盤會通知CPU,CPU就來看看鍵盤幹了什麼事。
CPU通過控制晶元知道是哪個設備發出的信號。一根線上有不同的設備。
為了充分利用CPU,多任務利用,(想第一件事10秒,想第二件事10秒,然後接著想第一件事。那麼第一件事的10秒記憶存儲在內存中)。那麼就需要劃分了,cpu被切分為一個個slice。內存分成多個段。這都是由操作系統完成的。
32位操作系統:最多物理內存2^
程序:放在操作系統上,只要不刪就一直存在。執行入口,進程:是有生命周期的,一定時間過後就消失。
.庫:一堆的程序,自己不能獨立執行,只提供調用介面,可被程序調用執行。
操作系統:有了操作系統之後,任何一個進程要跟硬體打交道,都得經過操作系統。操作系統通過最底層的調用:system call(系統調用)。然後封裝之後,形成了庫。
shell:人機交互介面
⑶ Linux操作系統的主要組成部分是什麼
Linux系統
一般有4個主要部分:內核、shell、文件系統和應用程序。內核、shell和文件系統一起形成了基本的
操作系統結構
,它們使得用戶可以運行程序、管理文件並使用系統。
一.
Linux內核
內核是操作系統的核心,具有很多最基本功能,如
虛擬內存
、多任務、共享庫、需求載入、
可執行程序
和TCP/
IP網路
功能。Linux內核的模塊分為以下幾個部分:
存儲管理
、CPU和
進程管理
、文件系統、設備管理和驅動、網路通信、系統的初始化和
系統調用
等。
二.Linux
shell
shell是系統的用戶界面,提供了用戶與內核進行交互操作的一種介面。它接收用戶輸入的命令並把它送入內核去執行,是一個命令
解釋器
。另外,
shell編程
語言具有普通編程語言的很多特點,用這種編程語言編寫的
shell程序
與其他應用程序具有同樣的效果。
三.
Linux文件系統
文件系統是文件存放在磁碟等存儲設備上的組織方法。Linux系統能支持多種目前流行的文件系統,如
EXT2
、
EXT3
、FAT、
FAT32
、VFAT和
ISO9660
。
四.Linux應用程序
標準的Linux系統一般都有一套都有稱為應用程序的
程序集
,它包括
文本編輯器
、編程語言、XWindow、
辦公套件
、Internet工具和資料庫等。
⑷ Linux系統I/O模型及select、poll、epoll原理和應用
理解Linux的IO模型之前,首先要了解一些基本概念,才能理解這些IO模型設計的依據
操作系統使用虛擬內存來映射物理內存,對於32位的操作系統來說,虛擬地址空間為4G(2^32)。操作系統的核心是內核,為了保護用戶進程不能直接操作內核,保證內核安全,操作系統將虛擬地址空間劃分為內核空間和用戶空間。內核可以訪問全部的地址空間,擁有訪問底層硬體設備的許可權,普通的應用程序需要訪問硬體設備必須通過 系統調用 來實現。
對於Linux系統來說,將虛擬內存的最高1G位元組的空間作為內核空間僅供內核使用,低3G位元組的空間供用戶進程使用,稱為用戶空間。
又被稱為標准I/O,大多數文件系統的默認I/O都是緩存I/O。在Linux系統的緩存I/O機制中,操作系統會將I/O的數據緩存在頁緩存(內存)中,也就是數據先被拷貝到內核的緩沖區(內核地址空間),然後才會從內核緩沖區拷貝到應用程序的緩沖區(用戶地址空間)。
這種方式很明顯的缺點就是數據傳輸過程中需要再應用程序地址空間和內核空間進行多次數據拷貝操作,這些操作帶來的CPU以及內存的開銷是非常大的。
由於Linux系統採用的緩存I/O模式,對於一次I/O訪問,以讀操作舉例,數據先會被拷貝到內核緩沖區,然後才會從內核緩沖區拷貝到應用程序的緩存區,當一個read系統調用發生的時候,會經歷兩個階段:
正是因為這兩個狀態,Linux系統才產生了多種不同的網路I/O模式的方案
Linux系統默認情況下所有socke都是blocking的,一個讀操作流程如下:
以UDP socket為例,當用戶進程調用了recvfrom系統調用,如果數據還沒准備好,應用進程被阻塞,內核直到數據到來且將數據從內核緩沖區拷貝到了應用進程緩沖區,然後向用戶進程返回結果,用戶進程才解除block狀態,重新運行起來。
阻塞模行下只是阻塞了當前的應用進程,其他進程還可以執行,不消耗CPU時間,CPU的利用率較高。
Linux可以設置socket為非阻塞的,非阻塞模式下執行一個讀操作流程如下:
當用戶進程發出recvfrom系統調用時,如果kernel中的數據還沒准備好,recvfrom會立即返回一個error結果,不會阻塞用戶進程,用戶進程收到error時知道數據還沒准備好,過一會再調用recvfrom,直到kernel中的數據准備好了,內核就立即將數據拷貝到用戶內存然後返回ok,這個過程需要用戶進程去輪詢內核數據是否准備好。
非阻塞模型下由於要處理更多的系統調用,因此CPU利用率比較低。
應用進程使用sigaction系統調用,內核立即返回,等到kernel數據准備好時會給用戶進程發送一個信號,告訴用戶進程可以進行IO操作了,然後用戶進程再調用IO系統調用如recvfrom,將數據從內核緩沖區拷貝到應用進程。流程如下:
相比於輪詢的方式,不需要多次系統調用輪詢,信號驅動IO的CPU利用率更高。
非同步IO模型與其他模型最大的區別是,非同步IO在系統調用返回的時候所有操作都已經完成,應用進程既不需要等待數據准備,也不需要在數據到來後等待數據從內核緩沖區拷貝到用戶緩沖區,流程如下:
在數據拷貝完成後,kernel會給用戶進程發送一個信號告訴其read操作完成了。
是用select、poll等待數據,可以等待多個socket中的任一個變為可讀,這一過程會被阻塞,當某個套接字數據到來時返回,之後再用recvfrom系統調用把數據從內核緩存區復制到用戶進程,流程如下:
流程類似阻塞IO,甚至比阻塞IO更差,多使用了一個系統調用,但是IO多路復用最大的特點是讓單個進程能同時處理多個IO事件的能力,又被稱為事件驅動IO,相比於多線程模型,IO復用模型不需要線程的創建、切換、銷毀,系統開銷更小,適合高並發的場景。
select是IO多路復用模型的一種實現,當select函數返回後可以通過輪詢fdset來找到就緒的socket。
優點是幾乎所有平台都支持,缺點在於能夠監聽的fd數量有限,Linux系統上一般為1024,是寫死在宏定義中的,要修改需要重新編譯內核。而且每次都要把所有的fd在用戶空間和內核空間拷貝,這個操作是比較耗時的。
poll和select基本相同,不同的是poll沒有最大fd數量限制(實際也會受到物理資源的限制,因為系統的fd數量是有限的),而且提供了更多的時間類型。
總結:select和poll都需要在返回後通過輪詢的方式檢查就緒的socket,事實上同時連的大量socket在一個時刻只有很少的處於就緒狀態,因此隨著監視的描述符數量的變多,其性能也會逐漸下降。
epoll是select和poll的改進版本,更加靈活,沒有描述符限制。epoll使用一個文件描述符管理多個描述符,將用戶關系的文件描述符的事件存放到內核的一個事件表中,這樣在用戶空間和內核空間的只需一次。
epoll_create()用來創建一個epoll句柄。
epoll_ctl() 用於向內核注冊新的描述符或者是改變某個文件描述符的狀態。已注冊的描述符在內核中會被維護在一棵紅黑樹上,通過回調函數內核會將 I/O 准備好的描述符加入到一個就緒鏈表中管理。
epoll_wait() 可以從就緒鏈表中得到事件完成的描述符,因此進程不需要通過輪詢來獲得事件完成的描述符。
當epoll_wait檢測到描述符IO事件發生並且通知給應用程序時,應用程序可以不立即處理該事件,下次調用epoll_wait還會再次通知該事件,支持block和nonblocking socket。
當epoll_wait檢測到描述符IO事件發生並且通知給應用程序時,應用程序需要立即處理該事件,如果不立即處理,下次調用epoll_wait不會再次通知該事件。
ET模式在很大程度上減少了epoll事件被重復觸發的次數,因此效率要比LT模式高。epoll工作在ET模式的時候,必須使用nonblocking socket,以避免由於一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。
【segmentfault】 Linux IO模式及 select、poll、epoll詳解
【GitHub】 CyC2018/CS-Notes
⑸ Linux基礎命令和原理總結
作為一個程序員或者測試開發人員,我們在進行項目部署和運維時,經常會用到一些linux命令,可是這些命令老是忘記,每次用到的時候都要去谷歌網路,很是麻煩!這不,為了自己使用方便,對常見的linux命令, SHELL, VIM, Linux性能調優和linux kernel的總結,以便在用到時能夠快速地找到相關命令,同時有需要的朋友也可以參考搜藏該篇文章!文章對講到的每個命令都有詳細的參數解釋,並且給出一些常用例子,因此也非常適合用來學習!
shell(命令解釋器)自帶的命令稱為內部命令,其它的是外部命令
內部命令使用help幫助:help cd
外部命令使用help幫助:ls --help
type命令:用於區分是內部命令還是外部命令:
ls is aliased to `ls --color=auto' #外部命令
cd is a shell builtin #內部命令
pwd命令:顯示當前目錄
ls命令:查看目錄和文件名稱
ls -l 查看目錄各個欄位含義
第一欄位:首字母代表的是文件類型 ,其中"-"為普通文件、"d"為目錄文件、"c"為字元設備文件、"b"為塊設備文件、"p"為管道文件、"l"為鏈接文件、"s"為socket文件。「rwx」分別代表擁有讀、寫和執行許可權,"-代表無對應許可權。三個"rwx"依次代表文件所有者、文件所有者所在用戶組、其它用戶對文件擁有的許可權。
第二欄位:文件硬連接數量
第三欄位:文件擁有者
第四欄位:文件擁有者所在組
第五欄位:文件大小(以位元組為單位)
第六欄位:文件最後更改時間
第七欄位:文件名(若為鏈接文件則追加顯示其鏈接的原文件的路徑)
ls命令其它參數含義:
-a顯示隱藏文件(.開頭的文件)
-r逆序排序
-t按照時間順序顯示
-R遞歸顯示
ls -lartR : 按照時間順序倒序顯示所有文件及其文件夾的文件
cd命令:更改當前的工作目錄
cd /path/... 絕對路徑
cd ./path/... 相對路徑(./可以省略)
cd ../path/... 相對路徑
mkdir -p 遞歸目錄:遞歸創建目錄
rmdir命令:刪除目錄
rmdir a/b/c/d/e/ #刪除空目錄
rm -r a/b/c/d/ #遞歸刪除目錄,但是系統會做多次詢問
rm -rf a/b/c/d/ #刪除目錄,不做任何詢問
cp命令:復制文件和目錄
-r 復制目錄
-p 保留用戶、許可權、時間等文件屬性
mv命令:移動文件和重命名
mv *.log 目標目錄
通配符:
*匹配任何字元串
?匹配一個字元串
[xyz]任何一個字元串
[a-z]匹配一個范圍
cat命令:文本內容顯示到終端
head命令:查看文件開頭
head -3 文件名稱 #顯示文件開頭3行
tail命令:查看文件末尾
tail -3 文件名稱 #顯示文件末尾3行
tail常用參數-f,文件內容更新後,同步顯示更新的文件信息
tail -f 文件名稱
wc命令:統計文件內容信息
wc 文件名稱
useradd命令:新建用戶
useradd 用戶名
userdel命令:刪除用戶
userdel 用戶名 用戶所在的家目錄不會被刪除
userdel -r 用戶名 用戶相關的所有配置都會被刪除
passwd命令:修改用戶密碼
passwd 用戶名
usermod命令:修改用戶屬性
/etc/passwd文件:查看用戶文件
tail /etc/passwd
/etc/shadow文件:查看用戶密碼
tail /etc/shadow
groupadd命令:添加用戶組
groupadd 用戶組
groupdel命令:刪除用戶組
groupdel 用戶組
用戶切換
su 用戶名 切換用戶,但是用戶所在環境不變,即pwd路徑不會變化
su - 用戶名 切換用戶,同時會切換到用戶家目錄,即/home/用戶名
sudo命令:普通用戶需要執行root用戶許可權的解決方案。
以下是一些常用命令匯總;The following table provides a reminder of most of the commands that we have covered so far. If you include the three, as-yet-unmentioned, commands in the last column, then you will probably be able to achieve >95% of everything that you will ever want to do in Unix (remember, you can use the man command to find out more about top , ps , and kill ). The power comes from how you can use combinations of these commands.
-c 'cc-address' -b 'bcc-address'
'to-address' | Command to send email | | mail -s "Subject"
to-address < Filename` | Command to send email with attachment |
File Permission commands
Hope this Linux reference guide helps you!
希望這些常用的命令和系統原理,以及linux操作可以幫助大家提升linux命令和操作!!!
⑹ Linux下的shell工作原理是什麼
Linux系統的shell作為操作系統的外殼,為用戶提供使用操作系統的介面。它是命令語言、命令解釋程序及程序設計語言的統稱。
shell是用戶和Linux內核之間的介面程序,如果把Linux內核想像成一個球體的中心,shell就是圍繞內核的外層。當從shell或其他程序向Linux傳遞命令時,內核會做出相應的反應。
shell是一個命令語言解釋器,它擁有自己內建的shell命令集,shell也能被系統中其他應用程序所調用。用戶在提示符下輸入的命令都由shell先解釋然後傳給Linux核心。
有一些命令,比如改變工作目錄命令cd,是包含在shell內部的。還有一些命令,例如拷貝命令cp和移動命令rm,是存在於文件系統中某個目錄下的單獨的程序。對用戶而言,不必關心一個命令是建立在shell內部還是一個單獨的程序。
shell首先檢查命令是否是內部命令,若不是再檢查是否是一個應用程序(這里的應用程序可以是Linux本身的實用程序,如ls和rm,也可以是購買的商業程序,如xv,或者是自由軟體,如emacs)。然後shell在搜索路徑里尋找這些應用程序(搜索路徑就是一個能找到可執行程序的目錄列表)。如果鍵入的命令不是一個內部命令並且在路徑里沒有找到這個可執行文件,將會顯示一條錯誤信息。如果能夠成功找到命令,該內部命令或應用程序將被分解為系統調用並傳給Linux內核。
shell的另一個重要特性是它自身就是一個解釋型的程序設計語言,shell程序設計語言支持絕大多數在高級語言中能見到的程序元素,如函數、變數、數組和程序控制結構。shell編程語言簡單易學,任何在提示符中能鍵入的命令都能放到一個可執行的shell程序中。
當普通用戶成功登錄,系統將執行一個稱為shell的程序。正是shell進程提供了命令行提示符。作為默認值(TurboLinux系統默認的shell是BASH),對普通用戶用「$」作提示符,對超級用戶(root)用「#」作提示符。
一旦出現了shell提示符,就可以鍵入命令名稱及命令所需要的參數。shell將執行這些命令。如果一條命令花費了很長的時間來運行,或者在屏幕上產生了大量的輸出,可以從鍵盤上按ctrl+c發出中斷信號來中斷它(在正常結束之前,中止它的執行)。
當用戶准備結束登錄對話進程時,可以鍵入logout命令、exit命令或文件結束符(EOF)(按ctrl+d實現),結束登錄。
⑺ linux驅動程序結構框架及工作原理分別是什麼
一、Linux device driver 的概念
系統調用是操作系統內核和應用程序之間的介面,設備驅動程序是操作系統內核和機器硬體之間的介面。設備驅動程序為應用程序屏蔽了硬體的細節,這樣在應用程序看來,硬體設備只是一個設備文件,應用程序可以象操作普通文件一樣對硬體設備進行操作。設備驅動程序是內核的一部分,它完成以下的功能:
1、對設備初始化和釋放;
2、把數據從內核傳送到硬體和從硬體讀取數據;
3、讀取應用程序傳送給設備文件的數據和回送應用程序請求的數據;
4、檢測和處理設備出現的錯誤。
在Linux操作系統下有三類主要的設備文件類型,一是字元設備,二是塊設備,三是網路設備。字元設備和塊設備的主要區別是:在對字元設備發出讀/寫請求時,實際的硬體I/O一般就緊接著發生了,塊設備則不然,它利用一塊系統內存作緩沖區,當用戶進程對設備請求能滿足用戶的要求,就返回請求的數據,如果不能,就調用請求函數來進行實際的I/O操作。塊設備是主要針對磁碟等慢速設備設計的,以免耗費過多的CPU時間來等待。
已經提到,用戶進程是通過設備文件來與實際的硬體打交道。每個設備文件都都有其文件屬性(c/b),表示是字元設備還是塊設備?另外每個文件都有兩個設備號,第一個是主設備號,標識驅動程序,第二個是從設備號,標識使用同一個設備驅動程序的不同的硬體設備,比如有兩個軟盤,就可以用從設備號來區分他們。設備文件的的主設備號必須與設備驅動程序在登記時申請的主設備號一致,否則用戶進程將無法訪問到驅動程序。
最後必須提到的是,在用戶進程調用驅動程序時,系統進入核心態,這時不再是搶先式調度。也就是說,系統必須在你的驅動程序的子函數返回後才能進行其他的工作。如果你的驅動程序陷入死循環,不幸的是你只有重新啟動機器了,然後就是漫長的fsck。
二、實例剖析
我們來寫一個最簡單的字元設備驅動程序。雖然它什麼也不做,但是通過它可以了解Linux的設備驅動程序的工作原理。把下面的C代碼輸入機器,你就會獲得一個真正的設備驅動程序。
由於用戶進程是通過設備文件同硬體打交道,對設備文件的操作方式不外乎就是一些系統調用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系統調用和驅動程序關聯起來呢?這需要了解一個非常關鍵的數據結構:
STruct file_operatiONs {
int (*seek) (struct inode * ,struct file *, off_t ,int);
int (*read) (struct inode * ,struct file *, char ,int);
int (*write) (struct inode * ,struct file *, off_t ,int);
int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);
int (*select) (struct inode * ,struct file *, int ,select_table *);
int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);
int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);
int (*open) (struct inode * ,struct file *);
int (*release) (struct inode * ,struct file *);
int (*fsync) (struct inode * ,struct file *);
int (*fasync) (struct inode * ,struct file *,int);
int (*check_media_change) (struct inode * ,struct file *);
int (*revalidate) (dev_t dev);
}
這個結構的每一個成員的名字都對應著一個系統調用。用戶進程利用系統調用在對設備文件進行諸如read/write操作時,系統調用通過設備文件的主設備號找到相應的設備驅動程序,然後讀取這個數據結構相應的函數指針,接著把控制權交給該函數。這是linux的設備驅動程序工作的基本原理。既然是這樣,則編寫設備驅動程序的主要工作就是編寫子函數,並填充file_operations的各個域。
下面就開始寫子程序。
#include <linux/types.h> 基本的類型定義
#include <linux/fs.h> 文件系統使用相關的頭文件
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/segment.h>
unsigned int test_major = 0;
static int read_test(struct inode *inode,struct file *file,char *buf,int count)
{
int left; 用戶空間和內核空間
if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )
return -EFAULT;
for(left = count ; left > 0 ; left--)
{
__put_user(1,buf,1);
buf++;
}
return count;
}
這個函數是為read調用准備的。當調用read時,read_test()被調用,它把用戶的緩沖區全部寫1。buf 是read調用的一個參數。它是用戶進程空間的一個地址。但是在read_test被調用時,系統進入核心態。所以不能使用buf這個地址,必須用__put_user(),這是kernel提供的一個函數,用於向用戶傳送數據。另外還有很多類似功能的函數。請參考,在向用戶空間拷貝數據之前,必須驗證buf是否可用。這就用到函數verify_area。為了驗證BUF是否可以用。
static int write_test(struct inode *inode,struct file *file,const char *buf,int count)
{
return count;
}
static int open_test(struct inode *inode,struct file *file )
{
MOD_INC_USE_COUNT; 模塊計數加以,表示當前內核有個設備載入內核當中去
return 0;
}
static void release_test(struct inode *inode,struct file *file )
{
MOD_DEC_USE_COUNT;
}
這幾個函數都是空操作。實際調用發生時什麼也不做,他們僅僅為下面的結構提供函數指針。
struct file_operations test_fops = {?
read_test,
write_test,
open_test,
release_test,
};
設備驅動程序的主體可以說是寫好了。現在要把驅動程序嵌入內核。驅動程序可以按照兩種方式編譯。一種是編譯進kernel,另一種是編譯成模塊(moles),如果編譯進內核的話,會增加內核的大小,還要改動內核的源文件,而且不能動態的卸載,不利於調試,所以推薦使用模塊方式。
int init_mole(void)
{
int result;
result = register_chrdev(0, "test", &test_fops); 對設備操作的整個介面
if (result < 0) {
printk(KERN_INFO "test: can't get major number\n");
return result;
}
if (test_major == 0) test_major = result; /* dynamic */
return 0;
}
在用insmod命令將編譯好的模塊調入內存時,init_mole 函數被調用。在這里,init_mole只做了一件事,就是向系統的字元設備表登記了一個字元設備。register_chrdev需要三個參數,參數一是希望獲得的設備號,如果是零的話,系統將選擇一個沒有被佔用的設備號返回。參數二是設備文件名,參數三用來登記驅動程序實際執行操作的函數的指針。
如果登記成功,返回設備的主設備號,不成功,返回一個負值。
void cleanup_mole(void)
{
unregister_chrdev(test_major,"test");
}
在用rmmod卸載模塊時,cleanup_mole函數被調用,它釋放字元設備test在系統字元設備表中佔有的表項。
一個極其簡單的字元設備可以說寫好了,文件名就叫test.c吧。
下面編譯 :
$ gcc -O2 -DMODULE -D__KERNEL__ -c test.c –c表示輸出制定名,自動生成.o文件
得到文件test.o就是一個設備驅動程序。
如果設備驅動程序有多個文件,把每個文件按上面的命令行編譯,然後
ld ?-r ?file1.o ?file2.o ?-o ?molename。
驅動程序已經編譯好了,現在把它安裝到系統中去。
$ insmod ?–f ?test.o
如果安裝成功,在/proc/devices文件中就可以看到設備test,並可以看到它的主設備號。要卸載的話,運行 :
$ rmmod test
下一步要創建設備文件。
mknod /dev/test c major minor
c 是指字元設備,major是主設備號,就是在/proc/devices里看到的。
用shell命令
$ cat /proc/devices
就可以獲得主設備號,可以把上面的命令行加入你的shell script中去。
minor是從設備號,設置成0就可以了。
我們現在可以通過設備文件來訪問我們的驅動程序。寫一個小小的測試程序。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
int testdev;
int i;
char buf[10];
testdev = open("/dev/test",O_RDWR);
if ( testdev == -1 )
{
printf("Cann't open file \n");
exit(0);
}
read(testdev,buf,10);
for (i = 0; i < 10;i++)
printf("%d\n",buf[i]);
close(testdev);
}
編譯運行,看看是不是列印出全1
以上只是一個簡單的演示。真正實用的驅動程序要復雜的多,要處理如中斷,DMA,I/O port等問題。這些才是真正的難點。上述給出了一個簡單的字元設備驅動編寫的框架和原理,更為復雜的編寫需要去認真研究LINUX內核的運行機制和具體的設備運行的機制等等。希望大家好好掌握LINUX設備驅動程序編寫的方法。
⑻ 實驗五 Linux操作系統是如何工作的
操作系統工作的基礎:
1、存儲程序計算機
馮.諾伊曼首先提出了「存儲程序」的概念,按照存儲程序的原理,計算機在執行程序時須先將要執行的相關程序和數據放入內存儲器中,在執行程序時CPU根據當前程序指針寄存器的內容,按地址順序取出存放在內存儲器中的指令(按地址順序訪問指令),然後分析指令,執行指令的功能,遇到轉移指令時,則轉移到轉移地址,再按地址順序訪問指令(程序控制)。linux操作系統就是以存儲程序計算機的工作原理為基礎去管理整個計算機以及整個計算機的執行工作流程。
存儲程序計算機以運算單元為中心, 採用存儲程序原理,存儲器是按地址訪問、線性編址的空間,控制流由指令流產生, 指令由操作碼和地址碼組成,數據以二進制編碼。(維基網路)
2、堆棧
堆棧(此處不同於數據結構的中堆棧)是內存中的一段存儲區域。堆棧用到的寄存器主要有%esp和%ebp,c語言中堆棧機制主要用於函數調用中上一層函數相關寄存器(包括堆棧相關寄存器,eip寄存器等)的保存,以便從調用函數返回至上一層函數,堆棧還會保存調用函數的參數以及函數中創建的局部變數。
操作系統中的堆棧分為用戶態堆棧和內核態堆棧,而程序的執行又是以進程為單位來執行的,操作系統使每個進程有各自獨立的4G地址空間,0~3G為用戶態,3G~4G為內核態,Linux為每個進程分配一個8KB大小的內存區域,用於存放該進程兩個不同的數據結構:Thread_info和進程內核堆棧。當我們進行系統調用或其他中斷時內核棧會保存用戶棧的寄存器信息以及返回地址等信息,當內核進行進程調度切換上下文時堆棧會保存前一個進程的上下文,再載入下一進程的上下文。
3、中斷
中斷機制最初是未解決計算機和外設的處理速度不匹配問題,為了提高cpu的工作效率,操作系統引入中斷機制。
處理器的速度跟外圍硬體設備的速度往往不在一個數量級上,因此,如果內核採取讓處理器向硬體發出一個請求,然後專門等待回應的辦法,顯然降低內核效率。中斷可以讓內核不用等待硬體響應,而是去執行其他事務進程,當硬體處理完畢,通過中斷告知CPU硬體數據准備好,CPU再切換來處理此硬體事務。
不同的設備對應的中斷不同,而每個中斷都通過一個惟一的數字標識,即中斷號。從而使得操作系統能夠對中斷進行區分,並知道哪個硬體設備產生了哪個中斷。這樣,操作系統才能給不同的中斷提供不同的中斷處理程序。
中斷使得進程能夠並發的去執行,當然,並發並不是並行,而是中斷允許CPU在多個進程之間切換,大大提高了CPU的利用率。中斷是多進程能夠正常執行以及進程間的切換的必不可少的要素。