24小時學通Linux核心之如何處理輸入輸出操作

2022-03-20 11:35:12 字數 3350 閱讀 1903

24小時學通linux核心之如何處理輸入輸出操作

真的是悲喜交加呀,本來這個寒假早上8點都去練車,兩個小時之後再來實驗室陪伴linux核心,但是今天教練說沒名額考試了,好糾結,不過想想就可以睡懶覺了,哈哈,自從大三寒假以來還沒睡過懶覺呢,現在也有更多的時間來分享自己學習linux核心的感受,前幾天覺得就是自己也有些不懂的,相信大家看了也是很模糊,以後我會標誌出來自己不懂的,希望大神們指教,也希望大家多多指點,共同攻克linux核心,今天將講到處理器是如何與其它裝置進行互動的,核心又是如何響應和控制這些互動的,今天內容不多但是很關鍵,寫的不好希望大家批評,純手打。

linux核心是如何將軟硬體結合起來的呢?這裡我們將一起**核心與周圍硬體主要是檔案io和硬體裝置之間的關係,來解釋這個問題。處理器與周圍裝置的通訊依賴於一系列的電路電線,匯流排就是具有類似功能的電線,裝置與處理器通訊主要是通過位址匯流排,資料匯流排,控制匯流排來實現,這裡在學習微控制器原理的時候也提到過,這裡對系統的基本結構就不多說了,覺得更新快,不好講解,也沒什麼好總結的,大家看看相關書籍就行。了解到裝置可以當做檔案系統中的檔案來處理,其細節都可隱藏在核心中,而對應用程式設計師透明,當程序對裝置檔案應用某一系統呼叫的時候,只要將這一系統呼叫轉換成某種裝置函式就足夠了,其中裝置驅動程式定義了這些函式,接下來看看這些裝置型別。其中應用層,檔案系統層,通用塊裝置層和裝置驅動程式之間的關係如下圖,這裡貼出來供大家了解一下。讀寫塊裝置如下:

先介紹塊裝置,裝置驅動在驅動程式初始化時為自己註冊,將這個驅動程式加入核心的驅動程式表中,並將裝置號對映到資料結構block_device_operations中,資料結構block_device_operations包含了系統中啟動和停止給設定塊裝置的函式(在include/linux/fs.h上。

struct

block_operations;

從處理器的角度來看,在適合的cidao4上定位磁頭並將磁碟轉到相應的塊要花費相當長的時間,這種延遲迫使核心實現了系統請求佇列,在linux2.6中,每個塊裝置都有自己的請求佇列,以便管理對該裝置的io口請求,程序只有在獲得請求佇列鎖之後才能 更新裝置的請求佇列,讓我們先來看看request_queue結構(這些**都是自己敲出來的,然後分析,分析不好的請各位大神批評改正。)這些**都可以在include/linux/blkdev.h中檢視。

struct

request_queue

;

linux核心通過在裝置的_init函式中呼叫下列函式來初始化塊裝置的請求佇列,這些函式中,,可以看出請求對了內部的細節和相關幫助教程,在現在的linux2.6核心中,每個塊裝置控制自己的鎖,並且將自旋鎖作為第二個引數來傳遞,其中第乙個引數是塊裝置驅動程式提供的請求函式,下面的**在drivers/block/11_rw_blk.c中檢視得到。

request_queue_t *blk_init_queue(request_fn_proc *rfn,spinlock_t *lock

)

if(elevator_init(q,chosen_elevator))  //這是個初始化的函式

goto

out_elv;

q->request_fn =rfn;

q->back_merge_fn =11_back_merge_fn;

q->front_merge_fn =11_front_merge_fn;

q->merge_requests_fn =11_merge_requests_fn;

q->prep_rq_fn =null;

q->unplug_fn =generic_unplug_device;

q->queue_flags = (1

<

q->queue_lock = lock

;    //上述賦值是將電梯排程程式相關的函式與該佇列關聯

blk_queue_segment_boundary(q,

0xffffffff

);  //檢查是否滿足最小尺寸

blk_queue_make_request(q,__make_request)  //設定驅動從佇列刪除

blk_queue_max_segment_size(q,max_segment_size);  //初始化歸併段的上限

blk_queue_max_hw_segments(q,max_hw_segments);  //初始化物理裝置可以處理的最大段數

blk_queue_max_phys_segments(q,max_phys_segments);  初始化每一請求的最大物理數目段

return q0

;  //返回已經初始化的佇列

out_elv:

blk_cleanup_queue(q);

out_init:

kmem_cache_free(requestq_cachep,q);

return

null;  //錯誤事件中清除記憶體的乙個例程

}

**實在太難,我知道的也只是皮毛,那些都需要好好體會,如若有補充的希望各路大神能夠多加改正我的缺點,現在來看看裝置操作,基本 的通用塊裝置有open,close,ioctl以及request函式,請求佇列不能直接被訪問,但是可以通過一組幫助例程來訪問,如下:

struct request *elv_next_request(request_queue_t *q)
這個幫助函式返回並指向下乙個請求結構的指標,驅動程式可以通過檢視該元素來收集所有資訊,以確定它的的大小方向以及該請求相關的任何其他自定義操作,之後通過end_request()想核心報告這一資訊:

void end_request(struct request *req,int

uptodate)  //在請求佇列中傳遞elev_next_request()獲得的引數

}

下面來介紹一下其它各種裝置,與塊裝置不同,字元裝置用來傳送資料流,所有序列裝置都是字元裝置,與字元裝置類似,網路裝置的資料在物理層上序列傳輸,而時鐘裝置是基於硬體脈搏跳動的裝置,其實就是時鐘相關的,還有那終端裝置,這裡就稍微提及一下。因為這些都和輸入輸出相關,大家只要有個印象就行了。

小結

結束了分析**之旅,小結一下今天主要的內容,今天主要分享的是linux核心是如何處理輸入輸出操作的,具體討論了linux是如何表示塊裝置和它的介面的,也介紹了linux排程程式並且重點分析了請求佇列,上述敲的**,我也還有好多不懂,只能自己慢慢去體會了,希望各路大神看了之後能夠稍加提醒一下,哎,反正這個寒假沒啥事了,就一直和核心作伴吧,這些寫的不好,以後繼續努力,fighting~

24小時學通Linux核心 核心探索工具類

24小時學通linux核心 核心探索工具類 寒假閒下來了,可以盡情的做自己喜歡的事情,專心待在實驗室裡燥起來了,因為大二的時候接觸過linux,只是關於核心方面確實是不好懂,所以十天的時間裡還是希望能夠補充一下linux核心相關知識,接下來繼續待在實驗室裡想總結一下linux核心程式設計,十天肯定完...

24小時學通Linux核心之如何處理輸入輸出操作

24小時學通linux核心之如何處理輸入輸出操作 真的是悲喜交加呀,本來這個寒假早上8點都去練車,兩個小時之後再來實驗室陪伴linux核心,但是今天教練說沒名額考試了,好糾結,不過想想就可以睡懶覺了,哈哈,自從大三寒假以來還沒睡過懶覺呢,現在也有更多的時間來分享自己學習linux核心的感受,前幾天覺...

24小時學通Qt之第三學時 Qt基礎

一 問題與答案 二 測試 1 setmaximumsize 函式的作用是什麼?答 設定所討論部件的最大尺寸。mini是可以具有的最小尺寸。2 setgeometry 函式的作用是什麼?答 用於設定部件的大小和位置。如果部件是乙個視窗,可以被移動或者沖洗調整大小。3 在源程式中包含qfont.h標頭檔...