Linux Boot Process 分析与研究

本文详细介绍了Linux系统的启动过程,从BIOS自检到MBR加载GRUB,再到内核初始化和根文件系统的加载。通过分析关键阶段,如bootsect.S模块的作用及setup.S的执行流程,揭示了Linux快速启动的秘密。
摘要由CSDN通过智能技术生成

pre { font-family: "Times New Roman"; }p { margin-bottom: 0.08in; }

			Linux Boot Process 分析与研究
                         作者: 钱国正 (淮阴师范学院)
   对于linux的研究正在紧锣密鼓的进行着,源于对系统启动的兴趣,开始对其启动过程全面的分析,建立在以前玩过Linux的基础上,知道Linux启动时有GRUB可以选择想要启动的系统,开始进行启动深入剖析。大家不要担心,即使您对计算机的启动过程一无所知也可以看下面的文章。
   当我们按下开机电源按钮的时候,系统就在启动的过程中了,相信使用过Windows的人或多或少的都对其启动速度有些意见,但是对它的启动过程却一无所知,这就让人很郁闷,呵呵,不急,下面进入正文。所有的计算机开机时都会有BIOS(Basic Input and Output System)对计算机进行自检,如内存测试等,并对本地设备进行枚举和初始化工作,接下来搜索BIOS中设置的处于活动状态并且可以引导的启动设备。通常情况下,Linux系统是从硬盘(也可以从CD,DVD,USB等)引导的,硬盘的引导扇区在每个分区中都存在,但是主引导扇区只有一个并位于第一个物理扇区。主引导扇区包含主引导记录(MBR)和硬盘分区表(DPT)。硬盘的主引导扇区中包含了主引导记录(MBR)的引导加载程序。此时BIOS将控制权交给MBR。Windows操作系统在这一步与Linux相同。
   主引导扇区大小为512B,包含MBR程序代码,分区表DPT(64KB)以及结束标志(AA55)。MBR中包含了关于GRUB(或者早期的LILO)信息。MBR加载并执行GRUB(Grand Unified Bootloader) boot loader。下面的事情就由GRUB boot loader来控制执行了。
   在Windows中MBR直接引导Windows操作系统,如果有两个版本的Windows系统,要先安装低版本的,否则只能进入一个操作系统!简单的说就是,Windows只认自己人,别的都不认,足见其霸道之处,所以如果要安装双系统如Windows和Linux要先安装Windows,然后安装Linux系统。现在回到GRUB,GRUB加载后基本上就完成了大部分工作了。BIOS与MBR都是硬件上的东东,咱不太熟悉,到了GRUB咱就可以对其代码进行分析了,由于篇幅限制,这里就不赘述了,其源代码大家可以到www.sourceforge.org下载。GRUB的工作是显示一个启动画面,如果你不输入或者选择,它将启动默认选择的操作系统(Ubuntu中如果想修改启动选项可以修改/boot/grub/grub.cfg,慎用!!!),其还可以识别文件系统,下面'Ubuntu, with Linux 2.6.32-27-generic'是系统启动所显示的默认选项
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Ubuntu, with Linux 2.6.32-27-generic' --class ubuntu --class gnu-linux --class gnu --class os {
        recordfail
        insmod ext2
        set root='(hd0,10)'
        search --no-floppy --fs-uuid --set e36d89d9-ad79-467d-8acf-fadef717c6b7
        linux   /boot/vmlinuz-2.6.32-27-generic root=UUID=e36d89d9-ad79-467d-8acf-fadef717c6b7 ro  splash vga=758  quiet splash
        initrd  /boot/initrd.img-2.6.32-27-generic
}
。由于咱侧重的是Linux的启动过程,下面介绍下Linux下的一个被成组自举引导的程序(bootsect-loader),在Linux源码树中的arch/i386/boot/bootsect.S,其为CPU实模式下的汇编程序,为了方便分析,对其源码进行简单介绍。
SETUPSECTS=4               //安装时的缺省值
BOOTSEG   =0x07C0          //引导时的原始地址
INITSEC   =DEF_INITSEG     //移动引导程序
SETUPSEG  =DEF_SETUPSEG    //从这里开始安装
SYSSEG    =DEF_SYSSEG      //系统装载
SYSSIZE   =DEF_SYSSIZE     //系统大小

在include/asm-i386/boot.h中的宏定义

#define DEF_INITSEG    0x9000
#define DEF_SYSSEG     0x1000
#define DEF_SETUPSEG   0x9020
#define DEF_SYSSIZE    0x7F00

以下这段初学者可以略过(摘自《Linux系统分析与实践》)!

    bootsect.S在内核编译时生成bootsect模块,在整个内核镜像文件的最前面。当计算机启动时先进入实模式,首先执行位于0xffff0这个地址的程序代码,这个地址实际上是映射到计算机ROM BIOS地址,也就是说首先执行BIOS的代码,执行某些检测,在地址0x0000位置设置中断向量表,并把第一个扇区读入到内存绝对地址0x7c00这个位置。bootsect的代码就位于第一扇区,所以跳到这个位置执行。bootsect将自己移动到0x90000,并把setup模块搬运到0x90200这个位置,bootsect执行完后,执行setup模块。在setup执行过程中,完成必要设置,并把system搬移到0x10000这个位置。但system前面的head部分执行完毕后,然后把system搬运到0x0000的地址以后,system模块中代码地址就等于物理地址,这样便于对内核操作,之所以不在开始的时候直接把system模块搬运到0x0000的位置是因为,当setup模块没有执行完毕的时候,0x0000这个位置还存放这BIOS的信息和一些中断向量表。如果开始就搬运就会把这些内容覆盖掉而出错。
    setup.S的主要功能就是将系统参数(包括内存、磁盘等,由BIOS返回)复制到0x90000~0x901FF内存中。这个位置原本是bootsect.S被存放的位置,这时它将被系统参数覆盖。以后这些参数将由保护模式下的代码来读取。除此之外,setup.S还将video.S中的代码包含进来,检测和设置显示器和显示模式。最后,setup.S将系统转换到保护模式,并跳转到0x100000的内核引导代码,Bootloader将控制权移交系统内核。
    Kernel负责加载根文件系统,执行/sbin/init中的程序,以及一些驱动程序。其由head.S开始执行初始地址为0x100000,主要完成一些初始化工作,清除BSS,复制启动参数,初始化寄存器,初始化GDT和IDT等,然后执行start_kernel()。
    Init为Linux的核心线程,完成外设的初始化工作,包括SMP(),以及调用do_basic_setup()完成外设及驱动的加在和初始化。
    至此,Linux已经启动完毕,虽然写了这么多,但是其速度快的惊人阿,只有不到30秒的时间,哈哈,快的可以达到10多秒,比Windows可好多啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钱国正

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值