Linux开机流程,模块管理与Loader
Table of Contents
1 Linux开机流程
1.1 总体流程
- 加载BIOS的硬件信息并进行自我检测,取得设定的第一个开机设备
- 读取并执行第一个开机设备内的MBR的Boot Loader
- 根据Boot Loader的设定加载内核(Kernel),内核会开始检测硬件,加载驱动程序
- 硬件驱动成功后,内核会调用init程序,init程序取得run level信息
- init 执行 /etc/rc.d/rc.sysinit 文件来准备软件的作业环境(如网络,时区等)
- init 执行 run level 的各个服务的启动(通过shell script的方式)
- init 执行终端仿真程序启动login程序,等待用户登录
1.2 详细过程
- BIOS,Boot Loader与内核载入 开机后系统首先加载BIOS(Basic Input Output System),并通过BIOS程序加载CMOS信息,由CMOS取得 主机的各项硬件配置,如CPU与各个设备沟通频率,开机装置搜索顺序,硬盘大小与类型等。BIOS会指定 开机装置,好从中读取操作系统内核,由于各个操作系统文件系统格式不同,因此需要一个开机管理程序 处理内核加载,这个开机管理程序就是Boot Loader。这个Boot Loader位于开机装置的第一个扇区内, 即MBR(Master Boot Record,主引导记录)。
- Boot Loader作用 每个文件系统都会保留一块启动扇区(Boot sector)给操作系统,用于安装Boot Loader,通常操作系统 都会安装一份Boot Loader到其根目录所在文件系统的Boot sector下。Linux安装时可以选择是否将Boot Loader安装到MBR上,如果安装了,那么MBR和Boot sector上都会保留一份Boot Loader。Windows安装时 没有选择,会在MBR和Boot sector上都会安装Boot Loader。系统只有一个MBR,所以安装多系统时,可能会 被覆盖。
Boot Loader的作用在于
- 提供菜单选择要载入的操作系统
- 载入内核,直接启动操作系统
- 转交其它Boot Loader
Windows的Boot Loader没有转交其它Boot Loader的能力,不能启动Linux所以安装Windows/Linux双系统 时要先安装Windows, 再安装Linux,这样可以用Linux的Boot Loader覆盖Windows的Boot Loader。
注:鸟哥在写此文章时Windows无此能力,现在的Windows 7已经可以了,我安装的双系统就是MBR上装有Windows 的Boot Loader,提供两个菜单,一个是启动Windows,另一个是转交Linux的Boot Loader,选入Linux后,就会进入 Linux的Boot Loader,这时会进入Grub,再次提供选择菜单。
- 加载内核 由Boot Loader开始读取内核后,Linux会将内核解压到内存中,此后内核会检测硬件信息,从BIOS手中接过系统 管理的功能。内核文件在/boot/linuz-xxx/下。另外,Linux内核是可以动态加载内核模块的,这些模块位于 /lib/modules/下。 SATA磁盘的驱动程序就是放在/lib/modules/下,这就有个两难问题,Linux要加载SATA的驱动才能识别磁盘,而要 加载SATA的驱动必须到/lib/modules下才行,可是此时还没有识别磁盘,如何进入/lib/modules呢?Linux使用虚拟 文件系统解决这个问题。虚拟文件系统使用文件/boot/initrd,它可以被Boot Loader加载到内存中,并且仿真一个 根目录,这个仿真的文件系统提供一个程序加载必要的驱动,如USB,SATA,RAID,LVM等。此后内核就会释放虚拟文件 系统,挂载真正的根目录。
- 第一个程序init 内核加载完成后,就会执行第一个程序/sbin/init。由命令ps aux | grep init,可以知道其PID为1。 init的配置文件位于/etc/inittab。 注:Ubuntu中启动由upstart控制,自9.10后不再使用/etc/event.d目录的配置文件,改为/etc/init。 关于Ubuntu的启动,参见:http://wiki.ubuntu.org.cn/%E5%90%AF%E5%8A%A8。 Linux启动过程,有一个非常重要的概念:runlevel。Linux由runlevel决定启动过程使用的不同服务。 下面即是Ubuntu中各个runlevel的含义。
0 系统停机状态 1 单用户或系统维护状态 2~5 多用户状态 6 重新启动
- 用户自定义开机启动程序 可以将要执行的命令写入/etc/init.d/rc.local文件。
另外,有一篇开机过程的文章最近被广泛转载,可以参阅一下:
http://www.ruanyifeng.com/blog/2013/02/booting.html
2 内核与内核模块
目前的内核都有“可读取模块化驱动程序”的功能,如果一个新的硬件,操盘系统不支持,可以:
- 加入此硬件驱动源代码,重新编译内核。
- 将此硬件驱动源代码编译成模块,在开机时加载此模块。
核心模块位于/lib/modules/$(uname -r)/kernel/目录中。 模块之间信赖关系记录在/lib/modules/$(uname -r)/modules.dep。使用depmod命令可以建立此文件。 使用lsmod命令可以列出已经加载的模块。
$ lsmod | head Module Size Used by ip6table_filter 12711 0 ip6_tables 18432 1 ip6table_filter ebtable_nat 12695 0 ebtables 21508 1 ebtable_nat ipt_MASQUERADE 12663 3 iptable_nat 13016 1 nf_nat 24959 2 ipt_MASQUERADE,iptable_nat nf_conntrack_ipv4 19084 4 iptable_nat,nf_nat nf_defrag_ipv4 12649 1 nf_conntrack_ipv4
使用modinfo可以获取模块的描述信息
$ modinfo ip6_tables filename: /lib/modules/3.2.0-37-generic-pae/kernel/net/ipv6/netfilter/ip6_tables.ko description: IPv6 packet filter author: Netfilter Core Team <coreteam@netfilter.org> license: GPL srcversion: 6F5DC4CD82D294A10583CD9 depends: x_tables intree: Y vermagic: 3.2.0-37-generic-pae SMP mod_unload modversions 686
模块加载可以使用modprobe 或者 insmod,前者会分析模块之间信赖关系,推荐用前者 模块移除可以使用modprobe -r 或者 rmmod
3 Boot Loader: Grub
- Boot Loader 两阶段 由于MBR很小,Boot Loader分两个阶段
- Boot Loader主程序,放在MBR中,不含配置文件
- 加载配置文件,这些文件位于/boot/下,如grub的相关配置在/boot/grub中,直接与grub有关的是 /boot/grub/grub.cfg