第四节 启用内核
通常,核心安装叫做vmlinuz。过去Unix使用者共同起了这名字。"z"表示压缩,"v"和"
m"意思是"virtual"(虚拟)和"sticky(粘性的)",各自属于内存和磁盘管理。建议保
留vmlinuz核心,直到知道它工作。
为了能够使用新版本的内核,还需要做一些改动:
#cp /usr/src/linux/System.map /boot/System.map-2.2.16
#cp /usr/src/linux/arch/i386/bzImage /boot/vmlinuz-2.2.16
以上这两个文件是刚才编译时新生成的。下面修改/boot下的两个链接System.map和vml
inuz,使其指向新内核的文件:
#cd /boot
#rm -f System.map vmlinuz
#ln -s vmlinuz-2.2.16 vmlinuz
#ln -s System.map-2.2..16 System.map
注意:要保留vmlinuz核心,以下列步骤进行
#cp /usr/src/linux/System.map /boot/System.map-2.2.16
#cp /usr/src/linux/arch/i386/bzImage /boot/vmlinuz-2.2.16
#cd /boot
#rm -f System.map
#ln -s System.map-2.2..16 System.map
现在#vi /etc/lilo.conf,增加如下一段:
image=/boot/vmlinuz-2.2.16 是设定为已经安装的核心
label=linux2.2.16 则是由 lilo 用来告诉你现在要启动的是那个核心或作业系统
,
read-only
root=/dev/hda2 则是这个特别的作业系统的根目录 /
其中root=/dev/hda2一行要根据需要自行加以修改。
运行:#/sbin/lilo -v 保存执行命令:lilo你将看到核心标签,第一个是星号。如果你
没有看到新核心的标签或LILO出现错误,你需要重新对/etc/lilo.conf工作(看下面的
LILO分析)。
确认对/etc/lilo.conf的编辑无误,现在重新启动系统:
#shutdown -r now
不建议使用热启动或ctrl+Alt+del键。在一些情况下,文件系统不完全卸栽会损坏打开
的文件。在LILO提示时,如果你需要启动旧的核心或使用一些参数启动,如果你没看见
启动提示,你可以试用shift或ctrl键,这样启动提示就出现了。一旦出现,按tab看核
心标签。输入标签和可选参数启动。通常,在/etc/lilo.conf文件指定的时间后自动启
动核心。启动时,你可能看见一些出错信息就象SIOCADDR。这常常显示模块(一般是网
络模块)没有引导。处理这事很简单,如果有此一错,"VFS,cannotmount root",你就
不要在核心中编译适当的磁盘或文件系统支持。
在机器重启后出现LILO时按TAB键,输入linux2.1.16,新内核发挥作用了。
附录:LILO分析(技术性强,仅供参考)
第一部分 LILO介绍
LILO(Linux Loader)是Linux自带的一个优秀的引导管理器,使用它可以很方便地引导
一台机器上的多个操作系统。与其他常用的引导加载程序相比,LILO引导方式显得更具
有艺术性,对其深入的理解,将有助于我们方便地处理多操作系统、网络引导、大硬盘
及大内存等诸多棘手的问题。
LILO的引导机制------众所周知,计算机的最初启动是由BIOS控制的,在对一些硬件(
如:内存、键盘等)初始化之后,它会试图加载硬盘的主引导记录(MBR)或软盘的引导
扇区。MBR可通过两种方式运行,其一是定位到活动分区并加载相应的引导扇区,然后由
引导扇区完成该分区内操作系统的基本组件的加载;其二是直接从一指定分区中加载信
息,并通过它装入任一分区的操作系统,诸如LILO、OS/2 boot loader及Partition Ma
gic等引导加载程序都可以配置成这种方式。软盘的引导扇区相当于硬盘活动分区的引导
扇区,它通常用于装入软盘上的操作系统。由此可见,只要把LILO安装在MBR、活动分区
或者引导软盘上,就能接管计算机的控制权,然后由LILO完成后继的引导过程。LILO中
建有一个引导表地址编码,借此它的引导程序就能定位到Linux的内核文件,这种地址编
码既可以按照柱面/磁头/扇区(CHS)模式,又可以采用LBA的线性块号模式,因此,即使
对某些SCSI控制程序LILO也能运转良好。
当LILO定位到配置文件后,经过预引导过程,就显示提示符:LILO boot:
此时,系统允许选择引导不同的操作系统或者不同的内核配置,按Tab键显示可选项列表
,然后输入可选项或者直接回车选择缺省配置,如果选择了引导Linux,还可以直接传递
参数到系统内核。
和其他系统的引导加载程序相比,LILO具有更大的灵活性,其引导方式也更丰富多彩。
●当LILO被安装在硬盘的MBR、活动分区或引导软盘上时,作为原引导程序的替身,它能
引导任一硬盘任一分区上的Linux和其他操作系统;除了引导扇区,它没有任何隐含文件
,也不需要使用特定的分区,它的配置文件可以在任何分区、甚至是存放在与Linux毫不
相干的DOS分区的某个子目录下;它能引导几个不同的内核配置,甚至是几个不同的内核
;它能引导同一机程序上的多个Linux版本;可达16个。
●它能从网络上引导Linux。
●LILO的灵活性使得其配置变得相当复杂,当有多个系统共存时,建议先安装其他操作
系统,最后再装Linux,这样,设置LILO对其他系统的引导会相对简单一些。
第二部分 LILO参数
通常我们谈到LILO,会涉及到两个方面——LILO引导程序和LILO安装命令/sbin/lilo。
为了不至于混淆这两个概念,本文将用LILO表示LILO引导程序,而lilo表示/sbin/lilo
。一般地,LILO使用一个文本文件/etc/lilo.conf作为其配置文件。lilo读取lilo.con
f,按照其中的参数将特定的LILO写入系统引导区。任何时候,修改了/etc/lilo.conf,
都必须重新运行lilo命令,以保证LILO正常运lilo.conf使用的配置参数很多,配置起来
也相当复杂。下面以RedHat Linux为例作一些初步探讨,RedHat的lilo程序包版本为0.
20,别的Linux发行版本可能会有所出入,但不会太大。
lilo.conf文件中的配置参数分为两部分,一部分是全局参数,另一部分是引导映像参数
。引导映像参数作用于每一个引导映像区。如果某一引导映像参数(例如:password与
全局参数的定义相抵触,则以该引导映像参数的定义为准,但仅限于该引导映像区。LI
LO的引导参数有很多,在此只对一些比较重要的参数作一介绍。与Linux系统其他的配置
文件一样,“#”号后的一行文字表示注释。
1.“boot=”此参数指明包含引导扇区的设备名(如:/dev/had),若此项忽略,则从当
前的根分区中读取引导扇区。
2.“root=”此参数告诉内核启动时以哪个设备作为根文件系统使用,其设定值为构造内
核时根文件系统的设备名,可用的设备名有:
(1)/dev/hdaN~/dev/hddN:ST-506兼容硬盘,a到d上的N个分区
(2)/dev/sdaN~/dev/sdeN:SCSI兼容硬盘,a到e上的N个分区
(3)/dev/xdaN~/dev/xdbN:XT兼容硬盘,a到b上的N个分区
(4)/dev/fdN:软盘,A:(N=0)或B:(N=1)
(5)/dev/nfs:由网络取得根文件系统的标志
3.“nfsroot=”若需通过NFS提供根文件系统来引导无盘工作站,此参数为内核指定了网
络根文件系统所在的机程序、目录及NFS,其格式为:nfsroot=(〈server_ip〉:)〈r
oot_dir〉(,nfs_options))
4.“nfsaddrs=”设定网络通讯所需的各种网络界面地址,如无此参数,则内核会试图用
反向地址解析协定(RARP)或启动协定(BOOTP)找出这些参数,其格式为:nfsaddrs=〈客
户端IP〉:〈服务端IP〉:〈网关IP〉:〈子网屏蔽〉:〈客户端名称〉:〈网络设备名〉
:〈auto〉
5.“image=”指定Linux的内核文件。
6.“delay=”设定引导第一个映像前的等待时间。
7.“disk=”此参数为某一特殊的硬盘定义非标准参数。
8.“append=”为内核传递一个可选的参数行,其典型的应用是为不能完全由系统自动识
别的硬盘指定参数,如:append = "hd=64,32,202"
9.“label=”此参数为每个映像指定一个名字,以供引导时选择。
10.“read-only”设定以只读方式挂入根文件系统,用于文件系统一致性检查(fsck)
。
11.“install=”安装一个指定文件作为新的引导扇区,缺省为/boot/boot.b。
12.“loader=”说明所使用的链加载程序(chain loader),缺省为/boot/chain.b,如果
不是从首硬盘或软盘启动,那么,此选项必须说明。
13.“table=”说明包含分区表的设备名,如果此参数忽略,引导加载程序将不能传递分
区信息到已引导的操作系统。当此参数指向的分区表被修改时,必须重新运行/sbin/li
lo。
14.“init=”内核初始化时执行的程序,通常过程为init、getty、rc和sh,版本1.3.4
3以来的Linux内核能够执行/sbin/init说明的命令行,若在引导过程中出现问
题,则可设置init=/bin/sh直接跳到Shell。
15.“ramdisk_start=”由于内核不能放在压缩的内存文件系统映像内,为使内核映像能
够和压缩的内存映像放在一张软盘内,加入“ramdisk_start=〈offset〉”,这样内核
才能开始执行。
16.“mem=”此参数的目的之一是为Linux指定使用的内存数量:如mem=96MB,目的之二
是指定mem=nopentium告诉内核不要使用4MB分页表。
17.“vga=”设置显示模式,如80×50、132×44等。
18.“linear” 产生用于替换硬盘sector/head/cylinder地址(硬盘几何参数)的line
ar扇区地址。linear地址在运行时产生并且不依赖于硬盘几何参数。某些SCSI硬盘和一
些以LBA方式使用的IDE硬盘可能会需要使用这个参数。注意:在将LILO安装到软盘上时
不能使用“linear”参数。
19.“prompt” 给出“boot:”提示,强制LILO等待用户的键盘输入,按下回车键则立即
引导默认的操作系统,而按下Tab键则打印可供选择的操作系统。当“prompt”被设置而
“timeout”没有被设置时,系统会一直处于等待状态而不引导任何操作系统。不设置该
参数时,LILO不给出“boot:”提示而直接引导默认操作系统,除非用户按下了Shift、
Ctrl、Alt三键中的任何一个。大多数情况下,如果你的硬盘上有多个操作系统,建议使
用参数,它留给用户一个选择的余地。
20.“timeout=” 设置等待键盘输入的时长,单位是0.1秒。超过这段时间没有输入则为
超时,系统将自动引导缺省的操作系统。如果不设置本参数,缺省的超时时间长度为无
穷大。
21.“other=” 设置包含非Linux操作系统,如DOS、SCO UNIX、Windows 95等系统引导
映像的文件或设备。
22.alias=name 给当前操作系统起一别名。
第三部分 LILO典型配置方法
通常情况下,Linux的安装程序自身就可以完成LILO的安装配置,从而较好地解决多重系
统的引导问题,如果系统不能自动完成这种配置,则可以通过手工修改配置文件/etc/l
ilo.conf来实现不同条件下的引导。
1.当系统能自动完成配置时
对于这种情况只有一个建议:将LILO安装到Linux分区的根上,而不是MBR这个多事地带
。假设当前hda1中装有DOS/Windows,hda2中安装了Linux,则/etc/lilo.conf的内容大
致如下:
boot=/dev/hda2#指定引导位置
compact
delay=50#延时5秒
root=current#根在当前分区
image=/boot/vmlinuz#指定linux的内核文件
label=linux#用linux为代表名称
other=/dev/hda1#其他操作系统所在的分区
table=/dev/hda#指定包含分区表的硬盘
label=dos#用dos为代表名称
2. 当系统无法自动完成配置时
系统无法自动完成配置的情况不外乎两种:
(1) BIOS不能直接看到Linux的根分区;
(2) BIOS只能读写标准IDE硬盘的前504MB。
这时,必须遵循一个最基本的原则:建立一个BIOS能存取的较小的Linux分区,其中包含
内核文件、映射文件及链加载程序等必要内容,而根则可以是另外一个独立的分区。至
通常情况下,Linux的安装程序自身就可以完成LILO的安装配置,从而较好地解决多重系
统的引导问题,如果系统不能自动完成这种配置,则可以通过手工修改配置文件/etc/l
ilo.conf来实现不同条件下的引导。
1.当系统能自动完成配置时
对于这种情况只有一个建议:将LILO安装到Linux分区的根上,而不是MBR这个多事地带
。假设当前hda1中装有DOS/Windows,hda2中安装了Linux,则/etc/lilo.conf的内容大
致如下:
boot=/dev/hda2#指定引导位置
compact
delay=50#延时5秒
root=current#根在当前分区
image=/boot/vmlinuz#指定linux的内核文件
label=linux#用linux为代表名称
other=/dev/hda1#其他操作系统所在的分区
table=/dev/hda#指定包含分区表的硬盘
label=dos#用dos为代表名称
2. 当系统无法自动完成配置时
系统无法自动完成配置的情况不外乎两种:
(1) BIOS不能直接看到Linux的根分区;
(2) BIOS只能读写标准IDE硬盘的前504MB。
这时,必须遵循一个最基本的原则:建立一个BIOS能存取的较小的Linux分区,其中包含
内核文件、映射文件及链加载程序等必要内容,而根则可以是另外一个独立的分区。至
于配置上的其他细节,我们通过以下实例来进行说明。
第四部分 lilo.conf配置实例
有了这些基础知识,我们可以很容易地按照自己的意图配置LILO。
例一.lilo.conf文件
boot=/dev/hda #将LILO安装在MBR。LILO作为主引导管理器
message=/boot/message #注释为/boot/message
compact #产生一个更小的“map”文件
map=/boot/map #指定“map”文件为/boot/map
install=/boot/boot.b
password=zhoudi #设置口令
vga=normal #80x25文本模式
linear #使用“linear”地址
prompt #提示用户键盘输入
timeout=50 #超时时长为5秒
default=dos #缺省引导label为dos的操作系统
image=/boot/vmlinuz-2.0.34-1#设定Linux所用核心
#设置Linux核心引导映像
label=linux #标识为linux
root=/dev/hda1 #设置根文件系统
read-only #LILO以只读方式载入根文件系统
#设定MS-DOS或Windows 95
other=/dev/hda2 #DOS分区为第一个IDE硬盘的第二分区
label=dos #标识为dos
table=/dev/hda #主设备为第一个IDE硬盘
#设定SCO UNIX 注意:SCO分区必须设为活动(active)分区并将LILO安装在MBR上。
other=/dev/hda3
label=sco
table=/dev/had
这个例子中,LILO是作为主引导管理器来管理机器上所有操作系统的。LILO也可作为二
级引导管理器,这只要将“boot”参数改为根分区就可做到。例如: boot=/dev/h
da1 以这种方式使用LILO时,Linux根分区必须用DOS或Linux的fdisk程序将其设置为活
动分区,并且这种方式只对硬盘主分区(不是扩展或逻辑分区)有效。
例二.一个标准的IDE大硬盘需安装Linux和DOS/Windows。
对于大硬盘问题,很多人只知道低于1024个柱面的限制,而不知为什么标准的IDE硬盘只
能认前504MB。其实,BIOS的int13调用是采用三个位元组的CHS编码,10位为柱面号,8
位为磁头号,6位为扇区号。可能的柱面号码是0~1023,可能的磁头号码是0~255,而
磁道上可能的扇区号码是1~63,以这24位最多可以定址8455716864个位元组(7.875GB)
。但不幸的是,标准的IDE介面容许256个扇区/磁道、65536个柱面及16个磁头。它自己
本身可以存取237= 137438953472(128 GB),但是加上BIOS方面63个扇区与1024个柱面
的限制后只剩528482304(504MB)可以定址得到。
对策:在硬盘的前500MB中划分350MB(/dev/hda1)给DOS,150MB(/dev/hda2)给Linux,在
相应的配置文件中应说明硬盘的参数。
boot=/dev/hda
... ...
disk=/dev/hda
bios=0x80
sectors=63
heads=16
cylinders=2100
image=/vmlunuz
append="hd=2100,16,23"
root=/dev/hda2
label=linux
例三.如果你有一块超过 8 G 的大硬盘, 并且需要把 Linux 安装在比较靠后的位置,可
以在安装的时候, 选择 linear 模式, 并且给它加上硬盘参数.
安装时候的硬盘参数可以这样写: hd?=CYLs, HEADs, SECs 其中的大写字母需要用实际
的硬盘参数来替换, 这些参数可以从硬盘的标签上查到, 也可以看看 BIOS 设置里硬盘
参数对应 LBA 模式的那一行. 问号是根据硬盘确定的, 实际使用时, 它可以是 a, b,
c, d 四个字母中的一个. 比如: hda=1869,63,255 这是 IBM 15.2G 硬盘的参数.
当然进入了 Linux 以后, 可以通过编辑 /etc/lilo.conf 加上这个文件, 然后运行一遍
lilo 达到同样的目的. 下面是本人未加参数前的 lilo.conf的内容:
boot = /dev/hda
map = /boot/map
install = /boot/boot.b
prompt
timeout = 50
image = /boot/vmlinuz
label = linux
root = /dev/hda1
initrd = /boot/initrd-2.2.12-20.img
read-only
按照 linear 方式加入参数以后是如下格式:
boot = /dev/hda
map = /boot/map
install = /boot/boot.b
prompt
linear <-----加进了这一行
timeout = 50
image = /boot/vmlinuz
label = linux
root = /dev/hda1
initrd = /boot/initrd-2.2.12-20.img
read-only
append = "hda=1869,63,255" <------加进了这一行 注意, append参数是针对每个系统
引导记录的, 一定要放在 image 的下面或者是 other 的下面,这样它才可以发挥作用.
当再次起动 Linux系统的时候, LILO 就按照线性模式对系统进行引导.除了在硬盘上寻
址定位的方式不同以外, 对其他方面没有什么影响.
第三章内核编译的应用
第一节嵌入式Linux技术
第二节你的Linux有多大?(及实践结果)
这可不是我写的,只是用来参考制造small kernel,效果还可以。
最小的 Linux kernel
我使用的是 Mandrake 内核的 2.2.15,我没有修改任何一行程序码,完全只靠修改组态
档得到这些数据。
首先,使用 make xconfig 把所有可以拿掉的选项都拿得。
不要 floppy
不要 SMP,MTRR
不要 networking,SCSI
把所有的 block device 移除,只留下 old IDE device
把所有的 character device 移除
把所有的 filesystem 移除,只留下 minix
不要 sound 支援
相信我,我己经把所有的选项都移除了。这样做之后,我得到了一个 188K 的核心。不
过这个核心恐怕很难发挥 Linux 的功能,因此我决定把网络加回去。把 General中的
network support 加回去,重新编译,核心变成 189 K。10K 换个 TCP/IP stack,似乎
是很上算的生意。
不过有 stack 没有 driver 也是惘然,所以我把 embedded board 常用的RTL8139 的
driver 加回去,195K。如果你需要 DOS 档案系统,那大小成为 213K。如果 minix 用
ext2 换代,则大小成长至 222K。
不过大家要注意,那里的大小指的是核心档的大小。那和所需要的随取记忆体是二回事
。这个数字代表的意义是你需要多小的 ROM 来存放你的核心。
Linux 所需的记忆体大约在 600~800 K 之间。1MB 可能可以开机了,但可能不太有用。
因为可能连载入 C 程序库都有困难。2MB 应该就可以做点事了,但可能要到4MB 以上才
可以执行一个比较完整的系统。
看到这里,是不是觉得 Linux 真的有点大。好吧! 那我们就来看看谁占用了这些空间,
下面这个列表是从 222K 这个核心做出来的。
# wc
arch/i386/kernel/kernel.o
arch/i386/mm/mm.o
kernel/kernel.o
mm/mm.o fs/fs.o
ipc/ipc.o
fs/filesystems.a
net/network.a
drivers/block/block.a
drivers/char/char.a
drivers/misc/misc.a
drivers/net/net.a drivers/pnp/pnp.a
/usr/src/smalllinux/arch/i386/lib/lib.a
/usr/src/smalllinux/lib/lib.a
/usr/src/smalllinux/arch/i386/lib/lib.a
结果如下 :
243 2250 81946 arch/i386/kernel/kernel.o
42 316 10569 arch/i386/mm/mm.o
173 1541 74660 kernel/kernel.o
266 2307 68053 mm/mm.o
222 3139 123193 fs/fs.o
49 602 21600 ipc/ipc.o
263 2940 106504 fs/filesystems.a
137 1510 65512 net/network.a
92 719 39178 drivers/block/block.a
230 2308 87556 drivers/char/char.a
1 1 8 drivers/misc/misc.a
83 721 25680 drivers/net/net.a
1 1 8 drivers/pnp/pnp.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
23 150 7714 /usr/src/smalllinux/lib/lib.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
1865 18879 731233 total
先说明一下,这里的大小和最终的大小有点差别,但大致还是可以做个参考。这边显示
730K 实际上大约在 600K 左右。很显然的,filesystem 相当的大。大约在 230K 左右
,占了 1/3 的体积。记忆体管理占了80K,和核心其它部份的总合差不多。TCP/IP sta
ck 占了 65K,驱动程序占了 120K。SysV IPC 占了 21K,必要的话可以拿掉,核心档应
该可以再小个 10K 左右。 所以如果要减核心大小,应该动那里呢? 答案应该很明显,
当然是档案系统。Linux 的 VFS 减化了档案系统的设计,buffer cache, directory c
ache 增加了系统的效率。但这些对整个系统都在flash 上的 embedded 系统而言根本就
用处不大。如果可以把它们对拿掉,核心可以马上缩小 20K 左右。如果跳过整个 VFS,
直接将档案系统写成一个 driver 的型式,应该可以将 230K 缩减至 50K左右。整个核
心缩到 100K 左右。
从上面的数据来看,ucLinux 所减小的 mm 部份反到省的不多,主要是 mm 除了 virtu
al memory 之外,也要处理 memory allocation 的部份,这部份是省不得的。如果二者
齐做,则 100K 以下的 Linux 核心不是不可能的事。
实践:成功编译196k的核心,但不能用来启动redhat,它太庞大了。280k可以启动,正
在向更小努力。
结束语
论文终于写完了,有必要回顾一下我的毕业设计过程。
对于一个非计算机专业的学生来说,这个课题更具有挑战性。在Linux大行其道的今天,
系统及网管方面的资料随处可见,但内核资料匮乏,让人不知所措。开始只要是Linux的
书籍就看,一个月后觉得视野大开,逐渐明确了方向。搜集翻译资料成了重要内容,有
时通宵在网上找资料,再在系统上不断检验。论文核心------编译流程开始就得到老师
指导,配置内核21大项数百个知识点可以说是一条一条积累起来的,让我很有成就感。
论文除了详细叙述怎么做,也说明了原因,甚至还有附录。我在突出重点的同时,又联
系了我课题以外的内容------嵌入式Linux操作系统,因为我知道我的课题是综合课题-
----设计具有嵌入式操作系统的器件(理论)------的前期工作。