Linux性能调优

May 11th, 2008 by thatday
Posted in 谈谈技术 | No Comments »

本文档从磁盘,文件及文件系统,内存和编译等方面详细的讲述了如何对Linux系统性能进行调谐。
一、磁盘调谐
优化的分区
对系统性能影响相对较大的分区置于磁盘的靠外部分,对内容经常改变的目录放在单独的分区
根据以上特点,需要如下分区策略:
分区1: /boot      200M
分区2: /swap      256M
分区3: /home      500M
分区4: /var       200M
分区5: /tmp       100M
分区6: /usr       800M
分区7: /        100M
分区8: /data      leave
如果系统有多块硬盘,可以考虑使用多个交换分区。每个磁盘上划分一个交换分区。通过在/etc/fstab文件中设置pri 选项,可使多个交换分区具有同样的优先级。Linux系统即可并行地使用它们。这样即可提高交换分区的性能。
/dev/hda5 swap swap defaults,pri=5 0 0
/dev/hdc5 swap swap defaults,pri=5 0 0
使用elvtune调谐磁盘I/O
在Linux 内核2.4以后的版本中,可以通过磁盘I/O的调度操作,来控制磁盘I/O的响应间和吞吐量。通过调整I/O请求在队列中的最大等待时间,可以在响应时间和吞吐量之间调谐。如果要求较少的响应时间,那么吞吐量将降低,反之,较长的响应时间则可以得到较大的吞吐量。可以使用工具 “/sbin/elvtune”来改变最大的响应时间值。使用方法如下:
查看当前的设置
# /sbin/elvtune /dev/sda1
修改当前的配置
# /sbin/elvtune -r 2000 -w 4000 /dev/hda1
其中-r参数针对读操作,-w参数针对写操作.
可以通过命令”iostat -d -x /dev/hda1″得到的平均信息(包括平均请求大小和平均队列长度)来监视以上I/O配置的效果,并调整配置,以得到最佳的性能。一般来讲,对于读写频繁,但操作的数据量较少的Linux服务器,且对实时性要求较高,那么可以将参数调小。反之如果对于读写不频繁,但要求具有较大的吞吐量的Linux服务器,可以将参数调大,以获得较大的吞吐量。
二、文件及文件系统调谐
块大小
使用较大的块大小将得到较好的性能。将ext2文件系统的块大小调整为4096byte而不是缺省的1024byte,可以减少文件碎片,另外,在ext2的文件系统中,为根目录保留了5%的空间,对一个大的文件系统,除非用作日志文件,5%的比例有些过多。可以使用命令”# mke2fs -b 4096 -m 1 /dev/hda6″将它改为1%并以块大小4096byte创建文件系统。如果系统用作邮件或者新闻服务器,使用较大的块大小,虽然性能有所提高,但会造成磁盘空间较大的浪费。比如文件系统中的文件平均大小为2145byte,如果使用4096byte的块大小,平均每一个文件就会浪费1951byte 空间。如果使用1024byte的块大小,平均每一个文件会浪费927byte空间。在性能和磁盘的代价上如何平衡,要看具体应用的需要。
调整缓冲区刷新参数
Linux内核中,包含了一些对于系统运行态的可设置参数。缓冲刷新的参数可通过
/proc/sys/vm/bdflush文件来完成,这个文件的格式是这样的:
# more /proc/sys/vm/bdflush
40 0 0 0 500 3000 60 0 0
第一个数:在”dirty”缓冲区达到多少的时候强制唤醒bdflush进程刷新硬盘,
第二个数:每次让bdflush进程刷新多少个dirty块。所谓dirty块是必须写到磁盘中的缓存块。接下的数:每次允许bd flush将多少个内存块排入空闲的缓冲块列表。
修改方法
# echo “100 128 128 512 5000 3000 60 0 0″>/proc/sys/vm/bdflush 并将这条命令加到/etc/rc.d/rc.local文件中去。
以上的设置加大了缓冲区大小,降低了bdflush被启动的频度,同时也增加了万一系统崩溃丢失数据的危险性。VFS的缓冲刷新是Linux文件系统高效的重要原因之一。
调整文件句柄数和i-节点数
在Linux内核2.4.x中需要修改源代码,然后重新编译内核才生效。编辑Linux内核源代码中的
include/linux/fs.h文件,将 NR_FILE 由8192改为 65536,将NR_RESERVED_FILES 由10 改为 128。编辑fs/inode.c 文件将 MAX_INODE 由16384改为262144。
一般情况下,最大打开文件数比较合理的设置为每4M物理内存256,比如256M内存可以设为16384,而最大的使用的i节点的数目应该是最大打开文件数目的3倍到4倍。
三、其它方面的调谐
调谐buffermem
文件buffermen和内核虚拟内存子系统密切相关。文件/proc/sys/vm/buffermem控制多大内存被用于缓冲区(百分数表示)。内核2.4的缺省值为:: “2 10 60″。可以按如下方法修改:
# echo “70 10 60″ >/proc/sys/vm/buffermem
并将之加到脚本文件/etc/rc.d/rc.local 中。或者在/etc/sysctl.conf文件中加入
vm.buffermem = 70 10 60
第一个参数 70意味着至少分配70%的内存用作缓冲区。后两个参数保持系统的默认值。第一个参数设置为多大合适,依赖于系统的内存大小和系统高负载时内存的使用情况(可用free监视)。
进程限制
Linux对于每个用户,系统限制其最大进程数。为提高性能,可以设置超级用户root的最大进程数为无限。编辑.bashrc文件(vi /root/.bashrc)增加行”ulimit -u unlimited”即可消除超级用户的进程限制。
核心和系统对用户进程其它的一些限制也可以通过ulimit命令来查看和更改。”ulimit -a” 用来显示当前的各种用户进程限制。一些更改用户限制的例子如下:
ulimit -n 4096 将每个进程可以打开的文件数目加大到4096,缺省为1024
ulimit -m 4096 限制每个进程使用的内存数。
优化gcc编译
将优化标志放在/etc/profile文件中。在pentium III级的处理器上使用以下优化标志将得到最优的应用程序:
CFLAGS=-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-frame-pointer -fno-exceptions
再将如下行加到/etc/profile 更靠后的位置:
export PATH PS1 HOSTNAME HISTSIZE HISTFILESIZE USER LOGNAME MAIL INPUTRC CFLAGS LANG LESSCHARSET使用以上的优化,gcc或者egcs编译的程序将得到最佳的性能。

Tags: ,

构造Linux的图形化安装程序

April 23rd, 2008 by thatday
Posted in 谈谈技术 | No Comments »

主要是向您介绍如何定制系统安装环境,包括生成安装内核,初始Ram盘的生成,最小化安装环境的定制。
自从Caldera推出了第一个Linux系统下的图形化安装程序以来,现在的主流Linux发布大多都使用图形化的安装程序进行系统环境的安装,比如RedHat的安装程序anaconda,Suse的安装程序yast2, Caldera的安装程序lizard,以及Mandrake的安装程序gi。
这些主流厂商的安装程序都有一个共同的特点,就是它们都是先构造一个完备的最小化的Linux运行环境,定制Linux的启动过程,使得系统内核启动后,加载一个系统装载程序,这个程序将定制好的 Linux运行环境部分或者全部加载进入内存,然后将控制转移到图形化安装程序。最后再由此程序启动的图形环境(XFree86),设置对应的语言环境,启动对应的系统安装过程。
1 主流安装程序简介
Caldera的安装程序lizard是Linux世界的第一个图形化安装程序,它的全部程序使用c++语言编制,图形化的风格是基于kde和qt的。值得一提的是,caldera在定制图形化安装时,修改了内核,实现了内核的图形化启动,同时其安装程序的硬件检测功能很强大,可以检测到部分非即插即用的isa设备,而且还提供了类似html风格的帮助系统。因为安装程序要求精炼的环境,而此时通用的XWindows窗口管理器是无法满足需求的(太大而且占用资源太多),所以caldera中还提供了一个最小化的窗口管理器lwm。在caldera安装系统包的过程中,您还可以玩吃豆子游戏,这也是lizard的一大创意。
Redhat的安装程序 anaconda可能是大家最熟悉的安装程序之一。它的全部程序都是由Python完成。Python是一种面向对象的脚本语言,您可以在http: //www.python.org获得它的相关资料。Redhat使用Python Gtk作为图形界面的开发工具。在您解开anaconda的源码包之后,您会发现一个anaconda的文件,这是程序执行的主文件。它提供了一个最小化的slang库以支持文本方式的安装。Redhat的安装程序最大的特点就是很稳健,支持的驱动程序较多,对硬件的支持很强(这说明Redhat安装内核定制得非常好,而且得到了相当多的厂商支持)。但是Redhat安装程序的功能不是特别强,比如对于reiserfs、lvm不提供支持,不支持中文安装(7.2可能会推出中文版)。也有很多厂商的安装程序是稍微修改了RedHat源码构成的,比如VALinux、中科红旗等。
对于Mandrake的安装程序gi,它的全部程序都是使用Perl编制,您可以从Mandrake的CVS服务器上下载最新的安装程序。Perl是一种功能强大的脚本语言,可以非常方便的处理Linux上的各种配置脚本,它的图形界面使用Perl-GTK编制。Mandrake的安装程序是第一种提供中文安装的主流发布。它的安装程序的特点是新,支持的功能相当多,包括配置复杂的文件系统,支持无线通讯设备,多种打印机支持等等。
Redhat和Mandrake的安装程序都是由脚本构成的,它们虽然速度稍慢,但是其构成的安装程序一般都比较稳定,而且便于移植到其他平台上。Redhat的整个安装环境是保存在一个stage2.img的文件里。您可用命令:
mount -o loop stage2.img /mnt/tmp
将其挂接到指定的目录下,察看Redhat安装程序的结构。Mandrake的安装环境保存在mdkinst的目录下。
2 安装环境的构成
一个图形化的安装环境实际上就是一个最小化的Linux运行环境。一般由如下几部分构成:Linux系统安装内核,Linux系统的初始Ram磁盘,系统运行所需的一些shell命令和程序所必需的系统库,初始化程序,系统运行时必须的外部命令,XFree86子系统,字体集和本地化的环境设置,系统的桌面风格和贴图,键盘映射,设备配置数据库,系统安装程序等部分。
系统内核vmlinuz存在系统的启动映像之中,在系统启动时调入,然后Linux调入初始Ram磁盘,由此Ram磁盘上的程序加载运行安装程序的第一阶段加载程序。这是个可执行程序,它一般执行加载硬盘驱动模块,将磁盘上的整个安装环境调入内存,并作为根分区挂接。
这时就有一个在内存中的最小化的Linux系统了,一段映像程序结束运行,释放自己所占的内存,并将控制转移到真正的系统安装程序。这时系统安装程序开始启动XFree86子系统,设置正确的本地化环境,包括本地化环境变量,字体集,正确的键盘映射等,这时就允许用户进行交互,从而在用户的干预下,完成整个系统的安装过程。
整个安装过程的一般流程:

2.1 定制安装内核
一个好的安装程序内核是和安装程序紧密相关的,它必须是完备的和精简的。完备的内核是指:如果安装程序要对某方面的功能进行支持的话,必须在内核中也提供相应的支持。精简的内核是指:对于安装程序不需要的功能,内核一定不要支持,而且能作为模块存在的,就一定要把它设置为模块。这样定制出来的内核很小,保证了定制的内核以及必须的硬盘驱动模块能放入启动映像中。
例如,对于2.4.3内核一组选项是:(在下面的一组选项中没有注明的选项,可以在定制安装程序的内核时省略)
Loadable module support 可加载模块支持
[*] Enable loadable module support 将可加载模块支持打入内核
[*] Kernel module loader  将内核模块加载器打入内核
Processor type and features 内核支持的处理器类型
(386) Processor family 选择386兼容方式编译内核
Toshiba Laptop support  东芝笔记本支持作为模块
(off) High Memory Support  对大于2GB的内存不提供支持
选择386兼容方式是为了保证安装程序具有良好的兼容性,在某种程度上来说,速度的快慢并不是衡量安装程序的指标。一个好的安装程序,应该具有高稳定性和高兼容性。
General setup  一般选项
[*] Networking support 内核级网络支持
[*] PCI support 内核级PCI总线支持
(Any)  PCI access mode PCI硬件的存取方式
[*] EISA support内核级EISA总线支持
[*] Support for hot-pluggable devices  支持热插拔设备
[*] System V IPCSystemV的进程间通讯机制
(ELF) Kernel core (/proc/kcore) format 内核文件格式为ELF
Kernel support for a.out binaries内核模块支持a.out文件
<*> Kernel support for ELF binaries 内核支持ELF格式
Kernel support for MISC binaries 内核模块支持其他的格式
对于网络支持和IPC机制的内核支持是必须的,因为Linux上的很多程序,即便它没有进行网络通讯,它也用这些方式进行进程间通讯。对于ELF的内核支持也是必须的,因为安装程序需要使用初始内存映像(initrd),这种方式需要调用程序完成一些初始化的工作,这就要求内核必须能够支持ELF可执行文件格式。其他对于PCI、EISA设备的支持,是提高安装内核硬件兼容性的必要选项。
Parallel port support并行端口支持,要引入并口设备支持时
Parallel port support 模块化的并行端口支持
  PC-style hardware PC类型的硬件
[*]  IEEE 1284 transfer modes IEEE 1284传送模式支持(支持设备自检)
对于并口而言,为了自动检测连接到并口的设备,必须将IEEE 1284传送模式支持打入内核。对于不支持IEEE 1284传送模式的并口设备,系统是无法进行自动检测的。
Plug and Play configuration 
Plug and Play support模块化的即插即用设备支持
ISA Plug and Play support  模块化的ISA即插即用设备支持
在2.4.x内核中,对ISA Plug and Play设备的支持存在一些错误,对于部分设备,将此选项置入内核,设备是无法正常工作的。因此,建议在定制内核时,对此类设备的支持采用内核模块方式。
Block devices  引入对块设备的支持
<*> RAM disk support 核心支持RAM磁盘
(4096) Default RAM disk size
[*] Initial RAM disk (initrd) support
初始RAM磁盘的内核支持。因为安装程序需要设置初始内存镜像以加载设备模块,所以这一选项对于安装程序是必须的。
其他的选项都作为设备模块存在,在需要时可以放入初始内存镜像中。
Multi-device support (RAID and LVM)
[*] Multiple devices driver support (RAID and LVM)
<*>RAID support 将设备模块md.o打入内核
如果将md.o不置入内核,仅为模块方式,raid分区将无法作为根分区启动系统。这主要是因为raid设备需要在启动之初对硬盘进行读写,以决定raid分区的位置,类型等参数。
Linear (append) mode
RAID-0 (striping) mode
RAID-1 (mirroring) mode
RAID-4/RAID-5 mode
Multipath I/O support
Logical volume manager (LVM) support
为了支持软件RAID设备和逻辑卷管理的分区,将上述设备定制为内核模块。为了对上述特殊类型的存储设备进行支持,就需要mkinitrd支持生成正确的初始内存映像,同时为了在正确挂接设备模块之后,系统能正确的安装文件系统并进行检查,也必须提供初始启动脚本的支持(initscript)。
Networking options
Packet socket设置包协议
<*> Unix domain sockets 支持unix域套接字
[*] TCP/IP networking  内核支持TCP/IP网络
ATA/IDE/MFM/RLL support 对ATA/(E)IDE和ATAPI的低端存储设备提供支持。
<*> ATA/IDE/MFM/RLL support
IDE, ATA and ATAPI Block devices
<*> Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
<*> Include IDE/ATA-2 DISK support
<*> Inculde IDE/ATAPI CDROM support
Inculde IDE/ATAPI TAPE support
<*> Inculde IDE/ATAPI FLOPPY support
SCSI emulation support
IDE chipset support/bugfixes作为内核支持存在
对常见的IDE设备支持,最好打入内核,这样保证了安装程序可以直接从硬盘、软盘、光驱启动,而无须额外的设置。
SCSI support
支持的SCSI设备全部作为内核模块。这些模块将压缩以后存入初始内存映像,以便在使用SCSI控制器时,系统能够插入正确的设备驱动模块。
Network device support
[*] Network device support
对网络设备包括ARCnet、Appletalk devices、Ethernet、PPP、SLIP、Token Ring等类型的设备提供支持,这些设备的驱动程序都可作为设备模块。
ISDN subsystem
ISDN support
对ISDN设备提供支持,为了减小内核底层的ISDN卡的硬件驱动程序全部作为模块。
Old CD-ROM drivers (not SCSI, not IDE)
[*] Support non-SCSI/IDE/ATAPI CDROM drivers
对于具体的老CDROM设备,它们的驱动程序也以模块的形式存在。
Input core support
Input core support
Keyboard support
Mouse support
Joystick support
Event interface support
打开USB设备的HID支持
Character devices
[*] Virtual terminal
允许您在一个虚拟终端上运行几个虚拟中断,可以使用Alt-<功能键>进行切换
[*]Support for console on virtual terminal
设置一个虚拟终端作为系统控制台
Standard/generic (8250/16550 and compatible UARTs) serial support
生成serial.o,允许串口鼠标、串口modem以及其他相似的设备连接到标准的串行端口上。
File systems
Kernel automounter support
Reiserfs support
DOS FAT fs support
MSDOS fs support
VFAT (Windows-95) fs support
Simple RAM-based file system support
ISO 9660 CDROM file system support
[*]  Microsoft Joliet CDROM extensions
  NTFS file system support
[*] /proc file system support
[*] /dev/pts file system for Unix98 PTYs
ROM file system support
<*> Second extended fs support
Network File Systems作为模块
Partition Types
[*] PC BIOS (MSDOS partition tables) support
Native Language Support作为模块
这样的选项使得定制的内核支持/proc,ext2和/dev/pts文件系统,可以使用插入模块的方式支持fat、vfat、ntfs、cdrom、 reiserfs、rom文件系统。支持NFS文件系统,并能支持内核级的自动挂接。同时,在挂接文件系统时提供本地语言支持,缺省值为iso8859- 1。
Console drivers
[*] VGA text console
[*] Video mode selection support
MDA text console (dual-headed)
Frame-buffer support
允许Linux的文本模式使用VGA模式或者是帧缓冲方式,支持Frame-buffer对于安装程序是必须的,它使得安装程序能够以fbdev的方式启动XFree86。
Sound
Sound card support
对于声卡的支持,内核可以把各个声卡的设备驱动定制成模块。
USB support
Support for USB
[*] Preliminary USB device filesystem
usb文件系统,必须定制到内核中,这样以后才可以通过/proc文件系统检测安装的usb设备。usb的桥接器(uhci、ohci)和其他不同的设备驱动程序都可以作为内核模块。
2.2 定制内存初始镜像
由于在定制安装程序的内核时,要求内核很小,而另一方面安装程序又要支持尽可能多的硬件设备。为了支持尽可能多的硬件,尤其是特殊的存储设备,我们需要在定制初始的启动镜像时将需要支持的部分,如常见的SCSI控制器和非标准的IDE控制器的驱动程序模块放入其中。这样才能够使内核在尝试使用硬盘或其他存储设备时,其设备驱动程序已经提前加载了。
在内核调入内存之后,如果存在内存初始镜像(initrd),那么控制会转到其上并执行配置脚本linuxrc。内存的初始镜像使引导加载器加载一个RAM盘,此RAM盘可以作为根文件系统挂接并且能在其上运行应用程序。此后,新的根文件系统能从不同的设备上挂接(比如光驱或者硬盘)。在挂接了新的文件系统之后,作为根分区的内存初始镜像将成为目录/initrd或者被卸装。
内存初始镜像(initrd)的使用将使得系统的引导过程分成两个阶段,初始启动的内核只需保留最精简的驱动程序最小集,当启动必须加载附加的驱动模块时再由内存初始镜像加载。比如,您在使用了软件RAID方式管理硬盘并使用RAID 1类型的分区作为系统的根分区之后,就必须创建内存初始镜像。这时的内存初始镜像中包含了设备模块raid1.o以及系统命令insmod,和一个 shell脚本linuxrc,其内容一定包含:
insmod raid1.o
在使用内存初始镜像时,系统引导过程如下:
引导加载程序加载内核和初始化RAM盘。
内核转变内存初始镜像为正常的RAM盘并释放内存初始镜像所用的内存。
内存初始镜像挂接为根分区,此分区允许读/写操作。
执行linuxrc(它可以是任何合法的执行程序,包括shell脚本;该程序以uid为0方式运行,可以完成init所做的每件基本工作)。
在linuxrc终止时,真正的根文件系统被挂接。
若/initrd目录存在,则initrd被移动到此处,否则,initrd被卸载。
在根文件系统上完成正常的引导过程。例如,对于正常的系统而言,执行/sbin/init,这时控制就会转到正常的大家所熟知的启动过程了。而对于安装程序,它只需将控制转到安装过程的第一阶段,由它完成后续的安装环境的加载,设备的进一步初始化等操作。
创建一个初始内存镜像实际上就是创建一个文件,这个文件上包含了一个ext2文件系统,它可以使用回环方式(loop)挂接到本地文件系统上。下面的shell程序段可以创建初始内存镜像:
dd if=/dev/zero of=/tmp/initrd bs=1k count=2000
创建一个2000k的整块文件,一定不能有碎片
mke2fs /tmp/initrd
创建一个ext2文件系统
mount -t ext2 /tmp/initrd /mnt -o loop
将此文件作为回环文件系统挂接到/mnt目录下
创建所需的路径和文件:
mkdir /mnt/dev
mknod /mnt/dev/tty1 c 4 1
mkdir /mnt/lib
cp raid1.o /mnt/lib/
mkdir /mnt/sbin
cp /sbin/insmod /mnt/sbin/
cp /sbin/ash /mnt/sbin/
… …
umount /mnt
卸载此文件系统
gzip -9 /tmp/initrd
cp -f /tmp/initrd.gz /boot/initrd.img
rm -f /tmp/initrd.gz
这样一个内存映像文件就生成了。
为了生成内存映像文件,内核在编译时必须打开ramdisk支持并且支持初始RAM盘,initrd中执行程序的所有对象(例如,可执行文件格式ELF和文件系统EXT2)必须编入内核,这样您生成的内存映像文件才是正常可用的。
缺省条件下,内核的标准设置指定了根设备,另外还可以由rdev设置,或者由命令行传递参数root=xxx指定。在initrd环境下也可以改变根设备。首先,系统要挂接/proc,然后使下列文件可用:
/proc/sys/kernel/real-root-dev
/proc/sys/kernel/nfs-root-name
/proc/sys/kernel/nfs-root-addrs
real-root-dev能通过向其写入新的根文件系统设备号来改变,例如
# echo 0×301 >/proc/sys/kernel/real-root-dev
总而言之,创建初始内存映像文件的主要目的是为了在系统安装(启动)时配置内核模块。这时整个安装过程的最初阶段会按如下方式工作:
系统由软盘或其它介质以最小内核启动(必须支持RAM盘,初始内存镜像,ELF类型的可执行文件,ext2类型的文件系统)并加载初始内存镜像。
/linuxrc决定下一步的工作:
挂接真正的根文件系统,包括对设备类型,设备驱动程序,文件系统等信息的处理。
安装程序的发布介质(例如,CDROM,网络,磁带…)。这可以通过询问用户,自动探测,或混合的方法完成。
/linuxrc加载必须的设备驱动程序模块。
/linuxrc创建和管理根文件系统。
/linuxrc写在根文件系统和任何已经挂接的其它文件系统,设置/proc/sys/kernel/…,终止。
挂接根文件系统。
引导加载程序被读入内存。
引导加载程序配置带有模块集的初始内存镜像(/initrd能被修改,卸载)。
完成系统引导时附加的安装任务。
2.3 定制最小化的运行环境
安装程序的运行环境是整个安装过程第二阶段,它是在内核以及初始内存映像运行之后,由第一阶段的安装程序装入内存的。在此之后,安装程序才正式从其上开始运行。定制最小化的安装程序运行环境也就是定制最小化的Linux系统运行环境。
定制怎样的安装程序运行环境和安装程序所提供的功能密切相关。一般而言,安装程序都要打开多个控制终端,所以为了便于调试,安装环境中应该具备完整的 shell命令环境。同时,为了支持图形化显示,那么安装环境还需要XFree86系统,Gtk(Qt)库环境,可能还需要gtk-engine以支持贴图的显示方式。而对于要提供多语言支持的安装程序,这就需要提供glibc的本地化环境,多种字体集,不同的键盘映射方式。另外对于安装程序提供支持的硬件设备,也应该将其驱动程序模块放入安装程序的运行环境中。
安装程序运行环境一般应包括如下内容:
运行时刻库,包括运行程序必须的动态库
驱动程序模块文件,包括安装程序需要支持的设备和服务模块
系统命令,包括各种系统命令
多语言环境,包括键盘映射、本地化环境、字体
XFree86系统,包括XFree86服务器
脚本解释程序运行环境,例如Perl或Python等
安装程序
为了使运行环境最小,构建安装程序运行时刻库时,必须也是最精简的,也就是说,每个库文件必须被至少一个命令或者安装程序的某个部分所使用。同时在拷贝的过程中,使用strip命令拨去所有的调试信息。要检查一个命令使用了哪些动态库可以使用命令ldd。
例如,当安装程序中包含fdisk命令时,要检查它所需要的运行库,只需要运行下面的命令:
ldd `which fdisk`
这样我们就可以知道,fdisk需要的动态库为libc.so.6和ld-linux.so.2。接下来的工作就是将这两个库拷贝到安装程序的运行环境,同时运行
strip libc.so.6
strip ld-linux.so.2
以拨去所有的调试信息。
下面我们以Mandrake 8.0为例,让我们看看它的安装程序运行环境包含了些什么东西。Mandrake 8.0的安装程序存放在光盘目录mdkinst下,其安装程序的目录结构是:
/etc
包含pcmcia设备的配置选项,sysconfig目录,调色板,Imlib缺生设置。
/lib
包含系统的运行库lib*和支持的驱动程序模块集。
/usr/X11R6/bin
包含XFree86服务器,包括XF86_FBDev、XF86_VGA16。
/usr/X11R6/X11
包含XFree86服务器的字体和本地化环境。
/usr/bin/
这是整个安装程序最关键的目录,它包含安装程序执行时需要的系统命令,安装程序源码,install2文件为安装程序的主控文件,所有安装程序的源程序保存在perl-install目录下。
/usr/lib/
包含多语言支持的运行库保存在gconv目录下,perl5运行所需的模块保存在perl5目录下,其他与本地化和gtk相关的设置。
/usr/share
包含控制台字体保存在consolefonts下,程序贴图和桌面主题贴图一部分保存在gtk目录下同时也包括此目录下的所有*.xpm,*.png文件,glibc的本地化环境保存在locale目录下,键盘映射分别保存在keymaps和xmodmap目录下,检测设备的信息文件(包含设备标识与设备驱动程序的对应关系)保存在ldetect-lst目录下。
保存在/lib/目录下的系统运行时刻库:
系统RPM包 动态库
Glibc Ld-linux.so.2,libc.so.6,libcrypt.so.1,libdl.so.2,libm.so.6,libnsl.so.1, libnss_dns.so.2,libnss_files.so.2,libnss_nis.so.2,libresolv.so.2
libext2fs2 libcom_err.so.2,libe2p,libuuid.so.1
db3 libdb-3.1.so
db3-devel libdb.so.2
zlib1 Libz.so.1
libpng2 libpng.so.2
libgtk+1.2-devel libgtk-1.2.so.0,libgdk-1.2.so.0
libimlib1 libgdk_imlib.so.1
libglib1.2 libglib-1.2.so.0
libglib1.2-devel libgmodule-1.2.so.0
libbzip2_1 libbz2.so.1
Lvm liblvm.so
Rpm librpm.so.0,librpmio.so.0
XFree86-devel LibX11.so.6,libXext.so.6
XFree86-libs libXi.so.6
XFree86-server-common libfont.so.1
Freetype libttf.so.2
表 2-1
保存在/usr/bin/目录下系统支持的命令:
系统rpm包 系统命令
Ash Ash
console-tools Consolechars
Cpio Cpio
Gzip Gzip
e2fsprogs badblocks,mke2fs,resize2fs,dumpe2fs
util-linux fdisk,rescuept
Modutils insmod_,rmmod
Raidtools mkraid,raidstart,
bzip2 bzip2
Rpmtools packdrake,parsehdlist
perl-base Perl
Lvm pvcreate,pvdisplay,vgchange,vgcreate,vgdisplay,vgextend,vgremove,vgscan,lvcreate,lvdisplay,lvremove
kernel-pcmcia-cs Ifport
Dosfstools Mkdosfs
reiserfs-utils mkreiserfs,resize_reiserfs
表 2-2
另外,因为perl语言具有一部分系统功能,所以为了减小运行环境,部分命令还可以采用perl语言编制。这些命令包括:
basename,bug,cat,chmod,chown,cp,dd,df,dirname,displaySize,dmesg,du, e2fsck,fsck.ext2,getopts,grep,gunzip,head,head_tail,header,hexdump, insmod,kill,ln,loadkeys,ls,lsmod,lspci,mkdir,mknod,mkswap,modprobe,more, mount,pack,ps,raidstop,report_bug,rights,rm,rmdir,route,sh,sort,strings, swapoff,swapon,sync,tail,tr,true,umount,uncpio,unpack,which

Tags: ,

制作基于 LFS-6.3 的 livecd

April 18th, 2008 by thatday
Posted in 谈谈技术 | No Comments »

lfs livecd文档

Tags: ,

截取中英文混排字符串的函数

March 20th, 2008 by thatday
Posted in 谈谈技术 | No Comments »

   效率比mb_string要高,尤其是当截取的跨度越大,和substr的效率越接近。不过我个人还是更喜欢用substr($str,$start,$len).chr(0),因为它的效率是最好的,更多时候没有必要对字符串作如此严格的截取。

public function csubstr($str,$start,$len=0){

  $strlen=strlen($str);

  /*默认取开始到末尾*/
  
if($len > $strlen - $start || $len <= 0)
    
$len = $strlen - $start;

  if(
$start >= $strlen)
    return
$str
  elseif(
$start < 0)
    
$start = 0;

    

  /*计算截取字符串的开始位置*/

  if($start > 0){
    for(
$i = 0 ; $i < $strlen ; $i++) {        
      if(
ord($str[$i])>0xa0)
        
$i++;

      if($i >= $start){
        
$start = $i+1;
        break;
      }
    }
  }

  /*计算截取字符串的後束位置*/

  if($start + $len < $strlen){
      for(
$i = 0 ; $i < $strlen ; $i++) {
      
/*如果是中文字符串,i++*/
      
if(ord($str[$i])>0xa0)
        
$i++;

      if(
$i >= $start + $len-1){
        
$len = $i - $start + 1;
        break;
      }
    }
  }
  return
substr($str,$start,$len);
}

【转帖】CSS在IE与Firefox下的兼容性

March 20th, 2008 by thatday
Posted in 谈谈技术 | No Comments »

       1.DOCTYPE 影响 CSS 处理

  2.FF: div 设置 margin-left, margin-right 为 auto 时已经居中, IE 不行

  3.FF: body 设置 text-align 时, div 需要设置 margin: auto(主要是 margin-left,margin-right) 方可居中

  4.FF: 设置 padding 后, div 会增加 height 和 width, 但 IE 不会, 故需要用 !important 多设一个 height 和 width

  5.FF: 支持 !important, IE 则忽略, 可用 !important 为 FF 特别设置样式,值得注意的是,一定要将xxxx !important 这句放置在另一句之上

  6.div 的垂直居中问题: vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了。缺点是要控制内容不要换行

  7.cursor: pointer 可以同时在 IE FF 中显示游标手指状, hand 仅 IE 可以

  8.FF: 链接加边框和背景色,需设置 display: block, 同时设置 float: left 保证不换行。参照 menubar, 给 a 和 menubar 设置高度是为了避免底边显示错位, 若不设 height, 可以在 menubar 中插入一个空格。

  9.在mozilla firefox和IE中的BOX模型解释不一致导致相差2px解决方法:div{margin:30px!important;margin:28px;}

  注意这两个margin的顺序一定不能写反,据阿捷的说法!important这个属性IE不能识别,但别的浏览器可以识别。所以在IE下其实解释成这样:div{maring:30px;margin:28px}

  重复定义的话按照最后一个来执行,所以不可以只写margin:XXpx!important;

  10.IE5 和IE6的BOX解释不一致

  IE5下div{width:300px;margin:0 10px 0 10px;}

  div的宽度会被解释为300px-10px(右填充)-10px(左填充)最终div的宽度为280px,而在IE6和其他浏览器上宽度则是以300px+10px(右填充)+10px(左填充)=320px来计算的。这时我们可以做如下修改div{width:300px! important;width /**/:340px;margin:0 10px 0 10px}

  关于这个/**/是什么我也不太明白,只知道IE5和firefox都支持但IE6不支持,如果有人理解的话,请告诉我一声,谢了!:)

  11.ul标签在Mozilla中默认是有padding值的,而在IE中只有margin有值所以先定义ul{margin:0;padding:0;}

  就能解决大部分问题

  注意事项:

  1、float的div一定要闭合。

  例如:(其中floatA、floatB的属性已经设置为float:left;)<#div id=\”floatA\” >

  <#div id=\”floatB\” >

  <#div id=\”NOTfloatC\” >

  这里的NOTfloatC并不希望继续平移,而是希望往下排。

  这段代码在IE中毫无问题,问题出在FF。原因是NOTfloatC并非float标签,必须将float标签闭合。

  在<#div class=\”floatB\”>

  <#div class=\”NOTfloatC\”>

  之间加上<#div class=\”clear\”>

  这个div一定要注意声明位置,一定要放在最恰当的地方,而且必须与两个具有float属性的div同级,之间不能存在嵌套关系,否则会产生异常。

  并且将clear这种样式定义为为如下即可:.clear{

  clear:both;}

  此外,为了让高度能自动适应,要在wrapper里面加上overflow:hidden;

  当包含float的box的时候,高度自动适应在IE下无效,这时候应该触发IE的layout私有属性(万恶的IE啊!)用zoom:1;可以做到,这样就达到了兼容。

  例如某一个wrapper如下定义:.colwrapper{

  overflow:hidden;

  zoom:1;

  margin:5px auto;}

  2、margin加倍的问题。

  设置为float的div在ie下设置的margin会加倍。这是一个ie6都存在的bug。
  解决方案是在这个div里面加上display:inline;
例如:
<#div id=\”imfloat\”>
  相应的css为
#IamFloat{
float:left;
margin:5px;/*IE下理解为10px*/
display:inline;/*IE下再理解为5px*/}

  3、关于容器的包涵关系

  很多时候,尤其是容器内有平行布局,例如两、三个float的div时,宽度很容易出现问题。在IE中,外层的宽度会被内层更宽的div挤破。一定要用Photoshop或者Firework量取像素级的精度。

  4、关于高度的问题

  如果是动态地添加内容,高度最好不要定义。浏览器可以自动伸缩,然而如果是静态的内容,高度最好定好。(似乎有时候不会自动往下撑开,不知道具体怎么回事)

  5、最狠的手段 - !important;

  如果实在没有办法解决一些细节问题,可以用这个方法.FF对于”!important”会自动优先解析,然而IE则会忽略.如下.tabd1{
background:url(/res/images/up/tab1.gif) no-repeat 0px 0px !important; /*Style for FF*/
background:url(/res/images/up/tab1.gif) no-repeat 1px 0px; /* Style for IE */}a

  值得注意的是,一定要将xxxx !important 这句放置在另一句之上,上面已经提过.

Tags: , ,