当前位置:IT快活林→网上冲浪工具软件

探究XWindow System原理与启动过程

作者:本站整理   发布时间:2008-9-8 16:44:20


一) 基本运行原理 X Window System采用C/S结构,但和我们常见的C/S不同.常见的C/S结构中,称提供服务的一方为server,即服务器(Server)端(如HTTP服务,FTP服务等),使用服务的称为client,即客户端.但在X Window System中,client是执行程序(Procedures)(Procedures)的一方,在上面执行各种各样X程序(Procedures)(Procedures),而不能是server则是负责显示client运行程序(Procedures)(Procedures)的窗口的一方. X Window System的组成可以分为X server,X client,X protocol三部分.X server主要控制输入输出,维护字体,颜色等相关资源.他接受输入设备的输入信息并传递给X client,X client将这些信息处理后所返回的信息,也由X server负责输出到输出设备(即我们所见的显示器)上.X server传递给X client的信息称为Event,主要是键盘鼠标输入和窗口状态的信息.X client传递给X server的信息则称为Request,主要是要求X server建立窗口,更改窗口大小位置或者是在窗口上绘图输出文字等.X client主要是完成应用程序(Procedures)(Procedures)计算处理的部分,并不接受用户的输入信息,输入信息绝大部分的都是输入给X server,然后由X server以Event的形式传递给X client(这里感觉类似Windows的消息机制,操作操作系统接收到用户的输入信息,然后以消息的形式传递给窗口,再由窗口的消息处理过程处理).X client对收到的Event进行相应的处理后,如果需要输出到屏幕上或者是更改画面的外观等,则发出Request给X server,由X server负责显示. 常见的情况是X server与X client都在同一台电脑上运行,但他们也可分别位于网络上不相同的电脑上.在X Window System中,X client是与硬件无关的,他并不关心您使用的是什么显卡什么显示器什么键盘鼠标,这些只与X server相关.我们平常安装完XFree86后运行xf86config或者是xf86cfg进行的配置实际上只是与X server有关,可以说就是配置X server吧,不配置照样可以运行X client程序(Procedures)(Procedures)(如:xeyes -display xserver:0就可以在xserver这台机器上的0号屏幕(屏幕编号displaynumber为0)上显示那对大眼睛了). X protocol就是X server于X client之间通信的协议了.X protocol支持现在常用的网络通信协议.我只能测试TCP/IP,可以看到X server侦听在tcp 6000端口(Port)上.那X protocol就是位于运输层以上了,应该属于应用层吧?. 总结下运行过程吧: I. 用户通过鼠标键盘对X server下达操作系统命令 II. X server利用Event传递用户操作信息给X client III. X client进行程序(Procedures)(Procedures)运算 IV. X client利用Request传回所要显示的结果 V. X server将结果显示在屏幕上 二) 启动操作系统过程 我们从控制台进入X一般是用startx系统命令.下面就从startx分析起.最开始man startx和man xinit可以看到staratx和xinit的使用方法:复制内容到剪贴板代码:startx [[client] options .....] [-- [server] options ....]
xinit [[client] options ] [-- [server] [display] options] 把上面[client]和[server]分别称为client程序(Procedures)(Procedures)和server程序(Procedures)(Procedures).man手册里写明其必须以/或者是./开头. 下面看看startx这一个脚本,中文为我加的注释,这一个脚本是安装x-window-system-core后得到的,绝大部分的都是XFree86,不同发行版的linux里该脚本应该大同小异:复制内容到剪贴板代码:#!/bin/sh
userclientrc=$HOME/.xinitrc #用户的client定义文件
userserverrc=$HOME/.xserverrc #用户的server定义文件
sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc #操作操作系统的client
sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc #操作操作系统的server
defaultclient=/usr/X11R6/bin/xterm #默认的client程序(Procedures)(Procedures)
defaultserver=/usr/X11R6/bin/X #默认的server程序(Procedures)(Procedures)
defaultclientargs="" #下面定义了client和server的参数变量
defaultserverargs=""
clientargs=""
serverargs="" 如果用户client文件存在则使用用户文件里定义的client,不然的话使用操作操作系统定义的client:复制内容到剪贴板代码:if [ -f $userclientrc ]; then
defaultclientargs=$userclientrc
elif [ -f $sysclientrc ]; then
defaultclientargs=$sysclientrc
fi
<ccid_page/>
<br><br><br><br><br><br><br><br><br><br><br><br>
#如果用户server文件存在则使用用户文件里定义的server,不然的话使用操作操作系统定义的server:
if [ -f $userserverrc ]; then
defaultserverargs=$userserverrc
elif [ -f $sysserverrc ]; then
defaultserverargs=$sysserverrc
fi 下面循环处理client和server的参数:复制内容到剪贴板代码:whoseargs="client"
while [ x"" !=x ]; do #若第一个参数为空,退出循环
case "" in
# '' required to prevent cpp from treating "/*" as a C comment.
/''*|./''*) #如果是/*或者是./*形式(xinit程序(Procedures)(Procedures)要求其参数里面的client程序(Procedures)(Procedures)
和server程序(Procedures)(Procedures)必须以/或者是./开头,不然的话会被视为client程序(Procedures)(Procedures)和server程序(Procedures)(Procedures)的参数,
见man xinit)
if [ "$whoseargs" ="client" ]; then #如果当前是在处理client的参数
if [ x"$clientargs" =x ]; then #如果clientargs为空,
则赋值给client变量,也即上面#startx使用方法里面的[client]参数
client=""
else
clientargs="$clientargs " #不然的话clientargs赋值为$clientargs ,
即上面#startx使用#方法里面的options参数
fi
else #当前在处理server的参数,代码的含义同上
if [ x"$serverargs" =x ]; then
server=""
else
serverargs="$serverargs "
fi
fi
;;
--)#如果为--,则表示开始处理server的参数,
--为client和server参数的分界
whoseargs="server"
;;
*)
if [ "$whoseargs" ="client" ]; then
#处理给client程序(Procedures)(Procedures)的参数
clientargs="$clientargs "
else #处理给server程序(Procedures)(Procedures)的参数
# display must be the FIRST server argument
#屏幕编号必须为第一个给server程序(Procedures)(Procedures)的参数,以的形式(x为数字),
这可从上面startx和xinit 的使用
#方法的区别看出,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参数的后果
if [ x"$serverargs" =x ] && expr "" : ':[0-9][0-9]*$' > /dev/null 2>&1; then
display=""
else #处理屏幕编号以外的参数
serverargs="$serverargs "
fi
fi
;;
esac
shift #所有参数左移一次
done
# process client arguments
if [ x"$client" =x ]; then #如果client程序(Procedures)(Procedures)为空
# if no client arguments either, use rc file instead
if [ x"$clientargs" =x ]; then #且clientargs为空,赋值$defaultclientargs给client程序(Procedures)(Procedures)
client="$defaultclientargs"
else
client=$defaultclient #使用默认的client程序(Procedures)(Procedures)
fi
fi
# process server arguments处理server参数,同上
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
#…………省略授权代码若干
xinit $client $clientargs -- $server $display $serverargs #把处理过的参数交
由xinit程序(Procedures)(Procedures)处理
#………… 由上面代码可以得出startx主要是置X client和X server所在的位置,并处理相关参数,最后交给xinit处理.可以看出startx 设置X client的位置是先搜寻$HOME/.xinitrc,然后是/etc/X11/xinit/xinitrc;设置X server的位置是先搜寻$HOME/.xserverrc,然后是/etc/X11/xinit/xserverrc.这就解释了我们平常为什么或者说怎么会说启动操作系统X Window时用户目录下的.xinitrc和.xserverrc文件优先级要高.所以我们用startx系统命令启动操作系统X时,如果用户目录存在. xinitrc和.xserverrc文件,则实际上等价于系统命令xinit $HOME/.xinitrc -- $HOME/.xserverrc .如果用户目录不存在那两个文件,则等价于xinit /usr/X11R6/lib/X11/xinit/xinitrc -- /usr/X11R6/lib/X11/xinit/xserver.别的情况类推.-----
至于xinit,则根据startx传过来的参数启动操作系统X server,成功后根据xinitrc启动操作系统X client. 以上即为X Window System的启动操作系统过程,startx只是负责一些参数传递,真正的X启动操作系统由xinit实现.实际上可以分为启动操作系统X server和启动操作系统X client两部分.下面在用户目录下构造.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 程序(Procedures)(Procedures),X client即是/usr/bin/X11/xeyes 程序(Procedures)(Procedures). 总结下单机用startx启动操作系统过程吧: I. startx置X client和X server的位置,处理参数并调用xinit II. xinit根据传过来的参数启动操作系统X server,成功后呼叫X client III. 根据xinitrc设置相关资源,启动操作系统窗口管理器,输入法和其他应用程序(Procedures)(Procedures)等X client程序(Procedures)(Procedures). 但还未搞清楚gnome是怎么起来的!gnome当然属于X client了,看上面启动操作系统过程第III.步.这里分两种情况看吧,第一种是用操作操作系统的xinitrc文件.看/etc/X11/xinit/xinitrc文件(我的sarge装x-window - system-core和gnome-core),里面只包含了. /etc/X11/Xsession一句话.接着看/etc/X11/Xsession这一个脚本,只看关键部分吧.最后面有:复制内容到剪贴板代码: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,然后循环运行该目录下的文件.看看该目录,即 /etc/X11/Xsession.d目录,可以看到几个以数字开头的文件,实际上这些数值就表示了这几个文件被运行的优先级,数字小的优先级高,因为在上面的run_parts () 里是用ls系统命令显示该目录下的文件,所以前面数字小的被ls时显示在前面,所以被:复制内容到剪贴板代码:for SESSIONFILE in $SESSIONFILES; do
. $SESSIONFILE
done 这一个for循环执行时也先被执行.看到/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 即设置启动操作系统程序(Procedures)(Procedures),实际上设置STARTUP变量,如果以上程序(Procedures)(Procedures)都没有找到,则会报错退出,即X环境没有被启动操作系统.再运行复制内容到剪贴板代码:xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP * 看到优先级最低也即最后被运行的99xfree86-common_start文件,里面只有一句话:复制内容到剪贴板代码:exec $STARTUP 好了,到这里就启动操作系统我们的X client了,终于完了^_^.总结下这第一种方式的启动操作系统过程,简单的说就是依次顺序查找/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 启动操作系统时可能会设置启动操作系统输入法等程序(Procedures)(Procedures),那就归gnome-session管了,也就不再分析了.可以试着把/usr/bin/x-session- manager 改为指向xfce4-session(如果安装了的话) ,再startx就会启动操作系统xfce4环境了.大概RedHat的switchdesk工具就是改这一个连接实现的吧?.或者是删掉/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启动操作系统的.也就不怎么会经过上面第一种情况的执行过程了. 终于把gnome(或者是说x-session-manger)的启动操作系统过程弄明白了,下面说点别的吧.xinit程序(Procedures)(Procedures)同时启动操作系统X server和X client,这在单机上还可.要是位于网络上的两台电脑分别是client和server,则xinit就无能为力了.这时就得靠纯“手工”来启动操作系统X 了.下面简单的“手工”启动操作系统X server和X client:在CUI模式下运行系统命令:复制内容到剪贴板代码:xdkui@Debian:~$X :1&-----
看到了一个灰色的全屏幕和一个鼠标指针,这就是X server了,其屏幕编号为1.下面构造X client,按Ctrl+Alt+F1回到刚才的CUI(Ctrl+Alt+F7对应本台电脑的第一个启动操作系统的X server,Ctrl+Alt+F8对应第二个,有个别的人说F7对应屏幕编号为0的X server实际上是不对的,如果第一个启动操作系统的屏幕编号为1,第二个启动操作系统的编号为0,则F7对应1屏幕,F8对应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对应屏幕编号1;而不能是F8对应屏幕编号0,且其X client为xterm.先退出上面的两个X server,下面复杂点手动启动操作系统我们的gnome吧,最开始:复制内容到剪贴板代码:xdkui@Debian:~$X& 然后:复制内容到剪贴板代码:xdkui@Debian:~$gnome-session 看到的就和用startx 启动操作系统的X一样了,这时X server是X这一个程序(Procedures)(Procedures),X client是gnome-session及其启动操作系统的窗口管理器等程序(Procedures)(Procedures).看到这里感觉xinit用处并不大(??不知是否正确),简单的脚本就可以实现.本来想把xinit反汇编了分析下,可懒得搞了^_^这是位于本台电脑的情况,对于X server和X client位于不同主机的情况见下面本文第三部分. 个人感觉对于X Window System,搞清楚X server与X client关系很重要.一般X server很简单,就是/usr/bin/X11/X程序(Procedures)(Procedures);X client则花样繁多,从高级的CDE,GNOME,KDE,到低级一点的只有twm,Window Maker,blackbox等窗口管理器,再到最简陋的只有xterm,rxvt,xeyes等单个单个x程序(Procedures)(Procedures).正是由于X client的各种各样搭配,使得我们的X Window System看起来多样化.这可能也是X Window System最大的卖点之一吧.-----
三) 跨网络运行X Window System 一般用来做服务器(Server)的操作操作系统(Linux,FreeBSD,Solaris等等)都不怎么会装X server,还超级有可能很多很多都没有显示器.这样可以在这些操作操作系统里安装简单的X client,以GUI的方式远程显示在管理员们所坐的X server里.我们实验室用FreeBSD做网关,提供WWW,FTP服务,一般在管理员的本地机器起个X server,然后ssh或者是telnet上网关运行X client程序(Procedures)(Procedures)显示在本地显示器上,当然,也可以用XDMCP(X Display Manager Control Protocol),man xsession里提到/etc/X11/Xsession一般被startx(我的/etc/X11/xinit/xinitrc里调用 Xsession脚本)或者是display manager调用,但有的display manager只调用Xsession而不能是不是xinitrc,故为了startx和display manager两种方式下都可正常启动操作系统GUI,最好把X client启动操作系统的程序(Procedures)(Procedures)放在Xsession文件里.远程运行X client程序(Procedures)(Procedures)需要设置DISPLAY环境变量,设置为 主机名称:屏幕编号(如19II.168.I.2:0,则表示X server是19II.168.I.2这台机器上的0号屏幕);或者是是给X client程序(Procedures)(Procedures)加个—display参数.由于条件限制,只测试了位于TCP/IP网络环境,X server为19II.168.I.2,X client为19II.168.I.1. 1) Windows操作操作系统做X server a) 用ssh或者是telnet方式 Windows下面的X server软件(soft)有很多很很多种的,我这里使用X-win32.在Windows里运行X-win32程序(Procedures)(Procedures),则相当于本地机器是个X server.远程登录(Logon)上Debian(我这里是用VMware仿真网络环境,直接或者间接进虚拟机就可以了^_^),运行:复制内容到剪贴板代码:xdkui@xclient:~$export DISPLAY=19II.168.I.2:0
xdkui@xclient:~$xterm& 这时即在Windows里面的X server里看到了xterm了,至于X client还运行什么程序(Procedures)(Procedures)就看您的需要了,文件管理器阿,资源查看器等.当然,这里X-win32要设置好授权,好像默认是禁止接入控制,即任何X client都可使用这一个X server. b) XDMCP方式 常见的Display Manager有xdm,gdm,kdm等.我这里使用的是gdm.需要修改gdm的配置文件/etc/X11/gdm/gdm.conf,修改 [xdmcp]段的Enable=true,使得可以远程登录(Logon),在X client运行gdm. 在X-win32里建一个XDMCP的session,查询方式,填入IP为运行gdm的机器地址.连接,就可以了看到登录(Logon)界面,下面的就不用说了,享受吧 2) Linux与Linux互联 a) ssh或者是telnet方式 在linux本地起个X server,需要注意授权问题,建立文件/etc/X0.hosts,填入X client的IP19II.168.I.1,当中X0.hosts表示本地第0个屏幕允许连接的X client地址,建立XI.hosts文件则是本地第1个屏幕允许连接的X client地址,以此类推,man xserver里有.运行复制内容到剪贴板代码:xdkui@xserver:~$X& 运行该程序(Procedures)(Procedures)时别加-nolisten参数,不然的话不怎么会在网络上侦听. 这一个时候Ctrl+Alt+F7是X server,返回Ctrl+Alt+F1还可以ssh上X client机器上. 然后登录(Logon)上X client,运行复制内容到剪贴板代码:xdkui@xclient:~$xterm –display 19II.168.I.2:0 就可以了在本地的X server里看到xterm了,如果有的话,还可把gnome-session也显示在本地来.同样可以在linux里面的VMware里做这一个测试,需要用点手腕了^_^见下 b) XDMCP方式 在我们的X client里运行gdm(别忘记了修改gdm.conf),然后在本地X server的CUI下面运行X -query 19II.168.I.1(X client开gdm机器的地址).可以看到登录(Logon)界面了吧. 我是在linux里面的VMware里做的测试,说一说所用的手腕吧.在Ctrl+Alt+F1的CUI下正常运行startx&启动操作系统GUI,这时 Ctrl+Alt+F7即为我的X server,X client启动操作系统的gnome,然后在这里运行VMware打开Debian虚拟机,并运行gdm.然后回到Ctrl+Alt+F1,运行X :1 -query 19II.168.I.1.看到登录(Logon)界面了吧.这时Ctrl+Alt+F7为我的0号屏幕,里面运行了虚拟机.Ctrl+Alt+F8为1号屏幕,在远程 GUI登录(Logon)X client.相当于我在本地起了两个X server. X Window System设计的真是相当神奇,使用方法更是眼花缭乱.佩服………-----
这是篇不错的文章...小迟网络实验室┈┈→ http://Chameleon168.cn
》热 点 关 注