linuxsound驅動架構怎麼寫 解釋一下linux驅動程式結構框架及工作原理

1.解釋一下linux驅動程式結構框架及工作原理

一、Linux device driver 的概念 系統呼叫是作業系統核心和應用程式之間的介面,裝置驅動程式是作業系統核心和機器硬體之間的介面。

linuxsound驅動架構怎麼寫 解釋一下linux驅動程式結構框架及工作原理

裝置驅動程式為應用程式遮蔽了硬體的細節,這樣在應用程式看來,硬體裝置只是一個裝置檔案,應用程式可以象操作普通檔案一樣對硬體裝置進行操作。裝置驅動程式是核心的一部分,它完成以下的功能: 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 基本的型別定義 #include 檔案系統使用相關的標頭檔案 #include #include #include 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_。

2.為什麼Linux的音訊驅動位於sound目錄下而不是driver/sound

1、早期的2.4核心所有的音訊驅動和其他驅動一樣都是位於drivers目錄下的:drivers/sound

2、到了2.5開發版核心,所有的音訊驅動包括音訊框架程式碼由drivers/sound移到了sound目錄下:

(1)2.6核心之前的git記錄查詢:mit;h=

author Jaroslav Kysela <[email protected]>

Wed, 13 Feb 2002 03:32:11 +0000 (19:32 -0800)

committer Jaroslav Kysela <[email protected]>

Wed, 13 Feb 2002 03:32:11 +0000 (19:32 -0800)

commit

tree tree | snapshot

parent commit | diff

[PATCH] ALSA patch for 2.5.4

Integrate ALSA into v2.5.4

Jaroslav

這個提交是在2.5.4~2.5.5-pre1之間發生的

從這個提交資訊可以看出,是在Linux核心正式引入ALSA音訊構架的時候,所有的程式碼都被移動到了drivers/sound下。

也就是在同一天,音訊子系統的維護由原來的Alan Cox轉為Jaroslav Kysela:

mit;h=

Make Jaroslav the sound maintainer, remove Alan on his request.

author Linus Torvalds <[email protected]>

Wed, 13 Feb 2002 04:05:43 +0000 (20:05 -0800)

committer Linus Torvalds <[email protected]>

Wed, 13 Feb 2002 04:05:43 +0000 (20:05 -0800)

commit

tree tree | snapshot

parent commit | diff

Make Jaroslav the sound maintainer, remove Alan on his request.

所以這個程式碼的移動應該是在ALSA那個分支開發的時候就已經是這樣的了

3.音效卡驅動說明這一段英文是什麼意思

步驟1:解壓縮原始碼tar xfvj 高階Linux聲音架構(Advanced Linux Sound Architecture)-驅動 1.0.xx.tar.bz2步驟2:a.讀取光碟中高階Linux聲音架構-1.0 xx驅動b..音效卡配置--inter 高保真音訊(High Definition Audio-inter )c.建立d.建立安裝步驟3:重啟您的機器步驟4.使用音訊混音器,終止靜音 (所有音訊裝置預設設定靜音)必須編譯和安裝高階Linux聲音架構庫和程式 (使用自動安裝已執行安裝)執行音訊混音器Note:注意:1.詳細細節可以查閱位於azx-021705.tar.bz2有關高階Linux聲音架構核心/程式說明書/ 高階Linux聲音架構配置文字文件.2.核心版本必須為2.6或者更新版3.所有混音器通道均被預設設定為靜音,你必須使用本地的或者一個unix平臺上一個統一的音訊介面(Open Sound System )混音器程式開啟音訊通道.4.如無法讀取原始碼,嘗試重新命名/usr/src/linux-2.x 檔案為 /usr/src/linux.5.驅動增加支援索尼-飛利浦數字介面格式(Sony-Philips Digital Interface Format,)功能.6.a.你可以訪問/ sound/其中,sound 就是音效卡模組存放目錄,大多數的硬體驅動放在 drivers目錄,fs 是檔案系統模組的目錄;net是與網路有關的存放目錄,比如一些網路協議支援的模組、防火牆支援的模組等;arch 是cpu方面 。 。

如果我們想自己載入模組,就到這些目錄中檢視相應模組的資訊,然後用 modprobe 來載入; [root@localhost beinan]# modinfo snd-intel8x0 檢視一個模組的資訊,我們用 modinfo 來檢視,所要查看的模組不要帶 .ko 或者.o 之類的;比如檢視到類似下面的資訊; description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455 通過這個我們足可以知道這是Intel 整合音效卡,通過lspci -v 得到的音效卡資訊,感覺他們很相近;所以就能嘗試用這個模組來驅動; [root@localhost beinan]# modprobe snd-intel8x0 用 modprobe 載入了模組,然後我們通過 lsmod 就能看到了;對於音效卡模組是這麼載入的,其它裝置的驅動模組也是如此。