一、i386的linux操作系统启动过程
bios上电自检——>加载中断向量到内存低1024个字节单元中——>执行int 19H软中断向量调用,加载并启动保存在硬盘MBR中的引导程序,装有系统盘的MBR最后的标志是55AAH,MBR引导程序加载并启动保存在活动分区PBR中的引导程序——>bios加载内核和initrd(由bootload初始化的内存盘,在linux内核启动前,bootload会将存储介质中的initrd文件加载到内存,内核启动时会在访问真正的根文件系统前访问该内存中的initrd文件系统)——>跳转执行内核(内核头部有自解压程序)——>执行initrd——>加载文件系统,启动第一个进程init。当然,如果我们在编译内核时,直接把SCSI、EXT3等编译进内核,则可以不用设置initrd。否则,initrd是必须的,不然在启动过程中会提示“VFS:unable to mounting root fs”。
另外,对于多操作系统,实际上是多内核的操作系统,比如本文将要加装2.6内核的情况下,启动过程略有不同。即在时,是借助grub来进行多个内核选择的。使用BootLoader等软件置换MBR中的引导程序或PBR中的引导程序,如Windows的NTBoot Loader,Linux下的Lilo、Grub等。Windows NTBoot Loader一般用于在一台机器上安装多个Windows系统;Lilo或Grub用于在一台机器上安装多个Linux系统或同时安装Linux和Windows系统。本机中通过修改grub.conf来置换PBR中的引导程序。
二、加装内核
1、相关工具制作安装
由于2.6内核的内核模块处理过程有所改变,因此linux 2.4内核下的modutils工具包已经不再适合linux 2.6内核。需要下载较新版本的module-init-tools和modutils。比如module-init-tools-3.2.2.tar.bz2和modutils-2.4.5-1.src.rpm
地址:
http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/
http://www.kernel.org/pub/linux/utils/kernel/modutils/v2.4/
安装modutils——由于下载的是源码包,所以得先生成modutils rpm包,再安装
#rpm -e --nodeps modutils (强行卸载原有的modutils RPM包)
#mv modutils-2.4.5-1.src.rpm /usr/src/redhat/ (把源代码包移到/usr/src/redhat目录下)
#cd /usr/src/redhat/SPECS (进入规范文件目录下)
#rmpbuild --bb modutils.spec (生成二进制的rpm包)
#cd ../RPMS/i386 (转入刚生成的二进制的RPM包所在位置)
#rpm -ivh modutils*.rpm (安装生成的modutils-2.4.5-1.i386.rpm和modutils-debuginfo-2.4.5-1.i386.rpm二进制RPM包)如下
安装module-init-tools,它会替代depmod[/sbin/depmod]和其他工具,运行如下命令:
#tar -jxvf module-init-tools-3.2.2.tar.bz2
#cd module-init-tools-3.2.2
#./configure --prefix=/sbin
#make
#make install
./generate-modprobe.conf /etc/modprobe.conf
由于,我们这里还得制作initrd,所以得安装工具mkinitrd,则需下载较新版本的mkinitrd,而mkinitrd又依赖于程序包device-mapper,而device-mapper又依赖于lvm2,因此需下载lvm2、device-mapper、mkinitrd。
下载地址:
http://down1.chinaunix.net/distfiles/LVM2.2.02.51.tgz
http://down1.chinaunix.net/distfiles/device-mapper.1.02.28.tgz
http://down1.chinaunix.net/distfiles/mkinitrd-4.2.0.3.tar.bz2
它们的安装与安装module-init-tools类似
2、内核相关操作
下载内核
随便点击版本的下载链接,然后在下载工具上改下载源地址
http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.6.15.5.tar.bz2
解压内核
# cp linux-2.6.15.5.tar.bz2 /usr/src
# cd /usr/src
# tar -jxvf linux-2.6.15.5.tar.bz2
# ln -s linux-2.6.15.5 linux-2.6
# cd linux-2.6
编译内核
# make mrproper (该命令可确保源代码目录下没有不正确的.o文件)
# make menuconfig (配置内核各选项)
个重要的配置:
* 关于"Code maturity level options"选项, 一定要选上"Prompt for development and/or incomplete code/drivers"
* 关于"Loadable Module support"选项, 一定要选上"Module unloading"和"Automatic kernel module loading"这两个选项.
* 关于"Processor type and features"选项, 一定要选上"Preemptible Kernel"选项, 这是2.6.x内核优于2.4.x内核的重要原因之一.
* 关于"Device Drivers -->Block Devices"的配置, 一定要选上对"Loopback device support"和"Ramdisk support"的支持.
* 关于"Device Drivers -->Multi-device support(RAID and LVM)", 要选上"Device mapper support".
* 关于"Device Drivers -->Input device support", 记得要选上"Keyboards,Sun XT Newton"和"Mice"的支持.
* 关于"Device Drivers -->Graphics support -->Console display driver support", 要选上对"Framebuffer Console support"的支持.
* 关于"Sound -->Sound card support,Advanced Linux Sound Architecture -->"ALSA, 要选上"OSS API emulation"选项. OSS可以不用了.
* 关于USB, 能选的都选上吧,能*的选*,M的选M
* 文件系统 ,请务必要选中ext3文件系统,
File systems--->
[*] Ext3 journalling file system support
[*] Ext3 Security Labels
[*] JBD (ext3) debugging support
以上三项一定要选上,而且要内建(即标*). 这个非常重要,在配置完后一定要检查一下.config文件有没有"CONFIG_EXT3_FS=y"这一项. 如果不是"CONFIG_EXT3_FS=y"而是"CONFIG_EXT3_FS=m",你在运行内核时就会遇上以下错误: pivotroot: pivot_root(/sysroot,/sysroot/initrd) failed
* 网卡驱动
请务必把自己网卡对应的驱动编译进内核,比较普遍的网卡是realtek 8139,以下就是这种网卡的配置,以供参考
Device Drivers--->
Networking support--->
Ethernet (10 or 100Mbit) --->
<*> Ethernet (10 or 100Mbit)
<*> RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)
<*> RealTek RTL-8139 PCI Fast Ethernet Adapter support
<*> AMD PCInet32 PCI support
* 声卡驱动
也要选择自己声卡对应的驱动编译进内核,比较普遍的声卡是i810_audio,以下就是这种声卡的配置,以供参考
Device Drivers --->
Sound --->
<*> Sound card support
Advanced Linux Sound Architecture --->
<*> Advanced Linux Sound Architecture
<*> Sequencer support
< > Sequencer dummy client
<*> OSS Mixer API
<*> OSS PCM (digital audio) API[*] OSS Sequencer API
<*> RTC Timer support
PCI devices --->
<*> Intel i8x0/MX440, SiS 7012; Ali 5455; NForce Audio; AMD768/8111
Open Sound System --->
< > Open Sound System (DEPRECATED)
*Ramdisk大小
Device Drivers --->Block device->Default Ramdisk的大小应为1024的整数倍。默认值为4096,我们改为12288。
注意,如果用vmware进行编译,那么需要注意一些地方:
如果你在vmware下重新编译内核,硬盘用的是scsi的,以下选项必选:
Device Drivers --->SCSI device support ---> <*> SCSI disk support
Device Drivers --->SCSI device support --->SCSI low-level drivers ---> <*> BusLogic SCSI support
配置部分来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/LUOPING198410/archive/2009/08/24/4480119.aspx
# make dep (建立编译时所需的从属文件。注意:如果内核从未编译过,此步可跳过)
# make clean (清除内核编译的目标文件。注意:如果内核从未编译过,此步可跳过)
# make bzImage (生成gzip压缩的内核bzImage,位于/usr/src/linux-2.6/arch/i386/boot目录)
3、编译内核模块并安装
# make modules (编译内核模块)
# make modules_install (安装内核模块,把内核模块安装/lib/modules/2.6.15.5目录)
4、针对2.6内核和2.4内核的差异,修改脚本和配置文件
# gedit /etc/modules.conf
将"alias scsi hostadapter BusLogic"这行注释掉,
即#alias scsi hostadapter BusLogic
保存 /etc/modules.conf,退出
由于在配置中,找不到"alias scsi hostadapter BusLogic"这行,所以上步可以省略。
#mkdir /sys
#gedit /etc/rc.sysinit
1)找到行"mount -f /proc"在其下面增加内容:
if [ "$KERNELVER" = "2.6" ]; then
mount -f /sys
fi
2)找到行"action $"Mounting proc filesystem: " mount -n -t proc /proc /proc",在其下面增加如下内容:
if [ "$KERNELVER" = "2.6" ]; then
action $"Mounting sysfs filesystem: " mount -n -t sysfs /sys /sys"
fi
3)修改/etc/fstab文件系统列表,在其中增加如下内容:
none /sys sysfs defaults 0 0
4)修改/etc/init.d/halt脚本中的halt_get_remaining函数,将
awk '$2 ~ /^\/$|^\/proc|^\/dev/{next}
改为
awk '$2 ~ /^\/$|^\/proc|^\/sys|^\/dev/{next}
由于内核符号文件/proc/ksyms被命名为/proc/kallsyms,所以必须修改启动脚本/etc/rc.sysinit。在其头部增加如下内容:
UNAME='uname -r'
KERNELVER=${UNAME:0:3}
if [ "$KERNELVER" = "2.6" ]; then
KSYMS=/proc/kallsyms
else
KSYMS=/proc/ksyms
fi
然后,把rc.sysinit文件中所有出现/proc/ksyms的地方都换成$KSYMS变量引用(用gedit打开文件有查找、替换功能)
Linux 2.6的USB驱动模块被改名了,在主机控制器方面,usb-ohci被改为ochi-hcd,usb-uhci被改为uhci-hcd。因此,需在/etc/modprobe.conf配置文件中进行相应修改(我在本次操作中发现没有此配置文件,故此不省略)
此外,支持USB键盘的模块名称也从keybdev改为usbkbd,支持USB鼠标的模块名称也从mousedev改为submouse,故修改启动脚本文件/etc/rc.sysinit:
UNAME='uname -r'
KERNELVER=${UNAME:0:3}
if [ "$KERNELVER" = "2.6" ]; then
KSYMS=/proc/kallsyms
KEYBDEV_NAME=usbkdb
MOUSEDEV_NAME=usbmouse
else
KSYMS=/proc/ksyms
KEYBDEV_NAME=keybdev
MOUSEDEV_NAME=mousedev
fi
然后把/etc/rc.sysinit脚本中出现keybdev和mousedev的地方都改为$KEYBDEV_NAME和$MOUSEDEV_NAME。
接着,修改脚本/etc/rc.sysinit中的如下内容:
needusbstorage=
if [ $usb = "1" ]; then
needusbstorage=`LC_ALL=C grep -e "^I.*Cls=08" /proc/bus/usb/devices 2>/dev/null`
LC_ALL=C grep 'hid' /proc/bus/usb/drivers || action $"Initializing USB HID interface: " modprobe hid 2> /dev/null
fi
action $"Initializing USB keyboard: " modprobe $KEYBDEV_NAME 2> /dev/null
action $"Initializing USB mouse: " modprobe $MOUSEDEV_NAME 2> /dev/null
fi
改为:
needusbstorage=
if [ $usb = "1" ]; then
if [ "$KERNELVER" = "2.6" ]; then
needusbstorage=`LC_ALL=C grep -e "^I.*Cls=08" /sys/bus/usb/devices 2>/dev/null`
LC_ALL=C grep 'hid' /sys/bus/usb/drivers || action $"Initializing USB HID interface: " modprobe hid 2> /dev/null
else
needusbstorage=`LC_ALL=C grep -e "^I.*Cls=08" /proc/bus/usb/devices 2>/dev/null`
LC_ALL=C grep 'hid' /proc/bus/usb/drivers || action $"Initializing USB HID interface: " modprobe hid 2> /dev/null
fi
action $"Initializing USB keyboard: " modprobe $KEYBDEV_NAME 2> /dev/null
action $"Initializing USB mouse: " modprobe $MOUSEDEV_NAME 2> /dev/null
fi
5、安装内核
# grub-install /dev/sda
# make install
make install主要完成如下几个工作:
复制生成的内核映像和内核符号表到/boot目录。在内核编译完成后,源码目录arch/i386/boot/中会生成bzImage文件,该文件被复制到/boot目录并重命名为vmlinuz-2.6.15.5。同时会在/linux-2.6/中生成内核符号表,该文件被复制到/boot目录并重命名为System.map-2.6.15.5。然后在/boot/目录下建立软连接文件vmlinuz和System.map,分别连接到vmlinuz-2.6.15.5和System.map-2.6.15.5。
在/boot/目录下生成initrd-2.6.15.5.img.
配置引导程序grub
注意,配置引导程序在/boot/grub/grub.conf文件中配置,千万不要把kernel /vmlinux-2.6.0 项后面的" ro root=LABEL=/" 改成"ro root=/dev/sda1",否则等你启用新内核时机器就会当掉,出错信息如下:kernel panic : no init found ,try passing init = option to kernel......或者是:kernel panic:VFS:Unable to mount root fs on unknown-block(0,0)。如果你是ext3文件系统,则在定制内核配置文件时把对Ext3、Ext2文件的支持直接编译进内核,否则,等你启用新内核时机器就会当掉,出错信息如下:kernel panic : no init found ,try passing init = option to kernel......或者是:kernel panic:VFS:Unable to mount root fs on unknown-block(0,0)。
注意:嵌入式操作系统启动过程则不同。先是开机启动uboot,uboot分两阶段,第二阶段会加载内核,其中在编译时生成的是zImage,通过# mkimage -n 'linux-2.6.25.8' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage.bin bzImage.bin。生成带头文件的压缩内核镜像。所以加载的是bzImage.bin内核。两次解压后,启动内核,并加载文件系统。即uboot——>bzImage——>文件系统(init、开机动画、Qt)。它并不需要initrd-xxx.img和grub等等。