日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux驱动】字符设备驱动

發(fā)布時間:2024/4/21 linux 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux驱动】字符设备驱动 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


一、linux系統(tǒng)將設(shè)備分為3類:字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備。使用驅(qū)動程序:

1、字符設(shè)備:是指只能一個字節(jié)一個字節(jié)讀寫的設(shè)備,不能隨機讀取設(shè)備內(nèi)存中的某一數(shù)據(jù),讀取數(shù)據(jù)需要按照先后數(shù)據(jù)。字符設(shè)備是面向流的設(shè)備,常見的字符設(shè)備有鼠標、鍵盤、串口、控制臺和LED設(shè)備等。
2、塊設(shè)備:是指可以從設(shè)備的任意位置讀取一定長度數(shù)據(jù)的設(shè)備。塊設(shè)備包括硬盤、磁盤、U盤和SD卡等。

  每一個字符設(shè)備或塊設(shè)備都在/dev目錄下對應(yīng)一個設(shè)備文件。linux用戶程序通過設(shè)備文件(或稱設(shè)備節(jié)點)來使用驅(qū)動程序操作字符設(shè)備和塊設(shè)備。

3、字符設(shè)備驅(qū)動模型


二、字符設(shè)備驅(qū)動程序基礎(chǔ):
1、主設(shè)備號和次設(shè)備號(二者一起為設(shè)備號):
  一個字符設(shè)備或塊設(shè)備都有一個主設(shè)備號和一個次設(shè)備號。主設(shè)備號用來標識與設(shè)備文件相連的驅(qū)動程序,用來反映設(shè)備類型。次設(shè)備號被驅(qū)動程序用來辨別操作的是哪個設(shè)備,用來區(qū)分同類型的設(shè)備。
  linux內(nèi)核中,設(shè)備號用dev_t來描述,2.6.28中定義如下:
  typedef u_long dev_t;
  在32位機中是4個字節(jié),高12位表示主設(shè)備號,低12位表示次設(shè)備號。

可以使用下列宏從dev_t中獲得主次設(shè)備號:                   也可以使用下列宏通過主次設(shè)備號生成dev_t:
MAJOR(dev_t dev);                             ?MKDEV(int major,int minor);
MINOR(dev_t dev);

//宏定義: #define MINORBITS 20 #define MINORMASK ((1U << MINORBITS) - 1) #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

?

2、分配設(shè)備號(兩種方法):

(1)靜態(tài)申請:
int register_chrdev_region(dev_t from, unsigned count, const char *name);

/*** register_chrdev_region() - register a range of device numbers* @from: the first in the desired range of device numbers; must include* the major number.* @count: the number of consecutive device numbers required* @name: the name of the device or driver.** Return value is zero on success, a negative error code on failure.*/

(2)動態(tài)分配:

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);/*** alloc_chrdev_region() - register a range of char device numbers* @dev: output parameter for first assigned number* @baseminor: first of the requested range of minor numbers* @count: the number of minor numbers required* @name: the name of the associated device or driver** Allocates a range of char device numbers. The major number will be* chosen dynamically, and returned (along with the first minor number)* in @dev. Returns zero or a negative error code.*/

注銷設(shè)備號

void unregister_chrdev_region(dev_t from, unsigned count);


創(chuàng)建設(shè)備文件
利用cat /proc/devices查看申請到的設(shè)備名,設(shè)備號。
(1)使用mknod手工創(chuàng)建:mknod filename type major minor
(2)自動創(chuàng)建;

  利用udev(mdev)來實現(xiàn)設(shè)備文件的自動創(chuàng)建,首先應(yīng)保證支持udev(mdev),由busybox配置。在驅(qū)動初始化代碼里調(diào)用class_create為該設(shè)備創(chuàng)建一個class,再為每個設(shè)備調(diào)用device_create創(chuàng)建對應(yīng)的設(shè)備。

?

3、字符設(shè)備驅(qū)動程序重要的數(shù)據(jù)結(jié)構(gòu)
(1)struct file:代表一個打開的文件描述符,系統(tǒng)中每一個打開的文件在內(nèi)核中都有一個關(guān)聯(lián)的struct file。它由內(nèi)核在open時創(chuàng)建,并傳遞給在文件上操作的任何函數(shù),直到最后關(guān)閉。當文件的所有實例都關(guān)閉之后,內(nèi)核釋放這個數(shù)據(jù)結(jié)構(gòu)。

//重要成員: const struct file_operations *f_op; //該操作是定義文件關(guān)聯(lián)的操作的。內(nèi)核在執(zhí)行open時對這個指針賦值。 off_t f_pos; //該文件讀寫位置。 void *private_data;//該成員是系統(tǒng)調(diào)用時保存狀態(tài)信息非常有用的資源。

(2)struct inode:用來記錄文件的物理信息。它和代表打開的file結(jié)構(gòu)是不同的。一個文件可以對應(yīng)多個file結(jié)構(gòu),但只有一個inode結(jié)構(gòu)。inode一般作為file_operations結(jié)構(gòu)中函數(shù)的參數(shù)傳遞過來。
  inode譯成中文就是索引節(jié)點。每個存儲設(shè)備或存儲設(shè)備的分區(qū)(存儲設(shè)備是硬盤、軟盤、U盤 ... ... )被格式化為文件系統(tǒng)后,應(yīng)該有兩部份,一部份是inode,另一部份是Block,Block是用來存儲數(shù)據(jù)用的。而inode呢,就是用來存儲這些數(shù)據(jù)的信息,這些信息包括文件大小、屬主、歸屬的用戶組、讀寫權(quán)限等。inode為每個文件進行信息索引,所以就有了inode的數(shù)值。操作系統(tǒng)根據(jù)指令,能通過inode值最快的找到相對應(yīng)的文件。

dev_t i_rdev; //對表示設(shè)備文件的inode結(jié)構(gòu),該字段包含了真正的設(shè)備編號。 struct cdev *i_cdev; //是表示字符設(shè)備的內(nèi)核的內(nèi)部結(jié)構(gòu)。當inode指向一個字符設(shè)備文件時,該字段包含了指向struct cdev結(jié)構(gòu)的指針。 //我們也可以使用下邊兩個宏從inode中獲得主設(shè)備號和此設(shè)備號: unsigned int iminor(struct inode *inode); unsigned int imajor(struct inode *inode);

(3)struct file_operations

本部分來源于:http://blog.chinaunix.net/space.php?uid=20729583&do=blog&id=1884550,感謝chinahhucai的分享。

struct file_operations ***_ops={.owner = THIS_MODULE,.llseek = ***_llseek,.read = ***_read,.write = ***_write,.ioctl = ***_ioctl,.open = ***_open,.release = ***_release, 。。。 。。。 };struct module *owner;/*第一個 file_operations 成員根本不是一個操作; 它是一個指向擁有這個結(jié)構(gòu)的模塊的指針.這個成員用來在它的操作還在被使用時阻止模塊被卸載. 幾乎所有時間中, 它被簡單初始化為 THIS_MODULE, 一個在 <linux/module.h> 中定義的宏.這個宏比較復(fù)雜,在進行簡單學(xué)習(xí)操作的時候,一般初始化為THIS_MODULE。*/loff_t (*llseek) (struct file * filp , loff_t p, int orig); /*(指針參數(shù)filp為進行讀取信息的目標文件結(jié)構(gòu)體指針;參數(shù) p 為文件定位的目標偏移量;參數(shù)orig為對文件定位 的起始地址,這個值可以為文件開頭(SEEK_SET,0,當前位置(SEEK_CUR,1),文件末尾(SEEK_END,2)) llseek 方法用作改變文件中的當前讀/寫位置, 并且新位置作為(正的)返回值. loff_t 參數(shù)是一個"long offset", 并且就算在 32位平臺上也至少 64 位寬. 錯誤由一個負返回值指示. 如果這個函數(shù)指針是 NULL, seek 調(diào)用會以潛在地無法預(yù)知的方式修改 file 結(jié)構(gòu)中的位置計數(shù)器( 在"file 結(jié)構(gòu)" 一節(jié)中描述).*/ssize_t (*read) (struct file * filp, char __user * buffer, size_t size , loff_t * p); /*(指針參數(shù) filp 為進行讀取信息的目標文件,指針參數(shù)buffer 為對應(yīng)放置信息的緩沖區(qū)(即用戶空間內(nèi)存地址), 參數(shù)size為要讀取的信息長度,參數(shù) p 為讀的位置相對于文件開頭的偏移,在讀取信息后,這個指針一般都會移動,移動的值為要讀取信息的長度值) 這個函數(shù)用來從設(shè)備中獲取數(shù)據(jù). 在這個位置的一個空指針導(dǎo)致 read 系統(tǒng)調(diào)用以 -EINVAL("Invalid argument") 失敗.一個非負返回值代表了成功讀取的字節(jié)數(shù)( 返回值是一個 "signed size" 類型, 常常是目標平臺本地的整數(shù)類型).*/ssize_t (*aio_read)(struct kiocb * , char __user * buffer, size_t size , loff_t p); /*可以看出,這個函數(shù)的第一、三個參數(shù)和本結(jié)構(gòu)體中的read()函數(shù)的第一、三個參數(shù)是不同 的, 異步讀寫的第三個參數(shù)直接傳遞值,而同步讀寫的第三個參數(shù)傳遞的是指針,因為AIO從來不需要改變文件的位置。 異步讀寫的第一個參數(shù)為指向kiocb結(jié)構(gòu)體的指針,而同步讀寫的第一參數(shù)為指向file結(jié)構(gòu)體的指針,每一個I/O請求都對應(yīng)一個kiocb結(jié)構(gòu)體); 初始化一個異步讀 -- 可能在函數(shù)返回前不結(jié)束的讀操作.如果這個方法是 NULL, 所有的操作會由 read 代替進行(同步地). (有關(guān)linux異步I/O,可以參考有關(guān)的資料,《linux設(shè)備驅(qū)動開發(fā)詳解》中給出了詳細的解答)*/ssize_t (*write) (struct file * filp, const char __user * buffer, size_t count, loff_t * ppos); /*(參數(shù)filp為目標文件結(jié)構(gòu)體指針,buffer為要寫入文件的信息緩沖區(qū),count為要寫入信息的長度, ppos為當前的偏移位置,這個值通常是用來判斷寫文件是否越界) 發(fā)送數(shù)據(jù)給設(shè)備. 如果 NULL, -EINVAL 返回給調(diào)用 write 系統(tǒng)調(diào)用的程序. 如果非負, 返回值代表成功寫的字節(jié)數(shù). (注:這個操作和上面的對文件進行讀的操作均為阻塞操作)*/ssize_t (*aio_write)(struct kiocb *, const char __user * buffer, size_t count, loff_t * ppos); /*初始化設(shè)備上的一個異步寫.參數(shù)類型同aio_read()函數(shù);*/int (*readdir) (struct file * filp, void *, filldir_t); /*對于設(shè)備文件這個成員應(yīng)當為 NULL; 它用來讀取目錄, 并且僅對文件系統(tǒng)有用.*/unsigned int (*poll) (struct file *, struct poll_table_struct *); /*(這是一個設(shè)備驅(qū)動中的輪詢函數(shù),第一個參數(shù)為file結(jié)構(gòu)指針,第二個為輪詢表指針) 這個函數(shù)返回設(shè)備資源的可獲取狀態(tài),即POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL等宏的位“或”結(jié)果。 每個宏都表明設(shè)備的一種狀態(tài),如:POLLIN(定義為0x0001)意味著設(shè)備可以無阻塞的讀,POLLOUT(定義為0x0004)意味著設(shè)備可以無阻塞的寫。 (poll 方法是 3 個系統(tǒng)調(diào)用的后端: poll, epoll, 和 select, 都用作查詢對一個或多個文件描述符的讀或?qū)懯欠駮枞?poll 方法應(yīng)當返回一個位掩碼指示是否非阻塞的讀或?qū)懯强赡艿? 并且, 可能地, 提供給內(nèi)核信息用來使調(diào)用進程睡眠直到 I/O 變?yōu)榭赡? 如果一個驅(qū)動的 poll 方法為 NULL, 設(shè)備假定為不阻塞地可讀可寫. (這里通常將設(shè)備看作一個文件進行相關(guān)的操作,而輪詢操作的取值直接關(guān)系到設(shè)備的響應(yīng)情況,可以是阻塞操作結(jié)果,同時也可以是非阻塞操作結(jié)果)*/int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); /*(inode 和 filp 指針是對應(yīng)應(yīng)用程序傳遞的文件描述符 fd 的值, 和傳遞給 open 方法的相同參數(shù). cmd 參數(shù)從用戶那里不改變地傳下來, 并且可選的參數(shù) arg 參數(shù)以一個 unsigned long 的形式傳遞, 不管它是否由用戶給定為一個整數(shù)或一個指針. 如果調(diào)用程序不傳遞第 3 個參數(shù), 被驅(qū)動操作收到的 arg 值是無定義的. 因為類型檢查在這個額外參數(shù)上被關(guān)閉, 編譯器不能警告你如果一個無效的參數(shù)被傳遞給 ioctl, 并且任何關(guān)聯(lián)的錯誤將難以查找.) ioctl 系統(tǒng)調(diào)用提供了發(fā)出設(shè)備特定命令的方法(例如格式化軟盤的一個磁道, 這不是讀也不是寫). 另外, 幾個 ioctl 命令被內(nèi)核識別而不必引用 fops 表.如果設(shè)備不提供 ioctl 方法, 對于任何未事先定義的請求(-ENOTTY, "設(shè)備無這樣的 ioctl"), 系統(tǒng)調(diào)用返回一個錯誤.*/int (*mmap) (struct file *, struct vm_area_struct *); /*mmap 用來請求將設(shè)備內(nèi)存映射到進程的地址空間. 如果這個方法是 NULL, mmap 系統(tǒng)調(diào)用返回 -ENODEV. (如果想對這個函數(shù)有個徹底的了解,那么請看有關(guān)“進程地址空間”介紹的書籍)*/int (*open) (struct inode * inode , struct file * filp ) ; /*(inode 為文件節(jié)點,這個節(jié)點只有一個,無論用戶打開多少個文件,都只是對應(yīng)著一個inode結(jié)構(gòu); 但是filp就不同,只要打開一個文件,就對應(yīng)著一個file結(jié)構(gòu)體,file結(jié)構(gòu)體通常用來追蹤文件在運行時的狀態(tài)信息)盡管這常常是對設(shè)備文件進行的第一個操作, 不要求驅(qū)動聲明一個對應(yīng)的方法. 如果這個項是 NULL, 設(shè)備打開一直成功, 但是你的驅(qū)動不會得到通知. 與open()函數(shù)對應(yīng)的是release()函數(shù)。*/int (*flush) (struct file *); /*flush 操作在進程關(guān)閉它的設(shè)備文件描述符的拷貝時調(diào)用; 它應(yīng)當執(zhí)行(并且等待)設(shè)備的任何未完成的操作. 這個必須不要和用戶查詢請求的 fsync 操作混淆了. 當前, flush 在很少驅(qū)動中使用;SCSI 磁帶驅(qū)動使用它, 例如, 為確保所有寫的數(shù)據(jù)在設(shè)備關(guān)閉前寫到磁帶上. 如果 flush 為 NULL, 內(nèi)核簡單地忽略用戶應(yīng)用程序的請求.*/int (*release) (struct inode *, struct file *); /*release ()函數(shù)當最后一個打開設(shè)備的用戶進程執(zhí)行close()系統(tǒng)調(diào)用的時候,內(nèi)核將調(diào)用驅(qū)動程序release()函數(shù): void release(struct inode inode,struct file *file),release函數(shù)的主要任務(wù)是清理未結(jié)束的輸入輸出操作,釋放資源,用戶自定義排他標志的復(fù)位等。在文件結(jié)構(gòu)被釋放時引用這個操作. 如同 open, release 可以為 NULL.*/int(*synch)(struct file *,struct dentry *,int datasync); //刷新待處理的數(shù)據(jù),允許進程把所有的臟緩沖區(qū)刷新到磁盤。 int (*aio_fsync)(struct kiocb *, int);/*這是 fsync 方法的異步版本.所謂的fsync方法是一個系統(tǒng)調(diào)用函數(shù)。系統(tǒng)調(diào)用fsync 把文件所指定的文件的所有臟緩沖區(qū)寫到磁盤中(如果需要,還包括存有索引節(jié)點的緩沖區(qū))。 相應(yīng)的服務(wù)例程獲得文件對象的地址,并隨后調(diào)用fsync方法。通常這個方法以調(diào)用函數(shù)__writeback_single_inode()結(jié)束, 這個函數(shù)把與被選中的索引節(jié)點相關(guān)的臟頁和索引節(jié)點本身都寫回磁盤。*/int (*fasync) (int, struct file *, int); //這個函數(shù)是系統(tǒng)支持異步通知的設(shè)備驅(qū)動,下面是這個函數(shù)的模板: static int ***_fasync(int fd,struct file *filp,int mode) {struct ***_dev * dev=filp->private_data;return fasync_helper(fd,filp,mode,&dev->async_queue);//第四個參數(shù)為 fasync_struct結(jié)構(gòu)體指針的指針。 //這個函數(shù)是用來處理FASYNC標志的函數(shù)。(FASYNC:表示兼容BSD的fcntl同步操作)當這個標志改變時,驅(qū)動程序中的fasync()函數(shù)將得到執(zhí)行。 } /*此操作用來通知設(shè)備它的 FASYNC 標志的改變. 異步通知是一個高級的主題, 在第 6 章中描述. 這個成員可以是NULL 如果驅(qū)動不支持異步通知.*/int (*lock) (struct file *, int, struct file_lock *); //lock 方法用來實現(xiàn)文件加鎖; 加鎖對常規(guī)文件是必不可少的特性, 但是設(shè)備驅(qū)動幾乎從不實現(xiàn)它. ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); /*這些方法實現(xiàn)發(fā)散/匯聚讀和寫操作. 應(yīng)用程序偶爾需要做一個包含多個內(nèi)存區(qū)的單個讀或?qū)懖僮?這些系統(tǒng)調(diào)用允許它們這樣做而不必對數(shù)據(jù)進行額外拷貝. 如果這些函數(shù)指針為 NULL, read 和 write 方法被調(diào)用( 可能多于一次 ).*/ssize_t (*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void *); /*這個方法實現(xiàn) sendfile 系統(tǒng)調(diào)用的讀, 使用最少的拷貝從一個文件描述符搬移數(shù)據(jù)到另一個. 例如, 它被一個需要發(fā)送文件內(nèi)容到一個網(wǎng)絡(luò)連接的 web 服務(wù)器使用. 設(shè)備驅(qū)動常常使 sendfile 為 NULL.*/ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); /*sendpage 是 sendfile 的另一半; 它由內(nèi)核調(diào)用來發(fā)送數(shù)據(jù), 一次一頁, 到對應(yīng)的文件. 設(shè)備驅(qū)動實際上不實現(xiàn) sendpage.*/unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); /*這個方法的目的是在進程的地址空間找一個合適的位置來映射在底層設(shè)備上的內(nèi)存段中. 這個任務(wù)通常由內(nèi)存管理代碼進行; 這個方法存在為了使驅(qū)動能強制特殊設(shè)備可能有的任何的對齊請求. 大部分驅(qū)動可以置這個方法為 NULL.[10]*/int (*check_flags)(int) //這個方法允許模塊檢查傳遞給 fnctl(F_SETFL...) 調(diào)用的標志. int (*dir_notify)(struct file *, unsigned long); //這個方法在應(yīng)用程序使用 fcntl 來請求目錄改變通知時調(diào)用. 只對文件系統(tǒng)有用; 驅(qū)動不需要實現(xiàn) dir_notify.

?

三、字符設(shè)備驅(qū)動程序設(shè)計

1.設(shè)備注冊
在linux2.6內(nèi)核中,字符設(shè)備使用struct cdev來描述;

struct cdev {struct kobject kobj;//內(nèi)嵌的kobject對象 struct module *owner;//所屬模塊 struct file_operations *ops;//文件操作結(jié)構(gòu)體 struct list_head list;dev_t dev;//設(shè)備號,長度為32位,其中高12為主設(shè)備號,低20位為此設(shè)備號 unsigned int count; };

字符設(shè)備的注冊分為三個步驟:

(1)分配cdev: struct cdev *cdev_alloc(void);
(2)初始化cdev: void cdev_init(struct cdev *cdev, const struct file_operations *fops);
(3)添加cdev: int cdev_add(struct cdev *p, dev_t dev, unsigned count)

/*** cdev_add() - add a char device to the system* @p: the cdev structure for the device* @dev: the first device number for which this device is responsible* @count: the number of consecutive minor numbers corresponding to this* device** cdev_add() adds the device represented by @p to the system, making it* live immediately. A negative error code is returned on failure.*/

?

2.設(shè)備操作的實現(xiàn):file_operations函數(shù)集的實現(xiàn)(要明確某個函數(shù)什么時候被調(diào)用?調(diào)用來做什么操作?)
特別注意:驅(qū)動程序應(yīng)用程序的數(shù)據(jù)交換:
  驅(qū)動程序和應(yīng)用程序的數(shù)據(jù)交換是非常重要的。file_operations中的read()和write()函數(shù),就是用來在驅(qū)動程序和應(yīng)用程序間交換數(shù)據(jù)的。通過數(shù)據(jù)交換,驅(qū)動程序和應(yīng)用程序可以彼此了解對方的情況。但是驅(qū)動程序和應(yīng)用程序?qū)儆诓煌牡刂房臻g。驅(qū)動程序不能直接訪問應(yīng)用程序的地址空間;同樣應(yīng)用程序也不能直接訪問驅(qū)動程序的地址空間,否則會破壞彼此空間中的數(shù)據(jù),從而造成系統(tǒng)崩潰,或者數(shù)據(jù)損壞。安全的方法是使用內(nèi)核提供的專用函數(shù),完成數(shù)據(jù)在應(yīng)用程序空間和驅(qū)動程序空間的交換。這些函數(shù)對用戶程序傳過來的指針進行了嚴格的檢查和必要的轉(zhuǎn)換,從而保證用戶程序與驅(qū)動程序交換數(shù)據(jù)的安全性。這些函數(shù)有:

unsigned long copy_to_user(void __user *to, const void *from, unsigned long n); unsigned long copy_from_user(void *to, const void __user *from, unsigned long n); put_user(local,user); get_user(local,user);

?

3.設(shè)備注銷:void cdev_del(struct cdev *p);

四、字符設(shè)備驅(qū)動小結(jié):

  字符設(shè)備是3大類設(shè)備(字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備)中較簡單的一類設(shè)備,其驅(qū)動程序中完成的主要工作是初始化、添加和刪除cdev結(jié)構(gòu)體,申請和釋放設(shè)備號,以及填充file_operation結(jié)構(gòu)體中操作函數(shù),并實現(xiàn)file_operations結(jié)構(gòu)體中的read()、write()、ioctl()等重要函數(shù)。如圖所示為cdev結(jié)構(gòu)體、file_operations和用戶空間調(diào)用驅(qū)動的關(guān)系。

?

五:字符設(shè)備驅(qū)動程序分析:

(1)memdev.h

#ifndef _MEMDEV_H_ #define _MEMDEV_H_#ifndef MEMDEV_MAJOR #define MEMDEV_MAJOR 251 /*預(yù)設(shè)的mem的主設(shè)備號*/ #endif#ifndef MEMDEV_NR_DEVS #define MEMDEV_NR_DEVS 2 /*設(shè)備數(shù)*/ #endif#ifndef MEMDEV_SIZE #define MEMDEV_SIZE 4096 #endif/*mem設(shè)備描述結(jié)構(gòu)體*/ struct mem_dev { char *data; unsigned long size; };#endif /* _MEMDEV_H_ */

?

(2)memdev.c

static mem_major = MEMDEV_MAJOR;module_param(mem_major, int, S_IRUGO);struct mem_dev *mem_devp; /*設(shè)備結(jié)構(gòu)體指針*/struct cdev cdev; /*文件打開函數(shù)*/ int mem_open(struct inode *inode, struct file *filp) {struct mem_dev *dev;/*獲取次設(shè)備號*/int num = MINOR(inode->i_rdev);if (num >= MEMDEV_NR_DEVS) return -ENODEV;dev = &mem_devp[num];/*將設(shè)備描述結(jié)構(gòu)指針賦值給文件私有數(shù)據(jù)指針*/filp->private_data = dev;return 0; }/*文件釋放函數(shù)*/ int mem_release(struct inode *inode, struct file *filp) {return 0; }/*讀函數(shù)*/ static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) {unsigned long p = *ppos; /*記錄文件指針偏移位置*/ unsigned int count = size; /*記錄需要讀取的字節(jié)數(shù)*/ int ret = 0; /*返回值*/ struct mem_dev *dev = filp->private_data; /*獲得設(shè)備結(jié)構(gòu)體指針*//*判斷讀位置是否有效*/if (p >= MEMDEV_SIZE) /*要讀取的偏移大于設(shè)備的內(nèi)存空間*/ return 0;if (count > MEMDEV_SIZE - p) /*要讀取的字節(jié)大于設(shè)備的內(nèi)存空間*/ count = MEMDEV_SIZE - p;/*讀數(shù)據(jù)到用戶空間:內(nèi)核空間->用戶空間交換數(shù)據(jù)*/ if (copy_to_user(buf, (void*)(dev->data + p), count)){ret = - EFAULT;}else{*ppos += count;ret = count;printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);}return ret; }/*寫函數(shù)*/ static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos) {unsigned long p = *ppos;unsigned int count = size;int ret = 0;struct mem_dev *dev = filp->private_data; /*獲得設(shè)備結(jié)構(gòu)體指針*//*分析和獲取有效的寫長度*/if (p >= MEMDEV_SIZE)return 0;if (count > MEMDEV_SIZE - p) /*要寫入的字節(jié)大于設(shè)備的內(nèi)存空間*/count = MEMDEV_SIZE - p;/*從用戶空間寫入數(shù)據(jù)*/if (copy_from_user(dev->data + p, buf, count))ret = - EFAULT;else{*ppos += count; /*增加偏移位置*/ ret = count; /*返回實際的寫入字節(jié)數(shù)*/ printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);}return ret; }/* seek文件定位函數(shù) */ static loff_t mem_llseek(struct file *filp, loff_t offset, int whence) { loff_t newpos; switch(whence) {case 0: /* SEEK_SET */ /*相對文件開始位置偏移*/ newpos = offset; /*更新文件指針位置*/break;case 1: /* SEEK_CUR */newpos = filp->f_pos + offset; break;case 2: /* SEEK_END */newpos = MEMDEV_SIZE -1 + offset;break;default: /* can't happen */return -EINVAL;}if ((newpos<0) || (newpos>MEMDEV_SIZE))return -EINVAL;filp->f_pos = newpos;return newpos;}/*文件操作結(jié)構(gòu)體*/ static const struct file_operations mem_fops = {.owner = THIS_MODULE,.llseek = mem_llseek,.read = mem_read,.write = mem_write,.open = mem_open,.release = mem_release, };/*設(shè)備驅(qū)動模塊加載函數(shù)*/ static int memdev_init(void) {int result;int i;dev_t devno = MKDEV(mem_major, 0);/* 申請設(shè)備號,當xxx_major不為0時,表示靜態(tài)指定;當為0時,表示動態(tài)申請*/ /* 靜態(tài)申請設(shè)備號*/if (mem_major)result = register_chrdev_region(devno, 2, "memdev");else /* 動態(tài)分配設(shè)備號 */{result = alloc_chrdev_region(&devno, 0, 2, "memdev");mem_major = MAJOR(devno); /*獲得申請的主設(shè)備號*/} if (result < 0)return result;/*初始化cdev結(jié)構(gòu),并傳遞file_operations結(jié)構(gòu)指針*/ cdev_init(&cdev, &mem_fops); cdev.owner = THIS_MODULE; /*指定所屬模塊*/cdev.ops = &mem_fops;/* 注冊字符設(shè)備 */cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);/* 為設(shè)備描述結(jié)構(gòu)分配內(nèi)存*/mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);if (!mem_devp) /*申請失敗*/{result = - ENOMEM;goto fail_malloc;}memset(mem_devp, 0, sizeof(struct mem_dev));/*為設(shè)備分配內(nèi)存*/for (i=0; i < MEMDEV_NR_DEVS; i++) {mem_devp[i].size = MEMDEV_SIZE;mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);memset(mem_devp[i].data, 0, MEMDEV_SIZE);}return 0;fail_malloc: unregister_chrdev_region(devno, 1);return result; }/*模塊卸載函數(shù)*/ static void memdev_exit(void) {cdev_del(&cdev); /*注銷設(shè)備*/kfree(mem_devp); /*釋放設(shè)備結(jié)構(gòu)體內(nèi)存*/unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*釋放設(shè)備號*/ }MODULE_AUTHOR("David Xie"); MODULE_LICENSE("GPL");module_init(memdev_init); module_exit(memdev_exit);



(3)應(yīng)用程序(測試文件):app-mem.c

#include <stdio.h>int main() {FILE *fp0 = NULL;char Buf[4096];/*初始化Buf*/strcpy(Buf,"Mem is char dev!");printf("BUF: %s\n",Buf);/*打開設(shè)備文件*/fp0 = fopen("/dev/memdev0","r+");if (fp0 == NULL){printf("Open Memdev0 Error!\n");return -1;}/*寫入設(shè)備*/fwrite(Buf, sizeof(Buf), 1, fp0);/*重新定位文件位置(思考沒有該指令,會有何后果)*/fseek(fp0,0,SEEK_SET);/*清除Buf*/strcpy(Buf,"Buf is NULL!");printf("BUF: %s\n",Buf);/*讀出設(shè)備*/fread(Buf, sizeof(Buf), 1, fp0);/*檢測結(jié)果*/printf("BUF: %s\n",Buf);return 0; }

測試步驟:

1)cat /proc/devices看看有哪些編號已經(jīng)被使用,我們選一個沒有使用的XXX。 2)insmod memdev.ko 3)通過"mknod /dev/memdev0 c XXX 0"命令創(chuàng)建"/dev/memdev0"設(shè)備節(jié)點。 4)交叉編譯app-mem.c文件,下載并執(zhí)行: #./app-mem,顯示: Mem is char dev!
參考網(wǎng)址:http://www.cnblogs.com/geneil/archive/2011/12/03/2272869.html 參考網(wǎng)址: http://blog.chinaunix.net/uid-26833883-id-4371047.html 與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的【Linux驱动】字符设备驱动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

在线观看你懂的网站 | 久久观看免费视频 | 成人观看视频 | 91综合久久一区二区 | av黄色在线观看 | 天天激情站 | 日本精品视频在线 | 九九交易行官网 | 国产精品成人免费一区久久羞羞 | 久久人人爽人人爽人人片av软件 | 爱色av.com| 久草爱视频 | 欧美va天堂va视频va在线 | 国产精品视频免费在线观看 | 五月婷婷在线观看视频 | 久久精品视频网址 | 国产视频中文字幕 | 色视频网站在线观看一=区 a视频免费在线观看 | 久久久久久久久毛片精品 | 免费三级骚| 黄色大片网 | 五月婷婷六月丁香在线观看 | 亚洲精品视频网址 | 日韩视频专区 | 免费高清无人区完整版 | 丁香婷婷在线 | 精品视频亚洲 | 少妇资源站 | 插插插色综合 | 日韩精品高清不卡 | 97在线看| 亚洲视频免费在线观看 | 国产 成人 久久 | 综合网欧美 | 免费看的国产视频网站 | 国产在线高清 | 狠狠色噜噜狠狠狠合久 | 狠狠干网址 | av在线一级 | 亚洲成人资源网 | 久久国产精品99久久久久久丝袜 | 亚洲最大成人网4388xx | 国产无套精品久久久久久 | 亚洲aⅴ久久精品 | 三级av中文字幕 | 美女视频黄的免费的 | 狠狠躁日日躁夜夜躁av | 成人高清在线观看 | 免费看片黄色 | 亚洲视频电影在线 | 91av在线播放视频 | 日日日爽爽爽 | 97精品电影院 | 91在线91拍拍在线91 | 男女啪啪免费网站 | 中文字幕在线资源 | 在线直播av | 高潮久久久久久久久 | 国产午夜在线观看 | 伊人网综合在线观看 | 免费av小说 | 欧美成人精品欧美一级乱黄 | 黄色a级片在线观看 | 2022中文字幕在线观看 | 国产在线一卡 | 99视频国产精品 | 久久久久久中文字幕 | 天堂av在线网站 | 久久久精品久久日韩一区综合 | 中文成人字幕 | 国产精品久久久毛片 | 特级黄色一级 | 伊人婷婷 | 欧美a级成人淫片免费看 | 免费看黄色91 | 久久久久久久久久久黄色 | 99久e精品热线免费 99国产精品久久久久久久久久 | 在线中文视频 | 日韩久久久久 | 日韩欧美一区二区不卡 | 三三级黄色片之日韩 | 亚洲成人国产精品 | 麻豆一区在线观看 | 国产在线资源 | 青草视频在线 | 五月在线视频 | 国产一级二级在线观看 | 亚州五月| 久久99国产综合精品 | 日本69hd | 性色av免费在线观看 | a在线观看视频 | 国产成人在线一区 | 日日夜夜婷婷 | 国产伦精品一区二区三区免费 | 亚洲免费婷婷 | 免费国产亚洲视频 | 日韩电影久久久 | 91亚洲精品久久久蜜桃借种 | 麻豆传媒视频在线 | 91网在线 | 99久久精品无码一区二区毛片 | 国产+日韩欧美 | 西西大胆啪啪 | 欧美一区二区三区特黄 | 国精产品999国精产品岳 | 成人一区二区三区在线观看 | 亚洲精品视频免费在线观看 | 成人a视频在线观看 | 97手机电影网 | 日韩av有码在线 | 成人avav| 成人97视频一区二区 | 国产污视频在线观看 | 天天操天天干天天综合网 | 日韩在线三级 | 碰超人人| 精品 一区 在线 | 91网址在线看 | 夜夜视频资源 | 日韩av免费一区二区 | 蜜臀av在线一区二区三区 | 国产成人中文字幕 | 国产成人精品久久亚洲高清不卡 | 91人人在线 | 狠狠干狠狠久久 | 亚洲一区二区三区在线看 | 久久人人97超碰精品888 | 欧美一级片免费在线观看 | 五月天久久久久 | 亚洲精品国产精品国自 | 四虎国产精品免费 | 亚洲免费在线观看视频 | 久久久999免费视频 日韩网站在线 | 日本黄色免费网站 | 国产精品日韩在线观看 | 国内免费久久久久久久久久久 | 91在线视频免费观看 | 手机av资源 | 欧美日韩一区二区视频在线观看 | 国产剧情一区二区在线观看 | 久久久午夜剧场 | www.亚洲视频 | 日韩在线欧美在线 | 亚洲精品视频网址 | 国产精品99久久久久久久久 | 欧美男男tv网站 | 日韩电影在线观看一区二区三区 | 精品国产一区二区三区噜噜噜 | 91超在线| 日韩久久久 | 日韩精品三区四区 | 狠狠色丁香婷婷综合久小说久 | 成人作爱视频 | 国产黄免费在线观看 | 久久久久电影网站 | 欧美夫妻性生活电影 | 国产99久久久久久免费看 | 天天草天天干 | 激情网站网址 | 国产国语在线 | 中文字幕传媒 | 懂色av懂色av粉嫩av分享吧 | 精品久久久国产 | 国产精品爽爽久久久久久蜜臀 | 亚洲天堂视频在线 | 九九九热 | 91精品久久久久久综合乱菊 | 天天色官网 | 久久精品毛片 | 四虎国产免费 | 久久99在线视频 | 激情网五月天 | 91精品国产综合久久婷婷香蕉 | 亚洲闷骚少妇在线观看网站 | 国产精品99久久久久的智能播放 | 国产粉嫩在线 | 国产精品免费一区二区三区在线观看 | 精品国产成人av在线免 | 国产在线观看你懂的 | 国产精品一区二区在线播放 | 国产精品久久久久久久久久东京 | 亚洲电影自拍 | 国产九色在线播放九色 | 日韩精品一区二区三区不卡 | 国产精品资源 | 视频在线观看91 | av中文字幕在线观看网站 | 色狠狠婷婷 | 最近最新mv字幕免费观看 | 四川妇女搡bbbb搡bbbb搡 | 色综合天天爱 | 国产精品久久一 | 成人av免费| 久久久久久久久久久免费 | 欧美精品中文在线免费观看 | 免费福利在线观看 | 国产福利一区二区三区在线观看 | 日韩成人免费电影 | 日本色小说视频 | 免费在线播放黄色 | 亚洲视频www | 91c网站色版视频 | 欧美一二三视频 | 精品a在线 | 国产流白浆高潮在线观看 | 免费色视频在线 | 国内精品免费 | 日韩在线精品一区 | 亚洲 综合 国产 精品 | 在线视频欧美日韩 | 国产免费又粗又猛又爽 | 夜夜爽天天爽 | 国产淫a| 日日夜夜人人精品 | 亚洲黄色一级视频 | 91成人区 | 日韩欧美在线视频一区二区三区 | 亚洲午夜久久久久 | 久久麻豆精品 | 日本免费久久高清视频 | 91色一区二区三区 | 亚洲美女精品区人人人人 | 欧美日韩不卡在线 | 黄在线免费看 | 欧美精品在线观看免费 | 91最新视频 | 日韩在线视频网址 | 国产在线观看91 | 一区二区三区四区不卡 | 毛片黄色一级 | 最近更新好看的中文字幕 | 天天综合网久久综合网 | 夜夜视频| 日韩精品三区四区 | 久久女同性恋中文字幕 | 日韩黄在线观看 | 一区二区视频在线看 | 成人黄色在线播放 | 夜夜躁狠狠躁日日躁 | 色综合天天综合 | 亚洲视频精品在线 | 日本最新一区二区三区 | 精品久久久久久久久久久久 | 久久国内视频 | 手机色站| 黄色大片中国 | 免费福利片 | 一本到视频在线观看 | 日本中文字幕在线观看 | 五月天婷婷在线观看视频 | 国产精品视频免费在线观看 | 免费看污在线观看 | 日韩一区二区三区在线观看 | 国产中文在线字幕 | 成人av免费 | 日本中文字幕在线免费观看 | 一本到视频在线观看 | 在线黄频| 婷婷五月在线视频 | www.com久久久| 亚洲国产精品成人av | 国产高潮久久 | 麻豆va一区二区三区久久浪 | 99在线热播精品免费 | 人人干人人干人人干 | 精品国产一区二区三区不卡 | 天天躁天天狠天天透 | 成 人 a v天堂 | 亚洲精品久久久久久久不卡四虎 | 国产黄免费在线观看 | 日韩久久精品 | 九九三级毛片 | 国产精品毛片一区二区在线看 | 不卡中文字幕av | 日韩黄色大片在线观看 | 97精品国产91久久久久久久 | 韩国av免费在线观看 | 欧美午夜a | 久久久久久久av | 69国产精品成人在线播放 | 天天综合网久久综合网 | 色吊丝av中文字幕 | 91久久奴性调教 | 久久免费在线视频 | 成年人黄色av | 国产精品女人网站 | av黄色一级片 | 九九精品毛片 | 久草在线视频资源 | 欧美精品亚洲精品 | 一区二区三区在线播放 | 美女网站视频色 | 国产精品不卡av | 成人小视频在线播放 | 亚洲黄色免费 | 久久精品久久精品久久39 | 玖玖综合网| 丝袜少妇在线 | 久久视频6| 亚洲电影一级黄 | 国产精品99久久久 | 91九色视频国产 | 久精品视频免费观看2 | 中文字幕中文字幕中文字幕 | 日本精品一区二区 | 亚洲精品乱码久久 | 色婷婷丁香 | 久久99精品国产一区二区三区 | 久久免费av电影 | 国产美女视频免费观看的网站 | 丰满少妇在线观看网站 | 日韩精品一区二区三区不卡 | 国产精品久久艹 | 天天综合精品 | 久久久99精品免费观看app | 中文字幕视频一区二区 | 精品一二三四在线 | 99久久精品国产一区 | 13日本xxxxxⅹxxx20 | 中文字幕资源网 | 久久国内精品 | 久久福利综合 | 在线观看岛国片 | 国产在线观看a | 色91av| 99re亚洲国产精品 | 亚洲一区不卡视频 | 在线观看理论 | 亚洲黄色激情小说 | 日日干夜夜操视频 | 国产经典三级 | 久久精品久久精品久久 | 久草在线网址 | 欧洲精品一区二区 | 亚洲伊人天堂 | 波多野结衣在线观看一区二区三区 | 久久久久久久久久久高潮一区二区 | 国产美女无遮挡永久免费 | 成人中文字幕在线 | 欧美日韩免费观看一区二区三区 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 日日操网| 久久人操 | 久热免费在线 | 中文字幕专区高清在线观看 | 麻豆视频在线免费 | 亚洲精品免费在线播放 | 成年人免费电影 | 成人av电影免费在线播放 | 欧美日韩国产欧美 | www.午夜视频 | 欧美俄罗斯性视频 | 国产v在线 | 亚洲人成综合 | 一区二区三区 中文字幕 | 国产系列在线观看 | 日本在线成人 | 中文字幕在线观看日本 | 91在线你懂的 | 中文字幕av全部资源www中文字幕在线观看 | 久久99久久99| 鲁一鲁影院 | 久久国产精品免费看 | 狠狠综合网 | 日韩电影在线观看一区二区三区 | 亚洲视频在线视频 | 日韩av不卡在线 | 久久精品99国产精品亚洲最刺激 | 日本激情视频中文字幕 | 在线免费观看视频一区 | 欧美一区在线看 | 黄色在线观看www | 久久综合九色综合欧美狠狠 | 九九视频热| 亚洲精品视频在线看 | 天天干天天操天天搞 | www.狠狠色 | 成年人免费在线播放 | 91精品国产综合久久久久久久 | 日韩系列在线观看 | 免费观看91 | 免费精品在线视频 | 亚洲精品乱码久久久久久 | 97视频总站 | 日本黄色一级电影 | 婷婷在线免费观看 | 2021久久| 国产精品美乳一区二区免费 | 久操97 | 日日碰狠狠添天天爽超碰97久久 | 91高清免费观看 | 国产精品欧美日韩在线观看 | 91亚洲国产成人 | 麻豆视频免费入口 | 亚洲高清av | 日韩av一区二区在线影视 | 亚洲国产精品va在线看黑人动漫 | se婷婷 | 黄色小说免费在线观看 | 日韩网站在线 | 国产精品成人国产乱 | 国产精品一区二区62 | 中文字幕高清有码 | 伊人官网| 精品国模一区二区三区 | 99免费精品视频 | 国产91精品一区二区绿帽 | 在线亚洲日本 | 免费看毛片在线 | 日日干视频 | 久久久久久久国产精品 | 在线观看av小说 | 97精品国产手机 | 国产免费一区二区三区最新6 | 国模精品一区二区三区 | 麻豆一二 | 日本h视频在线观看 | 欧美一性一交一乱 | 国产视频资源在线观看 | 色视频在线看 | 国产精品自产拍在线观看蜜 | 91精品影视| 视频 天天草 | 久久草| 国产精品美女久久久网av | 国产视频一区二区三区在线 | 国产精品一区一区三区 | 国语自产偷拍精品视频偷 | 伊人电影在线观看 | 一区二区三区影院 | 91看片在线播放 | 国产精品美女毛片真酒店 | 丁香网五月天 | 丝袜一区在线 | 婷婷丁香九月 | 日韩网站一区 | 玖玖视频免费在线 | 五月精品 | 日韩电影久久 | 国产精品亚洲综合久久 | 色夜视频 | 尤物一区二区三区 | 国产精品久久久久久久久软件 | 久久精品国产成人精品 | 日韩激情免费视频 | 97精品在线 | 午夜丁香视频在线观看 | 精品国产一区二区三区四区vr | 91福利在线观看 | 天天操天天艹 | 美女视频黄是免费的 | 亚洲一区视频免费观看 | 国产一区观看 | 久草视频网| 免费看v片网站 | 狠狠色狠狠色 | 天天爽夜夜爽精品视频婷婷 | 国产精品永久久久久久久久久 | 久久久久久久久久久综合 | 99精品一级欧美片免费播放 | 国产精品激情 | 人人超在线公开视频 | 成年人免费观看在线视频 | 欧美日韩综合在线观看 | 丁香婷婷久久久综合精品国产 | 99精品色| 久久久久亚洲国产精品 | 探花国产在线 | 国产精品区在线观看 | 超薄丝袜一二三区 | 99免费在线观看视频 | 精品国产精品一区二区夜夜嗨 | 日日狠狠| 久久成人一区 | 免费男女羞羞的视频网站中文字幕 | av免费高清观看 | 国内精品视频在线播放 | 99综合影院在线 | 制服丝袜在线91 | 人人爱在线视频 | 国产精品激情在线观看 | 国产亚洲婷婷 | 天天干天天拍天天操天天拍 | 亚洲乱码久久久 | 国产精品久久久久久久7电影 | 久久免费黄色网址 | 日韩欧美在线不卡 | www.伊人色.com | 日韩av电影中文字幕 | 狠狠狠狠狠狠干 | 夜夜嗨av色一区二区不卡 | 91午夜精品| 亚洲91网站 | 成人一级黄色片 | 91在线视频导航 | 96视频在线 | 91精品国产麻豆国产自产影视 | 青青草久草在线 | 国产 日韩 在线 亚洲 字幕 中文 | 日韩中文字幕视频在线观看 | 少妇视频一区 | 日韩欧美一区二区三区免费观看 | 五月激情姐姐 | 美女黄色网在线播放 | 亚洲高清视频一区二区三区 | 欧美性生活大片 | 99热精品在线 | 久久专区 | 午夜久久电影网 | 四月婷婷在线观看 | 日韩欧美视频免费在线观看 | 国产精品99久久免费观看 | 91丨九色丨高潮 | 精品久久久久久亚洲综合网站 | 免费看在线看www777 | 久久优 | 久久只精品99品免费久23小说 | 欧美日韩一区二区在线观看 | 亚洲一区日韩在线 | 麻豆va一区二区三区久久浪 | 国产福利专区 | 五月婷婷六月综合 | 免费无遮挡动漫网站 | 国产麻豆成人传媒免费观看 | 福利一区在线视频 | 99r在线精品 | 亚洲精品av中文字幕在线在线 | 天天色成人网 | 亚洲国产精品va在线看 | 91免费的视频在线播放 | 国产麻豆精品久久一二三 | 国产一区二区精品久久 | 人人插人人澡 | 91av大全 | 久草精品视频在线观看 | 丰满少妇对白在线偷拍 | 亚洲欧美婷婷六月色综合 | 精品久久久久国产 | 中中文字幕av在线 | av电影一区二区 | 国产一级在线视频 | 在线视频1卡二卡三卡 | 国产精品精品视频 | 久久夜夜夜| 精品久久久久久久久久久久久久久久久久 | 国产精品99久久久久久久久 | v片在线播放 | 国内精品久久久久久久 | 国产日韩精品一区二区在线观看播放 | 日韩精品中文字幕在线观看 | 国际精品网 | 久久免费视频精品 | 午夜精品视频在线 | 国产精品福利在线观看 | 色婷婷九月 | 香蕉视频亚洲 | 91人人人| 91网页版在线观看 | 久久久一本精品99久久精品 | 西西人体4444www高清视频 | 国产精品福利小视频 | 国产欧美久久久精品影院 | 国产原厂视频在线观看 | 91亚洲国产 | 久久成人欧美 | 日韩亚洲在线视频 | 久久99国产精品久久99 | 欧美另类69 | 中文字幕日本电影 | 欧美成人免费在线 | 欧美在线视频精品 | 婷婷色5月 | 亚洲精品在线免费观看视频 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 韩国精品一区二区三区六区色诱 | 永久免费观看视频 | 午夜神马福利 | 五月婷婷一级片 | 欧美做受高潮 | 91成人精品一区在线播放69 | 91av在线播放视频 | 99热日本| 精品国产一二三 | v片在线播放 | 日韩黄视频 | 国产一级视屏 | 亚洲高清91 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 人人插人人艹 | 99久热在线精品视频 | 毛片网站免费在线观看 | 精品欧美小视频在线观看 | 九色在线视频 | 草久在线| 狠狠干成人 | 久久精品福利视频 | 麻豆91精品视频 | 97在线精品国自产拍中文 | 国产日韩在线看 | 欧美午夜精品久久久久久孕妇 | 激情婷婷 | 成人黄色影片在线 | 午夜影院日本 | 国产精品福利av | 国产成人一二三 | 亚洲色图激情文学 | 国产精品久久久一区二区三区网站 | 精品麻豆入口免费 | 丁香六月婷婷开心婷婷网 | 国产精品一级视频 | 999视频精品 | www.五月激情.com | 日日干天天干 | 国产正在播放 | 日日摸日日添夜夜爽97 | 香蕉视频日本 | 亚洲少妇天堂 | 日韩中文字幕在线不卡 | 97精品国产91久久久久久 | 五月天伊人 | 综合国产在线 | 国产成人精品av久久 | 亚洲午夜久久久久久久久电影网 | 成人中文字幕av | 青青河边草观看完整版高清 | 中文字幕视频免费观看 | 国产玖玖精品视频 | 国产日韩欧美在线 | 日韩精品观看 | 亚洲午夜大片 | 中文字幕在线看视频国产中文版 | 日韩精品视频在线免费观看 | 五月天久久 | 成人h动漫精品一区二 | 丰满少妇高潮在线观看 | 日韩有码专区 | 国产高清无线码2021 | 国产精品免费成人 | 午夜久久影视 | 色综合久久中文综合久久牛 | 毛片永久免费 | 国产在线超碰 | 亚洲欧美综合 | 日韩黄色大片在线观看 | 成人丝袜 | 一级性生活片 | 色夜视频 | 手机在线中文字幕 | 成人精品福利 | 国内外成人在线视频 | 婷婷激情综合五月天 | 成人在线中文字幕 | 6080yy精品一区二区三区 | 色视频网站在线观看一=区 a视频免费在线观看 | 99视频偷窥在线精品国自产拍 | 国产三级香港三韩国三级 | 五月丁色 | 国产丝袜制服在线 | 免费看污片 | 国产黄色大全 | 久久好看免费视频 | 美女网站在线免费观看 | 久色伊人 | www激情久久 | 99视频精品| 日本乱码在线 | 91av国产视频| 丁香激情综合 | 久久精品国产99 | 日本成人中文字幕在线观看 | 久久99精品国产99久久 | 福利av影院 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 欧美日韩免费在线观看视频 | 人九九精品 | 国产精品第72页 | 摸阴视频 | 视频三区 | 波多野结衣精品 | 国内精品久久久久久中文字幕 | 不卡的av电影在线观看 | 96精品视频| 国产一级二级在线 | 精品中文字幕在线 | 日本精品免费看 | 91麻豆操 | 天天拍天天草 | 在线视频app | 天天干,狠狠干 | 日韩xxxx视频 | 天天草av| 国产色拍拍拍拍在线精品 | 二区三区在线视频 | 日韩欧美一区二区三区视频 | 婷婷伊人综合亚洲综合网 | 久热色超碰 | 在线观看免费av网 | 97在线观看视频免费 | 不卡视频国产 | 一区二区中文字幕在线播放 | 婷婷在线网 | 成人av观看 | 久久久久久激情 | 亚洲精品中文字幕视频 | 亚州欧美视频 | 天天操天天艹 | 97视频在线观看网址 | 欧美一二三区在线观看 | 看片网站黄 | 免费av网址大全 | 欧美va天堂va视频va在线 | 国产精品婷婷 | 国产夫妻性生活自拍 | 国产精品欧美久久久久无广告 | 91麻豆精品一区二区三区 | 亚洲97在线 | 九九久久久久久久久激情 | 精品视频99 | 中文字幕网站视频在线 | 国产精品成人aaaaa网站 | 黄色一级免费 | 国产精品免费观看网站 | 久草在线久草在线2 | 国产成人在线免费观看 | 在线观看免费视频你懂的 | 欧美一二三四在线 | 国产精品成人在线观看 | 欧美一级片在线观看视频 | 成人性生交大片免费看中文网站 | 国产视频精品视频 | 99免费在线观看视频 | 91完整版观看 | 中文字幕人成人 | 欧美一区日韩精品 | 五月婷婷久久丁香 | 人人干人人超 | 国产精品久久久久一区 | 狠狠色丁香婷综合久久 | 免费精品人在线二线三线 | 久久精品影片 | 手机看国产毛片 | 精品久久久久久一区二区里番 | 国产综合精品一区二区三区 | 国产在线观看99 | 密桃av在线| 国产日韩在线观看一区 | 视频91在线 | 国产精品18久久久久久久网站 | 日韩免费播放 | 国产一区二区三区在线 | 色免费在线 | 一级欧美日韩 | www久久99| 日韩精品一区二区三区在线播放 | 天天爽综合网 | 久久久久久蜜av免费网站 | 色综合天 | 亚洲精品视频偷拍 | 日韩欧美在线国产 | 丝袜美腿在线视频 | 日韩精品视频久久 | 国产美女无遮挡永久免费 | 久久久资源 | 国产特级毛片 | 国产成视频在线观看 | 精品一区二三区 | 制服丝袜一区二区 | 成人黄色小说网 | 天天骚夜夜操 | 国产99在线免费 | 天天插天天操天天干 | 日日碰狠狠添天天爽超碰97久久 | 最近日韩中文字幕中文 | 蜜臀av夜夜澡人人爽人人桃色 | 91在线日本| 中文字幕日韩国产 | 国产一级片播放 | 国产成人亚洲在线电影 | 婷婷色狠狠 | 日韩最新在线视频 | 欧美福利精品 | 亚洲国产成人精品久久 | 国产美女精品在线 | 亚洲欧洲精品一区二区 | 久久99精品国产麻豆宅宅 | 日韩在线电影一区 | 99riav1国产精品视频 | 成人网大片| 久久中文字幕在线视频 | 伊人成人激情 | 天天操天天操天天 | 综合在线色 | 97人人网| 亚洲综合爱 | 97视频在线看 | 欧美一级欧美一级 | 亚洲一级片 | 91亚洲精品久久久中文字幕 | 日韩中文字幕一区 | 四虎在线观看精品视频 | av免费在线观看1 | 日本 在线 视频 中文 有码 | www.黄色在线| 国产一区高清在线 | 国产视频资源 | 在线观看的av | 在线中文字幕一区二区 | 亚洲精品国产精品国自产观看浪潮 | 国产91全国探花系列在线播放 | 久久国产视频网站 | 天天操天天操天天操天天操天天操 | 欧美激情视频一区 | 国产精品免费一区二区三区在线观看 | 欧美在线观看视频免费 | 国产视频欧美视频 | 黄色av免费看 | 97在线看| 91亚洲精品久久久久图片蜜桃 | 美腿丝袜一区二区三区 | 国产69精品久久99的直播节目 | 91麻豆精品久久久久久 | 黄色国产区 | 欧美色图亚洲图片 | 国产一区二三区好的 | 麻豆视频免费在线播放 | 日日夜夜网| 91亚洲精品久久久蜜桃 | 999热线在线观看 | 亚洲欧美综合精品久久成人 | 国产黄色看片 | 久久国产99| 丁香av在线 | 日日夜夜狠狠操 | 亚洲日本在线视频观看 | 一区二区三区久久精品 | 国产精品porn | 亚洲综合色播 | 就色干综合 | 一二三区高清 | 国产精品久久久久久欧美 | 国产亚洲精品精品精品 | 欧美一区二区在线免费观看 | 亚洲观看黄色网 | 免费国产黄线在线观看视频 | 天天搞天天干 | 久久1区| 日韩精品资源 | 狠狠操狠狠干天天操 | 亚洲视频在线观看 | 欧美一区日韩一区 | 国产精品成人av久久 | 五月丁色| 免费在线成人 | 日韩免费电影 | 欧美一级电影在线观看 | 国产精品毛片完整版 | 91九色成人蝌蚪首页 | 久久99热国产 | 美女黄色网在线播放 | 久99热| 免费看污污视频的网站 | 久久国产精品影片 | 成人午夜片av在线看 | 国产精品久久在线 | 久久综合五月婷婷 | 婷婷精品 | 久草视频在 | 日韩大片在线 | 黄色视屏免费在线观看 | 91av看片 | 日日躁夜夜躁xxxxaaaa | 亚洲天堂网在线观看视频 | 中文字幕在线播放第一页 | 国产成人精品一区二区三区网站观看 | 西西大胆免费视频 | 久久久国产一区二区 | 日本黄区免费视频观看 | 337p西西人体大胆瓣开下部 | 私人av | 国产精品毛片久久久久久 | 国产视频二 | 在线观看黄色国产 | 成人精品一区二区三区中文字幕 | 怡红院av久久久久久久 | 亚洲人成在线电影 | 国产精品久久久久影院 | 91视频电影| 精品在线看 | 免费人做人爱www的视 | 国产99久久久国产精品免费看 | 精品在线视频一区 | 91大神在线观看视频 | 精品久久1| 人人澡视频 | 欧美亚洲一区二区在线 | 国产香蕉97碰碰碰视频在线观看 | 99精品偷拍视频一区二区三区 | 麻豆精品传媒视频 | 69xx视频| 99热日本 | 久久成年人网站 | 久久国产精品免费一区二区三区 | 在线观看视频你懂的 | 久久国产亚洲精品 | 国产不卡在线 | 精品久久久久久电影 | 亚洲精品影视 | 成人a免费视频 | 欧美精品免费一区二区 | 亚洲成av人影片在线观看 | 日本久久精品 | 久久久噜噜噜久久久 | 亚洲粉嫩av | 在线天堂日本 | 黄色一二级片 | 久久99国产精品久久 | 中文字幕av免费观看 | 久久久影视 | 天天综合色天天综合 | 日本精品视频免费 | 91精品久久久久久久久久久久久 | 成人h在线| 成人国产网址 | 亚洲 中文 在线 精品 | 国产中文字幕三区 | 狠狠色丁香久久婷婷综 | 中文字幕中文字幕中文字幕 | 色播六月天 | 手机看片福利 | 狠狠干综合网 | 一区二区三区四区五区六区 | 999精品视频 | 中文字幕视频观看 | 成人欧美亚洲 | 伊人丁香 | 亚洲人久久 | 日日爽视频 | 五月天激情综合 | 日韩精品一区二区三区三炮视频 | 精品中文字幕视频 | 亚洲精品a区 | 久久www免费视频 | 黄在线免费看 | 日韩小视频网站 | 激情综合站 | 亚洲精品免费在线 | 国精产品永久999 | 97国产在线视频 | 国产一区91 | 高清国产午夜精品久久久久久 | 天天玩天天操天天射 | 日韩欧美极品 | 一级片免费观看 | 永久免费视频国产 | 丁香六月欧美 | 国产亚洲欧美日韩高清 | 国产精品成人aaaaa网站 | 久操视频在线观看 | 亚洲精品久久久蜜臀下载官网 | 欧美日韩亚洲在线 | 国产成人久久精品 | 在线高清 | 日韩成人邪恶影片 | 日日夜夜天天久久 | 久久深夜 | 亚洲夜夜综合 | 久久av电影| 色网站在线看 | av免费观看高清 | 波多野结衣视频网址 | 精品久久免费看 | 国产精品久久久久一区 | 99中文字幕在线观看 | 久久精彩视频 | 色综合久久综合中文综合网 | 成人午夜精品福利免费 | 91资源在线| 狠狠的操你 | 国产 色 | 国产欧美精品一区二区三区四区 | 久久综合影院 | 亚洲精品毛片一级91精品 | 久久首页| 久久国产区 | 久操久 | 国产精品a成v人在线播放 | www夜夜| 久久精品久久精品 | 国产精品18久久久久vr手机版特色 | 三级免费黄色 | 国产最新精品视频 | 久久亚洲区 | 黄色视屏在线免费观看 | 国产视频在线观看一区二区 | 日本黄色一级电影 | 九色在线| av福利第一导航 |