激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Linux|Centos|Ubuntu|系統進程|Fedora|注冊表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服務器之家 - 服務器系統 - Linux - linux操作系統原理 linux系統基礎教程

linux操作系統原理 linux系統基礎教程

2022-02-25 17:00Linux教程網 Linux

很多對linux操作系統有興趣的朋友想有一個深入的學習,本篇文章給大家詳細講解了linux操作系統的原理,希望能夠對你有所幫助。

本篇文章系統的給大家講述linux操作系統原理,這是一篇非常好的linux系統基礎教程,我們總結了相關的全部精選內容,一起來學習下。

linux操作系統原理文字版

一.計算機經歷的四個時代

1.第一代:

真空管計算機,輸入和輸出:穿孔卡片,對計算機操作起來非常不便,做一件事可能需要十幾個人去共同去完成,年份大概是:1945-1955。而且耗電量特別大,如果那個時候你家里有臺計算機的話,可能你一開計算機你家的電燈泡亮度就會變暗,哈哈~

2.第二代:

晶體管計算機,批處理(串行模式運行)系統出現。相比第一臺省電多了。典型代表是mainframe。年份大概是:1955-1965。在那個年代:fortran語言也就誕生啦~一門非常古老的計算機語言。

3.第三代:

集成電路出現,多道處理程序(并行模式運行)設計,比較典型的代表就是:分時系統(把cpu的運算分成了時間片)。年份大概是:1965-1980年左右。

4.第四代:

pc機出現,大概是從:1980年左右。相信這個時代典型人物代表:比爾蓋茨,喬布斯。

二.計算機的工作體系

雖然說計算機經過了四個時代的演變,但是到今天為止,計算機的工作體系還是比較簡單的。一般而言,我們的計算機有五大基本部件。

1.mmu(內存控制單元,實現內存分頁【memory page】)

運算機制被獨立在cpu(計算控制單元)上,在cpu當中有一個獨特的芯片叫mmu。他是用來計算進程的線線地址和物理地址的對應關系的。它還用于訪問保護的,即一個進程先要訪問到不是它的內存地址,是會被拒絕的!

2.存儲器(memory)

3.顯示設備(vga接口,顯示器等等)【屬于io設備】

4.輸入設備(keyboard,鍵盤設備)【屬于io設備】

5.硬盤設備(hard dish control ,硬盤控制器或適配器)【屬于io設備】

擴充小知識:

                          linux操作系統原理 linux系統基礎教程

這些硬件設備在一條總線上鏈接,他們通過這條線進行數據交互,里面的帶頭大哥就是cpu,擁有最高指揮權。那么它是如何工作的呢?

a.取指單元(從內存中取得指令);

b.解碼單元(完成解碼[講內存中取到的數據轉換成cpu真正能運行的指令]);

c.執行單元(開始執行指令,根據指令的需求去調用不同的硬件去干活。);

我們通過上面知道了mmu是cpu的一部分,但是cpu有還要其他的部件嗎?當然是有的啦,比如指令寄存器芯片,指令計數器芯片,堆棧指針。

指令寄存器芯片:就是cpu用于將內存中的數據取出來存放的地方;

指令計數器芯片:就是cpu為了記錄上一次在內存中取數據的位置,方便下一次取值;

堆棧指針:cpu每次取完指令后,就會把堆棧指針指向下一個指令在內存中的位置。

他們的工作周期和cpu是一樣快的速度,跟cpu的工作頻率是在同一個時鐘周期下,因此他的性能是非常好的,在cpu內部總線上完成數據通信。指令寄存器芯片,指令計數器芯片,堆棧指針。這些設備通常都被叫做cpu的寄存器。

寄存器其實就是用于保存現場的。尤其是在時間多路復用尤為明顯。比如說cpu要被多個程序共享使用的時候,cpu經常會終止或掛起一個進程,操作系統必須要把它當時的運行狀態給保存起來(方便cpu一會回來處理它的時候可以繼續接著上次的狀態干活。)然后繼續運行其他進程(這叫計算機的上下文切換)。

三.計算機的存儲體系。

1.對稱多處理器smp

cpu里面除了有mmu和寄存器(接近cpu的工作周期)等等,還有cpu核心,正是專門處理數據的,一顆cpu有多個核心,可以用于并行跑你的代碼。工業上很多公司采用多顆cpu,這種結構我們稱之為對稱多處理器。

 

2.程序局部性原理

空間局部性:

程序是由指令和數據組成的。空間局部性指的是一個數據被訪問到之后,那么離這個數據很近的其他數據隨后也可能會被訪問到。

時間局部性:

一般而言當一個程序執行完畢后,可能很快會被訪問到。數據也是同樣的原理,一個數據的被訪問到,很可能會再次訪問到。

正是因為程序局部性的存在,所以使得無論是在空間局部性或者時間的局部性的角度來考慮,一般而言我們都需要對數據做緩存。

 

擴充小知識:

由于cpu內部的寄存器存儲的空間有限,于是就用了內存來存儲數據,但是由于cpu和速度和內存的速度完全不在一個檔次上,因此在處理的數據的時候回到多數都在等(cpu要在內存中取一個數據,cpu轉一圈的時間就可以處理完,內存可能是需要轉20圈)。為了解決使得效率更加提高,就出現了緩存這個概念。

既然我們知道了程序的局部性原理,有知道了cpu為了獲得更多的空間其實就是用時間去換空間,但是緩存就是可以直接讓cpu拿到數據,節省了時間,所以說緩存就是用空間去換時間

3.就算進存儲體系

                                linux操作系統原理 linux系統基礎教程

工作時間就的朋友可能見過磁帶機,現在基本上都被out了,企業很多都用機硬盤來替代磁帶機了,所以我們這里就從我們最熟悉的家用電腦的結構來說,存下到上一次存儲數據是不一樣。我們可以簡單舉個例子,他們的周存儲周期是有很大差距的。尤為明顯的是機械硬盤和內存,他們兩個存取熟讀差距是相當大的。

擴充小知識:

相比自己家用的臺式機或是筆記本可能自己拆開過,講過機械式硬盤,固態硬盤或是內存等等。但是可能你沒有見過緩存物理設備,其實他是在cpu上的。因此我們對它的了解可能會有些盲區。

先說說一級緩存和耳機緩存吧,他們的cpu在這里面取數據的時候時間周期基本上查不了多少,因一級緩存和二級緩存都在cpu核心內部資源。(在其他硬件條件相同的情況下。一級緩存128k可能市場價格會買到300元左右,、一級緩存256k可能會買到600元左右,一級緩存512k可能市場價格就得過四位數這個具體價格可以參考京東啊。這足以說明緩存的造價是非常高的!)這個時候你可能會問那三級緩存呢?其實三級緩存就是就是多顆cpu共享的空間。當然多顆cpu也是共享內存的。

 

                          linux操作系統原理 linux系統基礎教程

4.非一致性內存訪問(numa)

我們知道當多顆cpu共享三級緩存或是內存的時候,他們就會出現了一個問題,即資源征用。我們知道變量或是字符串在內存中被保存是有內存地址的。他們是如何去領用內存地址呢?我們可以參考下圖:

linux操作系統原理 linux系統基礎教程

沒錯,這些玩硬件的大牛們將三級緩存分割,分別讓不同的cpu占用不同的內存地址,這樣我們可以理解他們都有自己的三級緩存區域,不會存在資源搶奪的問題,但是要注意的是他們還是同一塊三級緩存。就好像北京市有朝陽區,豐臺區,大興區,海淀區等等,但是他們都是北京的所屬地。我們可以這里理解。這就是numa,他的特性就是:非一致性內存訪問,都有自己的內存空間。

擴展小知識:

那么問題來了,基于重新負載的結果,如果cpu1運行的進程被掛起,其地址在他自己的它的緩存地址是有記錄的,但是當cpu2再次運行這個程序的時候被cpu2拿到的它是如何處理的呢?

這就沒法了,只能從cpu1的三級換粗區域中復制一份地址過來一份或是移動過來一份讓cpu2來處理,這個時候是需要一定時間的。所以說重新負載均衡會導致cpu性能降低。這個時候我們就可以用進程綁定來實現,讓再次處理該進程的時候還是用之前處理的cpu來處理。即進程的cpu的親緣性。

5.緩存中的通寫和回寫機制。

     linux操作系統原理 linux系統基礎教程

cpu在處理數據的地方就是在寄存器中修改,當寄存器沒有要找的數據是,就會去一級緩存找,如果一級緩存中沒有數據就會去二級緩存中找,依次查找知道從磁盤中找到,然后在加載到寄存器中。當三級緩存從內存中取數據發現三級緩存不足時,就會自動清理三級緩存的空間。

我們知道數據最終存放的位置是硬盤,這個存取過程是由操作系統來完成的。而我們cpu在處理數據是通過兩種寫入方式將數據寫到不同的地方,那就是通寫(寫到內存中)和回寫(寫到一級緩存中)。很顯然回寫的性能好,但是如果斷電的話就尷尬了,數據會丟失,因為他直接寫到一級緩存中就完事了,但是一級緩存其他cpu是訪問不到的,因此從可靠性的角度上來說通寫方式會更靠譜。具體采用哪種方式得你自己按需而定啦。

四.io設備

1.io設備由設備控制器和設備本身組成。

設備控制器:集成在主板的一塊芯片活一組芯片。負責從操作系統接收命令,并完成命令的執行。比如負責從操作系統中讀取數據。

設備本身:其有自己的接口,但是設備本身的接口并不可用,它只是一個物理接口。如ide接口。

擴展小知識:

每個控制器都有少量的用于通信的寄存器(幾個到幾十個不等)。這個寄存器是直接集成到設備控制器內部的。比方說,一個最小化的磁盤控制器,它也會用于指定磁盤地址,扇區計數,讀寫方向等相關操作請求的寄存器。所以任何時候想要激活控制器,設備驅動程序從操作系統中接收操作指令,然后將它轉換成對應設備的基本操作,并把操作請求放置在寄存器中才能完成操作的。每個寄存器表現為一個io端口。所有的寄存器組合稱為設備的i/o地址空間,也叫i/o端口空間,

2.驅動程序

真正的硬件操作是由驅動程序操作完成的。驅動程序通常應該由設備生產上完成,通常驅動程序位于內核中,雖然驅動程序可以在內核外運行,但是很少有人這么玩,因為它太低效率啦!

3.實現輸入和輸出

設備的i/o端口沒法事前分配,因為各個主板的型號不一致,所以我們需要做到動態指定。電腦在開機的時候,每個io設備都要想總線的i/o端口空間注冊使用i/o端口。這個動態端口是由所有的寄存器組合成為設備的i/o地址空間,有2^16次方個端口,即65535個端口。

linux操作系統原理 linux系統基礎教程

如上圖所示,我們的cpu有要想跟指定設備打交道,就需要把指令傳給驅動,然后驅動講cpu的指令轉換成設備能理解的信號放在寄存器中(也可以叫套接字,socket).所以說寄存器(i/o端口)是cpu通過總線和設備打交道的地址(i/o端口)。

擴展小知識:

三種方式實現i/o設備的輸入和輸出:

a..輪詢:

通常指的是用戶程序發起一個系統調用,內核將其翻譯成一個內核對應驅動的過程調用,然后設備驅動程序啟動i/o,并在一個連續循環不斷中檢查該設備,并看該設備是否完成了工作。這有點類似于忙等待(就是cpu會用固定周期不斷通過遍歷的方式去查看每一個i/o設備去查看是否有數據, 顯然這種效率并不理想。),

b..中斷:

中斷cpu正在處理的程序,中斷cpu正在執行的操作,從而通知內核來獲取中斷請求。在我們的主板通常有一個獨特的設備,叫做可編程中斷控制器。這個中斷控制器可以通過某個針腳和cpu直接進行通信,能夠出發cpu發生某個位置偏轉,進而讓cpu知道某個信號到達。中斷控制器上會有一個中斷向量(我們每一個i/o設備在啟動時,要想中斷控制器注冊一個中斷號,這個號通常是唯一的。通常中斷向量的每一個針腳都是可以識別多個中斷號的),也可以叫中斷號。

因此當這個設備真正發生中斷時,這個設備不會把數據直接放到總線上,這個設備會立即向中斷控制器發出中斷請求,中斷控制器通過中斷向量識別這個請求是哪個設備發來的,然后通過某種方式通知給cpu,讓cpu知道具體哪個設備中斷求情到達了。這個時候cpu可以根據設備注冊使用i/o端口號,從而就能獲取到設備的數據了。(注意,cpu是不能直接取數據的喲,因為他只是接收到了中斷信號,它只能通知內核,讓內核自己運行在cpu上,由內核來獲取中斷請求。)舉個例子,一個網卡接收到外來ip的請求,網卡也有自己的緩存區,cpu講網卡中的緩存拿到內存中進行去讀,先判斷是不是自己的ip,如果是就開始拆報文,最后會獲取到一個端口號,然后cpiu在自己的中斷控制器去找這個端口,并做相應的處理。

內核中斷處理分為兩步:中斷上半部分(立即處理)和中斷下半部分(不一定)。還是從網卡接收數據為例,當用戶請求到達網卡時,cpu會命令講網卡緩存區的數據直接拿到內存中來,也就是接收到數據后會立即處理(此處的處理就是將網卡的數據讀到內存中而已,不做下一步處理,以方便以后處理的。),這個我們稱之為中斷的上半部分,而后來真正來處理這個請求的叫做下半部份

c.dma:

直接內存訪問,大家都知道數據的傳輸都是在總線上實現的,cpu是控制總線的使用者,在某一時刻到底是有哪個i/o設備使用總線是由cpu的控制器來決定的。總線有三個功能分別是:地址總線(完成對設備的尋址功能),控制總線(控制各個設備地址使用總線的功能)以及數據總線(實現數據傳輸)。

通常是i/o設備自帶的一個具有智能型的控制芯片(我們稱之為直接內存訪問控制器),當需要處理中斷上半部分時,cpu會告知dma設備,接下來總線歸dma設備使用,并且告知其可以使用的內存空間,用于將i/o設備的數據讀取到內存空間中去。當dma的i/o設備將數據讀取完成后,會發送消息告訴cpu以及完成了讀取操作,這個時候cpu再回通知內核數據已經加載完畢,具體中斷下半部分的處理就來交個內核處理了。現在大多數設備都是用dma控制器的,比如:網卡,硬盤等等。

五.操作系統概念

通過上面的學習,我們知道了的計算機有五大基本部件。操作系統主要就是把這五個部件給它抽象為比較直觀的接口,由上層程序員或者用戶直接使用的。那事實上在操作系統中被抽象出來的東西又該是什么呢?

1.cpu(time slice)

在操作系統中,cpu被抽象成了時間片,而后將程序抽象成進程,通過分配時間片讓程序運行起來。cpu有尋址單元用于來識別變量在內存的中所保存的集體內存地址。

        linux操作系統原理 linux系統基礎教程

而我們主機內部的總線是取決于cpu的位寬(也叫字長),比如32bit的地址總線,它能表示2的32次方個內存地址,轉換成10進制就是4g內存空間,這個時候你應該就明白為什么32位的操作系統中只能識別4g內存了吧?即使你的物理內存是16g,但是可用的還是4g,所以,你如果發現你的操作系統能識別4g以上的內存地址,那么你的操作系統一定就不是32位的啦!

2.內存(memory)

在操作系統中,內存的實現是通過虛擬地址空間來實現的。

3.i/o設備

在操作系統中,最核心的i/o設備就是磁盤,大家都知道磁盤是提供存儲空間的,在內核中把它抽象成了文件。

4.進程

說白了,計算機存在的主要目的不就是運行程序嗎?程序跑起來,我們統一叫進程(我們暫時不用理會線程)。那如果多個進程同時運行就意味著把這些有限的抽象資源(cpu,memory等等)分配給多個進程。我們把這些抽象資源統稱為資源集。

資源集包括:

1>.cpu時間;

2>.內存地址:抽象成虛擬地址空間(如32位操作系統,支持4g空間,內核占用1g空間,進程也會默認自己有3g可用,事實上未必有3g空間,因為你的電腦可能會是小于4g的內存。)

3>.i/o:一切皆文件打開的多個文件,通過fd(文件描述符,file descriptor)打開指定的文件。我們把文件分為三類:正常文件、設備文件、管道文件。

每一個進行都有自己作業地址結構,即:task struct。其就是內核為每個進程維護的一個數據結構(一個數據結構就是用來保存數據的,說白了就是內存空間,記錄著該進程所擁有的資源集,當然還有它的父進程,保存現場【用于進程切換】,內存映射等待)。task struct模擬出來了線性地址,讓進程去使用這些線性地址,但是它會記錄著線性地址和物理內存地址的映射關系的。

5.內存映射-頁框

只要不是內核使用的物理內存空間我們稱之為用戶空間。內核會吧用戶空間的物理內存切割成固定大小的頁框(即page frame),歡聚話說,就是且更成一個固定大小的存儲單位,比默認的單個存儲單元(默認是一個字節,即8bit)要大.通常每4k一個存儲單位。每一個頁框作為一個獨立的單元向外進行分配,且每一個頁框也都其編號。【舉個例子:假設有4g空間可用,每一個頁框是4k,一共有1m個頁框。】這些頁框要分配給不同的進程使用。

我們假設你有4g內存,操作系統占用了1個g,剩余的3g物理內存分配給用戶空間使用。每一進程啟動之后,都會認為自己有3g空間可用,但是實際上它壓根就用不完3g。進程進行寫入內存是被離散存儲的。哪有空余內存就往哪存取。具體的存取算法不要問我,我也沒有研究過。

進程空間結構:

1>.預留空間

2>.棧(變量存放處)

3>.共享庫

4>.堆(打開一個文件,文件中的數據流存放處)

5>.數據段(全局的靜態變量存放處)

6>.代碼段

進程和內存的存儲關系如下:

linux操作系統原理 linux系統基礎教程

每個進程空間都有預留空間,當某個進程發現自己打開的數據已經不夠用,它需要打開一個新文件(打開一個新文件就需要在進程的地址空間存放數據),很顯然我們上圖的進程地址空間是線性的并不是真正意義上的。當一個進程真正去申請使用一個內存時,需要向內核發起系統調用,由內核在物理內存上找一個物理空間,并告訴該進程可以使用的內存地址。比方說進程要在堆上打開一個文件,它需要向操作系統(內核)申請使用內存空間,且在物理內存允許的范圍內(即請求的內存需要小于空閑物理內存),內核會分配給該進程內存地址。

每一進程都有自己想線性地址,這個地址是操作系統虛擬出來的,并不真實存在,它需要把這個虛擬地址和真正的物理內存做一個映射關系,如圖“進程和內存的存儲關系”,最終的進程數據的存放處位置還是映射到內存中了。這就意味著,當一個進行跑到cpu上執行時,它告訴cpu的是自己的線性地址,這時候cpu不會直接去找這個線性地址(因為線性地址是虛擬出來的,不真實存在,真正存放地址進程的是物理內存地址。),它會先去找這歌進程的“task struct”,并裝載頁表(page table)[記錄著線性地址到物理內存的映射關系,每一個對應關系叫做一個頁表項。],以讀取到進程的所擁有的線性地址所對應的真正的物理內存地址。

擴展小知識:

cpu訪問進程的地址時,首先獲取到的是進程的線性地址,它將這個線性地址交給自己的芯片mmu進行計算,得到真正的物理內存地址,從而達到訪問進程內存地址的目的。換句話說,只要他想要訪問一個進程的內存地址,就必須經過mmu運算,這樣導致效率很低,因此他們有引進了一個緩存,用于存放頻繁訪問的數據,這樣就可以提高效率,不用mmu進行計算,直接拿到數據去處理就ok了,這個緩存器我們稱之為:tlb:轉換后援緩沖器(緩存頁表的查詢結果)

注意:在32bit的操作系統是線線地址到物理內存的映射。而在64bit操作系統是恰恰相反的!

6.用戶態和內核態

操作系統運行時為了呢能夠實現協調多任務,操作系統被分割成了2段,其中接近于硬件一段具有特權權限的叫做內核空間,而進程運行在用戶空間當中。所以說,應用程序需要使用特權指令或是要訪問硬件資源時需要系統調用。

只要是被開發成應用程序的,不是作為操作系統本身的一部分而存在的,我們稱之為用戶空間的程序。他們運行狀態稱之為用戶態。

需要在內核(我們可以認為是操作系統)空間運行的程序,我們稱之他們運行在內核空間,他們運行的狀態為用戶態,也叫核心態。注意:內核不負責完成具體工作。在內核空間可用執行任何特權操作。

每一個程序要想真正運行起來,它最終是向內核發起系統調用來完成的,或者有一部分的程序不需要內核的參與,有我們的應用程序就能完成。我們打個比方,你要計算2的32次方的結果,是否需要運行在內核態呢?答案是否定的,我們知道內核是不負責完成具體工作的,我們只是想要計算一個運算結果,也不需要調用任何的特權模式,因此,如果你寫了一些關于計算數值的代碼,只需要把這個代碼交給cpu運行就可以了。

如果一個應用程序需要調用內核的功能而不是用戶程序的功能的話,應用程序會發現自己需要做一個特權操作,而應用程序自身沒有這個能力,應用程序會向內核發申請,讓內核幫忙完成特權操作。內核發現應用程序是有權限使用特權指令的,內核會運行這些特權指令并把執行結果返回給應用程序,然后這個應用程序拿到特權指令的執行結果后,繼續后續的代碼。這就是模式轉換。

因此一個程序員想要讓你的程序具有生產力,就應該盡量讓你的代碼運行在用戶空間,如果你的代碼大多數都運行在內核空間的話,估計你的應用程序并不會給你打來太大的生產力喲。因為我們知道內核空間不負責產生生產力。

擴充小知識:

我們知道計算機的運行就是運行指定的。指令還分特權指令級別和非特權指令級別。了解過計算機的朋友可能知道x86的cpu架構大概分成了四個層次,由內之外共有四個環,被稱為環0,環1,環2,環3。我們知道環0的都是特權指令,環3的都是用戶指令。一般來講,特權指令級別是指操作硬件,控制總線等等。

一個程序的執行,需要在內核的協調下,有可能在用戶態和內核態互相切換,所以說一個程序的執行,一定是內核調度它到cpu上去執行的 。有些應用程序是操作系統運行過程當中,為了完成基本功能而運行的,我們就讓他在后臺自動運行,這叫守護進程。但是有的程序是用戶需要的時候才運行的,那如何通知內核講我們需要的應用程序運行起來呢?這個時候你就需要一個解釋器,它能和操作系統打交道,能夠發起指令的執行。說白了就是能夠把用戶需要的運行請求提交給內核,進而內核給它開放其運行所需要的有賴于的基本條件。從而程序就執行起來了。

下面我們在看推薦幾本關于linux操作系統原理的書

linux操作系統原理電子書

操作系統原理及應用(linux) pdf掃描版[30mb]

深度探索linux操作系統:系統構建和原理解析 pdf掃描版[129mb]

操作系統原理linux篇 徐德民 pdf

linux內核注釋 孫更新等 pdf掃描版(86m)

linux操作系統視頻內容

跟阿銘學Linux第二版最新版(附阿銘linux全套視頻教程)chm格式

linux系統掛載數據盤的方法(視頻圖文教程)

以上就是我們給大家整理的關于linux操作系統原理 linux系統基礎教程的全部內容,希望我們整理的內容能夠給你提供到幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本黄色大片免费 | 国产91精品久久久久久 | 午夜小视频免费观看 | 欧美一区二区三区久久综合 | 日韩一级毛毛片 | 成人毛片网站 | 欧美大穴| 爱视频福利 | 黄色片网站在线免费观看 | 欧美日韩亚洲另类 | 国产一国产精品一级毛片 | 久久精品视频7 | 久久久久久久久久久综合 | 香蕉视频h| 在线天堂中文字幕 | 国产成人在线观看免费网站 | 亚洲天堂ww | 91久久国产露脸精品免费 | 国产91在线高潮白浆在线观看 | 亚洲第一成人久久网站 | av免播放 | 91性视频 | 久久久一区二区三区视频 | 精品一区二区三区免费视频 | 国产一级在线免费观看 | 国产视频91在线 | 日本高清无遮挡 | 国产va在线观看免费 | 亚洲成人在线免费 | 小雪奶水翁胀公吸小说最新章节 | 国产一区二区视频观看 | 国产免费传媒av片在线 | 国产高清美女一级毛片 | 欧美日韩免费一区 | 亚洲热线99精品视频 | 影视免费观看 | 黄色影院一级片 | 免费观看视频91 | 91福利在线观看 | 日韩视频观看 | 91高清视频在线观看 |