銀色幻想

          常用鏈接

          統(tǒng)計

          積分與排名

          學習交流

          最新評論

          X Window System運行原理與啟動過程

          一) 基本運行原理
          X Window System采用C/S結(jié)構(gòu),但和我們常見的C/S不同。常見的C/S結(jié)構(gòu)中,稱提供服務(wù)的一方為server,即服務(wù)器端(如HTTP服務(wù),F(xiàn)TP服務(wù)等),使用服務(wù)的稱為client,即客戶端。但在X Window System中,client是執(zhí)行程序的一方,在上面執(zhí)行各種X程序,而server則是負責顯示client運行程序的窗口的一方。

          X Window System的組成可以分為X server,X client,X protocol三部分。X server主要控制輸入輸出,維護字體,顏色等相關(guān)資源。它接受輸入設(shè)備的輸入信息并傳遞給X client,X client將這些信息處理后所返回的信息,也由X server負責輸出到輸出設(shè)備(即我們所見的顯示器)上。X server傳遞給X client的信息稱為Event,主要是鍵盤鼠標輸入和窗口狀態(tài)的信息。X client傳遞給X server的信息則稱為Request,主要是要求X server建立窗口,更改窗口大小位置或在窗口上繪圖輸出文字等。X client主要是完成應(yīng)用程序計算處理的部分,并不接受用戶的輸入信息,輸入信息都是輸入給X server,然后由X server以Event的形式傳遞給X client(這里感覺類似Windows的消息機制,系統(tǒng)接收到用戶的輸入信息,然后以消息的形式傳遞給窗口,再由窗口的消息處理過程處理)。X client對收到的Event進行相應(yīng)的處理后,如果需要輸出到屏幕上或更改畫面的外觀等,則發(fā)出Request給X server,由X server負責顯示。

          常見的情況是X server與X client都在同一臺電腦上運行,但他們也可分別位于網(wǎng)絡(luò)上不同的電腦上。在X Window System中,X client是與硬件無關(guān)的,它并不關(guān)心你使用的是什么顯卡什么顯示器什么鍵盤鼠標,這些只與X server相關(guān)。我們平常安裝完XFree86后運行xf86config或xf86cfg進行的配置實際上只是與X server有關(guān),可以說就是配置X server吧,不配置照樣可以運行X client程序(如:xeyes -display xserver:0就可以在xserver這臺機器上的0號屏幕(屏幕編號displaynumber為0)上顯示那對大眼睛了)。

          X protocol就是X server于X client之間通信的協(xié)議了。X protocol支持現(xiàn)在常用的網(wǎng)絡(luò)通信協(xié)議。我只能測試TCP/IP,可以看到X server偵聽在tcp 6000端口上。那X protocol就是位于運輸層以上了,應(yīng)該屬于應(yīng)用層吧?。
          總結(jié)下運行過程吧:
          (1) 用戶通過鼠標鍵盤對X server下達操作命令
          (2) X server利用Event傳遞用戶操作信息給X client
          (3) X client進行程序運算
          (4) X client利用Request傳回所要顯示的結(jié)果
          (5) X server將結(jié)果顯示在屏幕上

          二) 啟動過程
          我們從控制臺進入X一般是用startx命令。下面就從startx分析起。首先man startx和man xinit可以看到staratx和xinit的使用方法:
          startx [[client] options .....] [-- [server] options ....]
          xinit [[client] options ] [-- [server] [display] options]
          把上面[client]和[server]分別稱為client程序和server程序。man手冊里寫明其必須以/或者./開頭。
          下面看看startx這個腳本,中文為我加的注釋,這個腳本是安裝x-window-system-core后得到的,都是XFree86,不同發(fā)行版的linux里該腳本應(yīng)該大同小異:
          #!/bin/sh
          userclientrc=$HOME/.xinitrc #用戶的client定義文件
          userserverrc=$HOME/.xserverrc #用戶的server定義文件
          sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc #系統(tǒng)的client
          sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc #系統(tǒng)的server
          defaultclient=/usr/X11R6/bin/xterm #默認的client程序
          defaultserver=/usr/X11R6/bin/X #默認的server程序
          defaultclientargs="" #下面定義了client和server的參數(shù)變量
          defaultserverargs=""
          clientargs=""
          serverargs=""

          #如果用戶client文件存在則使用用戶文件里定義的client,否則使用系統(tǒng)定義的client
          if [ -f $userclientrc ]; then
          defaultclientargs=$userclientrc
          elif [ -f $sysclientrc ]; then
          defaultclientargs=$sysclientrc
          fi

          #如果用戶server文件存在則使用用戶文件里定義的server,否則使用系統(tǒng)定義的server
          if [ -f $userserverrc ]; then
          defaultserverargs=$userserverrc
          elif [ -f $sysserverrc ]; then
          defaultserverargs=$sysserverrc
          fi

          #下面循環(huán)處理client和server的參數(shù)
          whoseargs="client"
          while [ x"" != x ]; do #若第一個參數(shù)為空,退出循環(huán)
          case "" in
          # '' required to prevent cpp from treating "/*" as a C comment.
          /''*|./''*) #如果是/*或者./*形式(xinit程序要求其參數(shù)里的client程序和server程序必須以/或./開頭,否則會被視為client程序和server程序的參數(shù),見man xinit)
          if [ "$whoseargs" = "client" ]; then #如果當前是在處理client的參數(shù)
          if [ x"$clientargs" = x ]; then #如果clientargs為空,則賦值給client變量,也即上面#startx使用方法里的[client]參數(shù)
          client=""
          else
          clientargs="$clientargs " #否則clientargs賦值為$clientargs ,即上面#startx使用#方法里的options參數(shù)
          fi
          else #當前在處理server的參數(shù),代碼的含義同上
          if [ x"$serverargs" = x ]; then
          server=""
          else
          serverargs="$serverargs "
          fi
          fi
          ;;
          --)#如果為--,則表示開始處理server的參數(shù),--為client和server參數(shù)的分界
          whoseargs="server"
          ;;
          *)
          if [ "$whoseargs" = "client" ]; then #處理給client程序的參數(shù)
          clientargs="$clientargs "
          else #處理給server程序的參數(shù)
          # display must be the FIRST server argument
          #屏幕編號必須為第一個給server程序的參數(shù),以的形式(x為數(shù)字),這可從上面startx和xinit 的使用
          #方法的區(qū)別看出,xinit多了個[display],這里即過濾出這個[display]。試試看這兩個命令:
          #xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X :1 -dpi 70&
          #xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X -dpi 70 :1&
          #即可看出不把屏幕編號作為第一個server參數(shù)的后果
          if [ x"$serverargs" = x ] && expr "" : ':[0-9][0-9]*$' > /dev/null 2>&1; then
          display=""
          else #處理屏幕編號以外的參數(shù)
          serverargs="$serverargs "
          fi
          fi
          ;;
          esac
          shift #所有參數(shù)左移一次
          done

          # process client arguments
          if [ x"$client" = x ]; then #如果client程序為空
          # if no client arguments either, use rc file instead
          if [ x"$clientargs" = x ]; then #且clientargs為空,賦值$defaultclientargs給client程序
          client="$defaultclientargs"
          else
          client=$defaultclient #使用默認的client程序
          fi
          fi

          # process server arguments處理server參數(shù),同上
          if [ x"$server" = x ]; then
          # if no server arguments or display either, use rc file instead
          if [ x"$serverargs" = x -a x"$display" = x ]; then
          server="$defaultserverargs"
          else
          server=$defaultserver
          fi
          fi
          #…………省略授權(quán)代碼若干

          xinit $client $clientargs -- $server $display $serverargs #把處理過的參數(shù)交由xinit程序處理
          #…………
          由上面代碼可以得出startx主要是置X client和X server所在的位置,并處理相關(guān)參數(shù),最后交給xinit處理。可以看出startx 設(shè)置X client的位置是先搜尋$HOME/.xinitrc,然后是/etc/X11/xinit/xinitrc;設(shè)置X server的位置是先搜尋$HOME/.xserverrc,然后是/etc/X11/xinit/xserverrc。這就解釋了我們平常為什么說啟動X Window時用戶目錄下的.xinitrc和.xserverrc文件優(yōu)先級要高。所以我們用startx命令啟動X時,如果用戶目錄存在. xinitrc和.xserverrc文件,則實際上等價于命令xinit $HOME/.xinitrc -- $HOME/.xserverrc 。如果用戶目錄不存在那兩個文件,則等價于xinit /usr/X11R6/lib/X11/xinit/xinitrc -- /usr/X11R6/lib/X11/xinit/xserver。別的情況類推。

          至于xinit,則根據(jù)startx傳過來的參數(shù)啟動X server,成功后根據(jù)xinitrc啟動X client。
          以上即為X Window System的啟動過程,startx只是負責一些參數(shù)傳遞,真正的X啟動由xinit實現(xiàn)。實際上可以分為啟動X server和啟動X client兩部分。下面在用戶目錄下構(gòu)造.xinitrc(即X client)和.xserverrc(即X server)文件。在.xserverrc里寫入/usr/bin/X11/X :1。.xinitrc里寫入/usr/bin/X11/xeyes -display localhost:1。這就是最簡單的X server + X client了,只不過把屏幕編號從默認的0改為了1,這里X server即是/usr/bin/X11/X 程序,X client即是/usr/bin/X11/xeyes 程序。
          總結(jié)下單機用startx啟動過程吧:
          (1) startx置X client和X server的位置,處理參數(shù)并調(diào)用xinit
          (2) xinit根據(jù)傳過來的參數(shù)啟動X server,成功后呼叫X client
          (3) 根據(jù)xinitrc設(shè)置相關(guān)資源,啟動窗口管理器,輸入法和其他應(yīng)用程序等X client程序。

          但還未搞清楚gnome是怎么起來的!gnome當然屬于X client了,看上面啟動過程第(3)步。
          這里分兩種情況看吧,第一種是用系統(tǒng)的xinitrc文件。看/etc/X11/xinit/xinitrc文件(我的sarge裝x-window- system-core和gnome-core),里面只包含了. /etc/X11/Xsession一句話。接著看/etc/X11/Xsession這個腳本,只看關(guān)鍵部分吧。最后面有:

          SESSIONFILES=$(run_parts $SYSSESSIONDIR)
          if [ -n "$SESSIONFILES" ]; then
          for SESSIONFILE in $SESSIONFILES; do
          . $SESSIONFILE
          done
          fi
          exit 0

          接著看run_parts(),位于本文件中間:
          run_parts () {
          # until run-parts --noexec is implemented
          if [ -z "" ]; then
          internal_errormsg "run_parts() called without an argument."
          fi

          if [ ! -d "" ]; then
          internal_errormsg "run_parts() called, but "" does not exist or is"
          "not a directory."
          fi

          for F in $(ls ); do
          if expr "$F" : '[[:alnum:]_-]+$' > /dev/null 2>&1; then
          if [ -f "/$F" ]; then
          echo "/$F"
          fi
          fi
          done
          }

          大概意思就是run_parts () 把$SYSSESSIONDIR目錄下的文件名取出來賦值給$SESSIONFILES,然后循環(huán)運行該目錄下的文件。看看該目錄,即 /etc/X11/Xsession.d目錄,可以看到幾個以數(shù)字開頭的文件,實際上這些數(shù)值就表示了這幾個文件被運行的優(yōu)先級,數(shù)字小的優(yōu)先級高,因為在上面的run_parts () 里是用ls命令顯示該目錄下的文件,所以前面數(shù)字小的被ls時顯示在前面,所以被
          for SESSIONFILE in $SESSIONFILES; do
          . $SESSIONFILE
          done

          這個for循環(huán)執(zhí)行時也先被執(zhí)行。看到/etc/X11/Xsession.d目錄下有個55gnome-session_gnomerc文件,里面提到了STARTUP變量。然后運行:
          xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
          看到50xfree86-common_determine-startup文件。里面有
          if [ -z "$STARTUP" ]; then
          if [ -x /usr/bin/x-session-manager ]; then
          STARTUP=x-session-manager
          elif [ -x /usr/bin/x-window-manager ]; then
          STARTUP=x-window-manager
          elif [ -x /usr/bin/x-terminal-emulator ]; then
          STARTUP=x-terminal-emulator
          fi
          fi

          即設(shè)置啟動程序,實際上設(shè)置STARTUP變量,如果以上程序都沒有找到,則會報錯退出,即X環(huán)境沒有被啟動。再運行
          xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
          看到優(yōu)先級最低也即最后被運行的99xfree86-common_start文件,里面只有一句話:
          exec $STARTUP
          好了,到這里就啟動我們的X client了,終于完了^_^。總結(jié)下這第一種方式的啟動過程,簡單的說就是依次順序查找/usr/bin/x-session-manager ,x-window-manager,/usr/bin/x-terminal-emulator 這三個文件。如果存在則啟動之,也即X client。如果三個都不存在則報錯退出了。看/usr/bin/x-session-manager文件可以看到是個符號連接,最終連接到 /usr/bin/gnome-session,也就是gnome 了。至于我們在gnome 啟動時可能會設(shè)置啟動輸入法等程序,那就歸gnome-session管了,也就不再分析了。可以試著把/usr/bin/x-session- manager 改為指向xfce4-session(如果安裝了的話) ,再startx就會啟動xfce4環(huán)境了。大概RedHat的switchdesk工具就是改這個連接實現(xiàn)的吧?。或者刪掉/usr/bin/x- session-manager ,再startx,只啟動了/usr/bin/x-window-manager 所指向的window manager了吧,我這里是blackbox。

          下面看第二種情況,即用戶目錄的xinitrc文件$HOME/.xinitrc。對比hiweed-debian- desktop_0.55_i386,存在$HOME/.xinitrc文件,在里面有exec xfce4-session。故其X client可以說最主要的x-session-manger是從$HOME/.xinitrc啟動的。也就不會經(jīng)過上面第一種情況的執(zhí)行過程了。

          終于把gnome(或者說x-session-manger)的啟動過程弄明白了,下面說點別的吧。xinit程序同時啟動X server和X client,這在單機上還可。要是位于網(wǎng)絡(luò)上的兩臺電腦分別是client和server,則xinit就無能為力了。這時就得靠純“手工”來啟動X 了。下面簡單的“手工”啟動X server和X client:在CUI模式下運行命令:
          xdkui@Debian:~$X :1&

          看到了一個灰色的全屏幕和一個鼠標指針,這就是X server了,其屏幕編號為1。下面構(gòu)造X client,按Ctrl+Alt+F1回到剛才的CUI(Ctrl+Alt+F7對應(yīng)本機的第一個啟動的X server,Ctrl+Alt+F8對應(yīng)第二個,有人說F7對應(yīng)屏幕編號為0的X server實際上是不對的,如果第一個啟動的屏幕編號為1,第二個啟動的編號為0,則F7對應(yīng)1屏幕,F(xiàn)8對應(yīng)0屏幕),運行命令: xdkui@Debian:~$xeyes -display localhost:1&

          然后按Ctrl+Alt+F7,看到我們的X client也就是xeyes了吧。再回到CUI,運行
          xdkui@Debian:~$X&
          開啟一個屏幕編號0的X server,CUI下再運行
          xdkui@Debian:~$xterm&

          這時Ctrl+Alt+F7對應(yīng)屏幕編號1;而F8對應(yīng)屏幕編號0,且其X client為xterm。先退出上面的兩個X server,下面復(fù)雜點手動啟動我們的gnome吧,首先
          xdkui@Debian:~$X&
          然后
          xdkui@Debian:~$gnome-session

          看到的就和用startx 啟動的X一樣了,這時X server是X這個程序,X client是gnome-session及其啟動的窗口管理器等程序。看到這里感覺xinit用處并不大(??不知是否正確),簡單的腳本就可以實現(xiàn)。本來想把xinit反匯編了分析下,可懶得搞了^_^這是位于本機的情況,對于X server和X client位于不同主機的情況見下面本文第三部分。

          個人感覺對于X Window System,搞清楚X server與X client關(guān)系很重要。一般X server很簡單,就是/usr/bin/X11/X程序;X client則花樣繁多,從高級的CDE,GNOME,KDE,到低級一點的只有twm,Window Maker,blackbox等窗口管理器,再到最簡陋的只有xterm,rxvt,xeyes等單個x程序。正是由于X client的各種搭配,使得我們的X Window System看起來多樣化。這可能也是X Window System最大的賣點之一吧 ^_^

          三) 跨網(wǎng)絡(luò)運行X Window System
          一般用來做服務(wù)器的系統(tǒng)(Linux,FreeBSD,Solaris等等) 都不會裝X server,甚至很多都沒有顯示器。這樣可以在這些系統(tǒng)里安裝簡單的X client,以GUI的方式遠程顯示在管理員們所坐的X server里。我們實驗室用FreeBSD做網(wǎng)關(guān),提供WWW,FTP服務(wù),一般在管理員的本地機器起個X server,然后ssh或telnet上網(wǎng)關(guān)運行X client程序顯示在本地顯示器上,當然,也可用XDMCP(X Display Manager Control Protocol),man xsession里提到/etc/X11/Xsession一般被startx(我的/etc/X11/xinit/xinitrc里調(diào)用 Xsession腳本)或display manager調(diào)用,但有的display manager只調(diào)用Xsession而不是xinitrc,故為了startx和display manager兩種方式下都可正常啟動GUI,最好把X client啟動的程序放在Xsession文件里。遠程運行X client程序需要設(shè)置DISPLAY環(huán)境變量,設(shè)置為 主機名稱:屏幕編號(如192.168.1.2:0,則表示X server是192.168.1.2這臺機器上的0號屏幕);或是給X client程序加個—display參數(shù)。由于條件限制,只測試了位于TCP/IP網(wǎng)絡(luò)環(huán)境,X server為192.168.1.2,X client為192.168.1.1。

          1) Windows系統(tǒng)做X server
          a) 用ssh或telnet方式
          Windows下面的X server軟件有很多種,我這里使用X-win32。在Windows里運行X-win32程序,則相當于本地機器是個X server。遠程登錄上Debian(我這里是用VMware仿真網(wǎng)絡(luò)環(huán)境,直接進虛擬機即可^_^),運行:
          xdkui@xclient:~$export DISPLAY=192.168.1.2:0
          xdkui@xclient:~$xterm&
          這時即在Windows里的X server里看到了xterm了,至于X client還運行什么程序就看你的需要了,文件管理器阿,資源查看器等。當然,這里X-win32要設(shè)置好授權(quán),好像默認是禁止接入控制,即任何X client都可使用這個X server。

          b) XDMCP方式
          常見的Display Manager有xdm,gdm,kdm等。我這里使用的是gdm。需要修改gdm的配置文件/etc/X11/gdm/gdm.conf,修改 [xdmcp]段的Enable=true,使得可以遠程登錄,在X client運行g(shù)dm。
          在X-win32里建一個XDMCP的session,查詢方式,填入IP為運行g(shù)dm的機器地址。連接,即可看到登錄界面,下面的就不用說了,享受吧

          2) Linux與Linux互聯(lián)
          a) ssh或telnet方式
          在linux 本地起個X server,需要注意授權(quán)問題,建立文件/etc/X0.hosts,填入X client的IP192.168.1.1,其中X0.hosts表示本地第0個屏幕允許連接的X client地址,建立X1.hosts文件則是本地第1個屏幕允許連接的X client地址,以此類推,man xserver里有。運行
          xdkui@xserver:~$X&
          運行該程序時別加-nolisten參數(shù),否則不會在網(wǎng)絡(luò)上偵聽。
          這個時候Ctrl+Alt+F7是X server,返回Ctrl+Alt+F1還可以ssh上X client機器上。
          然后登錄上X client,運行
          xdkui@xclient:~$xterm –display 192.168.1.2:0
          即可在本地的X server里看到xterm了,如果有的話,還可把gnome-session也顯示在本地來。同樣可以在linux里的VMware里做這個測試,需要用點手腕了^_^見下

          b) XDMCP方式
          在我們的X client里運行g(shù)dm(別忘了修改gdm.conf),然后在本地X server的CUI下面運行X -query 192.168.1.1(X client開gdm機器的地址)。可以看到登錄界面了吧。
          我是在linux里的VMware里做的測試,說說所用的手腕吧。在Ctrl+Alt+F1的CUI下正常運行startx&啟動GUI,這時 Ctrl+Alt+F7即為我的X server,X client啟動的gnome,然后在這里運行VMware打開Debian虛擬機,并運行g(shù)dm。然后回到Ctrl+Alt+F1,運行X :1 -query 192.168.1.1。看到登錄界面了吧。這時Ctrl+Alt+F7為我的0號屏幕,里面運行了虛擬機。Ctrl+Alt+F8為1號屏幕,在遠程 GUI登錄X client。相當于我在本地起了兩個X server。

          X Window System設(shè)計的真是相當神奇,使用方法更是眼花繚亂。

          posted on 2006-02-24 17:37 銀色幻想 閱讀(216) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 临澧县| 来凤县| 呼伦贝尔市| 嘉义县| 延边| 北海市| 宜丰县| 莱芜市| 眉山市| 扎兰屯市| 德兴市| 南宁市| 洞头县| 临朐县| 江安县| 新田县| 万山特区| 焉耆| 秭归县| 治县。| 四子王旗| 娱乐| 大兴区| 泸定县| 荆州市| 浦城县| 西和县| 微山县| 台湾省| 蚌埠市| 白朗县| 新乐市| 高青县| 惠来县| 洛浦县| 芮城县| 嵊泗县| 赫章县| 吉木萨尔县| 崇明县| 芦溪县|