LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: probing

╭∩╮(︶︿︶)╭∩╮FreeBSD使用大全FreeBSD╭∩╮(︶︿︶)╭∩╮

[复制链接]
 楼主| 发表于 2003-2-11 19:42:26 | 显示全部楼层

FreeBSD连载(49):进入X Window

进入X Window

  X服务器的执行程序位于/usr/X11R6/bin目录中,并且使用一个符号联接 “X” ,指向具体的执行程序,如XF86_VGA16或XF86_S3V等。因此直接输入X命令就能启动设置好的X服务器,系统将进入图形状态,并出现一个可以移动的X形鼠标指针,但并没有其他反应。这是因为X服务器只负责处理输入和显示,具体对使用者的输入进行处理则由其他X客户负责,而直接启动X服务器没有启动任何X客户,因而不能处理用户的任何输入。

    * 手工启动X Window

  因此为了利用图形界面的处理能力,在启动X服务器的同时还应该启动X客户程序来负责回应用户的输入。这个任务可以通过shell程序startx或 xinit来作到,这两个程序能在启动X的同时,启动X Window的窗口管理程序和其他X程序。

  startx和xinit缺省查看使用者个人目录下的.xinitrc文件,在这个文件内应该包含启动各个X客户程序的命令。最简单的.xinitrc可能只包含一个命令来启动一个仿真终端xterm,也可以包含一系列命令来启动多个程序,创建出漂亮的X环境。想自己定制X Window操作环境的使用者可以手工创建和修改这个文件,以得到不同的用户界面。

xmodmap -e 'keysym Alt_L = Meta_L Meta_L'
xterm &
xearth &
twm

  在这个例子中执行了 xmodmap用于修改X的键盘定义,然后在后台执行xterm提供一个仿真终端,执行xearth设置X Window的背景,最后在前台执行一个简单的窗口管理器twm。窗口管理器被放到前台执行,这样当退出窗口管理器时将退出整个X服务器的执行。

  缺省情况下,用户并没有创建这个.xinitrc文件,这样xinit命令就只能启动一个xterm终端仿真程序,而没有执行任何其他的X程序,也没有执行窗口管理器。因此,直接使用xinit启动的X Window仅仅具备一个终端窗口,将鼠标移动到它上面之后,才能输入命令执行其他操作。用户如果想要启动窗口管理器或其他程序,必须在终端窗口中输入相应的命令。

  由于X Window中存在多个窗口,但只有一个称为 “焦点” 的窗口才能接收输入。X Window缺省使用鼠标的位置来选择输入焦点窗口,当然另一些窗口管理器也可以通过键盘来切换输入焦点窗口。

  但是即使不存在.xinitrc文件,使用startx也能启动窗口管理器和几个 X客户程序,这是由于startx发现用户个人目录下不存在.xinitrc文件之后,就使用系统中的/usr/X11R6/lib/X11/xinit/xinitrc作为xinit程序的启动文件(startx只是调用xinit的一个shell脚本)。因此更改系统的xinitrc文件,就能使所有没有创建.xinitrc的用户仍然享有启动文件来启动X Window系统。由于FreeBSD是一个多用户系统,这样配置启动文件就能简化每个用户的初始配置任务。在用户对X Window的了解加深之后,就能进一步配置自己的启动文件来定制自己使用的X Window风格。

    * XDM系统登录方式

  startx或xinit必须先在控制台下登录之后,输入相应命令才能进入X Window 环境。另一种方法为预先启动X Window系统,在X Window下登录进系统。这种方式是使用xdm来实现的。

  以root用户登录之后,在命令行输入xdm,则系统立即启动X服务器,并启动相应的登录管理程序,在X Window上出现一个登录窗口,允许各个用户登录入系统。

  在用户通过登录认证之后,xdm就需要为用户启动登录会话。xdm就以用户身份执行/usr/X11R6/lib/X11/xdm/Xsession文件,然后再执行用户个人目录下的.xsession文件。个人目录下的.xsession文件与.xinitrc文件类似,也是一个标准shell脚本,以下是一个例子。

PATH=/usr/bin:/usr/sbin/:/usr/X11R6/bin:/usr/local/bin
xrdb -load .Xdefaults
xterm &
xearth &
twm

  这个文件与.xinitrc文件的不同之处在于,由于.xinitrc是在用户登录之后由xinit使用的,因此包括PATH在内的环境变量都已经在用户的.profile等文件中设置正确了,而通过xdm登录的用户并没有执行.profile等设置文件,因此必须在.xsession中设置PATH等环境变量,才能正确找到各个执行文件,否则就必须使用绝对路径来启动应用程序。

  另一个不同之处在于,个人目录下的.xsession文件必须存在,用户才能通过XDM正常进入X Window,否则登录过程就会发生错误。而对于xinit来讲,.xinitrc 不是必需的如果.xsession的执行有问题,用户就不能从xdm的登录界面上登录进系统。此时可以检查相应用户目录下的.xsession-errors文件,这个文件中将包含执行.xsession的错误信息。

  在FreeBSD 3.1-RELEASE中存在一个小问题,.xsession必须具备有可执行属性,否则就不能正确执行,这个问题在3.2-RELEASE中已经修正。可以从.xsession-errors 中的错误信息中来发现这个错误。

  先使用root登录系统,再手工执行xdm显然只是一个调试时的执行方式,如果要真正使用xdm让用户登录系统,应该在系统启动时自动执行xdm,最简单的方法是在/usr/X11R6/etc/rc.d目录下增加一个可执行的文件,例如命名为xdm.sh,并使用chmod +x xdm.sh使其可以被执行,最简单的xdm.sh可以为以下的形式:

#! /bin/sh
echo “Enter xdm”
/usr/X11R6/bin/xdm

  这样系统将在启动后直接启动xdm,进入X Window并展示一个登录界面等待用户登录。xdm以一种守护进程的方式运行在后台,每次用户退出之后会自动重新启动另一个登录界面,允许用户登录。

  当然也可以将xdm命令放入rc.local文件中,然而使用单独的启动文件使得启动文件更为整齐、清晰。

  启动Xdm的另一种方式是更改/etc/ttys中的设置,系统会根据ttys文件中的配置在相应终端上启动相应的程序,因此可以在一个空余的控制台终端上,通常是第四个虚拟控制台ttyv3,启动xdm。

ttyv3     "/usr/X11R6/bin/xdm -nodaemon"       xterm    on secure

  ttys中指定的进程具备再产生的特性,每个进程退出之后立即被重新执行。因此可以不必使用xdm本身的守护进程功能,而让系统来维护Xdm自动执行。就需要使用-nodaemon参数,使xdm以普通进程的方式运行。

    * 远程启动X客户程序:

  X Window本身的X协议支持网络,是一种分布式的体系结构。如果使用者的 FreeBSD与其他Unix通过网络相连接,就能在一个计算机上运行X客户程序,而将窗口显示在另一个运行X服务器的计算机上。

  由于一台计算机上可以运行多个X服务器,每个服务器会支持多个显示屏,那么X客户程序必须确认在计算机上的某一个服务器的某一个显示屏上进行显示,因此必须包括计算机地址、X服务器序号和显示屏号来唯一确定一个显示资源的位置,例如xserver:0.0,通常一台计算机中并没有过多的X服务器,该X服务器也不具备多个显示屏,因此就可以对显示资源的位置进行简化,一般使用xserver:0的表示方式。

  这种表示方式就可以标志远程X服务器的显示位置,当执行X客户程序时,就需要在命令行上使用display选项,来告诉X客户程序这个显示位置的参数。

xclient $ xterm -display xserver:0&

  或者通过设置DISPLAY环境变量来达到同样的目的。

xclient $ DISPLAY=xserver:0; export DISPLAY
xclient $ xterm &

  这两种方法都向名为xserver的计算机上的X服务器发出了请求,但能否正常开出窗口还必须得到这个X服务器的许可。缺省情况下X服务器具备访问控制能力,标准访问控制方法使得只有具备访问许可的X客户,及其子程序才能访问X服务器的资源,而其他X客户程序不能使用X服务器资源。当使用者使用startx和xinit启动 X服务器时,或者通过xdm登录进系统时,其后启动的X客户程序就继承了原有的访问权限。然而通过网络启动的X客户程序,使用X服务器资源就受到了这个访问控制的限制,不能正常启动。

  控制X服务器的访问控制能力的命令为xhost,为了使得xserver的显示资源能被xclient上的X客户程序所使用,就必须在已经具备X服务器访问能力的X仿真终端下执行以下指令:

xserver $ xhost xclient

  上面的xhost命令允许xclient计算机上的X客户程序使用这个X服务器,也可以执行使用+作为xhost的参数,这将允许任意X客户程序访问X服务器,因此就存在一定的安全性问题。如果通过网络使用X服务器的情况比较多,就可以将相应的xhost 指令放入.xinitrc或.xsession中,自动进行设置。

xserver $ rsh xclient /usr/X11R6/bin/xterm -display xserver:0
wb’s password:

  上面是一个使用rsh在一个远程计算机上执行X程序,而将窗口开回X服务器上的例子,在执行这个命令之前应该执行了xhost client以打开访问权限。

未完,待续。。。  
 楼主| 发表于 2003-2-11 19:44:15 | 显示全部楼层

FreeBSD连载(50):定制X Window的基本方法

定制X Window的基本方法

  与其他图形界面相比,X Window是高度可配置的,这是因为X Window 本身只是定义了一系列最基本的显示功能调用,而并没有规定图形窗口应该是什么样子的,因此大批程序员为X Window开发了各种不同风格的开发工具包和窗口管理程序,使得X Window的风格多种多样。因此X Window的使用者有多种选择,可以根据自己的喜好来定制工作站的图形界面。

    * 颜色深度、分辨率与字体配置:

  在前面的设置过程中可以设置X服务器使用多种色彩深度,如8bpp、 16bpp、24bpp和32bpp,一般来讲色彩深度越大,所能表现的色彩越丰富,而 24bpp就被称为真彩色,能真实的表现图象的色彩(32bpp实际也只是24bpp,它是为了让每个象素都占据独立的32位双字,以对齐象素边界,加速处理速度)。缺省的色彩深度为对应于256色的8bpp,显然这不足于表现图象的色彩,在硬件能力满足的条件下应该使用更高的色彩深度(要受显存大小和分辨率大小的限制)。例如要设置X服务器工作在16bpp的准真彩色下,可以使用带参数的 startx或xinit。

  $ startx -- -bpp 16

  其中前面的两个--线表示将后面的参数不加改变的传递给X服务器。另一种设置缺省色彩深度的方法是在X的设置文件XF86Config中设置DefaultColorDepth 选项。

由于X Window中的色彩深度是可以改变的,为了帮助客户程序使用具体的色彩,X客户程序中使用的色彩将通过X服务器映射为真实的色彩。X中还定义了多种标准色的名字,在X程序或资源定义文件中直接使用色彩名字,如 Red、Blue,就得到常用的颜色。

X服务器也可以同时支持多种分辨率,并能够在运行时刻动态切换它所支持的分辨率。在前面XF86Setup设置程序中的显示器设置选项中,有部分显示器能同时设置了几个显示模式,然而这些分辨率并不是该显示器能支持的分辨率的全部,如果是使用xf86config或者手工更改设置文件,还能设置更多的分辨率。当设置了多个分辨率模式的时候,就能在X Window下使用热键、和<+>向后切换模式,使用 、和<->向前切换分辨率模式,其中<+>和 <->是小键盘上的键,主键盘上的<+><->并不能用来切换分辨率。

  虽然存在不同的分辨率模式,但是X服务器显示的虚屏大小仍然相同,虚拟显示屏大于实际显示屏,但可以通过鼠标的移动,在实际显示屏上显示虚拟显示屏的不同部分。因此在有多个分辨率的时候,虚拟显示屏至少应该等同于最大分辨率的大小,这样不论切换到哪个分辨率,应用程序的窗口仍然保持原有的样子,只是窗口有可能位于真实的显示屏外,需要通过移动鼠标来移动虚拟显示屏,看到应用程序窗口的全貌。由于移动虚拟显示屏是通过直接控制显示卡上的寄存器来进行的,不需要在显存或内存中进行额外的移动或复制操作,因此几乎不消耗资源,也不影响任何显示速度。

  虽然XFree86缺省已经支持了相当丰富的字体,但是还是有可能需要安装新的字体,例如某种中文字体。X Window的字体应该在配置文件中设置其搜寻路径,但在启动X Window之后,也可以使用xset命令来重新设置字体的搜寻路径。

  xset fp+ :增加一个字体搜寻目录。

  xset fp- :删除一个字体搜寻目录。

  xset fp= :重新设置字体搜寻目录。

  xset fp rehash:更改某个字体目录中的内容后,强迫系统刷新字体搜寻路径。

  要想使用一些使用者自己设置的字体,就要按下面的步骤将这些字体加入到X Window的搜寻路径。

    *   将这些字体单独放在一个目录下,或者放到系统原有的字体目录下。

    *   运行 “mkfontdir 该字体目录” ,构建这个字体目录(将按照所有的字体,重新生成fonts.dir文件)。

    *   使用 “xset fp+ 该字体目录” 或 “xset fp rehash” ,使设置生效。

  fonts.dir文件中包含该字体目录下所有字体的名字,以下为一个例子的部分内容,该文件每一行都给出一个字体的名字。

gb16st.pcf.gz -isas-song ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
gb24st.pcf.gz -isas-song ti-medium-r-normal--24-240-72-72-c-240-gb2312.1980-0
10x20.pcf.gz -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso8859-1
gb16fs.pcf.gz -isas-fangsong ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0

  可以看出font.dir中的内容分为两部分,第一部分为字体文件的名字,第二部分为字体的名字。每个字体的名字用 “-” 将不同的部分分隔开了,这些相互分隔的部分包括字体的开发者、字体的类别、字体本身的尺寸(磅数)、倾斜度和点的大小,字符间距的类型、字体所为的字符集,以及字符的风格。

  可以看出,每个字体的名字相当复杂,然而可以通过定义别名的方式来简化具体字体的名字,在一个字体目录下,都有一个对应的fonts.alias的文件,这里就登记了很多字体的别名,使用者也可以自己根据需要增添。

fixed        -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
variable     -*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1
5x7          -misc-fixed-medium-r-normal--7-70-75-75-c-50-iso8859-1
5x8          -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso646.1991-irv

  上面就是某个font.alias的一部分,它的第一列就为简单易记的别名。在运行 X Window时,可以使用xlsfonts来查看系统中可以使用的字体信息,使用xfontsel来查看每种字体的外观。

    * 定制客户桌面基本方法

  根窗口的特征可以使用xsetroot命令来设置,可以使用它来定制窗口的颜色(背景色和前景色),或者使用一个位图作为背景等。也可以使用”xset s seconds”来定义屏幕保护的激活时间,”xset s default”将屏幕保护设为系统的缺省配置。

  还有很多更强大的X程序能用来定制X的根窗口,设置壁纸和屏幕保护。例如可以使用xv来将gif或jpg等类型的图片设置为壁纸,这些程序都可以在FreeBSD的Packages Collection 和Ports Collection中找到。

  X客户程序通常使用标准的构件,通常这些构件都有一些标准的参数来定义它们使用的字体、文字的前景色、背景色、滚动条等。这些参数可以通过更改构件的资源设置,来改变其设置。一般使用用户个人目录下的.Xdefaults或.Xresoures作为用户的个人资源文件,资源文件在启动时在.xinitrc文件中由xrdb命令载入系统。

  除了资源设置之外,标准X客户程序中的构件也支持标准的命令行选项,可以用来改变窗口构件的属性:

  -borderwith或-bw,框架的宽度,以像素为单位

  -foreground或-fg,前景色

  -background或-bg,背景色

  -display,客户程序要使用的X服务器的显示位置

  -font或-fn,显示特殊文字使用的字体

  -geometry,窗口的几何结构,包括位置和大小

  -iconic,以图标方式启动

  -title,标题栏的标题

    * 选择窗口管理器和桌面环境

  在FreeBSD安装好XFree86之后,缺省的窗口管理器是twm,这是一个比较简单的窗口管理器,会使得第一次接触X Window的使用者对X Window产生不好的印象,但是如果进一步了解X Window系统,就会知道X Window本身并没有包括真正好用的窗口管理器,但是却存在很多种优秀的窗口管理器能达到这个目的,使X Window变得更华丽、更易用。

  因此必须从Packages Collection中选择安装相应的窗口管理器或桌面环境,可供选择的有fvwm95、AfterStep、KDE等。

  fvwm95是从另一个窗口管理器fvwm2的进行改进之后的版本,它被设置为与Windows95 的桌面非常相似,因此习惯于Windows95界面的个人计算机使用者常常会选择这个窗口管理器,然而既然使用的是X Window,没有必要一定还要使用Window95的显示风格,使用 fvwm2、AfterStep等其他窗口管理器来尝试其他风格更为有益。一般情况下使用者还是会安装一个fvwm95,fvwm95使用的配置文件是用户主目录下的.fvwm2rc95文件,而缺省配置文件为/usr/X11R6/lib/fvwm95/system.fvwm2rc95文件。使用fvwm95时最简单的启动文件.xinitrc应包括:

  /usr/X11R6/bin/fvwm95

  AfterStep是模仿NextStep的窗口管理器,这个窗口管理器精巧而且漂亮,如果不是过于沉迷于Windows95的操作方式,不妨使用这个窗口管理器,它还有几个派生的管理器,如WindowMaker、enlightenment等。为了充分发挥AfterStep的华丽,X的显示屏应该大于800x600的分辨率,并至少使用16bpp的色彩深度。AfterStep的所有配置文件均放置在用户主目录下的GNUStep目录中,相应的启动文件为:

  /usr/X11R6/bin/AfterStep

  与前面两者不同,gnome和KDE不仅仅是一个窗口管理器,还包括大量的应用程序和相关工具(gnome使用enlightenment作为其缺省窗口管理器)。这些桌面环境包括各种应用程序、控制条、图形化的设置程序等,使用它们能够全面享受到图形桌面环境的优点,但它们占用的系统资源也相对较多。如果是将安装FreeBSD的计算机用做一台工作站,那么就应该选择其中一种桌面环境,用户可以根据自己的喜好来选择安装gnome或者KDE。

  如果选择安装了KDE时,在.xinitrc及.xsession中应该包含的相应启动命令为:

  /usr/local/bin/startkde

  在3.2=RELEASE之后,FreeBSD能通过Sysinstall来设置不同的桌面环境,Sysinstall 能安装相应的软件包,并在/usr/share/skel中添加dot.xinitrc和dot.xsession文件,这样在生成用户时就自动生成.xinitrc和.xsession文件。

    * 配置和使用KDE

  KDE不单单是一个窗口管理程序,它包括了使用X Window图形界面进行操作所需要的各种应用程序。它的主要部分为一个拥有任务条、工具条、快捷图标的桌面环境,并包括可用于浏览WWW网页的文件管理器、编辑器、计算器、CD播放器、邮件处理程序、新闻组阅读程序等等大量的应用程序。

  KDE的另一个特点就是包括了对图形界面外观的定制程序,一般情况下Unix中进行配置需要修改对应的配置文件,虽然这种方式提供了很大的灵活性,但对于很多不重要的设置,并不需要这么灵活的方式,而要求方便、简易。在KDE下不需要使用手工更改配置文件,而是通过图形界面的设置程序进行设置,因此更容易使用。下面为一个KDE 界面的例子:

  由于KDE是为了高性能的图形界面开发的,因此为了获得较好的观感,至少应该以800x600分辨率运行X Window,建议使用1024x768以上的分辨率,以充分发挥KDE的显示效果。

  KDE图形桌面由桌面背景、快捷图标、工作栏和任务条组成,每个可以点击的位置上通常使用左键一次点击启动相应的功能,使用右键点击出现一个菜单,可以进行相关设置。上图为进行工作栏和任务条的外观设置,设置它们显示的不同的大小和位置。此外,在桌面上使用右键可以配置桌面外观,包括墙纸和屏幕保护。点击左下角的K图标可以弹出一个菜单,菜单中包括了KDE环境提供个多种应用程序,也可以添加对其他应用程序的连接。

  与MS Windows不同,KDE(以及大部分X窗口管理器),使用一次点击启动应用程序,而不是双击。KDE下切换窗口的热键与Windows相同为Alt-Tab。

  KDE界面低部工作栏上的各个按钮都对应一个相应的应用程序,而其中并列的四个按钮,对应四个不同虚拟屏幕,每个屏幕上的内容各不相同,可以分别配置。KDE最多可支持八个虚拟屏幕,每个窗口只显示在一个屏幕上,除非使用鼠标将窗口左上角的图钉标志打开,这样操作之后这个窗口总显示在屏幕上,而不管如何切换虚拟屏幕。

  KDE的配置工作全部可以通过KDE配置中心(KDE Control Center)来完成。点中左下角的 “K” 图标,在菜单中选中KDE Control Center或使用工作栏上的快捷图标,就可以启动它对KDE的外观进行配置。

  KDE控制中心可以设置KDE桌面环境的排列方式,如工作栏、任务栏的大小和位置,窗口的风格,使用的颜色,屏幕保护以及其他一些应用程序的相关设置。这些设置也可以在KDE桌面环境中,使用鼠标右键弹出的菜单中的选项来启动。

  由于KDE是一种国际化的应用程序,因此可以使用上面的设置程序将KDE使用的字符设置为中文。当将KDE使用的语言设置为中文时,那么所有KDE的菜单都使用中文,但是这需要中文X服务器或其他中文系统的中文显示能力的支持,否则KDE虽然显示的是中文字符,但是显示的却会是乱码。

  对于使用XDM登录方式的系统,需要使用xdm以提供系统登录。虽然用户登录后可以从.xsessin中启动KDE,但仍然摆脱不了xdm过于简陋的登录画面。而KDE的另一个特点就是提供一个xdm的替代程序kdm,这使得系统管理员可以替换掉简单的xdm界面,使用kdm来提供更漂亮的XDM登录界面,这使得X Window系统表现得更为华丽。

  上图就是一个kdm的外观,它同样也是在KDE控制中心中来进行配置的,只是由于 kdm属于系统程序,因此只有root运行的KDE控制中心才能选择这一项配置功能。设置KDM ,需要选择KDE配置中心的第一个选项Desktop Manager。

  这个选项中可以设置kdm的图标、出现在kdm的用户列表中的用户、或者不出现在kdm 的用户列表中的用于,以及在会话结束时用于关闭系统的指令等。

    * 将工作站用作专用X终端

  专用机房中常常使用X终端为公共使用者提供服务,使用者可以通过这些终端以XDM 方式登录到机房中的Unix主机上去。X终端不允许使用者登录到自己系统中,而只能使用本地X服务器的处理能力,登录到其他主机上进行使用。

  由于个人计算机硬件更为便宜,并且由于硬件的发展其性能也并不落后,使用个人计算机作X终端也是一种在使用专用X终端之外很不错的选择。可以使用FreeBSD作操作系统,Xfree86支持X Window系统,就能将FreeBSD系统用作专用X终端,这样的优势是所有的软件都可以免费得到,就使得在实现几乎同样的性能的条件下,却减少了大量的资金投入。

  同样也可以通过设置使得用户不能登录进本地系统,而是直接登录到网络上的其他Unix主机中去。这需要那台提供登录服务的Unix主机运行xdm,这样X终端就能通过xdmcp 协议在网络中通过广播或者直接查询的方式,查找到运行xdm的主机,并连接上来提供登录登录画面,就如同在本地系统一样。用作X终端的FreeBSD系统需要以使用特别的参数运行X,以查找XDM主机。

  如果运行XDM的Unix主机和用作X终端的FreeBSD系统在同一个以太网段上,可以使用广播的方式寻找运行XDM的主机,此时启动X的命令为:

  # /usr/X11R6/bin/X -broadcast

  这样系统上将列出本地所有运行XDM的Unix主机,供使用者选择登录。或者可以直接查询方式,通过query参数直接与某台Unix主机相连接,这可以用在客户机和服务器不在同一个网段上的时候。

  # /usr/X11R6/bin/X -query Unixhost

  为了使系统一启动就进入这个登录状态,可以将这个命令写入shell脚本,并放入系统启动目录/usr/X11R6/etc/rc.d中。然而此时使用ttys文件进行设置更佳,因为此时可能同时想关闭虚拟控制台,以防止X终端使用者切换到虚拟控制台上。

未完,待续。。。
 楼主| 发表于 2003-2-11 19:46:16 | 显示全部楼层

FreeBSD连载(51):中文X应用软件

X Window下的中文环境

  Unix的中文化对于Unix的推广使用一向是个难题,对于象FreeBSD这样的操作系统来讲,中文化工作比较零乱,虽然有不少X下的中文软件,但是由于国内软件发展的水平还不高,自由软件的开发水平更是如此,并且自由软件的开发者之间也没有被有效的组织起来,因此还没有出现一个很完整的中文系统。

  然而中文相关的软件却相当丰富,在Ports Collection中,有一个类别就是chinese,专门收集中文相关的处理软件,但其中绝大多数是台湾的BIG5 版本。因为台湾在FreeBSD领域的发展相当快,很多软件都是先由台湾出现相应BIG5版本之后,再出现GB版本。

bash-2.02$ ls /usr/ports/chinese
CJK             big5fonts       gbfonts         nvi-big5        ted
CVS             c2t             gbscript        nvi-euc-cn      tin
Makefile        celvis          hc              nvi-euc-tw      xcin
README.html     cless           hztty           pine3
Wnn             cnsfonts        kcfonts         pine4
bg5ps           cxterm          lunar           pkg
big5con         gb2ps           mule-wnn4       rxvt

    * 中文X应用软件

  在X Window下使用中文的基本条件之一就是需要安装合适的中文字库。当前的XFree86发行版本中带有一些基本中文字库,在系统安装选择X组件的设置时需要将其包括在内,然而中文存在不同的编码方式,使用不同编码的应用程序就使用不同的字体文件,XFree86中提供的中文字体对于另外一些中文程序还是不够的。

  Packages Collection中的chinese类别中也提供了其他的一些BIG5和GB 编码的字体,如gbfonts、kcfonts、big5fongs等软件包,需要使用pkg_add命令将其安装入系统。在真正执行中文X应用程序时,可以使用xlsfont命令可以查看系统中是否有相应字库,如:

$ xlsfonts *gb*
-cc-song-medium-r-normal-jiantizi-0-0-75-75-c-0-gb2312.1980-0
-cc-song-medium-r-normal-jiantizi-40-400-75-75-c-400-gb2312.1980-0
-cc-song-medium-r-normal-jiantizi-48-480-75-75-c-480-gb2312.1980-0
-isas-fangsong ti-medium-r-normal--0-0-72-72-c-0-gb2312.1980-0
-isas-fangsong ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
-isas-song ti-medium-r-normal--0-0-72-72-c-0-gb2312.1980-0
-isas-song ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0
-isas-song ti-medium-r-normal--24-240-72-72-c-240-gb2312.1980-0
hanzigb16fs
hanzigb16st
hanzigb24st

  当一个字体不存在但同时存在同样编码的其他字体的时候,可以通过在 fonts.alias中定义别名的方法来帮助解决这个问题。

  除了Packages Collection提供的字体之外,从网络上也可以得到其他的一些中文字体。在ftp://ftp.ifcss.org站点中收 ... 和中文软件。

    * cxterm

  cxterm是一个使用非常广泛的中文X终端程序,已经被移植到很多种类的Unix系统中。它已经被FreeBSD的爱好者做成Packages,因此安装起来非常简单。cxterm支持GB、BIG5以及日、韩文等编码和多种输入法。

  直接启动cxterm只能用于浏览中文而不能进行输入,这是由于cxterm需要X系统的一些资源设置,以使用快捷键切换不同输入法,并根据设置寻找其输入法对应的数据文件。要输入中文必须进行设置,将资源文件预先载入,指定热键、输入法和输入字典所在的目录。cxterm软件包中提供了一个缺省的资源文件 CXterm.ad,一些使用者将这个文件中的相应资源定义放入~/.Xdefault中,用户登录进入X Window时就载入这些资源。另外,cxterm还提供了一个shell脚本 ── CXterm,可以在启动cxterm之前完成相应的资源设置工作,所以一般应该 用如下CXterm命令来启动cxterm,这种启动方式更为简易。

  $ CXterm &

  在中文的仿真终端下使用bash作为shell时,会发现在命令行中无法输入中文,这是因为bash对输入进行了额外处理,可以在~/.bashrc中设置bash让其通过中文(另一个可能的因素为stty的终端设置):

stty pass8
bind 'set convert-meta off'
bind 'set meta-flag on'
bind 'set output-meta on'

  在FreeBSD下的预编译的cxterm软件包中,cxterm的输入法及输入字典放在了/usr/X11R6/lib/X11/cxterm.dic目录中。由于cxterm的影响,它的输入法被相当多的X Window下的中文软件所使用。

  标准的CXterm是黑白的,但也存在一个补丁,使CXterm能显示彩色。然而,Packages Collecion中预编译好的CXterm为标准程序,要使用彩色CXterm就需要自己下载补丁并重新编译CXterm。

    * Xcin与crxvt

  crxvt是另一个中文X仿真终端软件,与cxterm相比,它更小巧,占用更少的内存,并能以ANSI标准显示彩色。Xcin是一个独立的输入服务器,它独立于具体的X程序之外来提供中文输入功能,X应用程序可以使用其接口支持中文输入。crxvt 就使用Xcin作输入系统。与cxterm的将输入与仿真终端集成在一起的方式不同, Xcin在crxvt外打开一个单独的窗口,但在crxvt中可以使用Ctrl-Space进行Xcin 下的中英文输入切换。可以看出Xcin的设计目的是作为一个通用输入模块来实现的,以便多个应用软件都能使用同一个输入模块来进行中文输入,而不是象cxterm 一样,每个程序使用自己的输入模块。

  FreeBSD的Packages Collection中,也包括了Xcin与crxvt,但遗憾的是,他们是台湾big5版本。当然这也容易理解,这个软件本来就是由台湾人开发的。其中 crxvt可以通过使用hztty使其能显示gb数据,但使用者显然不会使用台湾的输入法输入中文。幸好这个软件已经被移植到GB环境下,并也有编译好的软件包形式(未被正式FreeBSD发行版本收录),这样就可以使用pkg_add等工具进行管理,而不再需要手工编译。

  执行时,需要启动xcin和cxrvt,注意要使用Xcin而不是xcin启动Xcin,主要是Xcin能使用正确的输入法参数启动真正的xcin程序,直接启动xcin由于没有指定输入模块的设置,就会导致程序启动失败。

$ Xcin &
$ cxrvt &

    * 其他支持中文的软件与中文本地化

  除了cxterm、cxrvt之外,Ports Collection还包括其他一些软件,如hztty 用于终端上hz、big5、gb等不同编码的动态转换,big5con用于在控制台上显示中文 big5码(在hztty的帮助下可以显示gb码),cvi用于替换vi进行中文编辑工作,cless 用于替换more显示中文,gb2ps用于中文文本文件的打印处理等。

$ LANG=zh_CN.EUC; export LOCALE
$ LC_ALL=zh_CN.EUC; export LC_ALL

  对于支持多语言的软件,使用环境变量LANG和LC_ALL来标识不同的语言、及不同的环境。缺省情形下使用的语言LANG被设置为C,如果要支持中文,应该设置为 zh_EUC.GB,同样LC_ALL用于设置不同语言使用的信息格式的不同,如日期、时间的表示方式等。虽然当前不是每个应用程序都支持这些环境变量,但随着FreeBSD系统的升级,应用程序国际化程度的提高,以后的软件越来越多会对各种语言提供更完善的支持。

  另外,FreeBSD下的一些传统工具程序不支持国际化的语言,应该使用较新的 GNU工具代替。例如标准的ls命令不能显示中文文件名,可以安装gnuls软件包,使用 gnuls -N命令来代替缺省的ls命令,可以通过shell中的alias设置,使得用户感觉不同执行命令的差异。

未完,待续。。。  
 楼主| 发表于 2003-2-11 19:48:48 | 显示全部楼层

FreeBSD连载(52):外挂式中文显示与输入软件

外挂式中文显示与输入软件

  对于支持中文的软件,可以使用自己的方式处理中文的显示与输入。然而更一般的软件中,都没有直接提供中文支持,有些能够部分识别中文但无法处理中文输入,如Netscape Navigator。有些根本不能识别中文,有些甚至将8位字符作为非法字符来看待。对于最后一种过滤8 位字符的情况,是没有办法能使其正常显示、输入中文,但对于前两种情况,就有变通的方式使其正常显示和输入汉字。

    * 动态连接库的wrap技术

  X Window下的客户程序要显示字符,需要调用libX11.so.6动态连接库中的XDrawString()等函数进行具体处理显示,如果这个函数能够区分出中文字符,并自动使用合适的中文字体进行显示,那么客户程序就能正常显示中文。因而最基本的想法是修改X11R6中这些相关的显示处理函数,使它们能正常显示中文。当然这可以通过直接修改XFree86发行版本中这个函数的源代码,并通过重新编译、安装库函数来做到。然而这需要更改原有的正式发行版本,不是每个用户都愿意并且能够重新编译X系统的,并且这种方法对于不具备源代码的商业X服务器系统就不使用。而且更改libX11.so.6也不太安全,缺乏灵活性,因此最好不更改原有的连接库,就能达到正确处理中文的目的。

  由于一般的应用程序使用动态连接的方式,在应用程序载入内存时,系统才将具体的动态连接库连接上。因此如果在系统载入标准的库之前,预先载入一个包含同样名字函数的动态连接库与应用程序连接,那么程序会使用先连接的第一个库中的同名函数库,而非原有的标准库函数,这种方式就称为包装(wrap)的方法。

  现代Unix都支持这种预连接动态连接库的能力,系统在载入动态连接库之前,首先查看LD_PRELOAD环境变量,如果这个变量定义了一个动态连接库,那么就在连接其他标准动态连接库之前先连接这个变量定义的动态连接库。因此如果这个预载入的动态库中有XDrawString()等函数的定义,那么它们就覆盖了系统中libX11.so.6库中的原有定义,而这个包装库可以通过直接访问libX11.so.6库来找到原有的标准函数,以真正处理显示。

  出于系统安全的考虑,系统不允许SetUID或SetGID的程序载入LD PRELOAD变量设置的动态连接库,这主要是避免用户通过定义自己动态连接库,在setuid等系统调用之后取得root权限。因此包装技术不适合具有 SetUID或SetGID属性的二进制执行文件。此外,静态连接的执行程序在程序内部查找显示函数,也不适合使用包装技术(可以使用ldd命令来查看执行程序的动态连接关系,来判断其连接类型),除了这两种情况之外的其他X应用程序,就能支持中文包装技术。

  在使用包装技术时,另一个重要的问题是FreeBSD系统中存在两种不同的执行文件格式,a.out和ELF格式,它们分别使用a.out和ELF格式的动态连接库。因此对于不同格式的执行文件,必须使用相应格式的包装库来包装不同的libX11.so动态连接库,不同格式的库不能相互连接。3.0版本以上,缺省格式为ELF,缺省库也为ELF格式的动态连接库。因此3.0版本以后要支持对a.out格式进行包装,一方面包装的动态连接库的位置就改变为/usr/X11R6/lib/aout/libX11.so.6.1,同时也需要使用编译器的 -aout选项生成a.out格式的动态连接库,以进行包装。当前发行的标准 Packages均已经转向ELF,仍使用a.out格式主要是一些商业软件,如 Netscape Navigator。

    * Xcin AnyWhere

  XA(Xcin AnyWhere)是一个较早的使用包装技术的中文输入软件,它原来仅仅是用于中文输入,为Xcin提供一个标准接口,后来被加入了中文显示能力。具备中文显示能力的XA被称为XA+CV版本。

  XA是由台湾开发者开发的,当前版本为XA-0.4b,它具备GB显示能力的国标版本为xa-1.04。它能够在FreeBSD下编译执行。对于这些包装方式的外挂中文系统,可以使用它提供的shell脚本xa来启动应用程序。

  $ Xcin&

  $ xa kvt&

  或者自己设置LD_PRELOAD变量为wrap动态库的全路径,再启动相应的应用程序。

  $ LD_RELOAD=/usr/X11R6/lib/wrap.so; export LD_PRELOAD

  $ kvt&

  在启动了它的输入服务器Xcin之后,那么就能在xa启动的程序中就能使用热键切换Xcin的中英文输入了。

    * Chinput与ZhXwin

  Chinput是另一个使用了包装技术的中文输入和显示软件,它是使用了cxterm的输入源代码模块在Linux下开发的,在FreeBSD下也能够正常编译运行。Chinput的作者在其正式发布1.4.1版本中包括了几个与中文显示和输入无关的软件,虽然单个软件都还很有用,但是将几个软件捆在一起,使得应用程序管理比较混乱,还是应该将每个单独的应用程序独立出来,Chinput就专门用于中文的输入和管理。FreeBSD中可以使用Packages 的管理机制来管理应用程序之间的关系。

  Chinput使用资源文件Chinput.ad,并需要Cxterm的输入法,因此需要预先安装Cxterm包。它还提供了一个脚本run来运行应用程序。但直接设置LD_PRELOAD变量的方法也不复杂(移植到FreeBSD后的package中的执行脚本被更名为crun),Chinput的输入服务器为chinput,因此可以使用下面的命令来启动Chinput。

  $ chinput &

  $ crun kvt &

  ZhXWin的输入服务器也使用Chinput的chinput,并加上一个比较简单却有效的用于处理显示的包装库,它可能是基于Chinput的一个早期版本发展的。ZhXWin的优点是简单、有效,标准Chinput使用了几种不同大小的字体进行显示,而ZhXWin仅仅使用一种字体,然而除了一些字符间距的处理方面,其显示效果还不错。

  $ LD_RELOAD=/usr/X11R6/lib/libst.so; export LD_PRELOAD; kvt&

    * 使用包装软件

  每个包装软件由两个部分组成,一个部分为输入模块,需要单独运行。XA使用Xcin作输入模块,Chinput和ZhXwin使用chinput作输入模块。另一个部分为包装库,需要使用LD_PRELOAD环境变量进行设置。

  如果要让窗口管理器,如KDE,也显示中文,就需要在启动这些窗口管理程序之前设置好包装库,这就需要在.xinitrc或.xsession文件中的最前面增加LD_PRELOAD变量的定义:

$ mv ~/.xinitrc ~/.xinitrc.orig
$ cat > ~/.xinitrc
LD_PRELOAD=/usr/X11R6/lib/wrap.so
export LD_PRELOAD
chinput &
^D
$ cat ~/.xinitrc.orig >> ~/.xinitrc

  然而由于这些中文包装软件需要处理键盘,以用于输入中文,直接让包装软件接管窗口管理器,就使得它也影响窗口程序的键盘控制,就使得一些热键不能正常使用。虽然通过包装KDE,使KDE能显示中文菜单和中文提示,但为了使用正常的键盘操作,还是推荐对每个需要中文能力的软件分别进行包装,而不要直接对窗口管理器进行包装。

  所有的这些中文包装库都比较新,没有经过足够的实践考验或测试,因此存在问题是难免的。当包装了窗口管理器时,如果包装库出现问题,就可能造成X服务器的键盘死锁,对使用者的操作没有反应。然而此时系统并没有停止运行,可以使用网络连接上去,杀死X服务器,更改包装设置。

未完,待续。。。  
 楼主| 发表于 2003-2-11 19:49:52 | 显示全部楼层

FreeBSD连载(53):中文X服务器

中文X服务器

  除了在X11的库函数级汉化,以支持显示中文的能力之外,另一种使 X Window系统显示中文的方法是在X服务器级进行汉化。汉化X服务器就使得所有的西文软件能正常显示中文,当然它必须没有对8位字符进行特殊的过滤处理。并且由于是在服务器低层对中文进行支持,因此速度和兼容性也很好。XFree86的汉化版本称为CXwin,也是由台湾开发者首先进行开发,当前移植到GB的版本为CXwin 0.5。

  为了安装CXwin,必须重新编译X Server,这样首先就要下载XFree86 的服务器源程序,展开后使用Patch命令打上CXwin的补丁后,重新编译X服务器。最后才能生成针对不同硬件的中文X服务器,那么就可以使用CXwin的X 服务器代替原有的同样硬件的X服务器,在X Window下就能够正常显示中文了。

  X服务器被放到/usr/X11R6/bin目录下,例如S3显示卡对应的X服务器为XF86_S3,需要使用同名的CXwin服务器替换原有的程序。除了标准的 XFree86的设置文件之外,CXwin还使用配置文件/etc/X11/ChineseConfig来设置中文字体等设置,一般缺省设置文件就能满足正确显示中文的要求。由于CXWin是直接替换原有的X服务器,因此必须保证安装CXwin之前XFree86已经安装和设置正常了。

  从显示效果来看,CXwin 0.5有最佳的显示效果,会根据不同英文字体大小而选择对应大小的中文字体,因此除了有时由于汉字字体过大而使得字体被切去一部分之外,对于字体的大小和间距处理的最好。然而中文输入还要依靠XA或Chinput。因此最佳的效果应该是使用CXwin用于基本显示,XA 或Chinput用于包装某个应用程序,提供中文输入,并设置了中文为缺省语言的KDE作桌面环境。有了这些之后,FreeBSD系统就具有了中文桌面操作环境的基本中文处理能力了。

  为了利用CXwin的显示,而不被包装软件截去中文显示能力,最好使用不带中文显示能力的xa(无CV代码)来管理中文输入。此外,Chinput也使用了多种不同大小的字体来提供输出,其显示效果也不错。带CV能力的xa 使用字体缩放技术来产生合适大小的字体,但字体缩放会消耗额外的系统资源。ZhXwin最简单,适合简单浏览中文的情况。

  由于CXwin需要针对每个不同的X服务器进行修改,因此对于不同的X 服务器,其显示效果存在差异,有的X服务器具有相当不错的显示效果,而有的效果较差,或不能正常显示,而有的X服务器还不支持中文显示能力。需要随着CXwin的进一步发展,各个问题才会被逐渐解决。

未完,待续。。。  
 楼主| 发表于 2003-2-11 19:55:05 | 显示全部楼层

FreeBSD连载(54):配置文件XF86Config

配置文件XF86Config

  位于/etc目录下的XF86Config文件是XFree86的X服务器的配置文件,XF86Setup 或者xf86config在配置完后就将配置信息保存在这个文件中。XFree86也提供了一个配置文件的样例文件,/usr/X11R6/lib/X11/XF86Config.eg,可以用作参考。很多情况下需要对X的行为进行微调,而并不想重新启动设置程序重复进行整个设置过程,这样手工修改配置文件就更为方便。

  有一些X服务器的参数使用配置程序并不能进行配置,必须在原有XF86Config上手工更改配置文件。

  下面将以一个简单的配置文件为例进行简单介绍XFree86的设置选项。

    * 文件搜寻路径

Section "Files"
    RgbPath    "/usr/X11R6/lib/X11/rgb"
    FontPath  "/usr/X11R6/lib/X11/fonts/75dpi/:unscaled"
    FontPath  "/usr/X11R6/lib/X11/fonts/100dpi/:unscaled"
    FontPath   "/usr/X11R6/lib/X11/fonts/misc/"
    FontPath  "/usr/X11R6/lib/X11/fonts/75dpi/"
    FontPath  "/usr/X11R6/lib/X11/fonts/100dpi/"
#    FontPath   tcp/fontserver:7000
#    ModulePath        "/usr/X11R6/lib/modules"
EndSection

  上面是配置文件的第一部分 “Files” ,这个文件部分定义了 X Window使用的搜索文件路径,如调色板文件的路径RGBPath,字体路径FontPath,以及ModulePath用来设置X服务器的动态可加载模块的路径。

  其中字体路径可以使用多行来设置多个路径,也可以在一行之内设置多个路径,路径之间使用逗号分隔。字体路径也能定义为网络上的字体服务器,这需要指定协议、主机名和端口地址,例如tcp/fontserver:7000表示一台名为fontserver的字体服务器使用tcp端口7000提供字体服务。Unscaled用于修饰表示对这个路径下的字体不进行缩放处理,处理固定字体可减少系统资源的消耗。使用字体服务器可以让多个服务器同享字体,从而达到节约磁盘空间的目的。

  在行首使用符号 “#” ,表示这一行为注释,并不被X服务器处理。

    * 可加载模块

# Section "Module"
# Load "xf86Jstk.so"
# EndSection

  如果前面Files部分定义了ModulePath,这个"Module"部分就用来装载相应路径下具体的模块。一般情况下,并不需要使用这个功能,除非是使用了一些非标准的功能,需要可加载模块的支持,如xf86Jstk.so就是一个游戏杆的驱动程序。

    * X服务器选项

Section "ServerFlags"
#    NoTrapSignals
#    DontZap
#    DontZoom
#    DisableVidModeExtension
#    AllowNonLocalXvidtune
#    DisableModInDev
#    AllowNonLocalModInDxev
EndSection

  "ServerFlags"部分设置一些X服务器的运行参数,对应于XF86Setup 中的Other选项中所设置的内容,一般不需改变。

  NoTrapSignals选项使得X服务器程序不去处理发送到X服务器的各个信号, 正常情况下不设置这个选项,X服务器应该接收并处理这些信号,当接收到某些信号时就释放X服务器占用的资源,切换显示模式并退出X服务器的执行。因此打开这个选项就使得发送到X服务器的信号没有得到处理,在错误不严重的情况下,X程序仍将继续执行而不退出。因此可以用于调试X服务器,观察X的出错原因及其影响。

  DontZap选项用于屏蔽Crtl-Alt-BackSpace热键,通常不设置这个选项时,使用者能够使用这个组合热键退出X服务器。当要将XFree86系统用作公用X终端时,最好使用这个选项屏蔽退出热键,让用户使用正常的退出方式退出登录会话。

  DontZoom这个选项用于屏蔽<Crtl><Alt><小键盘 “+” >或< 小键盘 “-” >两个用于动态切换分辨率模式的组合键,当然X服务器必须同时设置了多个分辨率模式,这两个组合键才有意义。

  xvidtune能实时改变X服务器的显示模式,例如调整显示区域位于显示器中的位置等。然而一旦针对某个显示器的显示模式调整正确之后,就没有必要动态改变了,因此可以使用DisableVidModeExtension 选项屏蔽xvidtune实时改变显示模式的能力,以保证显示器的安全。一般只有本服务器上的 xvidtune可以完成这个操作,在当前X服务器上运行远程计算机上的xvidtune不允许改变本服务器的状态。但是,也可以通过设置AllowNonLocalXvidtune选项, 使得非本服务器上的xvidtune也有能力和本地的X服务器进行通信。第二个选项必须在第一个没有设置的条件下才能设置。为了安全的原因,不应该允许远程系统上的xvidtune获得本服务器的硬件设置信息,不要设置这个选项。

  使用DisableModInDev选项,可以屏蔽客户程序对输入设备(鼠标或键盘)的动态改变。 而AllowNonLocalModInDxev选项可以许可非本地的程序(xset)能动态改变键盘或鼠标的设置。同样,这两个选项是冲突的。

    * 键盘设置

Section "Keyboard"
    Protocol   "Standard"
#    Protocol  "Xqueue"
AutoRepeat 500 5
#    ServerNumLock
#    Xleds      1 2 3
     LeftAlt     Meta
     RightAlt    ModeShift
     RightCtl    Compose
     ScrollLock  ModeLock
#    XkbDisable
XkbKeycodes     "xfree86"
XkbTypes        "default"
XkbCompat       "default"
XkbSymbols      "us(pc101)"
XkbGeometry     "pc"
XkbRules        "xfree86"
XkbModel        "pc104"
     XkbLayout       "us"
EndSection

  "Keyboard"用于定义键盘的参数,指定了键盘使用的协议、重复率以及对一些功能键的重映射。通常在XF86Setup下就可以设置这些选项,而不必手工修改这些设置。

  "Standard"和"Xqueue"是两种不同的键盘协议,一般应该使用Standard协议,Xqueue是一种同时支持键盘和鼠标的硬件使用的协议,在个人计算机平台上很少使用。

  "AutoRepeat"用于定义键盘的重复速度,"ServerNumLock"让X服务器处理 NumLock的状态,否则是由系统的键盘驱动程序处理这个状态。有些X客户程序不能从系统键盘驱动程序中获得小键盘的情况,此时就需要设置这个选项。”Xleds”允许X程序,如xset,能够改变键盘上三个LED状态灯NumLock、CapsLock和ScrollLocal的状态。

  下面的"LeftAlt"等设置,用于将个人计算机键盘上的键重新映射为一些传统Unix 工作站的键盘上使用的键,如Meta、Compose等,由于传统X程序大多数是在工作站上开发的,因此这些程序需要这些特殊的功能键来完成操作,就需要映射这些键的定义以保证兼容性。

  "XkbDisable"选项可以用于屏蔽X服务器对键盘的扩展能力, 通常不应该屏蔽这个能力,而不设置这个参数。这样就可以在设置文件中使用下面的设置选项重新定义键盘的类型、排列方式、符号类型、型号、编码等等。当然一般情况下可以不重新定义这些参数,缺省设置为101 键PC键盘,适用于绝大多数的情况。

    * 鼠标设置

Section "ointer"
    Protocol  "Sysmouse"
         Device           “/dev/sysmouse”
#    Protocol   "Microsoft"
#    Device     "/dev/ttyd0"
#    BaudRate  1200
#    SampleRate     150
#    Emulate3Buttons
#    Emulate3Timeout     50
#    ChordMiddle
EndSection

  "ointer"部分用于定义鼠标的参数,最重要的内容是定义鼠标的类型和使用的设备文件。对于使用moused来管理鼠标的情况,鼠标配置相当容易,首先在控制台下设置好鼠标,然后使用/dev/sysmouse作设备文件,Sysmouse作为鼠标类型即可。如果不打算使用moused来管理鼠标,而想直接使用鼠标设备,就需要正确指定鼠标类型及其设备文件。例如最常见的MS两键串口鼠标使用/dev/ttyd0(或ttyd1串口),使用 Microsoft鼠标类型,等等。

  注意必须保证系统内核识别出所使用的鼠标设备(或者串口设备)。

  此外,BaudRate与SampleRate参数定义鼠标驱动程序与设备通信的波特率和采样率,Emulate3Buttons和Emulate3Timeout让两键鼠标能模拟三键鼠标, 然而伪设备Sysmouse的模拟三键能力的设置需要在moused的启动参数中设置,这里的设置是无效的。ChordMiddle与上面参数意义相反,定义按下三键鼠标的中间键,等价于同时按下左右两键。

    * 显示器设置

Section "Monitor"
    Identifier  "Hyundai DeluxScan 15G+"
    VendorName  "Unknown"
    ModelName   "Unknown"
    HorizSync   30-70
    VertRefresh 50-150
#    ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 Interlace
#    Mode "1024x768i"
#        DotClock        45
#        HTimings        1024 1048 1208 1264
#        VTimings        768 776 784 817
#        Flags                "Interlace"
#    EndMode
# 800x600 @ 72 Hz, 48.0 kHz hsync
Modeline "800x600"     50     800  856  976 1040   600  637  643  666 +hsync +vsync
# 1024x768 @ 70 Hz, 56.5 kHz hsync
Modeline "1024x768"    75    1024 1048 1184 1328   768  771  777  806 -hsync -vsync
# 1280x1024 @ 87 Hz interlaced, 51 kHz hsync
Modeline "1280x1024"   80    1280 1296 1512 1568  1024 1025 1037 1165 Interlace
EndSection

  "Monitor"部分定义了显示器的各种属性,其中前三项设置Identifier 、VendorName、ModelName起到的只是标识显示器的作用, 如果具备多个显示器定义选项的时候可以用来区分不同的定义选项,因此这三个设置主要用在配置文件内部,并不重要。 后面的水平同步HorizSync与垂直刷新VertRefresh的数据才是真正定义显示器属性的参数,应该与具体的硬件相一致,这将决定显示器能否工作在具体的显示模式下。

  ModeLine或Mode定义了具体显示模式使用的时序等参数,只有在这里定义了相应模式,X服务器才能使用对应的模式,并在各种模式之间动态切换。然而XF86Setup并没有设置在显示器的同步频率范围内支持的全部模式,因此会需要手工增加所需要的模式。而xf86config能将很多显示模式都加进设置文件中,其中很多是不必要的,例如320x200等低分辨率,需要手工删除。此外一个分辨率可能会有多个显示模式相对应,但不同模式的刷新频率不同,显然应该保留一个显示器支持的非隔行扫描、并具备最高刷新频率的模式。这些显示模式受到水平同步和垂直刷新数据的限制,X服务器会在启动时屏蔽超过前面定义的水平同步和垂直刷新数据范围的模式,一避免损坏显示器。

  显然,Modeline和Mode选项中的设置数据是一般使用者无法正确设置的,因此就需要从XFree86 的文档中查询各种常见的显示器和及其常用的显示模式数据,来决定最接近自己显示器的显示模式,在复制到自己的设置文件中。XFree86的文档位于在/usr/X11R6/lib/X11/doc目录下,Readme.Config和 VideoModes.doc文件描述了各种显示模式的对应数据,Monitors文件中收集了各种常见显示器的水平同步和垂直刷新数据。

  如果没有定义多个模式,就不能使用X Server提供的动态切换分辨率模式的功能。

    * 显示卡设置

Section "Device"
    Identifier "Generic VGA"
    VendorName "Unknown"
    BoardName  "Unknown"
    Chipset    "generic"
#    VideoRam  256
#    Clocks    25.2 28.3
EndSection
Section "Device"
    Identifier  "ViRGE/DX or /GX"
    VendorName  "Unknown"
    BoardName   "Unknown"
    #VideoRam    2048
EndSection

  "Device"部分定义显示卡设备的参数,同样Identifier、 VendorName、ModelName起到标识作用,具体设置如使用的芯片、显示内存等设置应与所使用的硬件相一致,但也可以不配置,留给X服务器自动探测。同样,也可以定义多个Device设置,某个具体的X服务器程序只使用某个选项中的设置。

  如果要针对某个显示卡更改具体参数,除了查阅显示卡手册之外,还要阅读 /usr/X11R6/lib/X11/doc/目录下的Devices、modeDB.txt和AccelCards等文档,在其中查找与具体显示卡相关的数据信息。

    * 屏幕设置

Section "Screen"
    Driver     "vga16"
    Device     "Generic VGA"
    Monitor     "Hyundai DeluxScan 15G+"
    Subsection "Display"
        Modes      "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
EndSection
Section "Screen"
    Driver      "accel"
    Device      "ViRGE/DX or /GX"
    Monitor     "Hyundai DeluxScan 15G+"
    DefaultColorDepth 16
    Subsection "Display"
        Depth       24
        Modes       "800x600" "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
    Subsection "Display"
        Depth       8
        Modes       "800x600" "640x480"
        ViewPort    0 0
        Virtual     800 600
    EndSubsection
    Subsection "Display"
        Depth       16
        Modes       "1024x768" "800x600" "640x480"
        ViewPort    0 0
        Virtual     1024 768
    EndSubsection
EndSection

              “Screen”部分将具体定义X服务器的显示属性,以及具体使用的设备和显示模式。同时可以存在多个Screen部分,而每个screen部分对应一种X服务器。虽然一般情况下都只使用一个X服务器,然而也可能会使用标准VGA模式的X服务器(如使用XF86Setup时),因此一般配置文件中都至少有两个Screen部分的定义,一个由标准VGA 的X服务器XF86_VGA16使用,在其中的Driver项中指定了vga16类型,另一个Screen 定义由支持更高模式的具备硬件加速能力的显示卡X服务器使用,如XF86_S3V,Driver 项为accel类型。X服务器根据Driver项的设置来寻找正确的Screen部分设置参数。

              除了在Driver选项中指定了Screen选项与具体X服务器的联系之外, 接下来的Device设置选项将指出这个Screen部分(也就是对应的X服务器)使用哪个显示设备,这个选项的值与设置文件前面定义的某一个Device部分中Identifier值相同,这就将X服务器和指定的显示设备相联系起来(会存在多个定义显示卡设备的Device部分)。同样,Monitor项将Screen部分与某个Monitor部分描述的显示器相联系。

              在一个Screen部分中也可以定义多个Display子部分,每个Display子部分为对应一种色彩深度的显示模式设置,颜色深度Depth可以使用的值有8位(256色)、16位伪真彩色、24位真彩色和32位真彩色(实际只用了24位),DefaultColorDepth用于设置缺省使用的色彩深度。X服务器不能动态切换显示颜色深度,只能在同一个颜色深度下切换不同的显示模式。这个颜色深度下可供使用的分辨率模式需要使用Modes定义,缺省的分辨率为第一个模式,然后可以使用热键向前或向后切换。

              动态切换分辨率不影响应用程序的显示,应用程序的显示内容也不变,XFree86提供了虚屏能力。虚屏提供了比实际屏幕更大的显示范围,例如使用800x600的显示模式,虚屏的大小可以是1024x768,这样可以显示更多的数据,实际屏幕之外的数据可随鼠标的移动而显示出来。这样在切换模式的时候,虚屏的大小却不变,可以移动鼠标来查看应用程序切换到虚屏之外的部分。缺省情况下,虚屏的大小为最大的分辨率模式,也可以使用Virtual参数定义更大的虚屏。可设置的虚屏大小受显示卡内存和所显示的色彩深度限制,色彩深度和虚屏大小的乘积不能超过显示内存的大小。为了达到最佳效果,还有一些其他考虑。例如加速卡内有自己的处理器进行图形加速处理,就要使用一些显存作为缓冲区,因此将所有的显存都用做虚屏会影响显示卡的加速处理。

            未完,待续。。。  
 楼主| 发表于 2003-2-11 20:00:51 | 显示全部楼层

FreeBSD连载(55):Ports Collection

第6章 定制应用软件与系统内核

  为了充分发挥系统的性能,便需要对系统进行各种维护和配置工作。前面进行的管理和维护还是基于最初安装的FreeBSD系统,以及FreeBSD安装介质中提供的二进制软件包。这样的系统适用于大多数情况,但不是最适合特定要求的系统设置。根据系统的具体情况来定制FreeBSD的各种设置,就需要进一步的工作。主要是由于 FreeBSD是一个自由软件系统,它提供了软件的源代码可以供用户定制,可以来适应系统的具体环境。如果不能充分利用这些FreeBSD提供的源代码,就不能真正发挥 FreeBSD的最大能力。

  FreeBSD系统提供的源代码包括三个部分,内核源代码、应用程序源代码和软件Ports的源代码。其中内核源代码用于定制内核、提高系统性能、维护硬件配置以及更新系统软件,根据需要升级硬件和保持系统不断升级以避免系统安全等方面的漏洞等任务,因此最为重要,一个系统在初始安装之后都需要重新编译内核;应用程序源代码包括安装到/bin、/sbin、/usr/bin、/usr/sbin目录中的各个应用程序的源代码;软件Ports的源代码并不是各个软件的源代码,而是各个软件的编译、安装方法的代码,这可以用来安装和管理各种应用程序。

  这些源代码均包括在FreeBSD的安装介质中,并能通过安装程序进行安装。除了在初始安装时安装这些组件之外,系统正常运行时也能通过sysinstall或手工运行相关目录下的安装脚本install.sh来添加他们。

    *
      编译应用软件

  在Internet上有很多软件包,它们遵循GPL、BSD或相似的版权许可,允许用户编译运行这些软件。正常情况下,安装一个应用软件的过程是:

    * 获得源代码文件,这通常是一个使用tar打包,并使用compress或gzip压缩后的文件。一般通过ftp等网络下载工具从Internet上得到。

    * 将文件解开,得到源代码文件,一般需要使用tar和gzip进行解包处理。

    * 根据系统情况进行配置,通常这些软件提供了自动配置程序,能根据系统环境自动进行配置,或者可以手工更改设置文件。

    * 然后就进行编译,创建可执行的程序。

    * 接下来就需要将应用程序安装到系统的指定位置。

    * 最后一步是配置应用程序的参数,使其能很好的执行。

  虽然软件的作者通常已经将源代码编写相当完善,适合在多个平台上编译,但是将源代码编译成最终可执行的文件,仍然是一个花费时间且需要繁琐操作的过程。尤其是当用户对系统不是很了解的情况下,往往就可能在某一步遇到了问题,结果就会导致整个安装过程不能正常完成。

  因此FreeBSD提供了Ports Collection机制来管理、安装软件。每种要被移植到FreeBSD上软件被称为一个Port,由某个FreeBSD的开发者维护。这个Port的维护者首先将软件移植到FreeBSD上,并将他所完成的这些移植工作按照Ports Collection 的要求进行设置,编写相关的脚本,使下载软件、配置、编译、安装的全过程能够自动完成,不需人工干预。每个Port中并没有保存软件包的源代码或者二进制代码,而只是提供了搜索它的源代码或者二进制软件包的方法。有了Ports Collection,编译、安装应用程序的过程就相当容易了。

  Ports Collection和Packages Collection是紧密相关的,大部分Port都会有对应的二进制软件包,除非这个软件的许可权对以二进制格式分发有所限制。通常每个源代码形式的Port使用tar.gz结尾,而相应的软件包使用.tgz结尾。因此可以使用后缀来区分Port和软件包。可以从Port中直接生成对应的二进制软件包。

    *
      Ports Collection

  对于一般的使用者,有了FreeBSD提供的众多预编译好的软件包,就可以直接安装这些应用软件的二进制版本,而不需要使用Ports Collection重新编译软件。然而安装介质上附带的软件包是按照缺省配置生成的,适合大多数用户的需要,但并不一定最适合特定用户的特定需求。如果需要对某个软件进行定制安装,就需要使用 Ports Collection,进行修改后重新编译安装。

  在启动这个软件的安装与管理机制之前,必须安装 ── Ports Collection的源代码ports.tgz,它在安装介质中提供,系统的初始安装过程中,安装程序将提示使用者安装Ports Collection,系统安装之后也能直接从安装介质上重新安装或更新。

  Ports Collection的源代码被安装到/usr/ports目录中,这个目录称为Ports 树,以树状结构保存了各个应用程序的Ports。与Packages Collection的目录结构相同,Ports中也按类别进行相关分类,/usr/ports下的每个子目录都包含某一类软件,在下一级的每个子目录下就放置各个Port。

$ cd /usr/ports
$ ls
CVS             archivers       devel           math            textproc
INDEX           astro           distfiles       mbone           vietnamese
LEGAL           audio           editors         misc            www
Makefile        benchmarks      emulators       net             x11
Mk              biology         games           news            x11-clocks
README          cad             german          palm            x11-fm
README.html     chinese         graphics        print           x11-fonts
Templates       comms           japanese        russian         x11-toolkits
Tools           converters      korean          security        x11-wm
WWW_SITE        databases       lang            shells
YEAR2000        deskutils       mail            sysutils

  因为每个Port的代码位于自己的目录中,如果仅仅只想安装某个软件包的port,在解压缩中只解某个具体的软件就可以了。

# tar zxvf /cdrom/prts/ports.tgz ports/www/netscape4.07

  由于Ports Collection是随着应用程序的发展而常常更新的,当某个软件升级造成软件的源代码文件的名字或位置改变,因此部分Port中有关下载软件源代码的位置的设置,就很可能不再适用,从而造成某些Ports不能正常编译安装。因此当应用软件更新之后,就需要从ftp.freebsd.org更新对应这个Port的源代码。可以下载某个Port的代码并放置到正确的位置上,就能完成该port的更新,而不必更新整个Ports Collection。或者使用cvsup来同步源代码,更新Ports Collection。

  由于Ports Collection中收集的软件相当多,因此要想了解每个软件的用途并找出有用的软件就有些困难。如果一个一个去看软件的文档,需要花费大量的时间。因此 FreeBSD提供了一些简单的索引和搜索能力。下面操作将产生所有port信息的索引文件。

# cd /usr/ports
# make print-index > index.txt

  例如要搜寻pine相关的port信息,可使用:

# cd /usr/ports
# make search key=pine

  也可以产生所有Ports的描述文件,在/usr/ports目录下产生一系列HTML超文本文件,然后通过netscape或lynx等浏览器查看各个软件的描述内容。

# cd /usr/ports
# make readmes

  Ports Collection与系统版本息息相关,因此如果要使用新版本系统的Ports Collection ,不但要升级Ports,而且要升级系统中的有关程序。FreeBSD提供了一些Packages来提供在不升级系统的情况下支持高版本的Ports Collection。例如从3.1Release升级到3.1stable就存在一个升级Package为:31Upgrade.tgz,可以查看http://www.freebsd.org/ports中 ... 最新的Ports。

    * 使用Ports Collection来编译安装软件

  每个Port单独占据一个子目录,在这个目录中就是Port的代码,包括使用make编译、安装这个软件所必须的Makefile文件,软件的描述文件README.html、用于版本维护的CVS目录、保存软件包安装信息的files目录,以及保存软件源代码的补丁文件的pkg目录等。

$ ls -al /usr/ports/security/ssh
total 13
drwxr-xr-x   7 root  wheel   512 Apr 19 01:18 .
drwxr-xr-x  53 root  wheel  1024 Apr 19 01:18 ..
drwxr-xr-x   2 root  wheel   512 Apr 14 16:36 CVS
-rw-r--r--   1 root  wheel  4974 Apr 19 01:18 Makefile
-rw-r--r--   1 root  wheel   715 Feb 15 17:06 README.html
drwxr-xr-x   3 root  wheel   512 Apr 14 16:36 files
drwxr-xr-x   3 root  wheel   512 Apr 19 01:18 patches
drwxr-xr-x   3 root  wheel   512 Apr 19 01:18 pkg

  由于Ports Collection就是用来简化应用软件的安装过程的,因此安装起来非常简单,例如要安装一个播放mp3的软件mpg123,则可以首先进入这个Port对应的目录,然后使用make 命令进行处理。

# cd /usr/ports/audio/mpg123
# make install

  在这台计算机连接到Internet上的条件下,在这个过程中系统将顺序完成下载、编译、安装几个步骤。

  make fetch: 每个Port中并没有保存应用软件的原始源代码文件,它保存的是如何获得软件的源代码,并产生可执行文件的操作过程。每种软件的源文件通常保存在其他介质上(一般位于Internet上),那么当通过Ports Collection来安装一个软件时,第一步就是要获得相关的文件。这个下载文件的功能是Ports Collection的一部分功能,如果这台计算机联接到Internet上了,它能够到网络上找到该文件并使用fetch命令将文件下载到本机内,所有的步骤都是完全自动完成的,需要使用者操作的仅仅是使用make命令来启动这个过程。

  如果使用的是make fetch命令,fetch参数将使得make仅仅完成下载任务,而不进行编译和安装处理过程。

  即使计算机没有联接到Internet上,也不必担心,因为Ports Collection将所有下载的文件都保存在/usr/ports/distfiles目录中,而make命令将首先检查该目录中是否已经存在了要下载的源文件,当发现存在这个文件之后,就不再重新下载。因而可以手工将这个应用软件的源代码文件拷贝到这个目录下,make时就不会再重复下载过程了。如果不能确定源文件的位置,可以从Makefile文件中获得源文件的位置,Makefile中将给出该源文件存在几个不同的网络地址,供fetch命令连续尝试下载,一般最新Ports Collection对应的软件的源文件都能从ftp.freebsd.org中下载得到。

  make: 不带任何参数的make命令在完成上述下载工作之后,就开始编译软件了。make程序首先在这个Port目录下建立一个工作子目录,命名为work,此后将源代码展开到这个目录下,再应用这个软件的各个补丁文件,并启动自动配置和编译过程。在这里,每进行一步操作,就在work目录下生成一个空文件,这些文件用于标记编译、安装port的工作进行到哪一步了。

$ ls -al /usr/ports/security/ssh
total 8
drwxr-xr-x  3 root  wheel   512 Apr 14 16:57 .
drwxr-xr-x  7 root  wheel   512 Apr 19 01:18 ..
-rw-r--r--  1 root  wheel   768 Apr 14 16:57 .PLIST.mktmp
-rw-r--r--  1 root  wheel     0 Apr 14 15:56 .build_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:56 .configure_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:55 .extract_done
-rw-r--r--  1 root  wheel     0 Apr 14 16:57 .install_done
-rw-r--r--  1 root  wheel     0 Apr 14 15:55 .patch_done
drwxr-xr-x  4 root  wheel  4608 Apr 14 15:56 ssh-1.2.26

  make展开应用软件包时会检查下载软件包的完整性,这是通过验证下载文件产生的MD5 数据是否与记载在Port中的数据相一致,来保证了下载软件的正确性。

  每个Port的Patch是一些补丁程序,它包括这个软件本身存在问题,用于修正或升级的补丁,或者是维护这个Port的FreeBSD开发者用于修正系统差异而制作的Patch。所有的补丁程序被放置在该Port目录下的patches目录中。

  要对这个软件进行定制时候,应该首先使用make命令,保证源代码展开到正确的目录下并编译完毕。这样能保证make应用了所有的补丁程序对源代码进行修正,然后才能在此目录中修改相应配置,并删除work子目录中的相应标记文件.build_done,使得可以重新开始编译过程,重新编译软件。

  make install: 如果使用的是make install命令,那么make先完成编译过程,然后还将自动安装这个Port,此时不但将软件的各个部分安装到正确的位置之外,还将执行Port 中附带的shell脚本进行软件的基本配置。当然这个配置过程是不完整的,完整的配置属于这个应用程序本身的功能。

  安装完毕之后,还可以针对自己定制的Port生成对应的软件包,使用make package命令将自动完成这个过程。

  安装每个Port的同时也就等同于安装相应的Package,安装过程同时也将在/var/db/pkg 目录下记载下相应Package的安装记录。由于软件包之间存在相互依赖关系,Ports Collection 中也使用同样的原则来处理软件之间的依赖关系,必须使用预先安装这个Port依赖的所有其他 Packages之后,才能安装(不影响编译)这个Port。这个过程也将在make install中自动完成的,系统就会检查依赖关系,自动使用Ports Collection安装它所依赖的Port,最后才能继续这个 Port的安装过程。

  由于安装过程依赖于软件包之间的依赖关系,因此可能会出现比较复杂的情况。例如 Ports Collection的源代码不完整,缺乏它所依赖的软件包的信息,这样安装就不能正常完成。还有就是Ports Collection之间不一致,由于软件的版本不同,就可能造成依赖关系不完整,安装过程不能继续进行。这就需要使用者检查依赖关系,更新整个Ports Collection来纠正问题。

  有的软件,本来就是提供的二进制形式的软件,例如Netscape Communicator,因此并不需要编译过程。所需要的仅仅是将它们下载并安装。即便如此,使用Ports Collection仍然能够帮助使用者更方便的完成这项工作。因为Ports Collection仍然维护着一些有用的信息,例如要下载的应用软件版本号和应用软件的下载位置,应用软件的安装目录和配置文件所在的目录等非常有用的信息。使用包的方式进行安装和管理,将保证应用软件之间的依赖关系的完整性,方便在不用的时候将包卸载,此外Ports Collection还将按照FreeBSD的习惯来组织文件和目录,便于将要安装的文件放置到合适的位置中。

  通常FreeBSD将应用软件安装到/usr/local目录下(X Window应用软件安装到/usr/X11R6 目录下),其执行程序位于/usr/local/bin中,配置文件位于/usr/local/etc中,而应用软件如果需要在系统启动时自动启动,相应的启动文件被放置到/usr/local/etc/rc.d目录中。

未完,待续。。。  
 楼主| 发表于 2003-2-11 22:57:44 | 显示全部楼层

FreeBSD连载(56):手工编译安装程序

手工编译安装程序

  虽然使用Ports Collection编译和安装软件非常简便,然而仍有两个理由来使用手工编译安装方式。一方面是Ports Collection中并不能涵盖所有的软件,有很多软件没有收入Ports Collection中。有很多原因使得一些很优秀的软件没有被收集入Ports Collection,例如,版权因素,或者没有志愿者对它移植到FreeBSD进行维护。另一方面,即使是通过Port来定制软件,仍需要了解了手工编译安装的过程和各种编译工具的使用,才能正常进行定制工作。

  通常在FreeBSD下编译并安装应用程序并不困难,因为FreeBSD是一种非常标准的Unix,为Unix开发的标准C程序很容易就能在它上面编译运行。

    * 编译和软件工具

  为了编译和安装一个应用程序,必须要了解编译和运行软件的一般方法。对于大型程序和要求高效率的软件,通常用高级语言C来开发,使用C语言编译器将C源程序编译成执行程序。由于使用高级语言不依赖于硬件结构,这使得软件非常容易移植。Unix不仅提供了编译器,而且还提供了众多的工具来帮助进行编译和维护,最有用的工具为make。

    * GNU C与编译连接过程

  C作为一种编译型的高级语言,这就是说运行C程序之前要将其先编译成可执行的由机器指令构成的执行程序,因此就需要使用一个编译器来对C源代码进行处理,FreeBSD使用的是GNU的C编译器。

$ cc hello.c
$ ./a.out
Hello, world!

  UNIX下缺省使用a.out作为生成的文件名,可以使用-o参数指出生成的执行文件名。

  事实上前面的编译生成执行文件的过程由两步组成,一是生成目标文件,通常使用.o为后缀,然后进行连接生成执行文件。因此,可以使用ar将多个目标文件组合成一个函数库文件,而可以使用nm来查看库文件的内容。

$ cc -c f1.c
$ cc -c f2.c
$ ar c mlib.a f1.o f2.o
$ nm mlib.a

  FreeBSD使用的C语言编译器gcc是一种非常流行的,多平台、高效率的C语言编译器,它提供了多种选项用于生成应用软件。以下为常用的一些选项:

-L

定义连接库文件的目录

-I

定义C源码的头文件的目录

-o

后面跟的参数为要生成的执行文件的名

-O

进行编译优化,可以指定使用不同的优化级别,从O2到O6,每个不同的级别使用的优化设置不同。

相关的选项还有定义生成的指令码类型的参数,如-m486生成486指令,缺省的gcc版本(2.7.2)不支持Pentium代码。

-g

加入调试代码,可以在完成后使用strip命令删除用于调试的信息

-c

仅仅进行编译而不进行连接,生成目标文件

-fPic

生成相对地址的代码,用于最后生成动态连接库

-static

强制生成静态连接的程序

-aout

生成a.out格式的执行文件、目标代码等,缺省使用ELF格式

-elf

3.0之后为缺省设置,生成ELF格式的目标和执行代码

  可以通过命令行参数查看当前使用的GNU C编译器的版本:

$ cc –version
Gcc version 2.7.2.1

  FreeBSD当前使用GNU的C编译器gcc的版本为gcc 2.7.2.1,这不是 gcc编译器的最新版本,但稳定性非常好。虽然当前新版本的gcc 2.8已经很稳定了,但是由于编译器在系统中的重要性,编译器出现问题会造成系统的稳定问题,因此FreeBSD还没有转向gcc 2.8。另一个没有完全使用 gcc 2.8的重要原因是生成的执行文件格式问题,gcc 2.8不再支持生成a.out 执行格式的二进制程序。但完全转向gcc 2.8版本是必然趋势,在当前正在开发的FreeBSD 4.0-current中,已经使用了gcc 2.8作为标准配置。

  在3.1系统中,如果想使用gcc 2.8,就需要安装Packages Collection 中提供的gcc-2.8软件包(或者使用Ports Collection对源代码进行编译)。事实上还有另外两个更强大的根据gcc进一步开发的编译器,pgcc支持Pentium 代码(标准的gcc只支持生成486代码),egcc除了支持Pentium代码之外,还提供了更大的优化能力。这些版本是商业公司依据gcc进行的开发,但根据GPL 许可,任意使用者都可以根据需要选择使用,使用这些编译器版本能进一步发挥系统的能力。

    * make

  通常应用程序都比较复杂,那么其源程序就不仅包括一个文件,而是由多个文件构成,这样应用程序的编译和连接过程就相对复杂得多。最简单的情况下可以使用shell程序来自动完成这个任务,然而由于并不是每次都更改了所有的文件,每次都完全重新编译所有的代码,不但浪费了处理器资源,也使得每次作一次小改变就得编译所有得文件,效率低下。最好是能够按照需要,编译改动过的代码文件,而对没有更新过的文件就不必重新编译,这样就节约了系统的处理能力。

  如果要使用shell脚本来处理这些依赖关系来,则要求根据文件的更新时间进行维护,需要的shell脚本就比较复杂。Unix提供了一个程序──make,来帮助按照代码之间的时间依赖关系来进行维护工作。

  make与其他解释语言不同,不是直接告诉make需要执行的命令,而是给定一些依赖规则,即在什么条件下应该执行什么处理,那么make就自动分析文件的更新时间,完成剩下的工作。规定make规则的文件一般命名为Makefile,这是一个make指令的集合,这个文件中包括目标定义、执行命令、宏定义和make 伪指令。下面为一个简单的Makefile:

CC = /usr/local/bin/egcc
hello:        hello.c
                $(CC) -o hello hello.c
clean:
                echo delete files!
                rm hello

  这个例子中首先定义了一个宏CC,然后定义一个执行目标hello,这个目标依赖于hello.c文件,一旦hello.c更新,就需要执行下面的编译指令。注意,位于定义目标之后的执行命令应该使用一个 “Tab” 制表符引导,而不是其他空白字符。执行命令中首先将宏替换为它的值,再执行egcc命令编译程序。

  一个Makefile文件中可以定义多个目标,如上面例子中的hello和clean,如果不使用任何命令行参数来启动make,那么缺省使用第一个目标。为了应用其他的make目标,则必须使用make的命令行参数。

$ make clean
delete files!

  make使用的缺省文件名为当前目录下的makefile或Makefile,如果使用其他文件,必须使用命令行参数-f指定文件名。

$ make -f newmakefile

  GNU的make命令首先查看的文件名为GNUmakefile。

  使用了make,对大型的应用软件进行维护就会容易一些。然而不同的系统有一些与系统相关的定义,这些定义需要在Makefile中依据不同的系统重新设置,例如X Window的目录等,这样要完成可以适合多个不同系统的Makefile文件,仍然具有困难。有一些工具能帮助进行这些系统相关的设置,并生成Makefile 文件,例如X Window系统使用xmkmf命令和imake模板文件来产生本地的Makefile 文件,这样就能正确侦知本地系统中有关X Window的正确设置,但软件开发者首先要完成Imakefile文件,以使用xmkmf。而GNU的软件使用autoconf工具,它使用configure命令用来侦测很多系统相关的设置,如编译器、头文件、库函数等等,然后使用预设置的Makefile.in模板文件来产生相应的Makefile。有了这些工具,进行编译各种多平台的应用程序都不再是困难的了。

未完,待续。。。  
 楼主| 发表于 2003-2-11 23:01:59 | 显示全部楼层

FreeBSD连载(57):可执行程序格式

可执行程序格式

  在FreeBSD下的可执行程序通常可分为两类,一类为使用各种解释语言编写的脚本,如sh、awk、perl、Tcl等,这些程序需要解释程序进行解释执行,小巧方便,对于实现不常使用、不要求效率的程序非常有用;另一类就是使用C等高级语言编译后产生的可执行二进制程序。

  Unix之所以功能强大,原因之一就在于它提供了强大的再开发能力。这不仅与提供了高级语言C的编译器有关,而且也与提供了很多种能以解释方式执行的简单脚本语言有关。解释程序脚本的特点是方便性、简单灵活,而且也比较容易学习入手。很多情况下,需要完成的工作任务功能比较单一,并不需要频繁运行,而且要求快速编写出来,这就适合使用解释型语言编写,并且解释程序本身就具备处理文本和字符串的便捷性,并能够和很多现有程序通过系统提供的管道、环境变量等方式结合起来,使得它们非常适合实现文本处理功能。

  解释语言的缺点是每次运行程序时都要载入语言的解释器,解释执行程序,因而效率较低,并且不能直接操纵内存和I/O设备,不适合编写大型程序和对效率要求较高的场合。

  每个解释脚本程序的第一行指出该脚本程序使用的解释器,例如一个普通的shell程序的第一行为:

#! /bin/sh

  不同的解释语言可用在不同的方面,最常用的有shell解释程序,依据使用shell的不同,也分为不同的shell脚本,基本上也分为sh和csh 两种不同的风格。系统管理中经常使用shell程序来执行一些日常管理任务,很多软件也使用shell程序来提供辅助安装和设置任务。perl也是一种常用的、功能强大的解释语言,它兼有解释性程序的方便性和高级编程语言的强大功能,使程序员能在很短的时间内写出非常有效的程序。因此perl得到了众多程序员的支持,通过为perl开发了更多的程序模块,进一步使得perl的处理能力变得更为强大。当前perl已经成为了最流行的一种解释语言,尤其在编写Web服务器上的CGI程序方面,更是处于无可争议的地位。Tcl/tk是另一种解释语言,它能用在X Window系统下,使用描述语言显示不同的X控件,因此很多X应用程序使用它来建立自己的图形接口。

    * 二进制执行程序

  使用高级语言编写、并经过编译得到的二进制执行程序执行效率更高,并且只有二进制格式的执行文件才能充分利用Unix系统提供的全部功能。同样系统内核也是一个特殊格式的二进制执行文件。

  早期的Unix使用a.out格式作为它的执行文件格式,随着Unix的发展,又出现了其他几种执行文件的格式,当前最重要的执行文件格式为ELF 格式,采用这种格式的最初想法是为了在不同平台间采用相同的执行文件格式,并实现动态共享连接库。虽然ELF文件格式并没有达到AT&T最初设想的全部目的,但这种文件格式却成为最流行的执行文件格式。除此之外,实际使用的文件格式还有一种较老的COFF格式,这种格式是在Unix System V R3.2中使用的,当前只有老版本的SCO Unix中还在使用它,而 SCO也正逐渐转向ELF格式。

  FreeBSD可以同时支持这两种执行文件的格式,FreeBSD 2.2.x之前的版本使用a.out格式作为缺省的执行文件格式,到FreeBSD 3.x之后ELF格式成为缺省的执行文件格式,并且以后会彻底转向ELF。事实上在FreeBSD 下的a.out格式具备了相当多的特性,如动态连接等ELF格式具备的特性,也有一些ELF格式不具备的特性,如压缩执行文件格式。但由于FreeBSD中使用的编译器gcc决定不再支持a.out格式的缘故,因此FreeBSD也必须转向 ELF格式。这也是当前还支持a.out格式的FreeBSD版本缺省使用较老版本编译器的原因之一。

  在FreeBSD中,a.out格式的执行文件可以支持压缩执行格式,这使得使用gzip压缩过的a.out格式的执行文件也能立即执行,当前还不能对ELF 格式的文件提供这种支持。

  FreeBSD的文件格式从aout到ELF的转变是渐变的,首先是在3.0-RELEASE 中将执行程序的缺省格式转变为ELF格式,内核文件还保持aout格式,直至 FreeBSD-3.1,全部执行文件格式才缺省设置为ELF格式。

  转向ELF也造成很多相关程序的转变,如原有的Boot Loader不支持 ELF格式的内核,3.1-RELEASE就升级到新Boot Loader;而原有的可加载模块lkm为aout格式,也需要转向ELF格式的modules。新可加载模块的位置为 /modules目录,并使用kldload、klduload、kldstat来进行管理。(aout格式的模块管理命令为modload、modstat和modunload)。

  a.out和ELF格式使用的库文件也是不同的,使用ELF执行文件格式的 FreeBSD 3.x中,/usr/lib下为ELF格式的函数库,而用一个子目录/usr/lib/aout 存放a.out格式的函数库,用于兼容2.2.x之前版本的FreeBSD程序。但这给一些使用包装技术的软件(一些中文外挂系统)造成了一些小麻烦。对不同格式的执行文件要使用不同的包装库,系统不会将与程序本身格式不同的连接库连接到程序上,对应的错误信息为 “bad magic”,指出文件格式的不同。

  由于3.x之后的缺省格式为elf格式,为了生成a.out格式的文件,必须在编译和连接时使用 -aout参数,告诉编译器gcc和连接器ld使用不同的格式生成执行文件。

    * 静态连接和动态连接

  在操作系统发展的早期,除了内核提供的接口,所有的库函数都要连接到程序中,这样所有的程序都可以直接在系统内核下运行。然而事实上大部分程序都会使用一些相同的库函数,尤其是在使用高级语言编程的时候,通常都使用同样的库。例如,C语言编写的程序通常都使用printf函数进行输出,使用scanf读入用户输入内容。如果每个库函数都连接到用户程序中,这样每个程序都会包括这个函数的一个拷贝,就浪费了内存空间。

  因此,现代操作系统使用动态连接的技术,不将常用的库直接编译进每个程序中,而是保留相应的接口,在内核载入程序时,再使用动态连接程序将库载入并和执行程序连接起来。这就是动态连接的技术,由于库和程序是分别载入的,因此多个程序可以共享一个库的同一个拷贝,节约了资源。

  不论对于a.out格式还是ELF格式,FreeBSD均支持动态连接,因此应用程序缺省就使用动态连接的方式。如果想使用静态连接,可以在应用程序编译连接时,指定-static连接选项,将目标程序连接成静态连接的执行文件。由于库代码被连接进执行文件中,静态连接的执行文件要比动态连接的执行文件要大。

$ cc -static -o a1 hello.c
$ cc -o a2 hello.c
$ ls -l  a1 a2
-rwxr-xr-x  1 wb  wheel  45017 Apr 18 16:26 a1
-rwxr-xr-x  1 wb  wheel   2540 Apr 18 16:27 a2

  在FreeBSD下,共享库被放到/etc/ld-config设定的目录下,通常为 /usr/lib,每个库文件使用.so和库的版本号结尾。例如,libc.so.3.1为一个标准C库函数的动态共享库文件。对于a.out格式的执行文件,其动态库文件位于/usr/lib/aout目录下。

  可以使用程序ldd来确定一个程序使用的动态连接库:

bash-2.02$ ldd /usr/bin/vi
/usr/bin/vi:
        libcurses.so.2 => /usr/lib/libcurses.so.2 (0x2808e000)
        libtermcap.so.2 => /usr/lib/libtermcap.so.2 (0x2809a000)
        libc.so.3 => /usr/lib/libc.so.3 (0x2809f000)

    * 其他系统的执行文件

  很多其他Unix系统,例如BSD/OS和Linux,也是运行在Intel平台上的系统,那么执行程序中的处理器指令是完全相同的,不同之处只在于应用程序的格式、应用程序与操作系统的接口、库文件等。事实上由于同为Unix系统,这些差异也很小,因此通过调整内核的一些参数设置,FreeBSD完全可以直接运行这些系统下的执行程序。

  FreeBSD能够同BSD/OS、NetBSD和OpenBSD的Intel平台上的应用程序相兼容,同为BSD家族的成员,他们非常类似。NetBSD、OpenBSD和FreeBSD同为免费系统,并且具有同样的起源,与FreeBSD的关系非常密切,因此FreeBSD能直接运行NetBSD和OpenBSD的Intel平台下的执行程序。然而NetBSD和OpenBSD 也是自由操作系统,因此它们中的应用程序也会有相应的FreeBSD版本,因此这个功能一般很少用到。BSDI是一个商业公司,因此会提供BSD/OS下的二进制执行文件,但不提供源代码。FreeBSD能够完美的运行BSD/OS下的a.out格式的执行文件,ELF执行格式的程序也能执行,但偶尔会有问题发生,因此就需要调整系统设置。

  FreeBSD也能够执行SCO Unix的执行文件,这需要使用内核的ibcs2( Intel binary compatibility system 2)选项。这需要载入一个内核可加载模块,这需要使用root身份执行ibcs2命令以载入ibcs2模块。

# ibcs2

  可以在rc.conf中设置 “ibcs2_enable=YES” ,使开机后立即载入这个模块。

  但是要执行SCO的应用程序,仅有内核支持还是不够的,还需要有SCO Unix的函数库。但SCO Unix的库函数是SCO Unix的一部分,受版权保护的。如果使用者拥有合法的SCO共享库和应用程序,就可以运行SCO Unix上的大型商业应用程序。

  同样,FreeBSD也能够运行Linux的可执行程序,与执行SCO程序类似,这也要求内核支持并载入相应的模块。rc.conf中的相应参数为 “linux_enable” 。

# linux

  但是与SCO不同的是,Linux是一种自由操作系统,其库函数为GNU开发的函数库,使用GNU通用许可保护自由使用的权利。因此FreeBSD在Packages Collection中提供了Linux的共享库,安装了这些Linux的库函数之后,就可以执行Linux的执行程序了。

# pkg_add /cdrom/packages/All/linux_lib-2.6.tgz

  FreeBSD也能执行Solaris x86和SCO Unixware的ELF格式执行程序,只是这个功能还没有加入正式发行版本。同样,这也需要相应的系统动态连接库文件,但是这些库是商业产品,因此使用起来就会受到限制。

    * 运行Linux应用程序

  在运行Linux应用程序时,会遇到一些程序不能正确执行的情况,很多情况下并不是FreeBSD本身的问题,而是由于系统的设置不正确造成的,必须作一些设置和调整。

  由于Linux使用Elf文件格式,有些时候FreeBSD不能分清一个ELF执行文件是那种系统的执行文件,而误认为是FreeBSD的执行文件,导致不能正确执行程序。此时就需要使用brandelf命令来指定需要执行的ELF执行文件的类型,Linux 的ELF执行文件为Linux:

$ brandelf -t Linux linux_application

  另一种差异是系统文件名字的差异,例如Linux的加密口令文件为shadow,而FreeBSD使用master.passwd,Linux的控制台终端设备文件为/dev/tty0,FreeBSD 为/dev/ttyv0,对于一些要使用这些系统文件的应用程序,就造成无法正确读取相应文件的问题,这种情况可以使用符号连接来解决。

# cd /etc
# ln -s master.passwd shadow
# cd /dev
# ln -s ttyv0 tty0

  此外,Linux动态连接库的版本不合适,也是很多Linux程序不能正常运行的主要原因。Linux使用GNU开发的glib作为库函数,编译器gcc首先实现了glibc1 ,用于兼容标准的C库函数libc5。随着gcc的发展,它发展到了glibc 2,也被称为libc6。这两个不同版本的库有一定的差异,glib2功能更强,但由于出现时间还短,不是所有的Linux版本都使用glibc2。有的Linux版本还在使用glibc1,如 Slackware 3.6,而另一些Linux如RedHat 5.0,Debin 2.0都使用glibc2,因此运行Linux应用程序的时候,首先就要确认其使用的C库函数版本。除了标准的C库之外,Linux应用程序使用的其他动态连接库也会存在不一致的问题。

  因此如果Linux应用程序使用的库和FreeBSD安装的Linux共享库版本不一致,那么就不会正常执行这些Linux程序。Linux是一个非常活跃的开发系统,某些版本的Linux常常等不及系统稳定就将应用程序及其使用的库升级,因此为了运行要求新动态连接库的Linux应用程序,就必须及时更新Linux的共享库。除了及时更新FreeBSD正式发行的Linux共享库(这个共享库通常为一个稳定版本,不会一味求新)之外,为了跟上Linux升级的脚步,还必须手工安装Linux的库和其他执行文件。

  当前FreeBSD提供的Linux动态连接库为Linuxlib-2.6,提供了对glibc2库及其他一些共享库的支持,然而众多的应用程序还会使用其他各种动态连接库。 FreeBSD的软件库只能支持常用的Linux应用程序,为了彻底解决Linux应用程序的动态连接库更新问题,并不能依靠FreeBSD提供的软件包。还是应该使用Linux的方式,按照Linux的方式安装所需要的Linux动态连接库。

  FreeBSD下用于与Linux相兼容的程序和库文件统统位于/usr/compat/linux 目录下(根目录下有它的一个连接/compat/linux,compat目录为兼容其他系统执行文件的目录),为了安装新的Linux文件,首先要将这个目录清除。

# cd /usr/compat/linux
# rm -fr *

  安装新的Linux兼容文件可以通过多种方式来完成,由于当前最流行的 Linux系统通常使用RPM的包管理方式,因此可以使用RPM包来安装Linux文件。这需要首先安装包管理程序rpm,这个程序有FreeBSD版本(此时还无法运行Linux程序)。可以在Packages Collection中找到这个软件。

  然后就要为安装Linux的RPM包初始化rpm,使rpm不使用根目录作为系统的起始路径,而使用/usr/compat/linux作为所有的rpm包的根进行安装,这就要使用 --root参数指定相对的根目录,以将Linux执行程序与FreeBSD执行执行程序区分开。rpm在/usr/compat/linux/var/local/lib/rpm中记录包的安装信息。

# mkdir -p /usr/compat/linux/var/local/lib/rpm


# rpm --initdb --dbpath /usr/compat/linux/var/local/lib/rpm

# rpm -i --ignoreos --root /usr/compat/linux ld.so-1.9.5-7.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux ldconfig-1.9.5-3.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux glib-1.0.1-3.i386.rpm

# rpm -i --ignoreos --root /usr/compat/linux glibc-2.0.7-17.i386.rpm

  当使用rpm -I安装好所有必须的系统支持文件,以及需要执行的应用程序,这样安装完毕之后,在通过调整一些参数,Linux程序就能正常执行了。主要需要根据应用程序的错误提示,修改FreeBSD和Linux在文件和目录结构上的不同,如Linux 执行程序的位置,应该更改为/usr/compat/linux/usr/bin目录或其他相应的路径,而非原有根目录下的路径,以使得Linux程序内部只调用Linux执行程序。只有一些对执行程序的格式不敏感的程序,可以使用/bin或/usr/bin下的相应FreeBSD执行程序。通过这样的设置之后,在FreeBSD下就能运行包括Oracle 8 for Linux在内的大型应用软件。

  但是FreeBSD并不可能运行所有的Linux程序,有的应用程序程序对Linux内核有一定要求,需要内核的特定版本的支持。一般来讲,对于这些对Linux特定内核有要求的应用程序,FreeBSD也就无法提供支持了。

  不管怎样,虽然在FreeBSD下运行Linux执行程序没有太大的问题,然而毕竟 Linux是一个独立的操作系统,处理问题的风格与FreeBSD不同,因此除了较小的程序之外,安装支持文件、必要的目录结构等参数的调整是免不了的。

未完,待续。。。  
 楼主| 发表于 2003-2-11 23:03:11 | 显示全部楼层

FreeBSD连载(58):为编译内核准备源代码

配置FreeBSD内核

  安装好FreeBSD之后,便需要根据硬件和计算机的应用需求重新配置FreeBSD的内核。标准内核已经能够满足正常运行FreeBSD的需要,但是不建立针对自己计算机的内核,就不能说完全完成了FreeBSD的配置任务。虽然FreeBSD提供了UserConfig可以来更改内核中硬件资源的,并通过可加载模块以扩展内核能力,但仍然有几个重要的原因使得FreeBSD使用者重新定制内核:

  通用内核不能对所有的硬件都进行支持,某些对安装和运行不是至关重要的硬件,如声卡,或者较少用到的硬件,如 ATM卡,就没有被编译到通用内核中去。如果用户的计算机上使用了这些硬件,就需要重新编译内核。

  某些应用程序和FreeBSD的功能对内核的参数有特殊要求,例如Windows的模拟器Windows E mulation等。重新编译内核能满足这些应用程序对内核参数的特殊要求。

  通用内核中有很多不必要的硬件驱动程序,这些程序不仅使启动时自动检测硬件需要的时间变长,并且占用了内存空间。由于内核是系统最重要的部分,将一直驻留在内存中,而不会置换到硬盘上,因此多余的内核驱动程序浪费了宝贵的物理内存,对于系统性能有一定影响。

  重新生成内核也可以根据自己的硬件和需求优化内核参数,例如用作服务器和系统和用于工作站的FreeBSD系统的最优参数是不同的,并且通用核心是使用386指令集,而当前计算机一般都是Pentium级,因此可以使用最新的编译器和最优化的编译选项,提高系统性能。

  定制内核能够按照硬件和需求量体裁衣,使内核简洁、干净,这是一个提供高效率系统的重要因素。而且在Free BSD下,定制内核并不困难,即使是对系统不太熟悉的使用者,也能够完成定制内核的任务,所需要的只是耐心等待编译过程。在安装好系统之后,应该及时进行定制内核的操作。

    *
      为编译内核准备源代码

  FreeBSD系统提供内核的源代码,在安装系统时是否安装内核代码与使用的不同安装选项有关。安装后的源代码位于/usr/src/sys目录中,如果这个目录不存在或者为空目录,则说明源代码没有安装。此时就必须重新安装内核源代码。

  仍然可以使用/stand/sysinstall程序,选择Distribution选项来安装源代码;也可以运行安装介质中src目录下的install.sh来安装。安装FreeBSD内核源代码之后,习惯上还创建了一个符号连接/sys,指向/usr/src/sys目录,以方便使用。

  在拥有了源代码之后,就可以编辑配置文件,进行配置工作了。源代码目录/usr/src/sys下有多个目录,每个FreeBSD支持的设备、文件系统都有自己的目录,以存放相关的源代码。在定制内核的时候,所关系的目录是内核配置文件所在的目录:/sys/i386/conf,i386目录表示是Intel 386体系的计算机,其下的c onf目录下就放置着内核的配置文件。

未完,待续。。。  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表