日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

linux

linux cached释放_正点原子Linux第四十一章嵌入式Linux LED驱动开发实验

發布時間:2025/3/12 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux cached释放_正点原子Linux第四十一章嵌入式Linux LED驱动开发实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1)資料下載:點擊資料即可下載

2)對正點原子Linux感興趣的同學可以加群討論:935446741

3)關注正點原子公眾號,獲取最新資料更新

第四十一章嵌入式Linux LED驅動開發實驗

上一章我們詳細的講解了字符設備驅動開發步驟,并且用一個虛擬的chrdevbase設備為例帶領大家完成了第一個字符設備驅動的開發。本章我們就開始編寫第一個真正的Linux字符設備驅動。在I.MX6U-ALPHA開發板上有一個LED燈,我們在裸機篇中已經編寫過此LED燈的裸機驅動,本章我們就來學習一下如何編寫Linux下的LED燈驅動。

41.1 Linux下LED燈驅動原理

Linux下的任何外設驅動,最終都是要配置相應的硬件寄存器。所以本章的LED燈驅動最終也是對I.MX6ULL的IO口進行配置,與裸機實驗不同的是,在Linux下編寫驅動要符合Linux的驅動框架。I.MX6U-ALPHA開發板上的LED連接到I.MX6ULL的GPIO1_IO03這個引腳上,因此本章實驗的重點就是編寫Linux下I.MX6UL引腳控制驅動。關于I.MX6ULL的GPIO詳細講解請參考第八章。

41.1.1地址映射

在編寫驅動之前,我們需要先簡單了解一下MMU這個神器,MMU全稱叫做Memory Manage Unit,也就是內存管理單元。在老版本的Linux中要求處理器必須有MMU,但是現在Linux內核已經支持無MMU的處理器了。MMU主要完成的功能如下:

①、完成虛擬空間到物理空間的映射。

②、內存保護,設置存儲器的訪問權限,設置虛擬存儲空間的緩沖特性。

我們重點來看一下第①點,也就是虛擬空間到物理空間的映射,也叫做地址映射。首先了解兩個地址概念:虛擬地址(VA,Virtual Address)、物理地址(PA,Physcical Address)。對于32位的處理器來說,虛擬地址范圍是2^32=4GB,我們的開發板上有512MB的DDR3,這512MB的內存就是物理內存,經過MMU可以將其映射到整個4GB的虛擬空間,如圖41.1.1所示:

圖41.1.1內存映射

物理內存只有512MB,虛擬內存有4GB,那么肯定存在多個虛擬地址映射到同一個物理地址上去,虛擬地址范圍比物理地址范圍大的問題處理器自會處理,這里我們不要去深究,因為MMU是很復雜的一個東西,后續有時間的話正點原子Linux團隊會專門做MMU專題教程。

Linux內核啟動的時候會初始化MMU,設置好內存映射,設置好以后CPU訪問的都是虛擬地址。比如I.MX6ULL的GPIO1_IO03引腳的復用寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的地址為0X020E0068。如果沒有開啟MMU的話直接向0X020E0068這個寄存器地址寫入數據就可以配置GPIO1_IO03的復用功能。現在開啟了MMU,并且設置了內存映射,因此就不能直接向0X020E0068這個地址寫入數據了。我們必須得到0X020E0068這個物理地址在Linux系統里面對應的虛擬地址,這里就涉及到了物理內存和虛擬內存之間的轉換,需要用到兩個函數:ioremap和iounmap。

1、ioremap函數

ioremap函數用于獲取指定物理地址空間對應的虛擬地址空間,定義在arch/arm/include/asm/io.h文件中,定義如下:

示例代碼41.1.1 ioremap函數

1 #define ioremap(cookie,size) __arm_ioremap((cookie),(size), MT_DEVICE)

2

3void __iomem * __arm_ioremap(phys_addr_t phys_addr,size_t size,unsignedint mtype)

4{

5return arch_ioremap_caller(phys_addr, size, mtype,

__builtin_return_address(0));

6}

ioremap是個宏,有兩個參數:cookie和size,真正起作用的是函數__arm_ioremap,此函數有三個參數和一個返回值,這些參數和返回值的含義如下:

phys_addr:要映射給的物理起始地址。

size:要映射的內存空間大小。

mtype:ioremap的類型,可以選擇MT_DEVICE、MT_DEVICE_NONSHARED、MT_DEVICE_CACHED和MT_DEVICE_WC,ioremap函數選擇MT_DEVICE。

返回值:__iomem類型的指針,指向映射后的虛擬空間首地址。

假如我們要獲取I.MX6ULL的IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器對應的虛擬地址,使用如下代碼即可:

#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)

static void __iomem* SW_MUX_GPIO1_IO03;

SW_MUX_GPIO1_IO03 = ioremap(GPIO1_GDIR_BASE, 4);

宏SW_MUX_GPIO1_IO03_BASE是寄存器物理地址,SW_MUX_GPIO1_IO03是映射后的虛擬地址。對于I.MX6ULL來說一個寄存器是4字節(32位)的,因此映射的內存長度為4。映射完成以后直接對SW_MUX_GPIO1_IO03進行讀寫操作即可。

2、iounmap函數

卸載驅動的時候需要使用iounmap函數釋放掉ioremap函數所做的映射,iounmap函數原型如下:

示例代碼41.1.2 iounmap函數原型

void iounmap (volatilevoid __iomem *addr)

iounmap只有一個參數addr,此參數就是要取消映射的虛擬地址空間首地址。假如我們現在要取消掉IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器的地址映射,使用如下代碼即可:

iounmap(SW_MUX_GPIO1_IO03);

41.1.2 I/O內存訪問函數

這里說的I/O是輸入/輸出的意思,并不是我們學習單片機的時候講的GPIO引腳。這里涉及到兩個概念:I/O端口和I/O內存。當外部寄存器或內存映射到IO空間時,稱為I/O端口。當外部寄存器或內存映射到內存空間時,稱為I/O內存。但是對于ARM來說沒有I/O空間這個概念,因此ARM體系下只有I/O內存(可以直接理解為內存)。使用ioremap函數將寄存器的物理地址映射到虛擬地址以后,我們就可以直接通過指針訪問這些地址,但是Linux內核不建議這么做,而是推薦使用一組操作函數來對映射后的內存進行讀寫操作。

1、讀操作函數

讀操作函數有如下幾個:

示例代碼41.1.2.1 讀操作函數

1 u8 readb(constvolatilevoid __iomem *addr)

2 u16 readw(constvolatilevoid __iomem *addr)

3 u32 readl(constvolatilevoid __iomem *addr)

readb、readw和readl這三個函數分別對應8bit、16bit和32bit讀操作,參數addr就是要讀取寫內存地址,返回值就是讀取到的數據。

2、寫操作函數

寫操作函數有如下幾個:

示例代碼41.1.2.2 寫操作函數

1void writeb(u8 value,volatilevoid __iomem *addr)

2void writew(u16 value,volatilevoid __iomem *addr)

3void writel(u32 value,volatilevoid __iomem *addr)

writeb、writew和writel這三個函數分別對應8bit、16bit和32bit寫操作,參數value是要寫入的數值,addr是要寫入的地址。

41.2 硬件原理圖分析

本章實驗硬件原理圖參考8.3小節即可。

41.3 實驗程序編寫

本實驗對應的例程路徑為:開發板光盤->2、Linux驅動例程->2_led。

本章實驗編寫Linux下的LED燈驅動,可以通過應用程序對I.MX6U-ALPHA開發板上的LED燈進行開關操作。

41.3.1 LED燈驅動程序編寫

新建名為“2_led”文件夾,然后在2_led文件夾里面創建VSCode工程,工作區命名為“led”。工程創建好以后新建led.c文件,此文件就是led的驅動文件,在led.c里面輸入如下內容:

示例代碼41.3.1.1 led.c驅動文件代碼

1 #include <linux/types.h>

2 #include <linux/kernel.h>

3 #include <linux/delay.h>

4 #include <linux/ide.h>

5 #include <linux/init.h>

6 #include <linux/module.h>

7 #include <linux/errno.h>

8 #include <linux/gpio.h>

9 #include <asm/mach/map.h>

10 #include <asm/uaccess.h>

11 #include <asm/io.h>

12/***************************************************************

13 Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved.

14文件名 : led.c

15作者 : 左忠凱

16版本 : V1.0

17描述 : LED驅動文件。

18其他 : 無

19論壇 : http://www.openedv.com

20日志 : 初版V1.0 2019/1/30 左忠凱創建

21 ***************************************************************/

22 #define LED_MAJOR 200 /* 主設備號 */

23 #define LED_NAME "led" /* 設備名字 */

24

25 #define LEDOFF 0 /* 關燈 */

26 #define LEDON 1 /* 開燈 */

27

28/* 寄存器物理地址 */

29 #define CCM_CCGR1_BASE (0X020C406C)

30 #define SW_MUX_GPIO1_IO03_BASE (0X020E0068)

31 #define SW_PAD_GPIO1_IO03_BASE (0X020E02F4)

32 #define GPIO1_DR_BASE (0X0209C000)

33 #define GPIO1_GDIR_BASE (0X0209C004)

34

35/* 映射后的寄存器虛擬地址指針 */

36staticvoid __iomem *IMX6U_CCM_CCGR1;

37staticvoid __iomem *SW_MUX_GPIO1_IO03;

38staticvoid __iomem *SW_PAD_GPIO1_IO03;

39staticvoid __iomem *GPIO1_DR;

40staticvoid __iomem *GPIO1_GDIR;

41

42/*

43 * @description : LED打開/關閉

44 * @param - sta : LEDON(0) 打開LED,LEDOFF(1) 關閉LED

45 * @return : 無

46 */

47void led_switch(u8 sta)

48{

49 u32 val =0;

50if(sta == LEDON){

51 val = readl(GPIO1_DR);

52 val &=~(1<<3);

53 writel(val, GPIO1_DR);

54}elseif(sta == LEDOFF){

55 val = readl(GPIO1_DR);

56 val|=(1<<3);

57 writel(val, GPIO1_DR);

58}

59}

60

61/*

62 * @description : 打開設備

63 * @param – inode : 傳遞給驅動的inode

64 * @param - filp : 設備文件,file結構體有個叫做private_data的成員變量

65 * 一般在open的時候將private_data指向設備結構體。

66 * @return : 0 成功;其他失敗

67 */

68staticint led_open(struct inode *inode,struct file *filp)

69{

70return0;

71}

72

73/*

74 * @description : 從設備讀取數據

75 * @param - filp : 要打開的設備文件(文件描述符)

76 * @param - buf : 返回給用戶空間的數據緩沖區

77 * @param - cnt : 要讀取的數據長度

78 * @param - offt : 相對于文件首地址的偏移

79 * @return : 讀取的字節數,如果為負值,表示讀取失敗

80 */

81static ssize_t led_read(struct file *filp,char __user *buf,

size_t cnt, loff_t *offt)

82{

83return0;

84}

85

86/*

87 * @description : 向設備寫數據

88 * @param - filp : 設備文件,表示打開的文件描述符

89 * @param - buf : 要寫給設備寫入的數據

90 * @param - cnt : 要寫入的數據長度

91 * @param - offt : 相對于文件首地址的偏移

92 * @return : 寫入的字節數,如果為負值,表示寫入失敗

93 */

94static ssize_t led_write(struct file *filp,constchar __user *buf,

size_t cnt, loff_t *offt)

95{

96int retvalue;

97unsignedchar databuf[1];

98unsignedchar ledstat;

99

100 retvalue = copy_from_user(databuf, buf, cnt);

101if(retvalue <0){

102 printk("kernel write failed!rn");

103return-EFAULT;

104}

105

106 ledstat = databuf[0]; /* 獲取狀態值 */

107

108if(ledstat == LEDON){

109 led_switch(LEDON); /* 打開LED燈 */

110}elseif(ledstat == LEDOFF){

111 led_switch(LEDOFF); /* 關閉LED燈 */

112}

113return0;

114}

115

116/*

117 * @description : 關閉/釋放設備

118 * @param – filp : 要關閉的設備文件(文件描述符)

119 * @return : 0 成功;其他失敗

120 */

121staticint led_release(struct inode *inode,struct file *filp)

122{

123return0;

124}

125

126/* 設備操作函數 */

127staticstruct file_operations led_fops ={

128.owner = THIS_MODULE,

129.open = led_open,

130.read = led_read,

131.write = led_write,

132.release = led_release,

133};

134

135/*

136 * @description : 驅動出口函數

137 * @param : 無

138 * @return : 無

139 */

140staticint __init led_init(void)

141{

142int retvalue =0;

143 u32 val =0;

144

145/* 初始化LED */

146/* 1、寄存器地址映射 */

147 IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE,4);

148 SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE,4);

149 SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE,4);

150 GPIO1_DR = ioremap(GPIO1_DR_BASE,4);

151 GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE,4);

152

153/* 2、使能GPIO1時鐘 */

154 val = readl(IMX6U_CCM_CCGR1);

155 val &=~(3<<26);/* 清除以前的設置 */

156 val |=(3<<26);/* 設置新值 */

157 writel(val, IMX6U_CCM_CCGR1);

158

159/* 3、設置GPIO1_IO03的復用功能,將其復用為

160 * GPIO1_IO03,最后設置IO屬性。

161 */

162 writel(5, SW_MUX_GPIO1_IO03);

163

164/* 寄存器SW_PAD_GPIO1_IO03設置IO屬性 */

165 writel(0x10B0, SW_PAD_GPIO1_IO03);

166

167/* 4、設置GPIO1_IO03為輸出功能 */

168 val = readl(GPIO1_GDIR);

169 val &=~(1<<3);/* 清除以前的設置 */

170 val |=(1<<3);/* 設置為輸出 */

171 writel(val, GPIO1_GDIR);

172

173/* 5、默認關閉LED */

174 val = readl(GPIO1_DR);

175 val |=(1<<3);

176 writel(val, GPIO1_DR);

177

178/* 6、注冊字符設備驅動 */

179 retvalue = register_chrdev(LED_MAJOR, LED_NAME,&led_fops);

180if(retvalue <0){

181 printk("register chrdev failed!rn");

182return-EIO;

183}

184return0;

185}

186

187/*

188 * @description : 驅動出口函數

189 * @param : 無

190 * @return : 無

191 */

192staticvoid __exit led_exit(void)

193{

194/* 取消映射 */

195 iounmap(IMX6U_CCM_CCGR1);

196 iounmap(SW_MUX_GPIO1_IO03);

197 iounmap(SW_PAD_GPIO1_IO03);

198 iounmap(GPIO1_DR);

199 iounmap(GPIO1_GDIR);

200

201/* 注銷字符設備驅動 */

202 unregister_chrdev(LED_MAJOR, LED_NAME);

203}

204

205 module_init(led_init);

206 module_exit(led_exit);

207 MODULE_LICENSE("GPL");

208 MODULE_AUTHOR("zuozhongkai");

第22~26行,定義了一些宏,包括主設備號、設備名字、LED開/關宏。

第29~33行,本實驗要用到的寄存器宏定義。

第36~40行,經過內存映射以后的寄存器地址指針。

第47~59行,led_switch函數,用于控制開發板上的LED燈亮滅,當參數sta為LEDON(0)的時候打開LED燈,sta為LEDOFF(1)的時候關閉LED燈。

第68~71行,led_open函數,為空函數,可以自行在此函數中添加相關內容,一般在此函數中將設備結構體作為參數filp的私有數據(filp->private_data)。

第81~84行,led_read函數,為空函數,如果想在應用程序中讀取LED的狀態,那么就可以在此函數中添加相應的代碼,比如讀取GPIO1_DR寄存器的值,然后返回給應用程序。

第94~114行,led_write函數,實現對LED燈的開關操作,當應用程序調用write函數向led設備寫數據的時候此函數就會執行。首先通過函數copy_from_user獲取應用程序發送過來的操作信息(打開還是關閉LED),最后根據應用程序的操作信息來打開或關閉LED燈。

第121~124行,led_release函數,為空函數,可以自行在此函數中添加相關內容,一般關閉設備的時候會釋放掉led_open函數中添加的私有數據。

第127~133行,設備文件操作結構體led_fops的定義和初始化。

第140~185行,驅動入口函數led_init,此函數實現了LED的初始化工作,147~151行通過ioremap函數獲取物理寄存器地址映射后的虛擬地址,得到寄存器對應的虛擬地址以后就可以完成相關初始化工作了。比如是能GPIO1時鐘、設置GPIO1_IO03復用功能、配置GPIO1_IO03的屬性等等。最后,最重要的一步!使用register_chrdev函數注冊led這個字符設備。

第192~202行,驅動出口函數led_exit,首先使用函數iounmap取消內存映射,最后使用函數unregister_chrdev注銷led這個字符設備。

第205~206行,使用module_init和module_exit這兩個函數指定led設備驅動加載和卸載函數。

第207~208行,添加LICENSE和作者信息。

41.3.2 編寫測試APP

編寫測試APP,led驅動加載成功以后手動創建/dev/led節點,應用APP通過操作/dev/led文件來完成對LED設備的控制。向/dev/led文件寫0表示關閉LED燈,寫1表示打開LED燈。新建ledApp.c文件,在里面輸入如下內容:

示例代碼41.3.2.1 ledApp.c文件代碼

1 #include "stdio.h"

2 #include "unistd.h"

3 #include "sys/types.h"

4 #include "sys/stat.h"

5 #include "fcntl.h"

6 #include "stdlib.h"

7 #include "string.h"

8/***************************************************************

9 Copyright ? ALIENTEK Co., Ltd. 1998-2029. All rights reserved.

10文件名 : ledApp.c

11作者 : 左忠凱

12版本 : V1.0

13描述 : LED驅測試APP。

14其他 : 無

15使用方法 :./ledtest /dev/led 0 關閉LED

16 ./ledtest /dev/led 1 打開LED

17論壇 : http://www.openedv.com

18日志 : 初版V1.0 2019/1/30 左忠凱創建

19 ***************************************************************/

20

21 #define LEDOFF 0

22 #define LEDON 1

23

24/*

25 * @description : main主程序

26 * @param - argc : argv數組元素個數

27 * @param - argv : 具體參數

28 * @return : 0 成功;其他失敗

29 */

30int main(int argc,char*argv[])

31{

32 int fd, retvalue;

33 char*filename;

34 unsignedchar databuf[1];

35

36 if(argc !=3){

37 printf("Error Usage!rn");

38 return-1;

39 }

40

41 filename = argv[1];

42

43 /* 打開led驅動 */

44 fd = open(filename, O_RDWR);

45 if(fd <0){

46 printf("file %s open failed!rn", argv[1]);

47 return-1;

48 }

49

50 databuf[0]= atoi(argv[2]);/* 要執行的操作:打開或關閉 */

51

52 /* 向/dev/led文件寫入數據 */

53 retvalue = write(fd, databuf,sizeof(databuf));

54 if(retvalue <0){

55 printf("LED Control Failed!rn");

56 close(fd);

57 return-1;

58 }

59

60 retvalue = close(fd);/* 關閉文件 */

61 if(retvalue <0){

62 printf("file %s close failed!rn", argv[1]);

63 return-1;

64 }

65 return0;

66}

ledApp.c的內容還是很簡單的,就是對led的驅動文件進行最基本的打開、關閉、寫操作等。

41.4 運行測試

41.4.1 編譯驅動程序和測試APP

1、編譯驅動程序

編寫Makefile文件,本章實驗的Makefile文件和第四十章實驗基本一樣,只是將obj-m變量的值改為led.o,Makefile內容如下所示:

示例代碼41.4.1.1 Makefile文件

1 KERNELDIR:= /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek

......

4 obj-m := led.o

......

11 clean:

12$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

第4行,設置obj-m變量的值為led.o。

輸入如下命令編譯出驅動模塊文件:

make-j32

編譯成功以后就會生成一個名為“led.ko”的驅動模塊文件。

2、編譯測試APP

輸入如下命令編譯測試ledApp.c這個測試程序:

arm-linux-gnueabihf-gcc ledApp.c -o ledApp

編譯成功以后就會生成ledApp這個應用程序。

41.4.2 運行測試

將上一小節編譯出來的led.ko和ledApp這兩個文件拷貝到rootfs/lib/modules/4.1.15目錄中,重啟開發板,進入到目錄lib/modules/4.1.15中,輸入如下命令加載led.ko驅動模塊:

depmod //第一次加載驅動的時候需要運行此命令

modprobe led.ko //加載驅動

驅動加載成功以后創建“/dev/led”設備節點,命令如下:

mknod /dev/led c 200 0

驅動節點創建成功以后就可以使用ledApp軟件來測試驅動是否工作正常,輸入如下命令打開LED燈:

./ledApp /dev/led 1 //打開LED燈

輸入上述命令以后觀察I.MX6U-ALPHA開發板上的紅色LED燈是否點亮,如果點亮的話說明驅動工作正常。在輸入如下命令關閉LED燈:

./ledApp /dev/led 0 //關閉LED燈

輸入上述命令以后觀察I.MX6U-ALPHA開發板上的紅色LED燈是否熄滅,如果熄滅的話說明我們編寫的LED驅動工作完全正常!至此,我們成功編寫了第一個真正的Linux驅動設備程序。

如果要卸載驅動的話輸入如下命令即可:

rmmodled.ko

總結

以上是生活随笔為你收集整理的linux cached释放_正点原子Linux第四十一章嵌入式Linux LED驱动开发实验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产毛片高清 | 精东影业一区二区三区 | 热99视频 | 野外做受又硬又粗又大视频√ | 91在线观看喷潮 | 高h av | 国产毛片基地 | 色奇米| 性中文字幕 | 艳妇乳肉豪妇荡乳av | 日本丰满少妇做爰爽爽 | 欧美精品乱人伦久久久久久 | 亚洲va天堂va国产va久 | 夜夜夜综合 | 一级做a爰| 国产精品久久久久久久久借妻 | 成人毛片视频在线观看 | 欧美日韩1| 日韩精品免费电影 | 三年大全国语中文版免费播放 | 日韩无套| 欧美视频一二区 | 一区免费在线观看 | 91传媒在线播放 | 天天摸天天爽 | 国产主播一区二区 | 手机在线观看av | 欧美一级片a | 五月综合色 | 1024精品一区二区三区日韩 | 日本体内she精高潮 男女视频在线免费观看 | 国产女人被狂躁到高潮小说 | 美女扒开内裤让男人桶 | 在线视频 亚洲 | 在线不卡国产 | 7799精品视频天天看 | 被警察猛c猛男男男 | aaa在线| a亚洲天堂 | 日本免费不卡一区二区 | 国产一级在线视频 | 侵犯亲女在线播放视频 | 欧美性猛交bbbbb精品 | 狠狠干in| 亲子乱子伦xxxx | 日本美女a级片 | 亚洲经典一区 | 亚洲国产精品国自产拍久久 | 欧美日韩精品一区二区三区蜜桃 | 已满十八岁免费观看 | 亚洲视频五区 | 色噜噜狠狠一区二区三区果冻 | 色诱av手机版| 丰满秘书被猛烈进入高清播放在 | 91精品久久久久久久 | 超碰2025 | 男女视频免费看 | 黑人巨大精品一区二区在线 | 日本精品久久久 | 久久中文字幕av | 天堂在线播放 | 懂色av蜜臀av粉嫩av分享吧最新章节 | 人妻精品无码一区二区三区 | 艳妇乳肉豪妇荡乳av无码福利 | 日韩激情网站 | 国产精品国产三级国产aⅴ浪潮 | 丝袜黄色片 | 国产 xxxx| 国产91黄色 | 日本v片| 男女无遮挡做爰猛烈视频 | 美女在线观看视频 | 97色伦97色伦国产欧美空 | 久久国产秒 | 天堂中文网在线 | 日韩av高清在线播放 | 琪琪秋霞午夜被窝电影网 | 黄色网在线看 | 黄色综合网 | av在线资源网 | 亚洲国产果冻传媒av在线观看 | 天天网综合| 欧美一区二区三区爽爽爽 | 色婷婷一区二区 | 成人性生交大片免费看r链接 | 亚洲精品国产精品乱码不99热 | 一区视频在线 | 中文字幕视频在线播放 | 激情拍拍| 天天干天天狠 | 草久久av | 国模精品视频一区二区 | 粉嫩av一区二区夜夜嗨 | 黄在线免费 | 国产精品99久久久久久一二区 | 成年人免费观看网站 | 精品国产99一区二区乱码综合 | 日韩高清片 | 人人看超碰 |