📄 linux caijian.txt
字号:
系统环境变量和登录配置文件
/etc/rc.d
放置启动脚本的目录
/etc/services
列出可用的网络服务及其端口(man services(5))
/etc/termcap
终端(terminal)功能数据库(man termcap(5))
还有那些跟特定应用程序相关的配置文件,比如apache服务器需要的/etc/htt
pd/conf/httpd.conf 等,此处不再一一列出。
5.2.4 库文件(libraries)
/lib,/usr/lib,/usr/share
库文件也是系统运行所必需的。到底需要哪些库文件,是根据所复制的可执行
程序用 ldd 工具来确定的。比如,要知道/bin/bash需要哪些库文件,使用如下命
令:
[root@lips xmdong]# ldd /bin/bash
libtermcap.so.2 => /lib/libtermcap.so.2 (0x40020000)
libdl.so.2 => /lib/libdl.so.2 (0x40024000)
libc.so.6 => /lib/tls/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
对复制到新的根文件系统的每个可执行程序,都要使用这种方法来确定其所需
要的库,然后把这些库文件也复制过来。
需要注意的是,有些库文件使用上述方法是找不出来的,但是却是系统必须的
。比如:
库文件
描述
/lib/libnss_files*
这个库是跟/etc/nsswitch.conf有关的,必不可少,否则系统不能正常使用。(ma
n nsswitch.conf(5))
/lib/security/pam_unix.so
这个库跟PAM有关,是安全、认证方面的,必不可少,否则系统无法登录。
5.2.5 必要的目录
/home,/mnt,/proc,/root,
/var,/var/log,/var/run,/var/lock/subsys
5.3 初始化RAM盘(initrd)
(参考资料[5])
初始化RAM盘(initrd)提供了引导器加载RAM盘的能力。这个RAM盘可以被挂载
(mount)成根文件系统,并执行其上的程序。然后,可以从另一个设备挂载一个新
的根文件系统,而原来的根文件系统(也就是initrd)会被移到一个目录里并卸载
。
initrd技术主要设计用来让系统启动过程可以分两个阶段进行,首先让内核以
一组最小的、被编译进内核里的驱动程序来启动,然后从initrd中加载其他的模块
。
5.3.1 操作步骤
使用initrd时,系统典型的引导步骤如下:
1) 引导器加载内核和初始化RAM盘;
2) 内核把initrd转到一个一般的RAM盘中,并且释放原来被initrd占用的RAM;
3) initrd以可读写模式被挂载到根目录;
4) 执行/linuxrc(linuxrc可以是任何可执行文件,包括shell脚本在内;它具有u
id 0即超级用户的权限,基本上可以做init程序中能够做的任何事情);
5) 在linuxrc中挂载真正的根文件系统;
6) linuxrc使用pivot_root系统调用,把真正使用的根文件系统挂载到根目录;
7) 在根文件系统上执行通常的引导过程(比如执行/sbin/init);
8) initrd文件系统被删除。
注意,改变根目录并不包括卸载旧的根文件系统,因此有可能在转变过程中仍
有进程在initrd上运行。另外,挂载在initrd目录下的根文件系统仍然是可用的。
5.3.2 引导选项
initrd技术增加了下列引导选项:
initrd=<path>
装入指定的文件作为初始化RAM盘。当使用 LILO 当引导器时,你可以用/etc/
lilo.conf 文件中 INITRD 这个配置参数,来指定初始化RAM盘文件。
noinitrd
initrd的数据仍会保留,但不会装入到一个RAM盘里,真正使用的根文件系统将
会被挂载。initrd的数据能夠从 /dev/initrd 这个设备中被读出来。注意,initr
d的数据可以是任何结构,并不一定必须是一个文件系统的映像,这个选项主要用来
进行debug。
注意:/dev/initrd 是一个只读并且只能使用一次的设备,最后一个程序一旦
关闭它, 所有数据将被释放,而且设备也不能再被打开。
root=/dev/ram0
initrd 先被挂载成根目录,接着进行正常的启动过程(这时RAM盘仍被挂载成
根)。
5.3.3 安装
首先:我们要在正常的根文件系统中创建一个容纳initrd文件系统的目录,例
如:
# mkdir /initrd
对目录名称并没有特别的限制,在pivot_root(2)的man手册页中有更详细的说
明。
如果根文件系统是在引导程序时被建立的(例如,你在制作安装软盘),在建
立根文件系统的同时应该创建 /initrd 目录。
在某些情况下initrd虽然未被挂载,只要有下列设备存在,它的內容仍是可被
访问的。(注意:这个设备无法在 devfs 下使用)
# mknod /dev/initrd b 1 250
# chmod 400 /dev/initrd
第二:支持初始化RAM盘的能力,及所有执行格式和文件系统模块,都必须直接
编译进内核,不能采用可加载模块的方式。
第三:必须制作一个RAM盘映像文件。大概的步骤是,在一个块设备上创建一个
文件系统,把需要的文件复制进去,然后把这个块设备的内容输出成一个initrd文
件。目前至少有3种设备适合作为这种块设备:
O 软盘(能拿到任何地方试验,但速度太慢);
O RAM盘(最快,但浪费内存);
O Loopback设备(比较合适的解决方案)。
下面,我们将讨论使用loopback设备创建initrd文件的方法。
1)
确认lookback设备已经配置到内核里。
2)
创建一个适当大小的空白文件系统,例如:
# dd if=/dev/zero of=initrd bs=300k count=1
# mke2fs -F -m0 initrd
3)
把这个文件系统挂载进来,例如:
# mount -t ext2 -o loop initrd /mnt
4)
创建控制台设备。
# mkdir /mnt/dev
# mknod /mnt/dev/console c 5 1
5)
复制所有可能在initrd环境中用到的文件到/mnt目录中。(别忘了/linuxrc文
件)
6)
initrd执行环境的测试需要反复进行修正,为了避免不断的重新启动,可以使
用下列命令:
# chroot /mnt /linuxrc
当然这样启用initrd还是有限制的,就是不能干扰正常系统的执行状态(比如
重新配置网络接口等等。如果在一个用pivot_root指令转换根目录的执行环境中,
就可以做这些事情了)。
7)
卸载这个文件系统:
# umount /mnt
8)
这时,初始化RAM盘系统就在“initrd”这个文件中了。可以把它压缩小一点:
# gzip -9 initrd
最后,必须启动内核并载入initrd系统。需要设置下列引导参数:
root=/dev/ram0 init=/linuxrc rw
(只有需要写入initrd文件系统时才需要附加rw参数)。
使用 LOADLIN 当引导器时,可以执行:
LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 i
nit=/linuxrc rw
使用 LILO当引导器时,可以在 /etc/lilo.conf 中如下设置:
image = /boot/bzImage
initrd = /boot/initrd.gz
append = "root=/dev/ram0 init=/linuxrc rw"
如果使用其他引导器,请参考相关文档。
5.3.4 改变根目录设备
在执行完重要任务的尾声,linuxrc一般会执行改变根目录设备的动作,并让所
有程序在真实的根文件系统中展开。这个过程包括下列步骤:
O 挂载新的根文件系统
O 把initrd自己转到这个根文件系统中
O 结束所有旧的对initrd根文件系统的存取动作
O 卸载initrd文件系统并释放RAM盘内存
挂载新的根文件系统很简单:只需要把它挂载到当前根文件系统中的一个目录
下即可。例如:
# mkdir /new-root
# mount -o ro /dev/hda1 /new-root
最终改变根文件系统由pivot_root()系统调用或者pivot_root工具来完成(参
考手册页pivot_root(8))。pivot_root可以把当前根文件系统转移到新根的一个目
录中,然后把指定的目录当作新的根。在调用pivot_root之前,必须先为旧根准备
目录,例如:
# cd /new-root
# mkdir initrd
# pivot_root . initrd
现在,linuxrc仍然可以访问旧的根文件系统。执行下列指令将完全结束与旧根
的联系:
# exec chroot . what-follows <dev/console >dev/console 2>&1
其中what-follows是新根下面的一个程序,比如/sbin/init。(注意,这时如
果没有/dev/console,系统不能启动)。同时,为了保持不同版本之间的兼容性,
需要特别注意下列事项:
O 在调用pivot_root之前,当前目录应该是新的根目录;
O 使用“.”(当前目录)作为pivot_root的第一个参数(新根),为旧根指定目录
的第二个参数也要用相对路径;
O chroot这个命令应该在新、旧根系统当中都能使用;
O 然后调用chroot转移根文件系统;
O 在exec命令中使用象 dev/console 这样的相对路径。
特别提示:让initrd文件系统的目录结构与新根文件系统的结构一致,有利于
转换过程的顺利。
这时,initrd可以卸载,RAM盘也可以释放:
# umount /initrd
# blockdev --flushbufs /dev/ram0
注意:如果linuxrc或者它调用的其他程序的执行因为某种原因中断,则会启用
旧的change_root机制。
5.3.5 使用场合
实现initrd的主要动机是允许系统安装时模块化的内核配置。这个过程大致如
下:
1) 系统可以用一个最小配置的内核从软盘或者其他存储媒体启动,然后载入initr
d系统;
2) /linuxrc来决定需要什么来进一步挂载真实的根文件系统(如设备类型、驱动程
序等)或者支持发行版媒体(如CD-ROM,网络,磁带等);
3) /linuxrc载入必须的内核模块;
4) /linuxrc建立并安装根文件系统;
5) /linuxrc调用pivot_root改变根文件系统,并通过chroot一个程序(继续安装过
程);
6) 安装引导器;
7) 引导器被配置成装入initrd以及相关的模块,建立起系统环境;
8) 现在,系统可以引导,并执行其他的安装任务。
Initrd的关键作用是能够多重配置一个正常操作的系统,而不需要用一个庞大
的内核,或者重新编译、连接内核。在制作Linux发行版(光盘等)、系统恢复盘等
方面有广泛的应用。
5.3.6 淘汰的根转换机制(change_root)
可以通过改写/proc/sys/kernel/real-root-dev这个文件的数字值来改变真实
的根设备。例如:
# echo 0x301 >/proc/sys/kernel/real-root-dev
但是这个机制已经被淘汰,虽然目前的内核仍然支持,不能保证以后的内核会
支持。所以不要使用。
5.4 系统初始化(init)
(参考资料[10])
5.4.1 init的任务
UNIX的init指的不是一个程序、而是一类程序。Init一般是指系统引导时执行
的第一个进程,也是唯一的进程。当内核完成计算机硬件的设置之后,就把控制权
交给init。内核只产生init这一个进程,而系统中其他所有进程都是由init负责产
生(spawn),主要包括各种系统服务进程,比如控制台的登录会话(getty)。主
要任务包括:
O 产生其他进程;
O 重新启动已经退出的进程;
O 负责清理系统中的“僵尸”进程(init是所有其他进程的祖先);
O 处理系统关机(stop所有进程,unmount文件系统);
内核并不关心拿什么来作为系统的init,可以是下列几种选择之一:
O SysVinit (作者:Miquel van Smoorenburg),或者
O simpleinit (作者:Peter Orbaek),或者
O 一个shell脚本,或者
O 嵌入式系统中你的应用程序。
不过路径名字必须是/sbin/init,/etc/init,或/bin/init(因为已经编译到
内核里面了)。如果这几个路径都找不到,系统就完蛋了。为了增加灵活性,内核
提供了命令行选项可以指定init路径:“init=”。
5.4.2 SysVinit
/etc/inittab
/etc/rc.d
大多数Linux发行版使用的init是SysVinit,也就是System V UNIX的实现。其
主要思想是规定了不同的“运行级别(runlevel)”。通过配置文件/etc/inittab
,定义了系统引导时做什么,进入或者切换到一个运行级别时做什么。配置文件每
一行的语法为:
id:runlevel:action:command
细节请参考手册页inittab(5)。
整个过程中用到的脚本都放在/etc/rc.d目录。
5.4.3 两种风格:Slackware vs. Debian
关于配置文件/etc/inittab和脚本/etc/rc.d的实现和组织主要有两种不同的风
格,其有代表性的发行版分别为Slackware和Debian(Redhat同Debian)。这两种风
格之间有几个明显的区别,可以比较容易的识别。
例如在/etc/inittab中,定义进入运行级别0时运行的脚本分别为/etc/rc.d/r
c.0和/etc/init.d/rc 0(在Redhat中/etc/init.d是指向/etc/rc.d/init.d的一个
符号链接,注意这里0是脚本rc的命令行参数)。因此,Slackware风格的/etc/rc.
d中应该是一系列相对独立的脚本,对应于配置文件中每个动作的定义(我没有见过
Slackware哦)。
在我们所熟悉的Redhat中,/etc/rc.d的组织要复杂的多,每个运行级别对应一
个子目录/etc/rc.d/rcX.d(X表示运行级别0~6),下面放的是一系列形如SXXfoo
和KXXbar(S表示Start某个服务,K表示Kill某个服务,XX是两位数字,决定了该脚
本执行的顺序)的符号链接,指向/etc/rc.d/init.d中的脚本,每个脚本对应一项
服务程序。
另外,还有两个重要脚本值得一提:/etc/rc.d/rc.sysinit是系统引导时首先
要执行的(完成系统初始化的各项工作),而/etc/rc.d/rc.local在最后执行(类
似DOS的autoexec.bat)。
读一下/etc/rc.d/rc.sysinit,/etc/rc.d/rc和/etc/rc.d/init.d/中的某个脚
本,就会对Redhat的启动过程和风格有比较清晰的了解。
据说Slackware风格比Debian的速度要快一些。可能是后者的组织结构比较复杂
的缘故吧。
5.5 PAM
(参考资料[11],http://www.kernel.org/pub/linux/libs/pam/,手册页pam
(8))
5.5.1 什么是PAM
PAM(Pluggable Authentication Modules)是为了解决计算机系统中用户认证
的问题而引入的一种实现方案。PAM的目标为:
O 将认证功能从应用中独立出来,单独进行模块化设计、实现和维护(而不是象以
前那样,将认证功能的代码跟应用程序编译在一块);
O 为这些认证模块建立标准API,以便各应用程序能方便的使用它们提供的各种功能
;
O 认证机制对其上层用户(包括应用程序和最终用户)是透明的。
PAM机制由SUN设计并首先在Solaris 2.3上部分实现,后来逐渐在其他UNIX平台
上实现,包括Linux(其实现称为Linux-PAM)。
5.5.2 PAM的结构
PAM采用分层的体系结构。最下面是模块层,负责实现具体的认证功能,包括帐
户管理(account)、口令鉴别(auth)、口令管理(password)和会话管理(ses
sion)4个模块。
应用接口层位于模块层之上,调用下层提供的服务,并向上(应用程序)隐藏
PAM实现的细节。
5.5.3 配置文件
/etc/pam.conf
/etc/pam.d (如果存在这个目录,则忽略/etc/pam.conf)
配置文件是应用接口层的另一个重要组件。其作用主要是为应用选定具体的鉴
别模块,模块间的组合以及规定模块的行为。
/etc/pam.conf的语法为每行5项(在Linux-PAM的手册页pam(8)中有更详细的描
述):
service type control module-path module-arguments
Service是服务的名字,比如login,su等。注意,/etc/pam.d目录下面有许多
配置文件,分别对应某项系统服务,文件名即等于service,因此每行只有4项。
Type为account,auth,password,session之一,即要使用的认证模块。每个
应用可以使用多个认证模块,或者说可以将模块“堆叠”使用,但是每一行只能定
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -