我们的新系统是要安装在文件系统上的.因此首先我们得使用命令mke2fs来创建文件系统,然后将其挂载到某个地方.我建议是挂载到/mnt/target这个目录上.接下来的操作中,我假定就用这个目录了.为了节省您的宝贵时间,您可以在/etc/fstab文件里面添加上这一项,以便每次源头系统启动的时候就能够自动将这个目录挂载上.
当我们启动了目标系统,放置在/mnt/target上的所有东西就会被当成了放置在/根目录上.
我们需要在目标系统上建立固定的目录结构.请参阅"文件层次结构标准(简称FHS, File Heirarchy Standard)",见于 文件系统一节来了解详情,或者只需要cd切换目录到目标系统所挂载的地方然后尽管执行以下命令∶
mkdir bin boot dev etc home lib mnt root sbin tmp usr var cd var; mkdir lock log run spool cd ../usr; mkdir bin include lib local sbin share src cd share/; mkdir man; cd man mkdir man1 man2 man3 ... man9
因为FHS标准和大部分的软件包在手册页(man page)放置位置处理上并不一致,因此我们需要做一个符号连接∶
我们要把源代码放置到目标系统的/usr/src目录下面.因此,举个例子吧,如果您的目标系统是挂载在/mnt/target这个地方,且您的tar 包是放在/root里面,那么您要做的就是∶
cd /mnt/target/usr/src tar -xzvf /root/MAKEDEV-2.5.tar.gz
然后就把这些tar包复制到您要解开它们的地方就行了.千万别迷糊了哦.;->
当您安装软件的时候,通常情况下您会把它们安装在正在使用的系统上.但是我们并不想这么做,因为我们是要把/mnt/target当做根文件系统(root filesystem),就是要把这些软件安装到这个地方.不同的软件包有不同的处理方式.比如说MAKEDEV设备生成器包,您要做的是∶
ROOT=/mnt/target make install
您得先在这个包当中的README说明文件和INSTALL安装说明文件当中查出这些选项,或者执行命令./configure --help查看帮助说明.
查看一下MAKEDEV包当中的Makefile文件,看看它是怎样处理我们在命令行当中设置的ROOT变量的.接著通过执行man ./MAKEDEV.man来查看一下它的手册页,看看它是怎么起到作用的.您会发现生成我们自己的设备的方式就是执行cd /mnt/target/dev然后./MAKEDEV generic.请使用ls命令来看看它都为我们生成了哪些设备文件吧.
下一步就是生成内核了.我假设您以前是做过编译内核这种事的,所以我就长话短说了.如果要启动的内核已经准备好的话,那么要安装lilo就会更容易.请返回到目标系统的usr/src目录,然后在那儿解开Linux内核源码.进入Linux 源码树(cd linux)然后使用您最喜欢的方式配置内核,比如make menuconfig.如果您想让自己的轻松一些,那么您可以为自己配置一个没有模块的内核.如果您已经配置了模块,那么您就得编辑Makefile文件,找出INSTALL_MOD_PATH并将其设置为/mnt/target.
现在您可以执行make dep,make bzImage了.如果您设置了模块项,可以再执行make modules,make modules_install.把内核映象文件arch/i386/boot/bzImage和系统函数映象文件System.map 复制到目标系统的boot启动目录/mnt/target/boot下面,然后准备安装系统引导器lilo了.
Lilo包里面带有一个很小巧的脚本,名叫QuickInst.请把lilo源码包解压到目标系统的源代码目录/mnt/target/usr/src下面,然后执行该脚本,方法是∶ROOT=/mnt/target ./QuickInst.它会询问您一些关于您想怎样安装lilo的问题.
切记∶因为我们已经设置ROOT根系统为目标系统分区了,所以您回答提问时所给出的文件名同它是密切相关的.比如当它询问您默认想启动哪个内核的时候,您的回答应该是/boot/bzImage,而并不是 /mnt/target/boot/bzimage哦.我发现这个脚本里面有个小错误,它会提示说∶
./QuickInst: /boot/bzImage: no such file
但是您甭理这个提示就是了,不会有事的.
我们该让QuickInst把引导扇区(boot sector)放在何处为妥呢?当我们重启时,我们希望可以选择引导进入源头系统或者目标系统或者其它共存于同一台机器的其它系统.而且我们还希望我们要 使用所编译的lilo来引导我们新系统的内核.我们怎么把这两件事情合而为一呢?让我们先跑一小会儿题,看看lilo在一个双重启动的Linux系统上是 怎样引导DOS的.在这样的一个系统上的lilo.conf文件的内容看起来可能会跟下面的差不多∶
prompt timeout = 50 default = linux
image = /boot/bzImage label = linux root = /dev/hda1 read-only
other = /dev/hda2 label = dos
如果机器是这么安装起来的,那么主引导记录(MBR,master boot record)就可以被BIOS读取并加载,然后MBR加载lilo启动引导器,而后者则给出一个提示.如果您在提示后面输入dos,lilo就会从hda2加载引导记录,就加载了DOS.
我们所要做的事情跟上头是一样的,除了在hda2的引导记录应该是另外一个lilo 引导记录之外,也就是在QuickInst所询问要安装的那个.因此来自Linux 发行套件的lilo会加载我们所编译安装的lilo,然后我们所编译安装的lilo就会加载我们所编译安装的内核.当您重启后,您会看到两次lilo的提示.
长话短说,当QuickInst询问您该把引导扇区(boot sector)放到什么地方时,您就回答目标系统所在的分区,比如说是∶/dev/hda2.
现在来修改您的源头系统上的lilo.conf配置文件,那么看起来会有点像这个样子∶
other = /dev/hda2
| |
下一步我们要安装init,但是同运行在Linux上几乎全部的程序一样, init使用了GNU C语言库glibc所提供库函数,因此我们先得把这个东东安装上.
Glibc库是一个很大而且很复杂的软件包.在我那个旧型的带8兆内存的386sx/16机器上,得花掉我90个小时来完成编译工作.但是在我那带有64兆内存的赛杨(Celeron) 433上只花掉了33分钟.如果您只有8兆内存(或者少得让人打颤的容量)的话,那就做好苦熬的准备吧.
glibc的安装文档建议在不同的独立分离目录里面编译.这样做就能够让您很轻松地再次编译,因为您可以该目录下面接著编译.您可能也会想这么做,因为可以为您节省大约265兆的磁盘空间哦!
跟平常一样,把glibc-2.1.3.tar.gz(或者其它版本)这个tar包解压到 /mnt/target/usr/src这个目录下面.接下来,我们得把附加库也解压到glibc库目录下面.所以先cd glibc-2.1.3,然后接著在这个目录下面把glibc-crypt-2.1.3.tar.gz和glibc-linuxthreads-2.1.3.tar.gz 这两个tar包解开.
现在我们就可以生成编译目录,设置选项,执行make编译和安装glibc库了.这些都是我所使用过的命令,但是最好您自己阅读一下文档,确认最适合您的状况的做法.然而在您开始前,您可能需要执行df命令来查看一下还有多少剩余空间.您还可以在编译并安装完毕glibc库之后再执行一次看看这玩意儿到底得占多大地儿.
cd .. mkdir glibc-build ../glibc-2.1.3/configure --enable-add-ons --prefix=/usr make
编译并安装SysVinit可执行代码是非常之简洁明了的.我偷懒一次,就给您操作命令吧.假定您已经解压并且进入SysVinit源码目录了∶
cd src make ROOT=/mnt/target make install
另外还有很多与init相关的脚本.在SysVinit包里面有一些工作正常的范例脚本,但是您得自个儿手工安装了.它们在SysVinit源码树中是有层次地布置在debian/etc下面的.您只需要执行类似这样的命令∶cd ../debian/etc; cp -r * /mnt/target/etc,直接把它们复制到目标系统的etc目录下面就行了.当然了,您最好是在复制之前查看一下.
当重启之后,目标系统的内核就会加载init,一切都该各就其位了.此时的问题可能是脚本不能正常运行,因为没有命令解释器bash来解释执行这些脚本.而且init还会尝试执行getty,但是根本就没有getty可供运行.请重新启动并确认没有其它的错误.
我们所需要的下一个东东是命令解释器Bash,而bash需要ncurses库,所以我们得先安装这玩意 儿.ncurses库可以代替termcap处理文本屏幕的活计,同时还通过支持termcap调用提供了向后兼容性.为了拥有一个简洁新潮的系统,我觉 得最好是禁止旧式的termcap方法.如果您后头要编译使用了 termcap的较老的应用程序,您可能会不断地与麻烦为伴了.但是您至少会知道什么东东使用了什么东东.如果您必须要用,那么您可以重新编译 ncurses库,使其带有termcap支持.
我所使用的命令是∶
./configure --prefix=/usr --with-install-prefix=/mnt/target --with-shared --disable-termcap make make install
make install_root=/mnt/target install
注意了,我们还有别的方法来告知一个软件包该装到什么地方
|
label = target
修改完毕,接著执行lilo安装LILO.我们应该可以第一个引导进入目标系统了.
cd ..; ln -s share/man man
为了把bash安装到我原以为它该呆的地方,我花费了很多时间做了大量阅读和思考以及不断地尝试和出错,可谓是历尽千辛万苦啊.我说使用的配置选项是∶
./configure --prefix=/mnt/target/usr/local --exec-prefix=/mnt/target --with-curses
一旦您已经编译并安装了bash之后,您需要生成一个符号连接,就象这样∶ cd /mnt/target/bin; ln -s bash sh.这是因为脚本通常头一句是这么写著的∶
#!/bin/sh
如果您没有这么一个符号连接,那么您的脚本就不能运行,因为它们会去寻找 /bin/sh而非/bin/bash.
如果您愿意,您也可以到这里时重新启动一次.您会注意到脚本这一次确实运行了.虽然您还是没能登录(login),这是因为还没有安装getty或者 login这些程序.
软件包util-linux包含有agetty和login.我们需要这两个程序才能登录系统(log in)和得到命令行提示符(bash prompt).在安装之后,请在目标系统的/sbin目录下为agetty建立一个符号连接到 getty.getty是所有Unix类系统当中被认为应该呆在那个地方的程序之一,所以生成连接的主意要强于改动inittab来运行 agetty.
对于util-linux这个包,我剩下的一个问题就是该包的编译.这个包还包含有more这个程序,而我没法让make进程给more 在目标系统上做一个指向ncurses 5库的连接,而不是在源头系统上指向 ncurses 4库的连接.我会努力克服这个困难的.
您还得在目标系统上准备一个密码文件/etc/passwd.login 登录程序正是通过查询该文件来确认您是否允许登录的.因为此次我们只是打造一个玩具系统,所以我们可以只设置根系统用户就够了,而且不需要任何密码!! 只需要在目标系统的密码文件/etc/passwd加上如下一行即可∶
root::0:0:root:/root:/bin/bash
所有的域是通过冒号(:)分隔开的,自左向右分别代表∶用户名称(user id),密码密串(password),用户号码(user number),用户群组号码(group number),用户真实姓名(user's name),用户主目录(home directory)和缺省命令解释器 (default shell).
我们所必须的最后一个软件包就是GNU sh-utils包.我们此时所需要从这个包里面得到的唯一的程序就是stty,它会在/etc/init.d/rc里面用到.而后者是用于改变运行级别和进入初始化运行级别的脚本.实际上我有一个而且用过仅包含有stty的软件包,但是却忘了是从何处得到的了.使用GNU的软件包是个好主意,因为在里头还有其它您需要的东西,增加了这些东东会使得系统可用性更好.
好了,打造完毕.您现在应该拥有一个可以启动并且能够提示您登录的系统了.输入``root'',您就会进入命令解释器了.但是您做不了很多事情,甚至没有一个ls命令给您看看您的作品里面都有些什么东西.请连续按两次 TAB键,您就会看到可用的命令了.这大概是这个系统中,我所发现的最令我满意的事情.
看起来好像我们打造的是一个毫无用处的系统.说真的,要让它能够有实用价值也并不是什么难事.首先要做的事情之一就是您应该使得根文件系统(root filesystem)以可读写方式挂载起来.SysVinit软件包里面有干这活儿的脚本,就在/etc/init.d/mountall.sh里面.还执行了一次mount -a 把所有在/etc/fstab当中的条目以您所指定的方式挂载起来.请在目标系统的etc/rc2.d目录下生成一个类似S05mountall 的符号连接.
您可能会看到这个脚本会用到您尚未安装的命令.如果真是这样,找到包含该命令的软件包并安装之.请参看 随机小技巧(Random Tips)这一小节,了解如何查找软件包.
看看在/etc/init.d里面的其它脚本.它们大部分都应该包含在任何正经的系统里面.一次添加一个,别忘了要确定添加下一个之前个个都运行无误.
请对照文件层次结构标准(File Heirarchy Standard),请参看 文件系统(Filesystem)一节.那里有一个命令列表,都是该在/bin和/sbin的命令.请确定您已经把那里列举的所有命令都安装在系统上了.最好就是再找找相关这类问题的POSIX文档来看看.
从此,在这个系统里面添加更多必要的软件包就真是个事儿了.越是早些把编译工具,比如说gcc和make这些添加进去就越好.一旦这些都完工了,您就可以利用目标系统来自我生息,就会越来越简单了.
如果您的Linux系统上曾经使用RPM安装过有一个叫做thingy命令,而您想获知这个命令的源码来源,那么您就使用如下命令∶
rpm -qif `which thingy`
如果您有小红帽RedHat的源码光盘,那么您就可以使用下列命令安装源码包了∶
rpm -i /mnt/cdrom/SRPMS/what.it.just.said-1.2.srpm
这个命令会把tar包以及任何RedHat补丁包放到/usr/src/redhat/SOURCES 目录下面.
|