简单来说,linux的启动流程为:
1,加载BIOS的硬件信息与进行自我测试,并依据设置取得第一个可启动的设备
2,读取并执行第一个启动设备内MBR的boot loader(即grub或者spfdisk等)
3,依据boot loader的设置加载kernel,kernel会开始检测硬件与加载驱动程序
4,在硬件驱动成功后,kernel会主动调用init进程,而init会取得run-level信息
5,init执行/etc/rc.d/rc.sysinit文件来准备软件执行的操作环境(如网络,时区等)
6,init执行run-level的各个服务的启动(script方式)
7,init执行/etc/rc.d/rc.local文件
8,init执行终端机模拟程序mingetty来启动login进程,最后等待用户登录
====多重启动原理====
linux的boot loader主要功能如下:
× 提供菜单:用户可以选择不同的启动选项,这也是多重引导的重要功能!
× 加载内核文件:直接指向可启动程序区段来开始操作系统
× 转交其他loader:将引导装载功能转交给其他loader负责
而windows的boot loader是没有第三个功能,也就是转交功能,所以要先安装windows,再安装linux才行。
====第一个进程init====
先解释下run-level,总共有7各等级:
× 0 – halt(系统直接关机)
× 1 – single user mode(单用户维护模式,用在系统出问题时的维护)
× 2 – Multi-user,without NFS(类似下面的runlevel3,但是没有NFS服务)
× 3 – Full multi-user mode(完整含有网络功能的纯文本模式)
× 4 – unused(系统保留功能)
× 5 – X11(与runlevel3类似,但多了各X Window,图形界面)
× 6 – reboot(重启)
这个init读取的配置文件为/etc/inittab,直接vim打开后查看,里面的内容很简单,不解释。
取得runlevel后,会立即执行/etc/rc.d/rc.sysinit脚本,大致要做的工作是:
1,取得网络环境与主机类型,读取配置文件/etc/sysconfig/network
2,测试与挂载内存设备/proc以及USB设备/sys
3,决定是否启动SELinux
4,启动系统随机数生成器
5,设置终端机console字体
6,设置显示于启动过程中的欢迎界面textbanner
7,设置系统时间clock与时区设置,读取/etc/sysconfig/clock配置文件
8,接口设备检测与Plug and Play即插即用参数测试
9,用户自定义模块加载:用户可以在/etc/sysconfig/modules/*.modules中加入自定义模块,则此时会被加载到系哦中去
10,加载内核相关设置:系统会主动读取/etc/sysctl.conf这个文件的设置值,使得内核功能称为我们想要的样子
11,设置主机名与初始化电源管理模块ACPI
12,初始化软件磁盘阵列:主要是通过/etc/mdadm.conf来设置好的
13,初始化LVM的文件系统功能
14,以fsck检测文件系统,进行filesystem check
15,进行磁盘配额quota的转换(非必要)
16,重新以可读写模式挂载系统磁盘(为了加速开机流程,开始是以只读模式挂载根目录)
17,启动quota功能:所以我们不需要自定义quotaon的操作
18,启动系统伪随机数生成器(pseudo-random)
19,清除启动过程中的临时文件
20,将启动相关信息加载/var/log/dmesg文件中
====启动系统服务====
以runlevel5的例子讲解,在/etc/inittab文件中:
l5:5wait:/etc/rc.d/rc 5
意义是这样的:
× 通过外部第一号参数($1)取得想要执行的脚本目录,即由/etc/rc.d/rc 5 可以取得/etc/rc5.d/这个目录来准备处理相关的脚本程序
× 找到/etc/rc5.d/K??*开头的文件,并进行/etc/rc5.d/K??*stop操作
× 找到/etc/rc5.d/S??*开头的文件,并进行/etc/rc5.d/S??*start的操作
====用户自定义开机启动程序====
就是/etc/rc.d/rc.local这个目录下,只要你把script放到这个里面来,开机就会自动执行
====重要的启动配置文件====
设备与模块对应文件:/etc/modprobe.conf
主配置文件目录:/etc/sysconfig/*:
× authconfig – 身份认证机制
× clock – 设置linux主机的时区
× i18n – 语系的设置,默认会被选择zh_CN.UTF8,命令行模式下,如果日期显示乱码,可以设置LC_TIME为en即可
× keyboard & mouse
× network – 可设置是否启用网络,以及设置主机名还有网关gateway这两个重要信息
× network-scripts/ – 在这里面的文件,主要用于设置网卡。
====内核与内核模块====
内核与内核模块放置的位置:
× 内核 – /boot/vmlinuz 或者是 /boot/vmlinuz-version
× 内核加压缩所需RAMDisk – /boot/initrd 或者是 /boot/initrd-version
× 内核模块:/ib/modules/$(uname -r)/kernel
× 内核源码 – /usr/src/linux 或者 /usr/src/kernels (要安装才有的)
如果内核被顺利加载到系统,那么就会有几个信息被记录下来:
× 内核版本:/proc/version
× 系统内核功能:/proc/sys/kernel
如果想要加入新的硬件,偏偏操作系统不支持,那么需要两步:
1,重新编译内核,计入最新的硬件驱动程序源码
2,将该硬件的驱动程序编译成模块,在启动时候加载该模块
内核模块依赖性:
# depmod [-Ane]
内核模块查看:
# lsmod
查看每一个模块的信息:
# modinfo [-adln] [module-name | filename]
内核模块的加载与删除:
# modprobe [-lcfr] module-name
-c:列出目前系统所有的模块
-l:列出目前在/lib/modules/$(uname -r)/kernel中所有模块完整文件名
-f:强制加载模块
-r:类似rmmod,删除某模块
内核模块的额外参数配置文件:/etc/modprobe.conf
====grub的配置文件====
/boot/grub/menu.lst中的磁盘代号:
第一块 | (hd0)(hd0,0)(hd0,1)… |
第二块 | (hd1)(hd1,0)(hd1,1)… |
第三块 | (hd2)(hd2,0)(hd2,1)… |
====root密码忘记时候的处理====
重启,开机进入grub菜单后,在要进入的菜单上点击e进入详细编辑模式,将光标移动到kernel那一行的末尾,加入空格和single,然后按下enter,再按下b就能进入单人维护模式,直接执行passwd,重建新的密码即可。
而如果/etc/inittab文件出错,跟上面一样,不过是把single修改成init=/bin/bash,让系统不以init进程初始化,然后:
# mount -o remount,rw /
# mount -a
====================END====================
本人博客已搬家,新地址为:http://yidao620c.github.io/