前言 本文是本系列文章的最后一篇,主要介绍MS-DOS,各类Windows和Linux操作系统的启动过 程,用了这么久的操作系统是该系统地了解一下启动的完整过程。 一、MS-DOS 启动过程 当PC启动时,读取启动盘第一个扇区并执行其中的引导代码。如果发现了DOS 引导扇区, 会将IO.SYS的前三个扇区加载到内存中,并将PC控制权交由IO.SYS(输入输出模块)。 IO.SYS接管计算机控制权执行如下操作: 首先将IO.SYS其他部分内容加载到内存,依此初始化每个缺省设备 接着加载处理MS-DOS内核文件MSDOS.SYS,不过在MS-DOS 7.0中,MSDOS.SYS改 为启动配置文件 再者处理 CONFIG.SYS文件,CONFIG.SYS是重要的配置文件,是可以进行编辑的文本 文件 内容示例: DEVICE=C:\DOS71\ECHO.SYS w/e/l/c/o/m/e .. DEVICE=C:\DOS71\ECHO.SYS c/o/p/y/r/i/g/h/t .. DEVICE=C:\DOS71\HIMEM.SYS ... SHELL=COMMAND.COM /P /E:640 ... SET PATH=C:\DOS71; ..; 注:SHELL行表示SHELL环境使用command.com,启动的工作路径为C:\DOS71,环境 大小是640字节,/p表示这个是父进程,不能够关闭或使用exit退出。更多详细内容请参 考wiki。 根据CONFIG.SYS配置加载相应的SHELL,MS-DOS一般为COMMAND.COM 处理COMMAND.COM时,会调用AUTOEXEC.BAT批处理脚本 AUTOEXEC.BAT里面的命令都是可以SHELL环境下执行的,主要作用是设置一些环境变 量。如键盘,声卡等等。同时也会初始一些低级的系统工具,如磁盘缓存,鼠标驱动, 键盘驱动等。最后显示命令提示符。 二、基于MS-DOS的Windows启动过程 Windows 3.x/95/98/Me 前期引导的由MS-DOS负责。在启动阶段,处理config.sys和执行autoexec.bat 同时会读取配置文件WIN.INI和SYSTEM.INI,并加载相应的虚拟设备驱动(从SYSTEM.INI或者 HKLM\System\CurrentControlSet\Services\VxD)。所有系统配置文件和设备驱动都被加载后,32 位vxd消息服务(Msgsrv32)会启动mprexe.exe,准备用户登录和网络登陆,当用户登陆到Windows 后,系统加载Explorer.exe,进入Windows。 基于MS-DOS的Windows,可以在启动到DOS的命令提示符下,键入win,手工启动Windows。 此时实际上是调用win.com文件。 详细的启动过程见转载的《Win 98系统启动过程全揭密》一文。 http://blog.csdn.net/liwei_cmg/archive/2008/09/15/2931385.aspx 三、基于Win NT 操作系统的启动过程 WIN NT与基于DOS的Windows有显著的不同,其操作系统引导程序为 NTLDR。引导启动过程 如下: x86或x64平台下,计算机以实模式启动并加载NTLDR。NTLDR是一个二进制文件,有两部分 组成,StartUp module 和 OS loader 。StartUp module 的主要任务就是将计算机切换到保护模式。 OS loader 主要包括识别访问IDE硬盘的分区文件系统(如FAT, NTFS等等)的基本功能,如果是 SCSI硬盘,还需要加载Ntbootdd.sys文件,获取相应的SCSI驱动。 引导程序接着读取boot.ini配置文件,并显示用户选择操作系统菜单。如果boot.ini丢失,系统会 缺省选择C:\Windows目录。 这个时候,Windows 2000以及后续版本的ntldr,会去查找hiberfil.sys(休眠文件,与内存等同大 小,是上次操作系统休眠时的内存镜象),将此文件读取并加载内存。 boot.ini文件内容示例: [boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect multi(a)disk(b)rdisk(c)partition(d)这部分内容是关键,是采用ARC命名规则。ARC第一部分用 于标识硬件适配卡(磁盘控制器),即为multi或者scsi选项,这里使用的是multi。multi表示一个非 scsi硬盘或一个由scsi bios访问的scsi硬盘,而scsi则表示一个scsi bios禁止的scsi硬盘。 (a)表示磁盘控制器的序号,从0开始。 disk(b),仅对multi项有意义,表示磁盘控制器的硬盘序号,从0开如。 rdisk(c),仅对scsi项有意义,表示磁盘控制器的硬盘序号,从0开始。 partition(d),表示对应硬盘分区号,从1开始。 注意,当只有一个操作系统选择项时,启动菜单不会显示。用户选择操作系统,如果不是基 于NT的操作系统,NTLDR会读取bootsect.dos,并交付计算机的控制权。如果选择的是基于NT 的操作系统,接下来NTLDR会执行ntdetect.com,收集硬件信息。此时,NTLDR清屏并显示 Windows启动进度条,这时如果按下F8,会显示高级启动菜单,包括安全模式选项。 收集完所有相关硬件信息后,接着启动NToskrnl.exe(NT 操作系统内核文件), 并读取加载硬 件抽象层文件(hal.dll)。如果有文件丢失,系统会提示 "Windows could not start because the following file was missing or corrupt",并终止启动。这时系统控制权交由内核,显示Windows Logo。 加载内核时,启动的硬件设备信息保存在 HKLM\SYSTEM,可以看到一系列键值组成Control Set, 如ControlSet001,ControlSet003,ControlSet004,CurrentControlSet等。Windows使用CurrentControlSet 读取存取当前信息。Windows在启动过程中使用HKLM\SYSTEM\Select确定对应的键值。 Default NTLDR的默认选择,Failed 值如果等于 Default值,NTLDR会显示错误信息,并提示 菜单是否以最后一次正确配置信息启动(LastKnownGood),如果用户选择LastKnownGood,Default 值也被修改为LastKnownGood的值。 内核启动过程: ntoskrnl.exe 内核 hal.dll 硬件抽象层 kdcom.dll 内核调试扩展dll bootvid.dll windows logo 以及进度条显示 配置信息注册表位置 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute 以相应顺序 HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder 启动服务,这 时会显示进度条,Windows 2000以前版本进度条能反映服务加载,Server 2003和XP则是意 思一下,服务加载是异步的。 所有的设备驱动加载好了以后,NToskrnl.exe启动Session Manager Subsystem (smss.exe)。 在所有文件打开之前,smss.exe启动Autochk。Autochk 挂载(mount)所有的驱动,检查是否正常, 上一次关闭是否彻底,否则会启动chkdsk进行扫描修复,即我们常见的Check Disk。Session Manager Subsystem 配置信息位置:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager。 启动时,smss.exe处理过程: 创建环境变量 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment 启动内核态Win32子系统(win32k.sys),允许windows切换到图形化 启动用户态Win32子系统Client/Server Runtime Server Subsystem (csrss.exe) 创建虚拟内存页 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management 启动winlogon.exe, 加裁 Graphical Identification And Authentication (GINA) ,提供用户登录支持 Winlogon启动过程: Winlogon 调用 GINA ,出现登录提示框,用户输入用户名密码 Winlogon 启动 Local Security Authority Subsystem Service (lsass.exe) 验证登录 Winlogon 启动 Service Control Manager (SCM) ,SCM依此启动设置为自动启动的服务 Winlogon之后的阶段就是用户登录阶段了。 用户登录阶段: 更新Control Sets的LastKnownGood 用户计算机的组策略被应用 启动如下位置的应用 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Run HKCU\Software\Microsoft\Windows\CurrentVersion\Run HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce All Users ProfilePath\Start Menu\Programs\Startup\ Current User ProfilePath\Start Menu\Programs\Startup\ Windows NT format 命令会将 Volume Boot Record 写入磁盘,主要是为了运行 NTLDR 程序。 在 Windows Vista 和 Windows Server 2008,NTLDR 不在使用,其被 winload.exe 和 Windows Boot Manager 所替代。 四、Windows Vista 启动过程 Wiki 关于 Vista 的启动预览: Bios > Master Boot Record > Boot Sector > Windows Boot Manager > Read from BCD > Search for hibernation file > Start winload.exe > Start ntoskrnl.exe > Start smss.exe > Start winlogon.exe > start services and login interface Vista 启动过程与 NT 内核的操作系统稍有区别。Boot Sector 加载的是 Windows Boot Manager (Bootmgr.) ,然后读取 Boot Configuration Data 启动操作系统。在NT 内核Boot Sector 加载 的是NTLDR。 Boot Configuration Data 存储在数据文件中,位置一般存放于系统卷的/boot/bcd下。Boot Configuration Data 可以使用bcdedit.exe进行编辑。 winload.exe是操作系统的引导程序,由Windows Boot Manager调用,与NT下NTLDR功能是等 同的。 五、Linux 启动过程 很容易发现,计算机启动的控制权都是如下变化,BIOS->Boot Loader->Kernel。Linux也不例外。 之前的文章《Linux手机DIY.内核初探.系统后台启动简单介绍》http://blog.csdn.net/liwei_cmg/archive/2006/11/28/1418109.aspx 也曾对Linux启动作过介绍,不过偏重于手机嵌入式的实际代码,这里我想只就理论体系去简单说明。 要理解内核启动的具体详细过程,就需要对内核源码有全面的认识,目前自感缺乏这方面的知识。 启动概览: 机器加电启动 BIOS 引导阶段 Boot loader stage 1 (MBR) Boot loader stage 2 (LILO, GRUB ...) 启动内核 (linux) 初始化 INIT (用户) Boot loader 阶段: 系统实模式下执行引导扇区代码,部分加载引导程序(Boot loader)后,将控制权交给引导程序。 Linux引导程序通常为lilo和grub。接着引导程序将剩余的内容加载到内存,并准备选择待引导的操 作系统。 <GRUB> Boot loader stage 1,BIOS 读取执行 MBR,然后继续引导 Boot loader stage 2。 Boot loader stage 2,控制权已经在GRUB手中,如果这部分的代码在一个大磁盘驱动器上,还 需要加载Boot loader stage 1.5,其中包括对超过1024柱面和LBA驱动器的支持。Boot loader stage 1.5 可以存放在MBR,也可以存放在分区上。Boot loader stage 2 执行并显示 GRUB 操作系统选择 菜单,也允许修改操作系统环境和参数。GRUB支持访问文件系统,本身的配置文件就是存放在 分区文件系统下,便于调整修改。/boot/grub 目录中包含了 stage1、stage1.5 和 stage2 GRUB 引导加载程序等。 注:《服务器配置实例(一).HP Prolient ML570 服务器》http://blog.csdn.net/liwei_cmg/archive/2007/05/20/1618174.aspx 一文中就介绍了GRUB不能引导的处理方法。 GRUB配置文件/etc/grub.conf,内容示例: # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You do not have a /boot partition. This means that # all kernel and initrd paths are relative to /, eg. # root (hd0,0) # kernel /boot/vmlinuz-version ro root=/dev/sda1 # initrd /boot/initrd-version.img #boot=/dev/sda default=0 timeout=10 splashimage=(hd0,0)/boot/grub/splash.xpm.gz title Red Hat Linux (2.4.20-8) root (hd0,0) kernel /boot/vmlinuz-2.4.20-8 ro root=LABEL=/ initrd /boot/initrd-2.4.20-8.img <LILO> LILO方式是比较古老的方式,不支持文件系统,其引导代码直接存放在MBR区。系统一旦引导 失败后,只能通过软盘启动盘之类的方式加以修复。LILO直接使用裸设备方式读取数据,显示菜单 以便用户选择操作系统,并加以引导。 LILO启动配置文件为/etc/lilo.conf,内容示例: prompt timeout=50 default=linux boot=/dev/sda map=/boot/map install=/boot/boot.b message=/boot/message linear image=/boot/vmlinuz-2.4.20-8 label=linux initrd=/boot/initrd-2.4.20-8.img read-only append="root=LABEL=/" Kernel 内核阶段: 引导程序将Linux内核映象加载到内存中,这个内核映象并不是可执行的内核,是经过压缩 后的内核,通常是一个zImage(小于512K)或者bzImage(大于512K) ,需要调用zlib进行解压缩。 内核加载时会处理一些硬件上的设置,并将内核映象完全解压缩到高位内存区,加载RAM disk, 然后启动内核。 <x86 系列的执行过程> 《Linux手机DIY.内核初探.系统后台启动简单介绍》http://blog.csdn.net/liwei_cmg/archive/2006/11/28/1418109.aspx 一文中虽然介绍的是arm系列的CPU,但从过程来讲是相似的,简单列下调用过程。 arch/i386/boot/head.S start() arch/i386/boot/compress/head.S startup_32() arch/i386/boot/compress/misc.c decompress_kernel() arch/i386/kernel/head.S startup_32() init/main.c start_kernel() init/main.c cpu_idle() pivot_root () 完成解压缩后的 startup_32 () 函数(也称为清除程序或进程 0),会进行内存管理(页表初 始化,内存分页)。然后检测 CPU 的类型以及可选的浮点单元(FPU),最后调用 start_kernel 函数,进入体系结构无关的 Linux 内核部分。其实可以理解为 Linux 内核的 main 函数。 start_kernel () 完成大部分的初始化任务,设置IRQs,内存配置,启动init进程(第一个用户进程), 最后启动空任务cpu_idle()。这时进程调度接管了计算机的控制权,通过启用中断,可以提供多 任务处理能力。 内核启动过程中同时也挂载了 initial RAM disk ("initrd") ,先前已加载,用户系统启动的临时root 文件目录。这使得加载驱动模块时不必要使用物理磁盘或者其他磁盘驱动,减小了内核体积。 内核启动会调用 pivot_root () ,卸载RAM disk,代替它的是真正的磁盘文件系统。RAM disk 使用的内存同时也被回收。 上述工作完成后,启动init进程(通常为/sbin/init)。init是所有进程的父进程,主要任务就是根据 /etc/inittab配置文件创建相应进程。init,inittab相关知识相参考man手册。 六、写在最后 文章的整理颇费时间,回顾整个系列,自感对存储相关的知识作了一次较为全面的梳理,从技术 到物理设备,再到逻辑结构,操作系统,每个知识点都有极为深层的内容。相信大多数人只停留在 皮毛,而这个系列已不在是皮毛,已接触到了皮层。
|