linux驅動層
㈠ linux中的底層,應用層,驅動之間的關系
內核--系統的底層,最核心的東西,操作系統運轉的基礎
驅動--應用程序與內核之間的介面,溝通應用軟體與操作系統的橋梁
應用層--所有的應用程序的統稱,實現某一個或幾個專有的功能
㈡ Linux網路設備驅動的結構
Linux網路設備驅動程序的體系結構從上到下可以劃分為4層,依次為網路協議介面層、網路設備介面層、提供實際功能的設備驅動功能層以及網路設備與媒介層,這4層的作用如下所示。
1)網路協議介面層向網路層協議提供統一的數據包收發介面,不論上層協議是ARP,還是IP,都通過dev_queue_xmit() 函數發送數據,並通過netif rx ()函數接收數據。這一層的存在使得上層協議獨立於具體的設備。
2)網路設備介面層向協議介面層提供統一的用於描述具體網路設備屬性和操作的結構體net device,該結構體是設備驅動功能層中各函數的容器。實際上,網路設備介面層從宏觀上規劃了具體操作硬體的設備驅動功能層的結構。
3)設備驅動功能層的各函數是網路設備介面層net_device數據結構的具體成員,是驅使網路設備硬體完成相應動作的程序,它通過hard_start_ xmit ()函數啟動發送操作,並通過網路設備上的中斷觸發接收操作。
4)網路設備與媒介層是完成數據包發送和接收的物理實體,包括網路適配器和具體的傳輸媒介,網路適配器被設備驅動功能層中的函數在物理上驅動。對於Linux系統而言,網路設備和媒介都可以是虛擬的。
㈢ linux內核,驅動,應用程三者的概念是什麼三者有什麼關系
首先,要理解操作系統的概念,操作系統是用戶和硬體之間的一層媒介程序。不管是Linux還是Windows或者安卓、IOS,它的主要功能有兩點:x0dx0a1、有效管理硬體。x0dx0a2、方便用戶操作。x0dx0ax0dx0a其次,Linux內核是Linux系統的核心程序,主要完成任務調度、內存管理、IO設備管理等等功能,主要目的是為了應用程序提供一個穩定良好的運行環境,這是一個基礎。x0dx0ax0dx0a再次,驅動程序是操作系統有效管理硬體的一個途徑。應用程序是方便用戶操作提供的程序,比如Shell,Linux中的bashshell以及KDE、gnome等圖形Shell都是應用程序。你可以簡單的理解為驅動程序實現了操作系統對硬體的有效管理,應用程序實現了操作系統方便用戶操作的目的。x0dx0ax0dx0a最後,從編程角度來看,Linux內核就是一個調用庫,應用程序通過調用Linux提供的API函數來實現操作,Linux內核通過與驅動通信實現對硬體的有效管理。具體的編程細節,需要自己在實踐編程中體會。這是一個整體的描述。
㈣ linux 應用層 能 訪問 驅動層 全局變數 嗎
當然不能了
應用層程序是以進程形式存在的,每個進程空間都是相互獨立的,互相不能訪問各自的變數,
更不用說訪問內核中驅動層的變數了。
㈤ linux非同步通知之驅動層怎麼釋放SIGUSR1/SIGUSR2
首先,Linux中的信號可以通過kill -l命令獲取,
如上圖所示,編號為1 ~ 31的信號為傳統UNIX支持的信號,是不可靠信號(非實時的),編號為32 ~ 63的信號是後來擴充的,稱做可靠信號(實時信號)。不可靠信號和可靠信號的區別在於前者不支持排隊,可能會造成信號丟失,而後者不會。
其次,SIGUSR1 ,這是留給用戶使用的信號。一般在編程中使用。舉例說明:sigqueue向本進程發送數據的信號,C語言代碼如下 :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void myhandler(int signo,siginfo_t *si,void *ucontext);
int main(){
union sigval val;//定義一個攜帶數據的共用體
struct sigaction oldact,act;
act.sa_sigaction=myhandler;
act.sa_flags=SA_SIGINFO;//表示使用sa_sigaction指示的函數,處理完恢復默認,不阻塞處理過程中到達下在被處理的信號
//注冊信號處理函數
sigaction(SIGUSR1,&act,&oldact);
char data[100];
int num=0;
while(num<10){
sleep(2);
printf("等待SIGUSR1信號的到來\n");
sprintf(data,"%d",num++);
val.sival_ptr=data;
sigqueue(getpid(),SIGUSR1,val);//向本進程發送一個信號
}
}
void myhandler(int signo,siginfo_t *si,void *ucontext){
printf("已經收到SIGUSR1信號\n");
printf("%s\n",(char*)(si->si_ptr));
}
㈥ 如何系統的學習Linux驅動開發
在學習之前一直對驅動開發非常的陌生,感覺有點神秘。不知道驅動開發和普通的程序開發究竟有什麼不同;它的基本框架又是什麼樣的;他的開發環境有什麼特殊的地方;以及怎麼寫編寫一個簡單的字元設備驅動前編譯載入,下面我就對這些問題一個一個的介紹。
一、驅動的基本框架
1.那麼究竟什麼是驅動程序,它有什麼用呢:
l驅動是硬體設備與應用程序之間的一個中間軟體層
l它使得某個特定硬體能夠響應一個定義良好的內部編程介面,同時完全隱蔽了設備的工作細節
l用戶通過一組與具體設備無關的標准化的調用來完成相應的操作
l驅動程序的任務就是把這些標准化的系統調用映射到具體設備對於實際硬體的特定操作上
l驅動程序是內核的一部分,可以使用中斷、DMA等操作
l驅動程序在用戶態和內核態之間傳遞數據
2.Linux驅動的基本框架
3.Linux下設備驅動程序的一般可以分為以下三類
1)字元設備
a)所有能夠象位元組流一樣訪問的設備都通過字元設備來實現
b)它們被映射為文件系統中的節點,通常在/dev/目錄下面
c)一般要包含open read write close等系統調用的實現
2)塊設備
d)通常是指諸如磁碟、內存、Flash等可以容納文件系統的存儲設備。
e)塊設備也是通過文件系統來訪問,與字元設備的區別是:內核管理數據的方式不同
f)它允許象字元設備一樣以位元組流的方式來訪問,也可一次傳遞任意多的位元組。
3)網路介面設備
g)通常它指的是硬體設備,但有時也可能是一個軟體設備(如回環介面loopback),它們由內核中網路子系統驅動,負責發送和接收數據包。
h)它們的數據傳送往往不是面向流的,因此很難將它們映射到一個文件系統的節點上。
二、怎麼搭建一個驅動的開發環境
因為驅動是要編譯進內核,在啟動內核時就會驅動此硬體設備;或者編譯生成一個.o文件,當應用程序需要時再動態載入進內核空間運行。因此編譯任何一個驅動程序都要鏈接到內核的源碼樹。所以搭建環境的第一步當然是建內核源碼樹
1.怎麼建內核源碼樹
a)首先看你的系統有沒有源碼樹,在你的/lib/ moles目錄下會有內核信息,比如我當前的系統里有兩個版本:
#ls /lib/ moles
2.6.15-rc72.6.21-1.3194.fc7
查看其源碼位置:
## ll /lib/moles/2.6.15-rc7/build
lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/moles/2.6.15-rc7/build -> /root/xkli/linux-2.6.15-rc7
發現build是一個鏈接文件,其所對應的目錄就是源碼樹的目錄。但現在這里目標目錄已經是無效的了。所以得自己重新下載
b)下載並編譯源碼樹
有很多網站上可以下載,但官方網址是:
http://www.kernel.org/pub/linux/kernel/v2.6/
下載完後當然就是解壓編譯了
# tar –xzvf linux-2.6.16.54.tar.gz
#cd linux-2.6.16.54
## make menuconfig (配置內核各選項,如果沒有配置就無法下一步編譯,這里可以不要改任何東西)
#make
…
如果編譯沒有出錯。那麼恭喜你。你的開發環境已經搭建好了
三、了解驅動的基本知識
1.設備號
1)什麼是設備號呢?我們進系統根據現有的設備來講解就清楚了:
#ls -l /dev/
crwxrwxrwx 1 root root1,3 2009-05-11 16:36 null
crw------- 1 root root4,0 2009-05-11 16:35 systty
crw-rw-rw- 1 root tty5,0 2009-05-11 16:36 tty
crw-rw---- 1 root tty4,0 2009-05-11 16:35 tty0
在日期前面的兩個數(如第一列就是1,3)就是表示的設備號,第一個是主設備號,第二個是從設備號
2)設備號有什麼用呢?
l傳統上,主編號標識設備相連的驅動.例如, /dev/null和/dev/zero都由驅動1來管理,而虛擬控制台和串口終端都由驅動4管理
l次編號被內核用來決定引用哪個設備.依據你的驅動是如何編寫的自己區別
3)設備號結構類型以及申請方式
l在內核中, dev_t類型(在中定義)用來持有設備編號,對於2.6.0內核, dev_t是32位的量, 12位用作主編號, 20位用作次編號.
l能獲得一個dev_t的主或者次編號方式:
MAJOR(dev_t dev); //主要
MINOR(dev_t dev);//次要
l但是如果你有主次編號,需要將其轉換為一個dev_t,使用: MKDEV(int major, int minor);
4)怎麼在程序中分配和釋放設備號
在建立一個字元驅動時需要做的第一件事是獲取一個或多個設備編號來使用.可以達到此功能的函數有兩個:
l一個是你自己事先知道設備號的
register_chrdev_region,在中聲明:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
first是你要分配的起始設備編號. first的次編號部分常常是0,count是你請求的連續設備編號的總數. name是應當連接到這個編號范圍的設備的名子;它會出現在/proc/devices和sysfs中.
l第二個是動態動態分配設備編號
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
使用這個函數, dev是一個只輸出的參數,它在函數成功完成時持有你的分配范圍的第一個數. fisetminor應當是請求的第一個要用的次編號;它常常是0. count和name參數如同給request_chrdev_region的一樣.
5)設備編號的釋放使用
不管你是採用哪些方式分配的設備號。使用之後肯定是要釋放的,其方式如下:
void unregister_chrdev_region(dev_t first, unsigned int count);
6)
2.驅動程序的二個最重要數據結構
1)file_operation
倒如字元設備scull的一般定義如下:
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
file_operation也稱為設備驅動程序介面
定義在,是一個函數指針的集合.每個打開文件(內部用一個file結構來代表)與它自身的函數集合相關連(通過包含一個稱為f_op的成員,它指向一個file_operations結構).這些操作大部分負責實現系統調用,因此,命名為open, read,等等
2)File
定義位於include/fs.h
struct file結構與驅動相關的成員
lmode_t f_mode標識文件的讀寫許可權
lloff_t f_pos當前讀寫位置
lunsigned int_f_flag文件標志,主要進行阻塞/非阻塞型操作時檢查
lstruct file_operation * f_op文件操作的結構指針
lvoid * private_data驅動程序一般將它指向已經分配的數據
lstruct dentry* f_dentry文件對應的目錄項結構
3.字元設備注冊
1)內核在內部使用類型struct cdev的結構來代表字元設備.在內核調用你的設備操作前,必須編寫分配並注冊一個或幾個這些結構.有2種方法來分配和初始化一個這些結構.
l如果你想在運行時獲得一個獨立的cdev結構,可以這樣使用:
struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;
l如果想將cdev結構嵌入一個你自己的設備特定的結構;你應當初始化你已經分配的結構,使用:
void cdev_init(struct cdev *cdev, struct file_operations *fops);
2)一旦cdev結構建立,最後的步驟是把它告訴內核,調用:
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
說明:dev是cdev結構, num是這個設備響應的第一個設備號, count是應當關聯到設備的設備號的數目.常常count是1,但是有多個設備號對應於一個特定的設備的情形.
3)為從系統去除一個字元設備,調用:
void cdev_del(struct cdev *dev);
4.open和release
㈦ 請教關於在linux網路驅動層對skb網路數據包
自己定義buf,把你私有數據放到buf里,該buf記錄原始的skb指針。不過自己要去修改驅動,buf的收發解析自己管理。
另外,非得在skb裡面搞,能不能放到其它永遠不會被使用的欄位里。
謝謝你的建議
首先我想明確一點,目前我所有的處理都是在網卡驅動層做的,因為想對上層的內核協議棧保持透明
你的意思是在網卡驅動層重新申請一個大一點的buf,然後把我自定義的數據放進這個buf,然後重新封裝數據包發送出去,然後在對端網卡驅動層解析數據包?
其實你的第二個建議我也有考慮,但是不知道報文頭里哪些欄位是永遠不會使用的,如果有這樣的欄位那處理就方便多了,能否給一些提示,非常感謝!
----------------------------------------
㈧ linux主機側與設備側USB驅動
USB採用樹形拓撲結構,主機側和設備側的USB控制器分別稱為主機控制器((Host Controller)和USB設備控制器(UDC),每條匯流排上只有一個主機控制器,負責協調主機和設備間的通信,而設備不能主動向主機發送任何消息。
在Linux系統中,USB驅動可以從兩個角度去觀察,一個角度是主機側,一個角度是設備側。從上圖主機側去看,在Linux驅動中,處於USB驅動最底層的是USB主機控制器硬體,在其上運行的是USB主機控制器驅動,在主機控制器上的為USB核心層,再上層為USB設備驅動層(插入主機上的U盤、滑鼠、USB轉串口等設備驅動)。因此,在主機側的層次結構中,要實現的USB驅動包括兩類:USB主機控制器驅動和USB設備驅動,前者控制插入其中的USB設備,後者控制USB設備如何與主機通信。Linux內核中的USB核心負責USB驅動管理和協議處理的主要工作。主機控制器驅動和設備驅動之間的USB核心非常重要,其功能包括:通過定義一些數據結構、宏和功能函數,向上為設備驅動提供編程介面,向下為USB主機控制器驅動提供編程介面;維護整個系統的USB設備信息;完成設備熱插拔控制、匯流排數據傳輸控制等。
㈨ LINUX 終端設備驅動
在Linux系統中,終端是一種字元型設備,它有多種類型,通常使用tty (Teletype)來簡稱各種類型的終端設備。對於嵌入式系統而言,最普遍採用的是UART (Universal Asynchronous Receiver/Transmitter)串列埠,日常生活中簡稱串口。
Linux內核中tty的層次結構它包含tty核心tty_10.c、tty或路規在n_tty.C(頭現N_11Y線路規程)和tty驅動實例xxx_tty.c,tty線路規程的工作是以特殊的方式格式化從一個用戶或者硬體收到的數據,這種格式化常常採用一個協議轉換的形式tty _io.c本身是一個標準的字元設備驅動,它對上有字元改備的職貢,買現tle_operatIonS雙貝圖效。但是tty核心層對下又定義了tty_driver的架構,這樣tty設備驅動的主體工作就變成了琪允tty_driVeT依構體中的成員,實現其中的tty_operations的成員函數,而不再是去實現file_operations這一級的工作。tty設備發送數據的流程為:tty核心從一個用戶獲取將要發送給一個tty設備的數據,tty核心將數據傳遞給tty線路規程驅動,接著數據被傳遞到tty驅動,tty驅動將數據轉換為可以發送給硬體的格式。接收數據的流程為:從tty硬體接收到的數據向上交給tty驅動,接著進入tty線路規程驅動,再進入tty核心,在這里它被一個用戶獲取。盡管一個特定的底層UART設備驅動完全可以遵循上述tty_driver的方法來設計,即定義tty_driver並實現tty_operations中的成員函數,但是鑒於串口之間的共性,Linux考慮在文件drivers'ttyliserial'serial_core.c中實現了UART設備的通用tty驅動層(我們可以稱其為串口核心層)。這樣,UART驅動的主要任務就進一步演變成了實現serial-core.c中定義的一組uart_xxx介面而不是tty_xxx介面。因此,按照面向對象的思想,可以認為tty_driver是字元設備的泛化、serial-core是tty_driver的泛化,而具體的串口驅動又是serial-core的泛化。
㈩ linux中的底層,應用層,驅動之間的關系
內核——系統的底層,最核心的東西,操作系統運轉的基礎
驅動——應用程序與內核之間的介面,溝通應用軟體與操作系統的橋梁
應用層——所有的應用程序的統稱,實現某一個或幾個專有的功能