1. 程式人生 > >《5.linux驅動開發-第10部分-5.10.塊裝置驅動介紹》

《5.linux驅動開發-第10部分-5.10.塊裝置驅動介紹》

《5.linux驅動開發-第10部分-5.10.塊裝置驅動介紹》

第一部分、章節目錄
5.10.1.正確理解塊裝置驅動的概念
5.10.2.塊裝置驅動框架簡介
5.10.3.塊裝置驅動案例分析1
5.10.4.塊裝置驅動案例分析2
5.10.5.塊裝置驅動案例分析3

第二部分、章節介紹
5.10.1.正確理解塊裝置驅動的概念
本節著重講塊裝置驅動和字元裝置驅動的差異,並且講了扇區、塊、頁等塊裝置驅動中重要搞的概念。
5.10.2.塊裝置驅動框架簡介
本節講述塊裝置驅動的整體框架,先打通上下脈絡再後面分析的時候就不會迷失。
5.10.3.塊裝置驅動案例分析1
本節開始塊裝置驅動案例分析,本節主要是進行實踐演示,教大家如何編譯安裝格式化掛載一個塊裝置,驅動原始碼是我提供好的。
5.10.4.塊裝置驅動案例分析2
本節開始分析提供的塊裝置驅動原始碼,這個驅動來自於LDD3,做了一些移植與修改。
5.10.5.塊裝置驅動案例分析3
本節接著分析提供的塊裝置驅動原始碼,這個驅動來自於LDD3,做了一些移植與修改。

第三部分、隨堂記錄
5.10.1.正確理解塊裝置驅動的概念
5.10.1.1、塊裝置和字元裝置的差異
(1)塊和字元是兩種不同的訪問裝置的策略
(2)同一個裝置可以同時支援塊和字元兩種訪問策略
(3)裝置本身的物理特性決定了哪一種訪問策略更適合
(4)塊裝置本身驅動層支援緩衝區,而字元裝置驅動層沒有緩衝
(5)塊裝置驅動最適合儲存裝置
5.10.1.2、塊裝置驅動的特點
(1)字元裝置只能順序訪問(如串列埠傳送資料順序),而塊裝置可以隨機訪問(不連續塊訪問)
(2)傳統的機械式塊裝置(如硬碟、DVD)雖然可以隨機訪問,但是連續訪問效率更高,因此塊裝置驅動中有排序邏輯將使用者的隨機訪問重新調整成儘量連續訪問以提升效率
(3)Nand、SD卡等隨機訪問效率等同於順序訪問
5.10.1.3、塊裝置相關的幾個單位
(1)扇區(Sector),概念來自於早期磁碟,在硬碟、DVD中還有用,在Nand/SD中已經沒意義了,扇區是塊裝置本身的特性,大小一般為512的整數倍,因為歷史原因很多時候都向前相容定義為512.
(2)塊(block),概念來自於檔案系統,是核心對檔案系統資料處理的基本單位,大小為若干個扇區,常見有512B、1KB、4KB等
(3)段(Section),概念來自於核心,是核心的記憶體管理中一個頁或者部分頁,由若干個連續為塊組成。
(4)頁(Page),概念來自於核心,是核心記憶體對映管理的基本單位。linux核心的頁式記憶體對映名稱來源於此。
總結:塊裝置驅動對下以Sector為單位管理塊裝置,對上以Block為單位和檔案系統互動。
注意:塊裝置驅動和字元裝置驅動不同,應用層對塊裝置驅動的訪問一般不是直接操作裝置檔案(/dev/block/xxx,或者/dev/sdax),而是通過檔案系統來簡潔操作。(思考裸機階段時刷機燒錄SD卡時說過的對SD卡的2種訪問:檔案系統下訪問和扇區級訪問)

5.10.2.塊裝置驅動框架簡介
5.10.2.1、塊裝置驅動框圖
(1)VFS
(2)通用塊層
(3)IO排程層(電梯演算法)
(4)塊裝置驅動層(真正硬體操作部分)
5.10.2.2、重點結構體
(1)struct request 對裝置的每一次操作(譬如讀或者寫一個扇區)
(2)struct request_queue request佇列
(3)struct bio 通用塊層用bio來管理一個請求
(4)struct gendisk 表示一個磁碟裝置或一個分割槽

5.10.3.塊裝置驅動案例分析1
5.10.3.1、塊裝置驅動案例演示
(1)驅動簡單介紹
(2)編譯
(3)模組安裝
(4)檢視資訊 cat /proc/devices cat /proc/partitions ls /dev/ lsmod
(5)掛載測試
5.10.3.2、塊裝置驅動簡單分析
(1)如何證明塊裝置驅動真的工作了: 格式化、掛載
格式化:mkfs.ext2 /dev/my_ramblock
掛載: mount -t ext2 /dev/my_ramblcok /tmp
(2)注意各種列印資訊
(3)體會塊裝置驅動的整體工作框架

5.10.4_5.塊裝置驅動案例分析2_3
5.10.4.1、原始碼分析
(1)register_blkdev(kernel/block/genhd.c),核心提供的註冊塊裝置驅動的註冊介面,在塊裝置驅動框架中的地位,等同於register_chrdev在字元裝置驅動框架中的地位。
(2)blk_init_queue 用來例項化產生一個等待佇列,將來應用層對本塊裝置所做的所有的讀寫操作,都會生成一個request然後被加到這個等待佇列中來。
(3)blk_init_queue函式接收2個引數,第一個是等待佇列的回撥函式,這個函式是驅動提供的用來處理等待佇列中的request的函式(IO排程層通過電梯演算法從等待佇列中取出一個request,就會呼叫這個回撥函式來處理這個請求),第二個引數是一個自旋鎖,這個自旋鎖是要求我們驅動提供給等待佇列去使用的。
(4)blk_fetch_request函式是IO排程層提供的介面,作用是從request_queue中(按照電梯演算法)取出一個(演算法認為當前最應該去被執行的一個請求,是被演算法排序、合併後的)請求,取出的請求其實就是當前硬體(塊裝置)最應該去執行的那個讀寫操作。