色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

整個操作系統就是一個中斷驅動的死循環

Linux愛好者 ? 來源:低并發編程 ? 作者:閃客sun ? 2021-11-22 09:36 ? 次閱讀
本來想寫內核如何接收一個網絡包這個過程,但發現把整個過程捋順了,還是很難的。推導整個過程的起點是中斷,包括硬中斷軟中斷而這個過程要是講清楚吧,感覺在整個網絡包接收原理的大流程中有點喧賓奪主。但要是一筆帶過吧,那對于這塊有困惑的人就很難受,一切的起點沒整明白在心里總是個疙瘩。所以,單拎出來一個主題中斷,給大家把這個問題搞明白了。另外,整個操作系統就是一個中斷驅動的死循環,操作系統原理如果用一行代碼解釋,下面這樣再合適不過了。
while(true){
doNothing();
}
其他所有事情都是由操作系統提前注冊的中斷機制和其對應的中斷處理函數完成,我們點擊一下鼠標,敲擊一下鍵盤,執行一個程序,都是用中斷的方式來通知操作系統幫我們處理這些事件,當沒有任何需要操作系統處理的事件時,它就乖乖停在死循環里不出來。所以,中斷,非常重要,它也是理解整個操作系統的根基,掌握它,不虧!那我們開始吧。

五花八門的中斷分類

關于中斷的分類,教科書上和網上有很多"標準"答案了,如果你用搜索引擎去尋找答案,可能會找出很多不一樣的分類結果。所以我打算直接在 Intel 手冊上找個最官方的標準答案。Intel 手冊 Volume 1 Chapter 6.4 Interrupts and Exception 給出。 翻譯過來就是,中斷可以分為中斷和異常,異常又可以分為故障、陷阱、中止第一句話有點奇怪,啥叫中斷分為中斷和異常呢?你看好多文章的時候也是這么寫的,不知道你有沒有曾疑惑過。但其實原文的意思準確說是,CPU 提供了兩種中斷程序執行的機制,中斷和異常。第一個中斷是個動詞,第二個中斷才是真正的機制種類。好吧,我感覺原文也挺奇怪的,但人家就這么叫,沒轍。接下來我只需要翻譯一下就好了,再夾雜點自己的解讀。An interrupt is an asynchronous event that is typically triggered by an I/O device.先說第一個機制中斷(interrupt),中斷是一個異步事件,通常由 IO 設備觸發。比如點擊一下鼠標、敲擊一下鍵盤等。An exception is a synchronous event that is generated when the processor detects one or more predefined conditions while executing an instruction.再說第二個機制異常(exception),異常是一個同步事件,是 CPU 在執行指令時檢測到的反常條件。比如除法異常、錯誤指令異常,缺頁異常等。這兩個機制,殊途同歸,都是讓 CPU 收到一個中斷號,至于 CPU 收到這個中斷號之后干嘛,我們暫且不管。 我們先看看收到中斷號之前,具體就是中斷和異常到底是怎么做到給 CPU 一個中斷號的。先說中斷,別眨眼。有一個設備叫做編程中斷控制器,它有很多的 IRQ 引腳線,接入了一堆能發出中斷請求的硬件設備,當這些硬件設備給 IRQ 引腳線發一個信號時,由于可編程中斷控制器提前被設置好了 IRQ 與中斷號的對應關系,所以就轉化成了對應的中斷號,把這個中斷號存儲在自己的一個端口上,然后給 CPU 的 INTR 引腳發送一個信號,CPU 收到 INTR 引腳信號后去剛剛的那個端口讀取到這個中斷號的值。估計你被繞暈了,但讀我的文章有個好處,太復雜就上動圖,來吧。 你看,最終的目標,就是讓 CPU 知道,有中斷了,并且也知道中斷號是多少比如上圖中按下了鍵盤,最終到 CPU 那里的反應就是,得到了一個中斷號 0x21那異常的機制就更簡單了,是 CPU 自己執行指令時檢測到的一些反常情況,然后自己給自己一個中斷號即可,無需外界給。比如 CPU 執行到了一個無效的指令,則自己給自己一個中斷號 0x06,這個中斷號是 Intel 的 CPU 提前就規定好寫死了的硬布線邏輯。好了,到目前為止,我們知道了無論是中斷還是異常,最終都是通過各種方式,讓 CPU 得到一個中斷號。只不過中斷是通過外部設備給 CPU 的 INTR 引腳發信號,異常是 CPU 自己執行指令的時候發現特殊情況觸發的,自己給自己一個中斷號。還有一種方式可以給到 CPU 一個中斷號,但 Intel 手冊寫在了后面,Chapter 6.4.4 INT n,就是大名鼎鼎的 INT 指令 INT 指令后面跟一個數字,就相當于直接用指令的形式,告訴 CPU 一個中斷號。比如 INT 0x80,就是告訴 CPU 中斷號是 0x80Linux 內核提供的系統調用,就是用了 INT 0x80 這種指令。那我們上面的圖又豐富了起來。 有的地方喜歡把他們做一些區分,把 INT n 這種方式叫做軟件中斷,因為他是由軟件程序主動觸發的。相應的把上面的中斷和異常叫做硬件中斷,因為他們都是硬件自動觸發的。但我覺得大可不必,一共就這么幾個分類,干嘛還要增加一層理解的成本呢,記三個方式不好么?好了,總結一下,給 CPU 一個中斷號有三種方式,而這也是中斷分類的依據。

1.通過中斷控制器給 CPU 的 INTR 引腳發送信號,并且允許 CPU 從中斷控制器的一個端口上讀取中斷號,比如按下鍵盤的一個按鍵,最終會給到 CPU 一個 0x21 中斷號。

2.CPU 執行某條指令發現了異常,會自己觸發并給自己一個中斷號,比如執行到了無效指令,CPU 會給自己一個 0x06 的中斷號。

3.執行 INT n 指令,會直接給 CPU 一個中斷號 n,比如觸發了 Linux 的系統調用,實際上就是執行了 INT 0x80 指令,那么 CPU 收到的就是一個 0x80 中斷號。

再往后,CPU 以各種不同的方式收到的這些 0x21 0x06 0x80,都會一視同仁,做同樣的后續處理流程,所以從現在開始,前面的事情就不用再管了,這也體現了分層的好處。

收到中斷號之后 CPU 干嘛?

那 CPU 收到中斷號后,如何處理呢?先用一句不太準確的話總結,CPU 收到一個中斷號 n 后,會去中斷向量表中尋找第 n 個中斷描述符,從中斷描述符中找到中斷處理程序的地址,然后跳過去執行為什么說不準確呢?因為從中斷描述符中找到的,并不直接是程序的地址,而是段選擇子段內偏移地址。然后段選擇子又會去全局描述符表中尋找段描述符,從中取出段基址。之后段基址 + 段內偏移地址,才是最終處理程序的入口地址。

然這個入口地址,還不是最終的物理地址,如果開啟了分頁,又要經歷分頁機制的轉換,就像下面這樣。

不過不要擔心,這不是中斷的主流程,因為分段機制和分頁機制是所有地址轉換過程的必經之路,并不是中斷這個流程所特有的所以我們簡單的把中斷描述符表中存儲的地址,直接當做 CPU 可以跳過去執行的中斷處理程序的入口地址,就好了,不影響理解他們。你看,這是不是簡單很多。那接下來的問題就很簡單了,這里出現了兩個名詞,那就分別對他們進行發問。

1. 中斷描述符表是啥?

2.中斷描述符是啥?

3. 去哪里找他們?

分別回答即可

中斷描述符表是啥?

就是一個在內存中的數組而已,操作系統初始化過程中,有很多結構都稱之為 XXX 表,其實就是個數組罷了。以 linux-2.6.0 源碼為例,就很直觀了。
structdesc_structidt_table[256]={{0,0},};
你看,是一個大小為 256 的數組。idt_table 這個名字就是 Interrupt Descriptor Table,逐字翻譯過來確實就是中斷描述符表

中斷描述符是啥?

就是中斷描述符表這個數組里的存儲的數據結構,通過剛剛的源碼也可以看出來,是一個叫 desc_struct 的結構。
structdesc_struct{
unsignedlonga,b;
};
好家伙,Linux 源碼里就這么簡單粗暴表示,一個中斷描述符的大小為 64 位,也就是 8 個字節,具體里面存的啥通過這個源碼看不出來。翻一下 Intel 手冊,在 Volumn 3 Chapter 5.11 IDT Descriptors 中找到了一張圖。 可以看到,中斷描述符具體還分成好幾個種類,有:

Task Gate:任務門描述符

Interrupt Gate:中斷門描述符

Trap Gate:陷阱門描述符

不要慌,其中任務門描述符 Linux 中幾乎沒有用到。中斷門描述符和陷阱門描述符的區別僅僅是是否允許中斷嵌套,實現方式非常簡單粗暴,就是 CPU 如果收到的中斷號對應的是一個中斷門描述符,就修改 IF 標志位(就是一個寄存器中一位的值),修改了這個值后就屏蔽了中斷,也就防止了中斷的嵌套。而陷阱門沒有改這個標志位,也就允許了中斷的嵌套。所以簡單理解的話,你把他們當做同樣一個描述符就好了,先別管這些細節,他們的結構幾乎完全一樣,只是差了一個類型標識罷了。那這個中斷描述符的結構長什么樣呢?我們可以清晰地看到,里面有段選擇子段內偏移地址 回顧下剛剛說的中斷處理流程。

沒騙你吧。

但以上這些如果你都搞不明白,還是那句話,記這個最簡單的流程就好了,不影響理解。

好了,現在我們直觀地看到了中斷描述符表這個 256 大小的數組,以及它里面存的中斷描述符長什么樣子,最終的目的,還是幫助 CPU 找到一個程序的入口地址,然后跳轉過去OK,下一個問題,就是 CPU 怎么尋找到這個中斷描述符表的位置呢?它是在內存中一個固定的位置么?

CPU 怎么找到中斷描述符表

答案是否定的,中斷描述符表在哪里,全憑各個操作系統的喜好,想放在哪里就放在哪里,但需要通過某種方式告訴 CPU,即可。怎么告訴呢?CPU 提前預留了一個寄存器叫 IDTR 寄存器,這里面存放的就是中斷描述符表的起始地址,以及中斷描述符表的大小。Volumn 3 Chapter 5.10 Interrupt Descriptor Table 中告訴了我們 IDTR 寄存器的結構。 操作系統的代碼可以通過 LIDT 指令,將中斷描述符表的地址放在這個寄存器里。還記得剛剛看的源碼么?中斷描述符表就是這個。
structdesc_structidt_table[256]={{0,0},};
然后操作系統把這個的地址用 LIDT 指令放在 IDTR 寄存器就行了。IDTR 寄存器里的值一共 48 位,前 16 位是中斷描述符表大小(字節數),后 32 位是中斷描述符表的起始內存地址,就是這個 idt_table 的位置。

Linux-2.6.0 源碼中是這樣構造這個結構的,簡單粗暴。

idt_descr:
.word256*8-1
.longidt_table

緊接著,一個 LIDT 指令把這個結構放到 IDTR 寄存器中。

lidtidt_descr

整個過程一氣呵成,呵得我連代碼格式都懶得調了,是不是很清晰明了。

這樣,CPU 收到一個中斷號后,中斷描述符表的起始位置從 IDTR 寄存器中可以知道,而且里面的每個中斷描述符都是 64 位大小,也就是 8 個字節,那自然就可以找到這個中斷號對應的中斷描述符接下來的問題就是,這個中斷描述符表是誰來提前寫好的?又是怎么寫的?

誰把中斷描述符表這個結構寫在內存的

很簡單,操作系統唄。在 Linux-2.6.0 內核源碼的 traps.c 文件中,有這樣一段代碼。
void__inittrap_init(void){
set_trap_gate(0,÷_error);
...
set_trap_gate(6,&invalid_op);
...
set_intr_gate(14,&page_fault);
...
set_system_gate(0x80,&system_call);
}
你看,我們剛剛提到的除法異常、非法指令異常、缺頁異常,以及之后可能通過 INT 0x80 觸發系統調用的中斷處理函數 system_call,就是這樣被寫到了中斷描述符表里。 經過這樣一番操作后,我們的中斷描述符表里的值就豐富了起來。好了,現在只剩下最后一個問題了,CPU 在找到一個中斷描述符后,如何跳過去執行?

找到中斷描述符后,干嘛

現在這個問題可以再問得大一些了,就是 CPU 在收到一個中斷號并且找到了中斷描述符之后,究竟做了哪些事當然,最簡單的辦法就是,直接把中斷描述符里的中斷程序地址取出來,放在自己的 CS:IP 寄存器中,因為這里存的值就是下一跳指令的地址,只要放進去了,到下一個 CPU 指令周期時,就會去那里繼續執行了。但 CPU 并沒有這樣簡單粗暴,而是幫助我們程序員做了好多額外的事情,這增加了我們的學習和理解成本,但方便了寫操作系統的程序員,拿到一些中斷的信息,以及中斷程序結束后的返回工作。但其實,就是做了一些壓棧操作

1. 如果發生了特權級轉移,壓入之前的堆棧段寄存器 SS 及棧頂指針 ESP 保存到棧中,并將堆棧切換為 TSS 中的堆棧。

2. 壓入標志寄存器 EFLAGS。

3. 壓入之前的代碼段寄存器 CS 和指令寄存器 EIP,相當于壓入返回地址。

4. 如果此中斷有錯誤碼的,壓入錯誤碼 ERROR_CODE

5. 結束(之后就跳轉到中斷程序了)

壓棧操作結束后,棧就變成了這個樣子。

特權級的轉移需要切換棧,所以提前將之前的棧指針壓入。錯誤碼可以方便中斷處理程序做一些工作,如果需要,從棧頂拿到就好了。拋開這兩者不說,剩下的就只有標志寄存器中斷發生前的代碼地址,被壓入了棧,這很好理解,就是方便中斷程序結束后,返回原來的代碼嘛~具體的壓棧工作,以及如何利用這些棧的信息達到結束中斷并返回原程序的效果,Intel 手冊中也寫得很清楚。

看下面的話,通過配合 IRET IRETD 指令返回。由于后續版本的 Linux 自己的玩法比較多,已經不用 Intel 提供的現成指令了,所以這回我們從 Linux-0.11 版源碼中尋找答案。比如除法異常的中斷處理函數,在 asm.s 中。
_divide_error:
 push dword ptr _do_divide_error ;
no_error_code: ;
 xchg [esp],eax ;
 push ebx
 push ecx
 push edx
 push edi
 push esi
 push ebp
 push ds ;
 push es
 push fs
 push 0 ;
 lea edx,[esp+44] ;
 push edx
 mov edx,10h ;
 mov ds,dx
 mov es,dx
 mov fs,dx
 call eax ;
 add esp,8 ;
 pop fs
 pop es
 pop ds
 pop ebp
 pop esi
 pop edi
 pop edx
 pop ecx
 pop ebx
 pop eax ;// 彈出原來eax 中的內容。
 iretd
只看最后一行,確實用了 iretd 指令。這個指令會依次彈出棧頂的三個元素,把它們分別賦值給 EIP,CS 和 EFLAGS,而棧頂的三個元素,又恰好是 EIP,CS 和 EFLAGS 這樣的順序,你說這巧不巧?當然不巧,人家 CPU 執行中斷函數前做了壓棧操作,然后又提供了 iret 指令做彈棧操作,當然是給你配套使用的!你看,中斷是如何切到中斷處理程序的?就是靠中斷描述符表中記錄的地址。那中斷又如何回到原來的代碼繼續執行呢?是通過 CPU 幫我們把中斷發生前的地址壓入了棧中,然后我們程序自己利用他們去返回,當然也可以不返回。這就是 CPU 和操作系統配合的結果,把中斷這個事給解決了。

總結

所以總結起來就是,理解中斷,只要回答了這幾個問題就好。如何給 CPU 一個中斷號?

外部設備通過 INTR 引腳,或者 CPU 執行指令的過程中自己觸發,或者由軟件通過 INT n 指令強行觸發。

同樣中斷也是這樣進行分類的。

CPU 收到中斷號后如何尋找到中斷程序的入口地址?

通過 IDTR 寄存器找到中斷描述符表,通過中斷描述符表和中斷號定位到中斷描述符,取出中斷描述符表中存儲的程序入口地址。

中斷描述符表是誰寫的?

操作系統代碼寫上去的。

找到程序入口地址之后,CPU 做了什么?

簡單說,實際上做的事情就是壓棧,并跳轉到入口地址處執行代碼。而壓棧的目的,就是保護現場(原來的程序地址、原來的程序堆棧、原來的標志位)和傳遞信息(錯誤碼)

好了,中斷講完了,如果再往后擴大一點點概念,以上說的中斷,統統都是硬中斷。注意,不叫硬件中斷哦。為什么叫硬中斷呢?因為這是 Intel CPU 這個硬件實現的中斷機制,注意這里是實現機制,并不是觸發機制,因為觸發可以通過外部硬件,也可以通過軟件的 INT 指令。那與硬中斷對應的還有軟中斷,這個概念網上好多地方都講錯了,把軟中斷和 INT 指令這種軟件中斷混淆了,所以我覺得軟件中斷最好稱其為,由軟件觸發的中斷,而軟中斷稱其為軟件實現的中斷軟中斷是純粹由軟件實現的一種類似中斷的機制,實際上它就是模仿硬件,在內存中有一個地方存儲著軟中斷的標志位,然后由內核的一個線程不斷輪詢這些標志位,如果有哪個標志位有效,則再去另一個地方尋找這個軟中斷對應的中斷處理程序。軟中斷是 Linux 實現中斷的下半部的一種非常常見的方式,之后我講 Linux 內核如何接受網絡包這個事情的時候也可以看到,軟中斷是研究整個過程的一個突破口。
責任編輯:haq
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 操作系統
    +關注

    關注

    37

    文章

    6808

    瀏覽量

    123291
  • 網絡
    +關注

    關注

    14

    文章

    7557

    瀏覽量

    88737
  • 中斷
    +關注

    關注

    5

    文章

    898

    瀏覽量

    41474

原文標題:好家伙!原來硬中斷就是這樣的

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    deepin操作系統介紹

    希望從自己的能力和對桌面操作系統的理解,能給 Linux 的用戶與開發者更多的選擇。我們也相信 deepin 能夠得到更多用戶的認可與喜愛,成為開源世界的最佳選擇。? 、 deepin 操作系統 先說 Linux
    的頭像 發表于 12-23 09:08 ?107次閱讀
    deepin<b class='flag-5'>操作系統</b>介紹

    linux操作系統安裝步驟 linux操作系統的特點及組成

    Linux操作系統安裝步驟 Linux操作系統種開源的操作系統,它以其穩定性、安全性和靈活性而聞名。以下是安裝Linux操作系統
    的頭像 發表于 10-21 11:24 ?534次閱讀

    使用CSL來補充操作系統調度程序處理級聯中斷

    電子發燒友網站提供《使用CSL來補充操作系統調度程序處理級聯中斷.pdf》資料免費下載
    發表于 10-16 10:12 ?0次下載
    使用CSL來補充<b class='flag-5'>操作系統</b>調度程序處理級聯<b class='flag-5'>中斷</b>

    為了學習內核開發,大佬手搓了輕量級操作系統YiYiYa OS

    作者:evilbinary(鴨佬) YiYiYa操作系統樸實無華的操作系統,追求快速開發,最小實現,同時遵循SOLID原則。編碼簡潔明了,非常適合學習
    發表于 08-30 14:57

    為了學習內核開發,大佬手搓了輕量級操作系統YiYiYa OS

    YiYiYa操作系統樸實無華的操作系統,追求快速開發,最小實現,同時遵循SOLID原則。編碼簡潔明了,非常適合學習操作系統的同學。目
    發表于 08-27 10:08

    嵌入式實時操作系統:Intewell操作系統與VxWorks操作系統有啥區別

    Intewell操作系統和VxWorks操作系統都是工業領域常用的操作系統,它們各有特點和優勢。以下是它們之間的些主要區別:
    的頭像 發表于 07-08 14:16 ?419次閱讀
    嵌入式實時<b class='flag-5'>操作系統</b>:Intewell<b class='flag-5'>操作系統</b>與VxWorks<b class='flag-5'>操作系統</b>有啥區別

    STM32F107中斷死循環的原因?

    STM32F107,中斷死循環
    發表于 05-11 06:31

    在freertos中,每個任務都是死循環,那么還需要使用看門狗嗎?

    在freertos中,每個任務都是死循環,那么還需要使用看門狗嗎?該怎么使用?
    發表于 05-07 06:55

    聊聊MCU死循環,用for(;;)還是while(1)?

    首先,問大家問題:你們寫單片機程序【死循環】時,喜歡用for(;;)還是while(1)?快來為你喜歡用的【死循環】打call,評論區等你哦~
    的頭像 發表于 04-29 08:10 ?1342次閱讀
    聊聊MCU<b class='flag-5'>死循環</b>,用for(;;)還是while(1)?

    帶你認識實時操作系統(rtos)

    實時操作系統(RTOS)是為嵌入式系統和實時應用提供穩定、可預測和高效運行環境的操作系統。實時操作系
    的頭像 發表于 04-16 16:30 ?1251次閱讀
    帶你認識實時<b class='flag-5'>操作系統</b>(rtos)

    STM32F412RET6串口輪詢發送阻塞等待TC,導致程序陷入死循環怎么解決?

    前段時間在做一個CAN轉USART的網關,使用的是STM32F412RET6,軟件框架使用的是RT-Thread操作系統,主要外設資源使用了CAN1、CAN2、UART2、UART3,在做通信壓力
    發表于 03-21 07:51

    rt1052如何將整個中斷程序搬到RAM中運行?

    我想將rt1052整個中斷程序都搬到itcm中運行,發現中斷總有小部分的匯編代碼還是在norflash中運行。 如下圖所示,: (注意,startup_MIMXRT1052.S中
    發表于 03-05 08:01

    成熟且可靠的開源實時操作系統

    市場上有許多專有和開源實時操作系統(RTOS)。ThreadX已經以其對小代碼大小和高性能的關注而聞名。然而,它的競爭優勢遠遠超出了這些屬性。
    的頭像 發表于 02-20 12:26 ?866次閱讀

    深度解析全球操作系統格局

    操作系統是負責協調、管理和控制計算機硬件與軟件資源的程序,是整個計算機的核心系統軟件。 按照操作系統面向的設備類型,通用操作系統主要包括桌面
    的頭像 發表于 01-18 15:00 ?1159次閱讀
    深度解析全球<b class='flag-5'>操作系統</b>格局

    詳解實時操作系統和非實時操作系統

    實時操作系統,當外界事件和數據產生時,系統能以足夠快的速度予以處理,其處理結果能在規定的時間內控制生產結果或對系統做出響應,并控制所有實時任務協調致運行的
    的頭像 發表于 12-26 09:54 ?4747次閱讀
    詳解實時<b class='flag-5'>操作系統</b>和非實時<b class='flag-5'>操作系統</b>
    主站蜘蛛池模板: 挺弄抽插喷射HH| 美女的让男人桶爽网站| 国产三级在线精品男人的天堂| 妈妈的朋友5在线观看免费完整版中文| 天天澡夜夜澡人人澡| 成人在无码AV在线观看一| 男人插曲女人的视频| 6080yy亚洲久久无码| 久久久久国产精品美女毛片| 亚洲裸舞 hd| 精品日韩二区三区精品视频 | 国产色偷偷男人的天堂| 午夜福利视频极品国产83| 国产剧情麻豆mv| 亚洲妈妈精品一区二区三区| 红色机尾快播| 中国女人内谢69XXXXXA片| 老师你狠狂| beeg日本老师按摩| 色色色999| 国内久经典AAAAA片| 影音先锋影院中文无码| 蜜桃麻豆WWW久久囤产精品免费| 9久久免费国产精品特黄| 青青热久久综合网伊人| videos gratis欧美另类| 日本无卡无吗在线| 国产精品无码人妻在线| 亚洲 欧美 国产 在线 日韩| 国产日韩欧美有码在线视频| 亚洲精品欧美精品中文字幕| 精品亚洲视频在线观看| 6080yy亚洲久久无码| 男生插女生下体| 国产97精品久久久天天A片| 亚洲精品国产在线网站| 久久婷婷五月综合色丁香花| caoporn 在线视频| 亚洲aaaa级特黄毛片| 久久99精品视频| caoporn 超碰免费视频|