CF卡上的Linux启动过程分析
一个嵌入式linux操作系统可以简单的抽象为,引导程序bootloader、内核vmlinuz、文件系统filesystem。
Bootloader是系统加电后运行的第一段代码,一般它只在启动系统时非常短的时间按内运行。对于linux系统来说,这是至关重要的一步。在系统中,整个bootloader由系统中的bios和u盘中MBR(主引导扇区)的一段代码来共同完成引导任务。这里我们采用grub引导方式。系统先将BIOS检测到的MBR内容读取到RAM中,然后将系统控制权交给grub,最后由grub负责把要引导的操作系统的内核镜像读取到系统RAM中,然后跳转到内核的入口点。
vmlinuz是Linux 内核的镜像文件,可以被引导程序加载,从而启动Linux系统。
initrd的全称是boot loader initialized RAM disk,它是系统启动时所使用的根文件系统映像文件,这个文件系统中包含几个驱动模块,都是系统启动时所必须加载的,另外当我们需要加载其它的模块时,也可以放在其中。
推荐阅读:
- Linux启动流程知多少之迷你系统 http://www.linuxidc.com/Linux/2012-10/71889.htm
- 解说Linux启动流程 http://www.linuxidc.com/Linux/2012-07/64469.htm
- Linux启动系统及故障排除 http://www.linuxidc.com/Linux/2012-10/71816.htm
- Linux启动流程介绍 http://www.linuxidc.com/Linux/2012-09/70564.htm
一、引导程序Grub
机器加电启动后,BIOS开始检测系统参数,如内存的大小,日期和时间,磁盘设备以及这些磁盘设备用来引导的顺序,通常情况下,BIOS都是被配置成首先检查软驱或者光驱,然后再尝试从硬盘引导。如果在这些可移动的设备中,没有找到可引导的介质,那么BIOS通常是转向第一块硬盘最初的几个扇区,寻找用于装载操作系统的指令。装载操作系统的这个程序就是boot loader。
linux里面的bootloader通常是lilo或者grub,从Red Hat Linux 7.2起,GRUB取代LILO成为了默认的启动装载程序。那么启动的时候grub是如何被载入的呢?
grub有几个重要的文件,stage1,stage2,有时候还需要stage1.5。这些文件
一般都在/boot/grub文件夹下面。grub被载入通常包括以下几个步骤:
1、装载基本的引导装载程序(stage1)
stage1很小,只有512字节,
stage1通常位于主引导扇区里面,它的主要功能就是装载第二引导程序(stage2)。这主要是因为在主引导扇区中没有足够的空间用于其它东西, grub中stage2文件的大小是103.9K。
2. 装载第二引导装载程序(stage2)
这第二引导装载程序实际上是引出更高级的功能,以允许用户装载入一个特定的操作系统。在GRUB中,这步是让用户显示一个菜单或是输入命令。
上面还提到了stage1.5这个文件,它的作用是什么呢?在/boot/grub目录下可以看到有fat_stage_1.5 e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系统有关系,有时候基本引导装载程序(stage1)不能识别stage2所在的文件系统分区,那么这时候就需要stage1.5来连接stage1和stage2了.因此对于不同的文件系统就会有不同的是stage1.5。但是对于我们做的grub好像stage1.5并不是很重要,因为我试过了,在没有stage1.5的情况下, 我把stage1安装在格式化为ext3的CF卡中,能够正常引导,并不需要e2fs_stage_1.5或者fat_stage_1.5。
我们的具体做法是把整个CF卡格式化为一个分区,文件系统为ext3格式,然后把stage1、stage2、grub.conf这几个启动的时候必须的文件拷贝到CF卡的指定目录下,然后进入grub使用一些命令将其安装到CF卡上。
二、内核配置
Linux内核所控制的东西非常广,从文件系统格式、程序开放、电源管理到用户的安全性等一大堆的项目,甚至连网络带宽的分配都在其中,由此可知内核的重要性。但是针对我们现在做的系统,在内核配置中我们主要对下面这些选项感兴趣
1、 Loadable module support 对模块的支持,这里面有三项: Enable loadable module support:除非你准备把所有需要的内容都编译到内核里面,否则该项应该是必选的。
Set version information on all module symbols:表示该模块不跟内核一起发布,通常不选。
Kernel module loader:该选项表示内核可以实现模块加载的功能。Kernel程序可以在需要的时候自动调用模块,而在不用该功能的时候自动卸载该模块
2、Processor type and features
在它的下面,同样有很多的选项,但我们只关心Processor family:根据我
们自己的情况选择CPU类型。在我们的故障诊断仪上,经过试验证明选择386、486或586/K5/5x86/6x86/6x86MK都可以,但是选择Pentium-3/Celeron或者Pentium-4不行。
3、General setup
这里是对最普通的一些属性进行设置。这部分内容非常多,一般使用缺省设置就可以了。但是必须选上,因为里面有PCI总线支持,电源管理模式等的支持。
4、Block devices
在它的选项下,我们一定要选的是: RAM disk support:。
(65536)default ramdisk size Initial ramdisk(initrd)support
因为我们做的就是ram disk,所以我们必须把这些都选上,内核不支持的话在内核启动完后是不能加载根文件系统的。其中的65536K是我们在内存中开辟的根文件系统空间。这里就是64M,我们可以根据我们的需要进行调整。
5、Character devices
一些字符设备的支持,例如鼠标,虚拟终端的支持等,使用缺省的就可以了。 6、Filesystem
在这里主要是要把ext3文件支持,/proc文件系统支持选上,一般默认即可。因为我们在后面做出的文件系统镜像是ext3格式的,所以内核必须对此文件格式支持。/proc文件系统是linux提供给用户和系统进行交互的通道,也要选上。
另外second extended fs support是标准的linux文件系统,建议编译进内核。其它的文件系统类型我们可以根据自己的爱好进行选择。
7、Console drivers
因为我们还没有桌面系统,我们选择的是VGA text console, 如果没有选择这项的话,开机运行到下载内核时就停止了。
另外对于IDE的支持,我们在不选的情况下系统是可以正常启动和工作的。但是我们的系统只是工作在内存中,我们即使把要运行的程序放在其中,关机后什么都没有保留。所以我们要在系统启动起来后重新把CF卡挂载到系统中,然后把程序运行的结果都保存在CF卡上,这样即使关机CF卡上也已经保存了我们程序的运行结果。所以我们在系统中必须加上对IDE的支持。同理,假如我们的系统要支持USB设备时,我们应该在配置选项中选择支持USB和SCSI。也就是添加上usb的驱动。这里选择SCSI的原因是只有支持SCSI时在USB的配置选项中才会出现USB Mass storage support。