Linux Boot Loaders Compared

Linux Boot Loaders Compared

L.C. Benschop

Copyright ©2002, 2003, L.C. Benschop, Eindhoven, The Netherlands. Permission is granted to make verbatim copies of this document. This is version 1.1 which has some minor corrections.

 

 

译者 Manson.Li

完成日期:2007-8-7

Email:lizhilianglove@163.com

译者序:

    本文主要讲解了Boot loader的基本原理,并对Linux下经常使用的几个boot loader进行了比较.同时还以示例的方式具体讲解了各个boot loader的具体使用方法.

    文章还讲解了RAM disk的相关知识.

    在文章的最后,作者还详细讲解了如何在硬盘上和CD-ROM安装boot loader.

 

目录

Introduction

How Boot Loaders Work

    What BIOS does for us

    Parts of a boot loader

    Loading the operating system

    Configuring the boot loader

Example Installations

    Example root file system and kernel

    Linux Boot Sector

    LILO

    GNU GRUB

    SYSLINUX

    LOADLIN

    Where Can Boot Loaders Live

RAM Disks

    Living without a RAM disk

    RAM disk devices

    Loading a RAM disk at boot time

    The initial RAM disk

Making Diskette Images without Diskettes

Hard Disk Installation

CD-ROM Installation

Conclusions

 

 

介绍

    有很多种方法来boot Linux,而且每种方法都有其有点和缺点.所有要清楚这些方法以及之前的不同.

 

    我们这里讨论的loader要符合下面的规定:

²        必须支持Linux.我们不讨论是否能独立load kernel, chain load, in turn boots Linux.

²        运行平台是 Intel PC.

²        必须可以是free的,有源码的.

²        不讨论network boot loaders.

 

    我们讨论这些boot loaders:

²        Boot Sector of the Linux kerner

²        LILO

²        GUN GRUB

²        SYSLINUX

²        LOADLIN

 

    其他如:nuni,Gujin,mbr03 and e2boot也符合我们的规定.

 

 

Boot Loaders是如何工作的

BIOS做了什么

    BIOS是一个在ROM中的firmware,当电脑上电时,BIOS是第一个运行的程序.其他的程序必须首先被Load到Ram中.BIOS保护以下部分:

²        POST(Power On Self Test)

²        Setup Menu:可以设定一些启动参数,比如设定boot order.可以调整 real time clock.

²        Boot sector loader:将boot disk最先的512-byte sector 装载到Ram中,并跳到装载的内存.这个512就是我们一直在说的boot loader.

²        BIOS interrupts:有关屏幕,键盘,硬盘的一些简单的device driver. Boot loader可能会依赖他们. Linux kernel开始后就不再需要这些了.

 

    除了BIOS外,还有其他的一些Roms,也是由BIOS启动的.比如VGA,SCSI host adapters and Ethernet cards. 网卡上的EPROM便可以实现无盘启动.

 

    BIOS是如何load这最先的512-byte sector的呢?

²        对应软盘来说,第一个sector将被装载到内存的0000:7C00. sector的最后两个bytes是0x55和0xAA用于检查.一起正常,BIOS就条至0000:7C00.

²        从硬盘启动类似与软盘.第一个sector(MBR: Master Boot Record)也被BIOS装载到0000:7C00然后跳至该地址. MBR再将自己移至其他地址然后将分区上的其他boot sector装载到0000:7C00,并跳至该地址.

²        支持从CD-ROM启动也就是BIOS假装将其当作一个软盘,然后试图对软盘的操作都将重定向至CD-ROM.当然也支持其他的方法.

 

    当boot sector被装载时,CPU处于real mode.关于real mode和 32-bit protected mode这里就不详述了.由于gcc不识别real mode,所有除了GRUB其他大部分boot loader都是用assembly写的. 除了GRUB其他所有的 boot sector程序都是用assembly写的.

 

    理论上boot loader可以直接访问硬件,但512bytes太小了,所有其就通过INT调用BIOS interrupts. 这些只能工作在real mode之下.

²        INT 0x10: 屏幕输出

²        INT 0x16: 键盘输入

²        INT 0x13: disk I/O.该调用对硬盘大小的支持是有限制的.目前应该能支持8GB.

²        INT 0x15: 其他的一些调用都集中在此.主要和内存操作有关.

 

Boot load的组成部分

    Boot load一般包含三个程序:

²        Boot sector program: 512byte,由BIOS直接装载.

²        Second stage program: 由boot sector program装载,其中就是你想boot loader该做的内容.

²        Boot loader installer: 将前两者安装到boot disk.不再启动的时候调用,而且储存在指定的位置,不能被copy.

 

Boot sector program

    Boot sector program在大小只能有512bytes,其中还包括末尾的两byte的校验位.对于硬盘上的MBR其包括一个64bytes的分区表.

 

    Boot sector program由于大小的限制不仅要优化代码,而且不能完成一个boot loader所能完成的所有事情.通常完成以下功能之一:

²        装载另一个boot sector.它可以寻找到active分区的第一个sector并且chain load. MBR program不支持在启动的时候改变active分区,但是LILO可以.

²        装载second stage boot loader. Boot sector不支持以文件名的方式寻找到需要loader的second stage文件,取而代之的是以sector number的方式.这个numbers在boot loader installer设定.

²        直接装载kernel.

 

    Linux kernel中的boot sector program不需要second stage boot loader就可以直接装载内核.如果内核是储存在一块连续的区域的话,也不需要通过file system. 实际上对于bZimage kernels是有一个小骗局的,boot sector program其实是引发一个子程序来将kernel的剩余部分装载到高内存地址.(这块没有完全理解,剩余部分,难道boot sector program也算内核的前一部分?)(看了后面Linux Kernel的组成就能理解了.)

 

Second stage of boot loader

    这边才是真正的boot program,包含用户界面和kernel loader.其大小限制也很宽裕.其包括以下的功能:

²        用户界面.可以是命令行,也可以是菜单.可以选择操作系统并且对其下参数.可用的选择项可以在配置文档中定义.

²        Operating system loader.装载操作系统并使之运行.我们也可以调用 chain LOADLINg:就是装载另外一个操作系统特定的boot loader并使之运行.

 

    LOADLIN不是一个完整的boot loader,其second stage是没有用户界面的.

 

Boot loader installer

    这个部分只在将boot loader装到disk的时候使用.与前两者不同的是其是个Linux程序.它的作用如下:

²        安装boot sector.安装在硬盘的MBR或则DOS file system.注意要保留分区表或则DOS parameter block.

²        告诉boot sector, second stage boot loader的位置.

²        通知second stage boot loader相关信息.(配置档,kernel)

 

LOADLINg the operating system

LOADLINg the Linux kernel

    Linux内核由以下部分组成:

²        Boot sector(arch/i386/boot/bootsect.S).这个只在直接从软盘启动时运行.

²        带有real mode初始化代码的setup part.(转变为包含模式)(arch/i386/boot/setup/.S)

²        Kernel的其余部分,包括:

1.     包含模式初始化.(arch/i386/boot/compressed/head.S)

2.     解压缩程式.(arch/i386/boot/compressed/misc.c and lib/inflate.c)

3.     真正的内核,在解压后包含以下部分:

(1)   保护模式初始化

(2)   Main C routine.(init/main.c)

(3)   其余.和本文相关的是RAM disk驱动.(drivers/block/rd.c)

 

    Linux boot loader应该能完成以下的任务:

²        将Linux kernel装载进内存.

1.     将boot sector(将不会再运行)和kernel的安装部分装载到内存的高地址.(通常9000:0000)

2.     不是bzImage格式的内核,那么内核的剩余部分将装载到低内存地址.(0000:1000)

3.     bzImage格式的Kernel,那么内核的剩余部分将装载到高地址.(start at 0x100000).

Boot loader本身并不知道也不在乎剩余的kernel是否保护一个压缩部分.

²        给内核传递参数.参数可以来自于配置文档,或则使用者手动输入.

²        装载initial RAM disk并将之传递给kernel. 其被加载的地址将在存储内核的高地址之上.

²        开始内核,boot loader在setup part设定相关的参数并且调到此处. 到此,内核开始控制,boot loader的工作宣告结束.内核接下来的将开始以下内容:

1.     安装代码将保存传过来的参数和命令行,以后将用到.

2.     保护代码将剩余的内核解压.

3.     解压后,head.S和main C rounting将初始化所有的内核.

4.     最后,init进程将被启动.(initrd下,有可能是其第一个linuxrc变体)

 

Chain LOADLINg

    大多说boot loader仅能boot一种操作系统.比如LILO仅支持Linux, DOS boot sector仅能加载DOS.如果你有多个系统,并不是说你要找到一个支持所有的boot loader,因为所有的操作系统都能由一个512 bytes的boot sector来启动,所以有些很先进的boot loader支持chain LOADLINg.

 

    一个boot loader加载另一个操作系统的boot sector就叫做chain LOADLINg.这个boot sector可以存放在disk,分区,甚至一个文件而被直接加载. 对于操作系统而言他并不在乎他的boot sector是被BIOS或则其他boot loader加载的. 实际上存在与分区上的boot sector就是被MBR program加载的.

 

    以下的chain LOADLINg方案是可行的:

²        Linux boot loader可以chain loader几乎所以的其他操作系统.

²        Linux boot loader也可以被其他操作系统的boot managers引导.比如Win NT boot manager 或者OS/2.

²        Linux boot loader也可以chain loader其他的Linux boot loader.

 

Boot load的配置

    LILO与GRUB都有一个configuration file(配置文档)用来指定许多菜单选项,其中每行可能都代表着一个需要启动的Linux kernel或者其他操作系统. 没一个Linux kernel还可以指定其command line和initrd.除去语法的不同,配置文档大体上是一致的,但是有一些基本的不同点:

²        LILO的配置档仅在安装这个boot loader的时候有效,系统启动的时候并不关心这个文件.也就是说,如果你改变启动的一些设定,就要重新调用LILO安装程序将这些改变写入.LILO的second stage boot program不知道如何在操作系统中寻找文件,其依赖于一个在安装过程中生成的map文件来寻找必要文件的data blocks.

²        GRUB和SYSLINUX在启动过程中读他们的配置文档.所以如果启动相关的有所改变,也只要改变配置文档就好了,不需要再次安装.同样他们的second stage boot program支持在文件系统中寻找文件.

 

 

安装示例

例:root file system和kernel

    作者在他的另外一个文章<Getting Linux into Small Machines>中有两个相关文件,分别是Linux kernerl image(zImage)和root file system(root.img.gz).作者将基于这两个文件,并将之安装在软盘上后,测试每一种boot loader的具体使用.而且还将测试boot loader如何chain loader位于磁盘上的操作系统.

 

Linux Boot Sector

    最古老的启动Linux的方法是使用kernel本身的boot sector,但是有许多限制:

²        他只能从一个没有普通文件系统的软盘上加载Linux Kernel.

²        不支持kernel命令行.实际上我们用rdev程式来给boot sector设置参数.在启动的时候是绝对没有选项可以选择的.

²        不支持initrd.但是支持其他格式的RAM disk.

    不支持overformatted 软盘,即使上面没有文件系统.这里的overformatted大概是这个意思:正常情况下软盘每个track都分为18个sector,但是在overformatted下,却分为21个.这样软盘的容量就会变得,两者之间的比率为6:7,所以之后软盘的大小为1680kb.(呵呵,具体原理我就不清楚咯)

 

    首先,将kenerl和压缩后的RAM disk镜像存放到软盘上.例如Kernel的大小小于450kb,我们可以把RAM disk精确的放置在位移量是450kb的区域(dd的seek选项).这样kernel和Ram disk就不会重合了.

dd if=zImage of=/dev/fd0

dd if=root.img.gz of=/dev/fd0 bs=1k seek=450

 

    为了能使其正常运转,我们要将RAM disk在软盘上的位置等信息告诉Kernel.这里就要用到rdev了. 我们使用rdev的“–r”选项,设置RAM disk Word.这个量的定义如下:

 

    现在我们知道Ram disk的偏移量是450k,然后要使用ramdisk,那么这个Word的值就等于450+2^14=450+16384=16834.

    我们也要设定/dev/fd0为root device.

rdev /dev/fd0 /dev/fd0    #设定/dev/fd0为root device,前面一个参数是kernel在的设备,

                         #后面一个参数代码要设定的root device.

rdev -r /dev/fd0 16834    #设定Ram disk的Word.

 

    我们可以把RAM disk image放置在另外一张软盘上,这里我们就不需要在dd的时候设定offset,但是rdev要如下设置:

rdev /dev/fd0 /dev/fd0

rdev -r /dev/fd0 49152

 

    当软盘启动的时候,RAM disk将在kernel初始化后被加载.但是initrd将在kernel初始化之前就被boot loader加载了.

 

    虽然Linux boot sector不能加载位于overformatted软盘上的kernel,但是对于RAM disk却没有这样的限制.如果你把Ram disk放置在这样的软盘上,那么命令如下:

rdev /dev/fd0 /dev/fd0u1722    #这个时候的root device是那种的软盘

rdev -r /dev/fd0 49152

   

    要想将kernel和RAM disk放置在同一张overformatted的软盘上,作者提出了以下的解决方案:

²        在overformatted的软盘上(就是每track都有21个sector),将kernel以18sectors/track的格式写入(多余的3个被浪费了),RAM disk以21sectors/tarck的格式写入.这样就可以工作了,相关的代码如下:

fdformat /dev/fd0u1722

dd if=zImage of=/dev/fd0H1440    #这样就能实现21个用18个,因为zImage是18的.

dd if=root.img.gz of=/dev/fd0u1722 bs=1k seek=600#指定了block size=1k,那么就转化了?

rdev /dev/fd0H1440 /dev/fd0u1722

rdev -r /dev/fd0H1440 16984

        对于上面?的地方我不是很理解…,感觉要对文件系统inode什么深入学习学习…

²        修改Kernel boot sector program的源文件,使之能支持21 sectors.

²        将一个小型的minix file system放置在软盘的开始区域,然后使用LILO来boot位于其中的kernel,除了minix以外的软盘区域用于存放RAM disk.

 

    如果21sectors你都觉得不够,那么就用24的吧,但是大的sectors loader并不识别,所以想尽可能将大容量的Linux放置在软盘里面可以试试下面的方法:

²        将软盘格式化成两个块,kernel放置在21的中,RAM disk放置在24的中.

²        将修改boot sector后的kernel放置在第一个块中.

²        将RAM disk放置在后一个中.

²        由于存在两种不同格式的块,要计算出RAM disk的Word,然后用作rdev的参数.

 

LILO

    LILO是最初能从硬盘启动Linux的boot loader之一.它依然是市场的领导者而且在过去的岁月里它有了新的发展比如 较好的启动菜单,使用新BIOS功能函数(克服了1024cylinder的限制).LILO的基本原理是一致的,这就是说大多数的工作在安装的时候就已经完成了,而不是在启动的时候(配置文件).LILO也是唯一的可以支持RAID system的boot loader.

 

    大多数的Linux发行版本都已经安装了LILO,但不一定是最新的版本.在这个列子中我们,我们将下载最先版本的source tarball并且进行安装.这里我们不安装LILO,但是我们将从我们built后的源文件目录中运行它.(本例中的版本是22.3.1)

 

    这里,我们要做一些特别的地方:(一般的安装还是参考作者的<Getting Linux into Small Machines>一文)

²        我们将安装在一个overformatted软盘.对当前的kernel和initial RAM disk这不是必要的,但是对于大文件就是必要的了.

²        我们将使用minix文件系统取代ext2.这样可以减小开销.要被启动的kernel不一定要支持minix,但是主机必须支持.

²        我们将使用启动菜单.

 

    首先创建LILO的配置文件 lili-initrd.conf:

prompt

timeout=100

boot=/dev/fd0u1722

map=/mnt/boot/map

disk=/dev/fd0u1722

geometric

install=/mnt/boot/boot.b

image=/mnt/boot/zImage

  label=linux

  root=/dev/ram

  initrd=/mnt/boot/root.img.gz

image=/mnt/boot/zImage

  label=noram

  root=/dev/fd0u1722

 

    注意以下的问题:

²        /dev/fd0u1722是软盘设备

²        使用这个版本的LILO和overformatted的软盘就不能使用”compact”选项了.这个选项是用作普通软盘的.

²        使用”prompt”和”timeout”是为了能让菜单瞬间出现并且在时间到后启动默认的kernel.

 

    最后我们使用下面的命令来在软盘上安装一个minix file system,然后复制文件并运行LILO.

fdformat /dev/fd0u1722

mkfs.minix /dev/fd0u1722

mount /dev/fd0u1722 /mnt

mkdir /mnt/boot

cp zImage /mnt/boot

cp root.img.gz /mnt/boot

cp lilo-22.3.1/boot-menu.b /mnt/boot/boot.b

lilo-22.3.1/lilo -C lilo-initrd.conf

umount /mnt

 

    配置文档有三种,分别为boot-menu.b(支持菜单),boot-text.b(文字模式),boot-bmp.b(显示一个bitmapped screen,老版本支持).

 

GUN GRUB

    GUN GRUB是GUN工程的一个boot loader.它是第一个使用新BIOS特征即可以启动超过1024 cylinders的限制而且在LILO之前就有了菜单.而且他还是第一个支持大于64M RAM.

 

    意图上希望所有操作系统的kernel都能符合统一的标注,这样kernel就可以被任意的loader启动.Mutiboot就是这一的一个标准,但是却很少有支持者.GRUB就是设计符合这一标准的.

 

    GRUB和LILO,SYSLINUX有很多的不同,尤其其自身便能支持许多的文件系统类型.而且他自身就能安装自己,还有许多有用或者没有的命令.你可以用其他的文件系统或者其他配置档重新compile他达到节省空间的目的.

 

    为了娱乐和证明GUN GRUB的灵活性,我们将同时安装一个符合Mutiboot的kernel-GRUB Invaders game.(一个包含很多游戏的Kernel).当然这不是必要的,我们将用到其中的一个二进制文档(invaders).

 

    我们使用的GRUB版本是0.92,在源文件目录中使用下面的命令.

./configure
make

 

    象下面这一创建其配置文档.menu.lst

root (fd0)    #指定root device
title Linux with RAM disk  #类似于lable
   kernel /boot/zImage     #指明kernel文件的位置
   initrd /boot/root.img.gz#如果有initrd也指明
title Linux without RAM disk
   kernel /boot/zImage root=/dev/fd0
title GRUB Invaders
   kernel /boot/invaders

 

    准备一个软盘并把需要的材料都复制进去.我们可以把软盘格式化成任意一种Linux支持的格式.stage1和stage2文件是GRUB的组成部分而且习惯上放置在/boot/grub下,配置文档就是上面说的menu.lst.与LILO不同,GRUB将在启动的时候参考这个文档的内容.

fdformat /dev/fd0H1440
mkfs.msdos  /dev/fd0    #随便一种Linux支持的格式
mount -t vfat /dev/fd0 /mnt
mkdir /mnt/boot
mkdir /mnt/boot/grub
cp zImage /mnt/boot
cp root.img.gz /mnt/boot
cp invaders/invaders /mnt/boot
cp grub-0.92/stage1/stage1 /mnt/boot/grub
cp grub-0.92/stage2/stage2 /mnt/boot/grub
cp menu.lst /mnt/boot/grub
umount /dev/fd0

 

    现在我们只要能让这个软盘可启动,有以下几种方法:

²        在现有平台上(也是由GRUB作为loader的)使用GRUB命令行把GRUB安装到软盘上.

²        使用GRUB shell(我们的选择).GRUB shell是运行在Linux的模拟GRUB命令的程序.你可以用它做除了真正boot kernel外的其他所有事情.

²        在shell script中调用一个非交换的工具grub-install来达到目的.

 

    使用GRUB shell:

        进入源文件目录 调用grub-0.92/grub/grub

        在GRUB shell中键入以下的命令:

root (fd0)
setup (fd0) #setup将boot sector程序安装到指定的设备
quit

 

    GRUB虽能能安装自己的boot sector,但是其他需要的文件比如stage*还是要自己手动的.

 

    在将GRUB安装到软盘以后,你可以复制需要的kernel并且根据需要修改menu.lst而且并不要重新安装GRUB.只有stage2不能被移动.(这边笔者也不是很明白…要仔细研究GRUB)

 

    当你从GRUB的软盘启动.你会得到一个包含三个入口的菜单,你可以做以下的任何事情:

²        选择一个入口并进入

²        键入”e”编辑菜单的配置档.这样就能随时根据需要改变一些设置.

²        键入”c”进入命令行.这个命令行是很强大的.

    1.cat命令可以查看所有磁盘上的文档.下面的例子是查看一个磁盘第一个分区(/dev/hda1)上的/etc/passwd文件.这个命令也支持TAB的自动补充功能.

cat (hd0,0)/etc/passwd

        2.Kernel命令允许你选择硬盘上任意地方的内核来启动,例如以下就可以boot位于/dev/hda3的kernel.

kernel (hd0,2)/boot/vmlinuz root=/dev/hda3 read-only
boot

 

SYSLINUX

    SYSLINUX是一种特别适用于软盘的boot loader.他仅支持DOS格式的磁盘(当然也可以是硬盘).他提供屏幕帮助的风格来引导用户使用软盘.DOS格式的软盘已经被大多数的使用者接受.和GRUB一样,SYSLNUX同样也在启动的时候读取配置文档.

 

    理论上SYSLINUX可以被安装在FAT格式的硬盘分区上并启动上面的Linux kernel.他还能chain load MSDOS或者其他的操作系统.SYSLINUX并不是从硬盘上启动Linux的首选.

 

    首先获得最先版本的SYSLINUX.解压并运行make.如果你要从源码重新build boot loader的话,你可能需要最先版本的nasm,但是这个二进制文档已经事先包含了.所以在安装他的时候你并不需要nasm.

 

    接下来创建配置文件syslinux.cfg

prompt 1
timeout 100
say Available options: linux and noram
label linux
kernel zimage
append initrd=root.gz   #指明initrd的位置.
label noram
kernel zimage

 

    下来,我们要格式化一个磁盘并且复制相关的文件进去.可以用overformatted磁盘,但是一定要用MSDOS文件系统.

fdformat /dev/fd0u1722
mkfs.msdos /dev/fd0u1722   #设置为msdos文件系统
cd syslinux-1.75
syslinux /dev/fd0u1722    #安装boot sector program并且设定了boot device
cd ..
mount -t msdos /dev/fd0u1722 /mnt
cp zImage /mnt/zimage    #复制相关的kernel, initrd, configuration文件.
cp root.img.gz /mnt/root.gz
cp syslinux.cfg /mnt
umount /mnt

 

    和GRUB一样,安装新的kernel或者initrd只要修改配置档而不要重新安装loader.于GRUB不同的是两着的大小.本例中GRUB是95k,而SYSLINUX为7k.

 

    笔者在这里还有两点要补充的:

1.     我们通常都是将SYSLINUX的相关kernel, initrd, configuration文件直接放置在根目录中.

2.     SYSLINUX好像对长名支持有问题.所以尽量把相关文件的名字取的短点(<8字符).

 

LOADLIN

    LOADLIN是可以在DOS里面启动Linux的程式.随着Win ME后Win XP,用户一般都不再PC中安装DOS了.回到以前的Win版本,Win 98有附带DOS所以可以使用LOADLIN.在作者看来使用LOADLIN只是历史的兴趣出发.当然还有其他的原因:

²        在加载设备的DOS驱动后,能使之在Linux下也能正常运作.有一些设备比如声卡,虽然有其Linux下的驱动,但是只能在使用DOS驱动初始化设备后,Linux的驱动才能正常使用.所以你要事先运行DOS,然后从DOS启动Linux.

²        98年前的BIOS并不支持直接从CD启动.所以在这样的机器上运行一个Live CD你可能就要附带一个boot floppy.这样便能从软盘(DOS)上使用LOADLIN来启动CD上的Linux.

²        安装Linux而不要改变硬盘,也就是说不要安装任何东西到MBR区域来使Linux从硬盘启动.因为LOADLIN可以简单的直接通过CONFIG.SYS添加在DOS boot menu之中.

 

    Linux甚至都可以不安装一个单独的分区中.为了这个目的,必须在kernel中添加UMSDOS文件系统.虽然今天看来并不实用,但却依然存在.Linux的系统文件在DOS分区的一个Linux目录中,他包含一个特别的机制将长文件名转化为DOS的8+3文件名并且明确文件和设备的使用者,组,读写权限等属性.Linux可以象安装一个大型DOS应用程序那样直接通过解压一个ZIP包.LOADLIN使得启动Linux和运行一个DOS应用程式一样简单.

 

    LOADLIN可以从Hans Lermen's home page得到(好像我打不开).下载lodln16.tgz并且解压.我们只需要loadlin.exe这个文件.

 

    为了运行LOADLIN我们需要DOS.创建一个可启动的DOS软盘,在其中放置一个裸系统(bare system)和COMMAND.COM文件.不管你现在使用的是WIN的什么版本或者其他什么OS,你都可以应用Freedos来完成这个任务.下载FDB8_144.DSK文件(the rewrite image)并将之传输到软盘上.

dd if=FDB8_144.DSK of=/dev/fd0

 

    然后只保留软盘上的KERNEL.SYS,COMMAND.COM,其余的都删除.

mount /dev/fd0 /mnt
cd /mnt
rm -rf config.sys *.bat kernel32.sys kernel16.sys readme/
    docs fdos games install util
cd
umount /mnt

 

    现在我们就有一个小型的DOS软盘,把LOADLIN.EXE复制其中,当然也包括Linux kernel和initrd:

mount /dev/fd0 /mnt
cd /home/lennartb/myboot
cp loadlin.exe /mnt
cp zImage /mnt/zimage
cp root.img.gz /mnt/root.gz
umount /mnt

 

    下面就可以尝试从软盘启动了.启动后就进入了DOS系统,由于没有AUTOEXEC.BAT,你可能被要求输入时间和日期,直接两次回车就好了.下面就到了DOS的命令行,输入下面的命令来启动Linux:

loadlin zimage initrd=root.gz

 

    当然你也可以把以上的命令放到AUTOEXEC.BAT这个batch文档中.

 

Where Can Boot Loaders Live

    下面这个表总结了boot loader可以安装的环境.

²        Linux kernel boot sector只能被安装在一个raw软盘上也就是没有任何的文件系统.不能安装在硬盘或者有文件系统的软盘上.

²        GRUB是唯一的可以在DOS文件系统和其他类型(ext2,minix)上运用的.LILO不能被安装在DOS文件系统,而SYSLINUX只能被安装在DOS文件系统之上.

²        Linux kernel boot sector和GRUB都不支持非标准sectors/track的软盘.LILO和SYSLINUX需要的软盘类型是21 sectors/track.没有Boot loader支持24 sectors/track.

²        对于启动软盘boot loader所占用的空间是估计值.它包括文件系统和second stage boot program的开销.比如LILO要添加map文件,GRUB和SYSLINUX我们要添加配置文档.LOADLIN则还需要一个DOS.

 

Where boot loaders can be installed

Boot Loader

DOS FS

Other FS

Overformatted FD

Hard disk

Overhead

Kernel boot sector

No

No

No

No

0

LILO

No

Yes

Yes

Yes

FS + 15k

GRUB

Yes

Yes

No

Yes

FS + 96k

SYSLINUX

Yes

No

Yes

Yes

FS + 8k

LOADLIN

Yes

No

Yes

Yes

FS + DOS + 32k

 

 

RAM Disks

    Linux kernel在执行任何进程前需要事先mount一个root file system.对于急救软盘和CD通常都会在启动时把root fs加载到RAM disk中并且把root fs mount在这个RAM disk中.这样的做法有以下的优点:

²        RAM disk可以以压缩格式保存在磁碟上,所以可以在软盘上保存更多的程序.

²        在RAM disk加载后,软盘和CD设备就可以被移除,将设备空闲用于其他目的,比如备份或者加载其他工具.

²        从RAM中比从软盘中加载程序速度快.

 

Living without a RAM disk

    通常将Linux安装在硬盘上的时候,是不需要的RAM disk的,但是如果要从软盘(不依赖于在其他地方的系统文件)上启动的话,那么只有一个原因不使用RAM disk:你没有足够大的内存.一般来说,如果你的内存小于6-8M,那么就最好不要用RAM disk了,因为它在解压后大概会有4M.

 

    如果你没有用RAM disk的方法从软盘启动,而是在上面放置了根目录文件,那么可能需要额外的一张软盘,就是将内核和系统文件放在两张独立的软盘上.这时候的根系统文件是不用压缩的.当然也可以将两者放在一起.这个时候根系统文件中就包含了内核,这个是就好比大多数硬盘安装的情形.在启动软盘上你需要安装一个能保存在系统文件中的boot loader,这就排除掉了SYSLINUX(要直接放在根目录下而且只能支持FAT),但是GRUB和LILO都可以.

 

    在一个没有RAM disk的软盘上安装Linux是一个需要技巧的过程,包含下面的几步骤:

²        由于没有RAM disk,那么软盘就不能移除.

²        对硬盘分区,初始化一个swap区域,并在硬盘上创建文件系统.

²        将软盘上的根系统文件复制到硬盘上.

²        重启并选择硬盘是root device.这个时候,软盘就释放了.

²        把你需要的其他文件都复制到硬盘.

 

RAM disk devices

    RAM disk就是另一个block device,只是他buffer中的内容不会真的写到实际的设备上,数据仅存在在内存中.标准的kernel可以支持16M的RAM disk.最初并没有内存被分配给RAM disk,但是buffers将在被写入的时候动态添加. 默认RAM disk的大小为4M,可以通过ramdisk_size这个命令选项在启动的时候修改.在LILO中,你可以通过添加以下命令在配置档中来获得双倍的大小.

append ramdisk_size=8192

 

    这里是指定最大的大小,实际上小的RAM disk占用较少的空间.

 

    看内核源文件drivers/block/rd.c了解RAM disk是如何初始化的,它有三种可能:

²        默认在启动时候不初始化RAM disk.如果系统启动没有RAM disk.你可以通过下面的命令来将数据写入并mount RAM disk.

mke2fs /dev/ram2 2880
mount /dev/ram2 /mnt

²        RAM disk可以在启动时候从一个设备上被加载.在这种情况上,内核将检查其是一个合法的gzip格式文件或者合法的文件系统(仅支持不多的类型).压缩的Ram disk image将由内核来解压缩.

²        RAM disk可以在启动时候从内存中被加载(boot loader将其放置在内存中).加载的方法和在普通设备上一样,但是主要的初始化代码将区别这类的RAM disk和被mount的那种类型.

 

Loading a RAM disk at boot time

    启动的时候从软盘上加载RAM disk在刚开始(1992年)的时候就出现了.从此,添加或者修改了一些特征.比如可以在启动软盘的指定偏移量加载或者从另外一张软盘上加载.

 

    有两个方法指定RAM disk的参数.

²        使用rdev命令来设定启动参数.参考3.2章节.

²        设定ramdisk_start, load_ramdisk, prompt_ramdisk 这些内核命令行参数.下面是LILO下的具体实现:

root=/dev/fd0
append ramdisk_start=0 load_ramdisk=1 prompt_ramdisk=1

 

    在软盘的第一个部分放置一个系统文件(安装LILO)并且利用软盘的其余部分放置压缩的RAM disk image是可行的.使用mkfs外加size参数明确用于文件系统的blocks的数目.

 

    将非压缩的系统文件放置在可启动的软盘上并在启动的时候将整个软盘当作一个RAM disk也是可行的.甚至kernel, LILO second stage boot loader和map file都可以装载进RAM disk.这样的软盘在启动的时候既可以有,也可以没有RAM disk.(这个笔者就糊涂了)

 

The initial RAM disk

    Initial Ram disk由boot loader加载,其有下面的两处用处:

²        最主要的目的和维护Linux发行版本有关.initial RAM disk使得可以在硬盘上安装一个较小的不带有文件系统和硬盘驱动的kernel文件.在启动的时候这些驱动从initrd上(不是硬盘)上被以module的形式被加载.在这之后,kernel可以切换到真正的root device(硬盘).没有initrd,你可能需要把硬盘的驱动和文件系统驱动都编译进内核中,所以你要么就有一个大体积的内核要么就有很对可选择的对象.

    Initrd disk需要这样的一个文件系统:

1.     一个带有基本设备的/dev目录.

2.     一些可以用作mount points的目录.

3.     一个shell和一些二进制档.busybox就可以满足这个需要.

4.     需要的kernel moudlues.

5.     一个启动脚本能加载需要的modules.

²        Initrd disk也可以用作救援,安装或者其他特殊目的的软盘,虽然你可能需要其他类型的RAM disk.你都用不着切回real root device.这种类型的软盘在作者的<Getting Linux into Small Machines>一文中有所讲述.

 

    对于不能把initrd安装在另一个软盘是没有道理的,按时大多数的boot loaders都不支持这样.这是boot loader而不是Linux本身的局限.使用GRUB的pause选项,GRUB可以实现这一个目的,如同以下修改配置档:

title Linux with RAM disk on separate diskette
kernel (fd0)/boot/vmlinuz 
pause Insert the second diskette.
initrd (fd0)/boot/initrd.gz

 

 

 

Making Diskette Images without Diskettes

    到目前我们都是用写真实软盘的方法来准备启动软盘.这看起来是符合逻辑的做法,但是有些时候我们需要在没有软盘的情况下来准备一个image文件.比如:

²        在你没有软盘设备的时候需要软盘image.

²        需要自动创建boot image.

²        为可启动CD-ROM创建软盘image.

²        为模拟机创建软盘image.

 

    基本上我们可以按照以下来创建这样的一个镜像:

²        使用dd来创建一个空的镜像.

²        为这个镜像创建文件系统.

²        将image以loop类型mount到系统并把文件复制进去.

²        为这个image文件安装boot loader.(可能需要实现umount)

 

    最后一部分针对LILO的技巧. 同样这对于SYSLINUX是很简单的,而对于GRUB也即是使用设备命令就可以的,对于这两者也有技巧(但对于LILO无效).

²        Start with an image file with just the boot loader installed and an empty file system and copy that image file each time you create another image. This image file may be extracted from a real diskette just once.(没看懂…)(可能是说在装载LILO的系统上进行image的创建?)

²        使用loop选项mount image文件然后复制所有的文件.

 

    在Timo's Rescue CD Page有一个很好的例子关于如果为CD-ROM创建一个2.88MB的软盘镜像,使用了所有的boot loaders.

 

 

Hard Disk Installation

    在硬盘上启动Linux有以下几个基本的选择:

²        使用OS的中立的MBR boot sector程序(比如DOS)并且用它来启动一个位于主分区的Linux boot loader.一些boot sector程序允许使用者在启动的时候选择许多OS中的一个.

²        直接从MSR启动Linux boot loader(GRUB,LILO).

²        使用其他OS的boot loader来chainload一个Linux boot loader.当然也可以用一个Linux的loader来chainload另一个. GRUB就是这样的一个例子,他可以从MBR启动也可以chianload许多位于独立分区中的LILO.

²        从软盘启动Linux.这个软盘可能只包含boot sector(需要加载的second stage 将来自于硬盘),完整的boot loader设置是boot loader外加kernel.

²        从DOS通过LOADLIN来启动Linux.

 

    到底选择哪个依据下面的因数:

²        在同一个机器上允许另一个操作系统是什么?在没有Windows NT的机器上通过NT 的boot loader来chainloading Linux是没有意义的.

²        硬盘上使用什么样的分区?是RAID吗?具作者所知,LILO是唯一支持RAID的Linux boot loader.

²        各个操作系统之间的重要联系是什么?

²        每个boot loader的可靠性.

²        个人的喜好.

 

    有个使得boot loader安装复杂化的因素:每个OS和GRUB都对硬盘和分区有其命名和序列规则.BIOS给每个硬盘都分配一个数字,第一个磁碟是0x80,第二个是0x81,依此类推.当你安装LILO,大多数情况下是没有问题的,但是有些情况必须为每个设备明确BIOS的编码.

 

    GRUB对硬盘的命名规则可能会导致混淆:

²        整个硬盘(如果你在MBR安装GRUB)被称作(hd0),(hd1)等.

²        分区是从0开始计数的,所以第一个硬盘上第一个分区称作(hd0,0).这样在Linux中从5开始计数的扩展分区在GRUB中就从4开始.

²        BIOS中也是从0开始对硬盘进行计数的.在许多系统中/dev/hda等同于(hd0)(除非系统只有SISI硬盘).但是(hd1)对于的Linux硬盘名又是什么却是要根据你连接到EIDE primary slave口的具体情况的.如果是个硬盘,那么这个硬盘就是/dev/hdb.如果是CD-ROM,同时secondary master连接的硬盘在Linux是/dev/hdc,但在GRUB中是(hd1).

 

    下表显示了在一个系统上有两个硬盘时候磁碟和分区数情况,两硬盘分别以master和slave连接到主IDE控制器.第一个磁碟包括两个主分区(DOS和Linux)和两个逻辑分区(DOS和Linux swap).第二个磁碟包括一个DOS主分区.

Disk and partition names (first example)

Disk

Linux

BIOS code (LILO)

GRUB disk name

DOS drive

IDE Primary Master

/dev/hda

0x80

(hd0)

-

Primary DOS

/dev/hda1

-

(hd0,0)

C:

Primary Linux

/dev/hda2

-

(hd0,1)

-

Extended

/dev/hda3

-

(hd0,2)

-

Logical DOS

/dev/hda5

-

(hd0,4)

E:

Linux swap

/dev/hda6

-

(hd0,5)

-

IDE Primary Slave

/dev/hdb

0x81

(hd1)

-

Primary DOS

/dev/hdb1

-

(hd1,0)

D:

 

    下表显示了系统中有三块硬盘时候磁碟和分区的情况,一块在primary IDE控制器,一块在secondary IDE控制器,第三块在SCSI.

Disk and partition names (second example)

Disk

Linux

BIOS code (LILO)

GRUB disk name

DOS drive

IDE Primary Master

/dev/hda

0x80

(hd0)

-

Primary DOS

/dev/hda1

-

(hd0,0)

C:

Primary Linux

/dev/hda2

-

(hd0,1)

-

IDE Secondary Master

/dev/hdc

0x81

(hd1)

-

Primary DOS

/dev/hdc1

-

(hd1,0)

D:

First SCSI

/dev/sda

0x82

(hd2)

-

Primary DOS

/dev/sda1

-

(hd2,0)

E:

 

    如果你使用FreeBSD那么情况将变得更复杂化.BSD将一个分区又分成几个子分区.Linux仅能支持那些编译进内核的BSD磁盘lables.不仅是Linux,BSD和GRUB对这些子分区都有不同的命名.

 

    在GRUB中你使用GRUB的分区名来访问文件,但在kernel命令行中Linux分区名可以用作参数.下面是一个在GRUB中常见的kernel命令行:

kernel (hd0,1)/vmlinuz root=/dev/hda2

 

    最后,在一些特别是老的系统上,磁盘分区会引起一些问题.如果所有的情况都支持LBA(逻辑磁盘管理模式),那么就不会有问题了.但是如果你的BIOS不支持LBA, boot loader使用BIOS将无法涉及超过1024cylinders的区域.在这种情况下,”nuni”(一个没有1024问题的引导器)可能是一种解决方案.但大多数情况下.你可能需要在磁盘的开始处创建一个小的分区,并把kernel放置在这里.

 

 

CD-ROM Installation

    大多数的Linux发行版本是在一张CD-ROM的而且现在有许多的可以烧入在CD-ROM上的救援磁盘镜像.在不远的将来.大多数的PC将不在使用软驱,光驱是唯一的选择.

 

    目前的BIOS都支持El Torito标准(从CD-ROM启动).现在有两种不同的方法来实现:

²        大多数情况下模拟软盘镜像的做法.在CD-ROM上面有一个软盘镜像文件.虽然可以有很多软盘大小,但1.44MB是最普通的.BIOS加载最初的512bit block进内存,就好像这些是软盘的boot sector.接下来,BIOS将INI 0x13调用从软盘重定向到CD-ROM上.通常从软盘启动的仅能使用BIOS调用来访问软盘的程式也能从模拟的软盘镜像上正常工作.而且LILO,GRUB和SYSLINUX也只能支持以这种方式CD-ROM启动.

 

    正如软盘上的initial RAM disk由boot loader使用BIOS调用加载,这些也能在CD-ROM  上的模拟软盘镜像上正常工作.但是不适用于由内核加载的RAM disk(非initrd类型),   因为kernel加载不使用BIOS.

 

    所有本文章涉及的启动软盘的LILO,GRUB和SYSLINUX都可以在CD-ROM上工作. 

    但是在可启动CD-ROM上使用overformatted软盘镜像是不行的,但是可以使用2.88M      的软盘镜像. 

²        也可以不使用模拟软盘的方法.ISOLINUX就是用于这种方法的程式.它包含在SYSLINUX源文件里面并且可以在ISO9660格式的CD-ROM上寻找到任何文件.它和SYSLINUX一样都包含一个配置文档.使用这种方法将没有不同Kernel数量和initial RAM disk大小的限制.注意:如果你使用的initial RAM disk大于4M(没有压缩),你必须在配置文件中指明ramdisk_size的参数.

 

    当Linux内核被启动后,它将RAM disk当作其根目录.从这里就很容易mount CD-ROM.CD-ROM上面可能有工具,安装包以及其他.理论上也可以将CD-ROM作为根文件系统,但在系统运行时切回到磁盘就显得不可能(和CD-ROM只读有关,所以不能mount其他文件系统).

 

    两种可启动的CD-ROM都可以用”mkisofs”来创建.创建好的镜像可以使用”cdrecord”烧入到CD-ROM中.作者对两种都进行了尝试.

 

    首先尝试模拟软盘的方式.在这个例子中作者使用GRUB软盘,已经事先格式化成1.44M(当然使用LILO也可以)首先为ISO镜像创建目录树.

mkdir iso
mkdir iso/boot
mkdir iso/data

 

    接下来复制文件到数据data目录并且复制软盘到boot目录.

cp somefile iso/boot/data
dd if=/dev/fd0 of=iso/boot/boot.img

 

    创建ISO镜像

mkisofs -o emuboot.iso -b boot/boot.img / #-o生成的文件;-b指出boot image
        -c boot/boot.catalog -r iso

 

    最后将这些烧到CD-ROM,使用合适的device ID.

cdrecord dev=0,1,0 -eject -pad -data emuboot.iso #dev的值可以通过cdrecord –scanbus

 

    这张CD是可启动的而且从已经启动的Linux你可以通过mount CD-ROM来访问数据文件.如果你的RAM disk image没有创建CD-ROM的设备文件名,你可以通过下列命令来手动创建:

mknod /dev/hdd b 22 64 #主设备号是22,辅设备好可以是0-255中任意的,通常hdc是22,0
mount -r -t iso9660 /dev/hdd /mnt

 

    接下来尝试通过ISOLINUX来创建可启动的CD-ROM.首先创建一个isolinux.cfg配置档

prompt 1
timeout 100
say Available options: linux and noram
label linux
kernel zimage
append initrd=root.gz
label noram
kernel zimage

 

    实际上这个文件就等同于syslinux.cfg.

 

    从创建好的iso目录中移除老的boot文件夹并且用包含内核,RAM disk image,boot files的isolinux目录代替:

rm -rf iso/boot
mkdir iso/isolinux
cp zImage iso/isolinux/zimage
cp root.img.gz iso/isolinux/root.gz
cp syslinux-1.75/isolinux.bin iso/isolinux
cp isolinux.cfg iso/isolinux

 

    创建ISO镜像并烧入到CD:

mkisofs -o isoboot.iso -b isolinux/isolinux.bin /
        -c isolinux/boot.catalog /
        -no-emul-boot -boot-load-size 4 /
        -boot-info-table -r iso

 

    对于老的不能从CD-ROM启动的BIOS有两个方案:

²        任何1.44M的El Torito启动镜像也可以作为软盘的启动镜像.也就是把光盘的启动镜像放到软盘上使用.使用RAWRITE.EXE或者dd.

²        如果DOS可以读CD-ROM,那么就可以在boot DOS后使用LOADIN来启动CD-ROM上的Linux.

 

    大多数Linux发行版本对这两种方法都支持,有些设置提供了启动软盘.

 

 

总结

    对于Linux存在许多种boot loader而且没有一个对所以情况都是最佳的.

 

    作者推荐使用以下的boot loader:

²        对于普通的硬盘安装,使用LILO或者GRUB

1.     GRUB有一个恢复的特征,但是它同样危险(也就是可以在启动的时候修改GRUB的配置档达到特别的目的).当然你可以用密码的方式来保护命令行.

2.     LILO是所以发行部的标配.如果你只是单纯的安装Linux(也许和DOS/Windows共存),使用LILO.另一方面,如果你安装不同的Linux版本,不同的操作系统而且需要经常编译内核,GRUB是绝对适合的.

3.     LILO支持RAID而GRUB不能.

²        SYSLINUX适合软盘安装.它将所以内容打包,所以一旦安装,你可以把需要的文件复制到DOS磁盘而且它支持overformatted软盘.

²        对于CD-ROM可以配合SYSLINUX使用软盘镜像,当然ISOLINUX也是值得尝试的.

²        一个仅仅安装了GRUB的软盘是对于不能启动的机器是一个很好的救援工具.使用GRUB软盘,你可以修复并匹配内核,从另一张软盘上修复initial RAM disk,而且你可以启动存在任何硬盘上的内核.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值