linux設備管理

Linux的設備管理

  • Linux的設備管理的主要任務是控制設備完成輸入輸出操作,所以又稱輸入輸出(I/O)子系統

  • 它的任務是把各種設備硬件的複雜物理特性的細節屏蔽起來,提供一個對各種不同設備使用統一方式進行操作的接口

  • Linux把設備看作是特殊的文件,系統通過處理文件的接口—虛擬文件系統VFS來管理和控制各種設備。


§6.1 設備管理概述

  1. Linux設備的分類

  • 設備被分爲三類,塊設備字符設備網絡設備

  • 字符設備是以字符爲單位輸入輸出數據的設備,一般不需要使用緩衝區直接對它進行讀寫

  • 塊設備是以一定大小的數據塊爲單位輸入輸出數據的,一般要使用緩衝區在設備與內存之間傳送數據。

  • 網絡設備是通過通信網絡傳輸數據的設備,一般指與通信網絡連接的網絡適配器(網卡)等。

Linux使用套接口(socket)以文件I/O方式提供了對網絡數據的訪問。

  1. 設備驅動程序

  • 系統對設備的控制和操作由設備驅動程序完成的。

  • 設備驅動程序是由設備服務子程序和中斷處理程序組成。設備服務子程序包括了對設備進行各種操作的代碼,中斷處理子程序處理設備中斷

  • 設備驅動程序的主要功能是:

  • 對設備進行初始化

  • 啓動停止設備的運行

  • 把設備上的數據傳送到內存

  • 把數據從內存傳送到設備

  • 檢測設備狀態

  • 驅動程序是與設備相關的。

  • 驅動程序的代碼由內核統一管理

  • 驅動程序在具有特權級的內核態下運行

  • 設備驅動程序是輸入輸出子系統的一部分。

  • 驅動程序是爲某個進程服務的,其執行過程仍處在進程運行的過程中,即處於進程上下文中

  • 若驅動程序需要等待設備的某種狀態,它將阻塞當前進程,把進程加入到該種設備的等待隊列中。。

  • Linux的驅動程序分爲兩個基本類型:字符設備驅動程序塊設備驅動程序

三.設備的識別

  • 對設備的識別使用設備類型主設備號次設備號

  • 設備類型:字符設備還是塊設備

  • 按照設備使用的驅動程序不同而賦予設備不同的主設備號。主設備號是與驅動程序一一對應的同時還使用次設備號來區分一種設備中的各個具體設備。次設備號用來區分使用同一個驅動程序的個體設備

  • 例如,系統中的塊設備IDE硬盤的主設備號是8

而多個SCSI硬盤及其各個分區分別賦予次設備號123…

[root@localhost /]# ls /dev/sda* -l
brw-r----- 1 root disk 8, 0 11-07 12:31 
/dev/sda
brw-r----- 1 root disk 8, 1 11-07 12:31 
/dev/sda1
brw-r----- 1 root disk 8, 2 11-07 12:31 
/dev/sda2

四.設備文件

  • Linux設備管理的基本特點是把物理設備看成文件,採用處理文件的接口和系統調用來管理控制設備。

  • 從抽象的觀點出發,Linux設備又稱爲設備文件

  • 設備文件也有文件名,設備文件名一般由兩部分組成

  • 第一部分23個字符,表示設備的種類,如串口設備是cu,並口設備是lpIDE普通硬盤是hdSCIS硬盤是sd,軟盤是fp等。

  • 第二部分通常是字母或數字,用於區分同種設備中的單個設備,如hdahdbhdc…分別表示第一塊、第二塊、第三塊IED硬盤。而hda1hda2…表示第一塊硬盤中的第一、第二個磁盤分區。

  • 設備文件一般置於/dev目錄下,如/dev/hda2/dev/lp0等。

  • Linux使用虛擬文件系統VFS做爲統一的操作接口處理文件設備

  • 與普通的目錄和文件一樣,每個設備也使用一個VFSinode來描述,其中包含着該種設備的主、次設備號

  • 設備的操作也是通過對文件操作的file_operations結構體來調用驅動程序的設備服務子程序

  • 例如,當進程要求從某個設備上輸入數據時,由該設備的

file_operations結構體得到服務子程序的操作函數入口,然後調用其中的read()函數完成數據輸入操作。

  • 同樣,使用file_operations中的open()close()write()

分別完成對設備的啓動停止設備運行,向設備輸出數據的操作。


§6.2 LinuxI/O控制

LinuxI/O控制方式有三種:查詢等待方式

中斷方式DMA(內存直接存取)方式.

一.查詢等待方式

  • 查詢等待方式又稱輪詢方式polling mode)。

  • 對於不支持中斷方式的機器只能採用這種方式來控制I/O過程,所以Linux中也配備了查詢等待方式。

  • 例如,並行接口的驅動程序中默認的控制方式就是查詢等待方式。

  • 如函數lp_char_polled()就是以查詢等待方式向與並口連接的設備輸出一個字符。

static inline int lp_char_polled(char lpchar, int minor)

{

int status, wait = 0;

unsigned long count = 0;

struct lp_stats *stats;


do { /* 查詢等待循環 */

status = LP_S(minor);

count ++;

if(need_resched)

schedule();

} while(!LP_READY(minor,status) && count < LP_CHAR(minor));


if (count == LP_CHAR(minor)) { /* 超時退出 */

return 0;

}

outb_p(lpchar, LP_B(minor)); /* 向設備輸出字符 */

  .

   .

二.中斷方式

  • 硬件支持中斷的情況下,驅動程序可以使用中斷方式控制I/O過程。

  • I/O過程控制使用的中斷是硬件中斷,當某個設備需要服務時就向CPU發出一個中斷脈衝信號CPU接收到信號後根據中斷請求號IRQ啓動中斷服務例程

  • 在中斷方式中,Linux設備管理的一個重要任務就是在CPU接收到中斷請求後,能夠執行該設備驅動程序的中斷服務例程。

  • 爲此,Linux設置了名字爲irq_action中斷例程描述符表

static struct irqaction *irq_action[NR_IRQS+1];

  • NR_IRQS表示中斷源的數目

  • irq_action[]是一個指向irqaction結構的指針數組,它指向的irqaction結構是各個設備中斷服務例程的描述符

struct irqaction {

void (*handler)(int, void *, struct pt_regs *); /* 指向中斷服務例程 */

unsigned long flags; /* 中斷標誌 */

unsigned long mask; /* 中斷掩碼 */

void *dev_id; /*

struct irqaction *next; /* 指向下一個描述符 */

};

  • 在驅動程序初始化時,調用函數request_irq()建立該驅動程序

irqaction結構體,並把它登記到irq_action[]數組中。

  • request_irq()函數的原型如下:

int request_irq(unsigned int irq,

void (*handler)(int, void *, struct pt_regs *),

unsigned long irqflags,

const char * devname,

void *dev_id);

  • 參數irq是設備中斷求號,在向irq_action[]數組登記時,它做爲數組的下標

  • 把中斷號爲irqirqaction結構體的首地址寫入irq_action[irq]。這樣就把設備的中斷請求號與該設備的服務例程聯繫在一起了。

  • CPU接收到中斷請求後,根據中斷號就可以通過irq_action[]找到該設備的中斷服務例程


§6.3 字符設備與塊設備管理

  • Linux中,一個設備在使用之前必須向系統進行註冊,設備註冊是在設備初始化時完成的。

一.字符設備管理

  • 在系統內核保持着一張字符設備註冊表每種字符設備佔用一個表項

  • 字符設備註冊表是結構數組chrdevs[]

#define MAX_CHRDEV 128

static struct device_struct chrdevs[MAX_CHRDEV];

  • 註冊表的表項是device_struct結構

struct device_struct {

const char * name; /* 指向設備名字符串 */

struct file_operations * fops; /* 指向文件操作函數的指針 */

};

  • 在字符設備註冊表中,每個表項對應一種字符設備的驅動程序。所以字符設備註冊表實質上是驅動程序的註冊表

  • 使用同一個驅動程序的每種設備有一個唯一的主設備號。所以註冊表的每個表項與一個主設備號對應

  • 在Linux中正是使用主設備號來對註冊表數組進行索引, 即chrdevs[]數組的下標值就是主設備號

  • device_struct結構中有指向file_operations結構的指針f_opsfile_operations結構中的函數指針指向設備驅動程序的服務例程

  • 打開一個設備文件時,由主設備號就可以找到設備驅動程序


二.塊設備管理

  • 塊設備在使用前也要向系統註冊

  • 塊設備註冊在系統的塊設備註冊表,塊設備註冊表是結構數組blkdevs[]

  • 它的元素也是device_struct結構

static struct device_struct blkdevs[MAX_BLKDEV]

  • 在塊設備註冊表中,每個表項對應一種塊設備

  • 註冊表blkdevs[]數組的的下標主設備號


  • 塊設備是以塊爲單位傳送數據的,設備與內存之間的數據傳送必須經過緩衝

  • 當對設備讀寫時,首先把數據置於緩衝區內,應用程序需要的數據由系統在緩衝區內讀寫。

  • 只有在緩衝區內已沒有要讀的數據,或緩衝區已滿而無寫入的空間時,才啓動設備控制器進行設備與緩衝區之間數據交換

  • 設備與緩衝區的數據交換是通過blk_dev[]數組實現的:

struct blk_dev_struct blk_dev[MAX_BLKDEV];

  • 每個塊設備對應數組中的一項,數組的下標值與主設備號對應。

  • 數組元素是blk_dev_struct結構

struct blk_dev_struct {

void (*request_fn)(void);

struct request * current_request;

struct request plug;

struct tq_struct plug_tq;

};

request_fn :指向設備讀寫請求函數的指針

current_request指向request結構的指針。

當緩衝區需要與設備進行數據交換時

緩衝機制就blk_dev_struct加入一個request結構

每個request結構對應一個緩衝區對設備的讀寫請求

在request結構中有一個指向緩衝區信息的指針

由它決定緩衝區的位置和大小等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章