程序天空

系统程序开发
posts - 52, comments - 34, trackbacks - 1, articles - 28

***Linux启动盘boot/root盘的制作请看(zt)****

Posted on Wednesday, December 08, 2004 11:51 AM
Linux启动盘boot/root盘的制作请看 boot/root盘由两部分组成,即核心和根文件系统。要把这两部分都放到一个1.44MB的软盘上去,通常要对内核和根文件系统进行压缩,压缩核心的最好方法是进行重新编译内核,将一些不必要的支持去掉,如对网络和其它周边设备的支持,重要的一点是记住内核必须支持RAMDISK及ext2,否则系统不能正常引导。 关于内核的编译本文不再阐述,下面重点介绍如何生成根文件系统的压缩包。 对于根文件系统的压缩包括两方面的问题, 第一是只保留必要的根文件系统组件, 第二是将根文件系统做成一个压缩包,类似于内核工作的原理。   (1)根文件系统概述   一个根文件系统必须包括支持完整Linux系统的全部东西,它至少应包括以下几项:   基本文件系统结构   至少含有以下目录:/dev、 /proc、 /bin、 /etc、 /lib、 /usr、 /tmp   最基本的应用程序,如sh、 ls、 cp、 mv等   最低限度的配置文件,如rc、 inittab、 fstab等   设备:/dev/hd*、 /dev/tty*、 /dev/fd0   基本程序运行所需的库函数   以上所需文件一般情况下会超过1.44M, 因此我们通常的做法是先准备好内容后 再压缩到软盘中,当用软盘启动时,再把文件解压到内存中, 形成一个虚拟盘(RAMDISK),通过RAMDISK控制系统启动。   为了能创建以上的根文件系统,你必须有一个空闲的能够放下大约4MB文件的RAMDISK。系统缺省情况下已替我们建好了一个大小为4096KB的RAMDISK,其设备名一般为/dev/ram0,我们就使用它来保存我们预先准备好的根文件系统。      (2) 创建根文件系统   Linux内核识别两种可以直接拷贝到RAMDISK的文件系统,它们是minix 和ext2,ext2性能更好。 mke2fs缺省情况下在1.44M的软盘上产生360个信息节点,使用压缩格式的根文件系统需要更多的信息节点,所以使用如下命令创建文件系统可以创建2000个信息节点,而且一般不会用完。   mke2fs -m 0 -i 2000 /dev/ram0   mke2fs将会自动判断设备容量的大小并相应地配置自身,-m 0参数防止它给root保留空间,这样会腾出更多的有用空间。接着把虚拟盘挂在节点/mnt上:   mount -t ext2 /dev/ram0 /mnt/floppy 接着是创建目录。根文件系统最少应该有如下8个目录:   /dev — 设备   /proc — proc 文件系统所需目录   /etc — 系统配置文件   /sbin — 重要的系统程序   /bin — 基本应用程序   /lib — 共享函数库   /mnt — 装载其他磁盘节点   /usr — 附加应用程序   执行如下命令创建这些目录:   #cd /mnt/floppy   #mkdir dev proc etc sbin bin lib mnt usr   接下来的工作就是确定各个目录下的内容了:   /dev:/dev中含有系统不可缺少的设备文件。可以把现有系统中/dev的文件拷贝过来,然后删除不必要的文件。命令cp -dpR /dev /mnt会拷贝/dev整个目录但不拷贝文件内容,dp开关保证链接文件仍然不变,不会拷贝链接所指原文件,而且属性不变。如果你没有SCSI设备,删除所有的以sd开头的文件。如果你不想使用串口设备,删除所有以cua开头的文件。不过记住一定要保留console、kmem、mem、null、ram、tty1等文件。   /etc:这个目录中含有一些必不可少的系统配置文件。这下面的文件比较多,那么到底哪些文件是必需的,哪些可有可无呢?由于这下面的文件一般是一些文本文件,都不是很大,干脆全部保留算了。   我的启动盘中含有不到15个配置文件,大致可分为3部分:   rc.d/* — 系统启动脚本   fstab — 列出要登录的文件系统   inittab — 包含启动过程参数   而且这些文件都是最简单的。rc应该包括:   #!/bin/sh   /bin/mount -av   /bin/hostname yjy   fstab应包括:   /dev/ram0 / ext2 defaults   /dev/fd0 / ext2 defaults   /proc /proc proc defaults   inittab包括:   id:2:initdefault:   si::sysinit:/etc/rc   1:2345:respawn:/sbin/getty 9600 tty1   2:23:respawn:/sbin/getty 9600 tty2 /bin和/sbin:该目录中包含有必不可少的应用程序,如ls, mv, cat,你可以根据自己的需要选择,不过一定要记住包括以下程序:init, getty,login, mount,运行你的rc的外壳shell。   /lib: 该目录中包含有你的启动盘启动过程中所需要的共享函数库,如果缺少必须的函数库,系统会停止启动或出现一大堆错误信息,所以一定要注意。   几乎所有的程序都需要libc库,列一下目录/lib中的libc:    ls -l /lib/libc*   -rwxr-xr-x 1 root root 4016683 Apr 16 18:48 libc-2.1.1.so*   lrwxrwxrwx 1 root root 13 Apr 10 12:25 libc.so.6 -> libc-2.1.1.so*   libc.so.6的6表示版本号,它指向的文件才是你真正需要的。   查看每一个程序使用的函数库,用命令ldd,如:    ldd /sbin/mke2fs   libext2fs.so.2 => /lib/libext2fs.so.2 (0x40014000)   libcom_err.so.2 => /lib/libcom_err.so.2 (0x40026000)   libuuid.so.1 => /lib/libuuid.so.1 (0x40028000)   libc.so.6 => /lib/libc.so.6 (0x4002c000)   /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)   输出右边的库都是必须的,有的可能是链接文件。   在/lib目录下你还必须有函数库装载器,这个装载器或是ld.so (对 a.out 库) 或是 ld-linux.so (对 ELF 库)。新版本的ldd一般会告诉你所需库的装载器。   把装载器和库拷贝到/lib后,再仔细检查一遍,一定保证没有遗漏。    模块   如果你有一个模块化的内核,你还得考虑需要加载的模块,它们都位于/lib/modules,你可以把不是很重要的模块放到别的盘上,当系统启动后再加载,这样会节省启动盘的空间。    打包   一旦你完成了上述工作,卸下虚拟盘,拷贝到一个文件中,然后压缩。   umount /mnt   dd if=/dev/ram0 bs=1k | gzip -v9>rfs.gz   压缩结束后,你就拥有了一个压缩的根文件系统,不过你得检查它的大小,如果大了,你还得删除一些东西。   (3) 组织引导盘   有了根文件系统和内核之后,最后的工作就是把它们组织在一起。   先检查总文件的大小,如果超出1.44MB,就得考虑重新创建所需或用两张磁盘,即使用两张磁盘,你的根文件系统也得小于1.44MB。 接着就是确定是用LILO控制启动还是直接用拷贝到盘上的内核控制启动。 用LILO的好处是你能增加支持初始化硬件的参数到内核中,缺点是较复杂且占用珍贵的磁盘空间,不过我还是建议使用LILO控制系统启动。下面我就介绍用LILO的过程,直接用拷贝到盘上的内核控制启动的方法就不作叙述了。   用LILO控制启动首先就得写一个LILO配置文件,以下是一个最简单的配置文件,但是已经够用了。   boot =/dev/fd0   install =/boot/boot.b   map =/boot/map   read-write   backup =/dev/null   compact   image = KERNEL   label = Bootdisk   root =/dev/fd0   参数说明见相关资料。然后把它命名为bdlilo.conf。 接下来就是创建一个内核文件系统。把一张干净的软盘插入软驱,在上面创建ext2文件系统。   mke2fs -i 8192 -m 0 /dev/fd0 50   “-i 8192”表示每8192位创建一个信息节点。接着登录系统:   mount /dev/fd0 /mnt/floppy   rm -rf /mnt/floppy/lost+found   mkdir /mnt/floppy{boot,dev}   删去目录/ lost+found,创建两个目录/boot和/dev,再执行:   cp -R /dev/{null,fd0} /mnt/floppy/dev   接着拷贝启动加载器boot.b到目录/boot中,   cp /boot/boot.b /mnt/floppy/boot   最后,拷贝你创建的配置文件bdlilo.conf和内核到内核文件系统的根目录下,   cp bdlilo.conf KERNEL /mnt/floppy   现在,根文件系统所需的所有文件都准备就绪了。再执行下面的命令可以帮助安装LILO引导器到软盘的根文件系统上面:   lilo -v -C bdlilo.conf -r /mnt   OK,可以运行它了,如果运行结果没有错误就表明成功,否则就应该仔细检查一下上面的设置。 1. 软盘上安装引导器(grub) 一般制作软盘上跑的linux引导器都使用syslinux这个工具(这个工具不支持ext2分区格式,只能支持fat分区格式),因为我对grub比较熟悉,并且我在软盘上安装grub只用了132KB空间,不是很耗磁盘空间。 具体操作如下: # mke2fs /dev/fd0 创建了 ext2 文件系统后,需要安装该文件系统: # mount /dev/fd0 /mnt/floppy 现在,需要创建一些目录,并将一些关键文件(原先安装 GRUB 时已安装了这些文件)复制到软盘: # mkdir /mnt/floppy/boot # mkdir /mnt/floppy/boot/grub # cp /boot/grub/stage1 /mnt/floppy/boot/grub # cp /boot/grub/stage2 /mnt/floppy/boot/grub 再有一个步骤,就能得到可用的引导盘。 在linux bash中,从 root 用户运行“grub”,该程序非常有趣并值得注意,因为它实际上是 GRUB 引导装入器的半功能性版本。 尽管 Linux 已经启动并正在运行,您仍可以运行 GRUB 并执行某些任务,而且其界面与使用 GRUB 引导盘或将 GRUB 安装到硬盘 MBR 时看到的界面(即GRUB控制台)完全相同。 在 grub> 提示符处,输入: grub> root (fd0) grub> setup (fd0) grub> quit 现在,引导盘完成了。 2. 安装根文件系统: 一套linux系统要正常启动,根文件系统要包括下列文件夹: /bin /etc /proc /tmp /var /dev /mnt 要包括下列基本的设备文件: /dev/console /dev/fd0 /dev/null /dev/ram0 /dev/tty /dev/tty0 要包括下列配置文件: /etc/rc.d/inittab /etc/rc.d/rc.sysinit /etc/fstab 要实现基本的功能,还要包括一些常用工具: 如:sh,ls,cd,cat…… 其中,前面三个部分不要多少空间的,但是常用工具会占用很多空间,要是用原来系统中的这些命令,就是全部用静态编译,不是用动态连接库,大概有2MB~3MB,放不进软盘。网络上解决的方案是使用BusyBox工具。具体可以到官方网站:www.busybox.net看看。 下载BusyBox工具的源代码,编译: 注意: (1) 译的时候要静态编译,修改 Makefile 中的 DOSTATIC 参数,从false 改为 true,这样,编译出来的代码就不要依赖glibc了。 (2) 因为我们用的是 BusyBox 上的 init,与一般所使用的 init 不太一样,会先执行 /etc/init.d/rcS 而非 /etc/rc.d/rc.sysinit,为了做出来的 FloppyLinux 架构与 Redhat 的架构一样,所以修改了 BusyBox 中的 init.c底下是修到的部分内容∶ #ifndef INIT_SCRIPT #define INIT_SRCIPT "/etc/rc.d/rc.sysinit" #endif 具体操作如下: (1) 官方网站上下载BusyBox的最新版本:busybox-0.60.5.tar.gz解开,按照上面的注意点修改源代码 (2) 运行下列命令: #make #make install (3) 译好的可势行文件放在 ./_install 文件夹里的。 #cp ./_install /tmp/floppy-linux -r (4) 动建立其它的文件或文件夹: #cd /tmp/floppy-linux # mkdir dev etc etc/rc.d proc mnt tmp var # chmod 755 dev etc etc/rc.d bin mnt tmp var # chmod 555 proc # cd dev # mknod tty c 5 0 # mknod console c 5 1 # chmod 666 tty console # mknod tty0 c 4 0 # chmod 666 tty0 # mknod ram0 b 1 0 # chmod 600 ram0 # mknod fd0 b 2 0 # chmod 600 fd0 # mknod null c 1 3 # chmod 666 null (5) 建启动配置文件:(inittab,rc.sysinit,fstab) initab: ::sysinit:/etc/rc.d/rc.sysinit ::askfirst:/bin/sh rc.sysinit: #!/bin/sh mount -a # chmod 755 rc.sysinit fstab: proc /proc proc defaults 0 0 (6) 作Ramdisk的镜像文件: # dd if=/dev/zero of=/tmp/initrd bs=1k count=4096 # losetup /dev/loop0 /tmp/initrd # mke2fs -m 0 /dev/loop0> # mount -t ext2 /dev/loop0 /mnt # cp -r /tmp/floppy-linux/* /mnt # umount /mnt # losetup -d /dev/loop0 # dd if=/tmp/initrd | gzip -9 > /tmp/initrd.gz # rm -f /tmp/initrd # sync 3.编译内核: 这部分内容不详细讲述,主要是去掉了一些不需要的选项,减小内核,编译出来的内核是725920Byte。里面包含了必要的网卡驱动和网络协议栈。 4.整合启动盘 现在所用到了的东西全部搞好了,下面就是整合一下: 全部文件(文件夹)如下: /lost+found/ /boot/ /boot/grub/ /boot/grub/stage1 =========èGrub启动时用到的两个文件 /boot/grub/stage2 /boot/grub/menu.lst =========èGrub的配置文件指向grub.conf /boot/grub/grub.conf /boot/kernel =============è内核 /initrd.gz ===============è内存镜像文件 这样这张软盘就能启动一套Linux系统了,占用1.213MB。 LILO(linux Loader)是Linux自带的一个优秀的引导管理器,使用它可以很方便地引导一台机器上的多个操作系统。与其他常用的引导加载程序相比,LILO引导方式显得更具有艺术性,对其深入的理解,将有助于我们方便地处理多操作系统、网络引导、大硬盘及大内存等诸多棘手的问题。   通常我们谈到LILO,会涉及到两个方面——LILO引导程序和LILO安装命令/sbin/lilo。为了不至于混淆这两个概念,本文将用LILO表示LILO引导程序,而lilo表示/sbin/lilo。   一般地,LILO使用一个文本文件/etc/lilo.conf作为其配置文件。lilo读取lilo.conf,按照其中的参数将特定的LILO写入系统引导区。任何时候,修改了/etc/lilo.conf,都必须重新运行lilo命令,以保证LILO正常运行。lilo.conf使用的配置参数很多,配置起来也相当复杂。下面以RedHat linux为例作一些初步探讨,RedHat的lilo程序包版本为0.20,别的Linux发行版本可能会有所出入,但不会太大。   lilo.conf文件中的配置参数分为两部分,一部分是全局参数,另一部分是引导映像参数。与linux系统其他的配置文件一样,“#”号后的一行文字表示注释。 一、LILO的全局参数   全局参数是全程有效的,它可以出现在文件lilo.conf中的任何地方。以下是具体的参数项:   1.backup=backup-file   在装入LILO之前将原先的引导区备份到backup-file,而不是RedHat 缺省的/boot/boot.NNNN。也可以备份到一个设备上,如: /dev/null。注意:如果原先已有一个同名文件,该参数将被忽略。我们可通过这个备份恢复原先的引导扇区:   dd if=/boot/boot.NNNN of=/dev/hda bs=446 count=1   原先的MBR。(注:虽然boot.NNNN有512字节,但只能恢复前446字节到MBR。)   2.boot=boot-device   指定一个用于安装LILO的设备。通常LILO可安装在如下几个地方:   MBR:第一个硬盘的主引导区, 对应于/dev/hda、/dev/sda等。   Root:linux根分区的超级块(Super block), 对应于/dev/hda1、/dev/hda2、/dev/hda5、/dev/sda1、/dev/sda5等。   Floppy:LILO安装在软盘上,对应于/dev/fd0。   不指定时,lilo缺省安装在根分区超级块上。   3.compact   该参数用于优化LILO,产生一个更小的“map”文件。如果在软盘上安装LILO,强烈推荐使用此参数。   4.default=name   指定缺省引导的操作系统。如default=dos 表示将label为DOS的系统作为缺省引导的操作系统。如不指定该参数,排在lilo.conf中的第一个操作系统将作为缺省操作系统。   5.delay=tsecs   在没有指定“prompt” 参数时,LILO将立即引导缺省的操作系统,“delay”参数在这之间插入一段延时,单位是1/10秒。   6.disk=device-name   为某些非标准硬盘定义参数。其内部还包括有几个可选的子参数。   bios=〈bios_device_code〉:  设备号。十六进制数0x80表示第一硬盘;0x81表示第二硬盘,依此类推。   sectors=〈sectors〉:硬盘扇区数。   heads=〈heads〉:硬盘磁头数。   cylinders=〈cylinders〉:硬盘柱面数。受系统BIOS限制,柱面数必须在1024以内。   partition=〈partition_device〉:用于物理定位特殊硬盘上的分区,有一个子参数start。   start=〈partition_offset〉:每一分区的起始扇区。   例如:   disk = /dev/sda   bios=0x80   #指定SCSI硬盘为第一硬盘    sectors = 32    heads = 64    cylinders=632   #硬盘参数为632/64/32   partition=/dev/sda1   start=2048   #第一分区起始扇区为2048   partition = /dev/sda2   start=204800   #第二分区起始扇区为204800    partition = /dev/sda3     start = 500000    partition = /dev/sda4     start = 900000   当机器上有两块硬盘,一块为SCSI硬盘,另一块为IDE硬盘时,LILO很有可能无法自动识别它们的主、从顺序,这时可进行如下设置:   disk = /dev/sda    bios = 0x80   disk = /dev/hda    bios = 0x81   #SCSI硬盘为主硬盘,IDE硬盘为从硬盘   该参数是为linux无法识别的硬盘准备的,一般Linux可以正确识别和使用大多数硬盘,除非最坏的情况,否则不用设置它。   7.force-backup=backup-file   类似“backup”参数,但是将覆盖原有的同名文件。   8.ignore-table   通知lilo忽略无效的硬盘分区表。   9.install=boot-sector   LILO实际上包含有几个部分,而这几部分都存放在/boot/boot.b文件中。如果忽略“install”参数,则lilo认为install=/boot/boot.b。   10.linear   产生用于替换硬盘sector/head/cylinder地址(硬盘几何参数)的linear扇区地址。linear地址在运行时产生并且不依赖于硬盘几何参数。某些SCSI硬盘和一些以LBA方式使用的IDE硬盘可能会需要使用这个参数。注意,在将LILO安装到软盘上时不能使用“linear”参数。   11.lock   出现LILO提示后立即按最近一次的引导映像启动计算机。也就是说,当我们在lilo.conf中加入了该参数,然后运行lilo安装LILO,再重新启动计算机,这时LILO会提示我们选择引导哪一种操作系统,这一选择将被LILO记录下来,即“锁定”,下次启动计算机时,LILO将忽略“delay”、“prompt”等参数及键盘输入而直接跳转到其“锁定”的操作系统。   12.map=map-file   指定map文件。 没有本项时缺省使用/boot/map,每次执行lilo命令都会产生一个新的map文件。   13.message=message-file   该命令用于指定一个包含注释信息的文件,该文件将在系统打印出字符串“LILO”之前显示。如果在LILO启动时想获取较多的信息,可以编辑一个文件,再使用该命令就可以了。文件中如果包含有ASCII码为0xFF的字符(Ctrl+L)则表示清屏。注意,文件的大小不能超过65535个字节。每次文件改变之后,都必须重新运行lilo命令重建map文件,以保证其正常显示。   14.optional   当用于启动的引导映像不存在时,该参数使lilo忽略它。这对用于测试一个不长期存在的linux核心是有用的。   15.password=password   为LILO设置口令保护,每次重新启动计算机提示用户输入口令。设置了口令后,建议将lilo.conf的文件属性改为600,以免让非root用户看到口令。   16.prompt   给出“boot:”提示,强制LILO等待用户的键盘输入,按下回车键则立即引导默认的操作系统,而按下Tab键则打印可供选择的操作系统。当“prompt”被设置而“timeout”没有被设置时,系统会一直处于等待状态而不引导任何操作系统。不设置该参数时,LILO不给出“boot:”提示而直接引导默认操作系统,除非用户按下了Shift、Ctrl、Alt三键中的任何一个。大多数情况下,如果你的硬盘上有多个操作系统,建议使用参数,它留给用户一个选择的余地。   17.restricted   与“password”联用,使“password”仅作用于在LILO提示后有命令行输入的时候。   18.serial=parameters   使用串行口控制。这将初始化指定的串口,并将使引导管理器能接受来自串口的输入。从串口发送一个中断信号相当于从控制台键盘上按下Shift键,它同样会被LILO捕捉到。如果不能保证来自串口的访问和控制台一样安全,比方说有一个modem连在串口上,建议为每个引导映像加上口令保护(password)。参数串有如下语法:   〈port〉[,〈bps〉[〈parity〉[〈bits〉>]   〈port〉:数字表示的串口号,0表示COM1,其余类推。所有四个串口都可被使用。   〈bps〉:串口速率,支持110、 150、300、600、1200、2400、4800和 9600 bps,缺省值为2400bps。   〈parity〉:设置串口校验。一般情况下,LILO忽略奇偶校验。n表示无校验,e 表示偶校验,o 表示奇校验。   〈bits〉:字符位数,只能取7或8,缺省值是8。当有奇偶校验时只能取7。   如果设置了“serial”,即使没有设置“delay”,系统也会将“delay”项的值自动增加20。   19.timeout=tsecs   设置等待键盘输入的时长,单位是0.1秒。超过这段时间没有输入则为超时,系统将自动引导缺省的操作系统。如果不设置本参数,缺省的超时时间长度为无穷大。 二、引导映像参数   引导映像参数作用于每一个引导映像区。如果某一引导映像参数(例如:password)与全局参数的定义相抵触,则以该引导映像参数的定义为准,但仅限于该引导映像区。以下是具体参数项:   image=pathname   设置包含linux核心引导映像的文件或设备。   other=pathname   设置包含非linux操作系统,如DOS、SCO UNIX、Windows 95等系统引导映像的文件或设备。   range=start-end   如果“image”参数被设置为一个设备,则linux核心引导映像的存放范围必须被设置。   image = /dev/fd0   range = 1-512   # linux核心引导映像存放在软盘上的第一至512扇区   label=name   通过此参数来标识当前操作系统,即操作系统名。用户可通过在LILO提示后输入“标识”来决定引导哪一个操作系统。   alias=name   给当前操作系统起一别名。   lock   类似同名全局参数。   optional   类似同名全局参数。   password=password   类似同名全局参数。   restricted   类似同名全局参数。   以下两个参数项用于非linux操作系统:   loader=chain-loader   如果要引导第二块硬盘上的非linux操作系统或将LILO安装到软盘,这个参数是必需的。不指定时,缺省值是/boot/chain.b。如启动第二块硬盘上的MS-DOS或Windows 95,可定义loader=/boot/any_d.b;对于OS/2,则为loader=/boot/os2_d.b。   作为一个特殊的功能模块,any_d.b已不合时宜,在0.20版以后的lilo程序包中已不再包含它并将其功能整合进chain.b,os2_d.b亦有所变动。它们的功能可用如下语句代替。   例:    other = /dev/hdb1      loader = /boot/any_d.b   替换为:    other = /dev/hdb1      map-drive = 0x80      to = 0x81      map-drive = 0x81      to = 0x80   对于os2_d.b:    other = /dev/hdb1      loader = /boot/os2_d.b   替换为:    other = /dev/hdb1    loader = /boot/os2_d.b    map-drive = 0x80        to = 0x81    map-drive = 0x81      to = 0x80   map-drive=〈bios_device_code〉   通知chain.b装入重映射软驱或硬驱的内存驻留驱动程序,使用它可以引导不同硬盘上的不同操作系统,条件只有一个, BIOS必须能访问硬盘。“map-drive”后跟有变量“TO=〈盘设备号〉”。实际上,“map-drive”起到了“软”交换两个软驱或硬驱主、从顺序的作用,避免了手工接线的麻烦。   例:交换软驱      map-drive = 0      to = 1      map-drive = 1      to = 0   交换硬驱(参看loader参数例)   table=device   指定包含非linux系统分区的主设备。举例来说,如果Windows 95在第一个IDE硬盘的第一个基本分区上,即/dev/hda1上,那么必须定义table=/dev/hda 。

Post Comment

Title  
Name  
Url
Comment   
Protected by Clearscreen.SharpHIPEnter the code you see: