前言:连linux的启动原理都不知道?那怎么对linux进行优化?那么问题来了,究竟linux是怎么启动的,哎!总结吧。
内容:
- 当然是对启动的总结,慢慢来吧!
1)当给电的时候,主板的控制芯片会对CPU进行重置并且等待电压稳定,等电压稳定之后CPU就开始从FFFF0H处开始执行指令,但是这个地方只有一个跳转指令,跳转到真正的BIOS代码处,这时候BIOS就会进行POST加电自检了,加电-CPU-ROM-BIOS-System Clock-DMA-64KB RAM-IRQ-显卡等。
2)BIOS这个时候就是掌权了,BIOS根据预先设定好的,去找对应分区或者硬盘上的MBR(Master Boot Record)。
3)读取并且执行MBR中的bootloader(主流的就是GRUB)
注意:此时的由于没有加载内核所以并没有文件系统,但是GRUB对文件系统敏感的(file-system sensitive)也就是说能够识别常见的文件系统。
4)botloader要加载Kernel了,Kernel会如果要想加载根文件系统就要能够识别硬盘分区等,但是此 时会没有硬盘驱动,那么就要有求于initrd(initial ram disk ),内核会将这个文件解开,作为根 文件系统使用,那么启动必须的一些驱动模块就可以通过initrd来加载。
注意:设计 initrd 的主要目的 目的是让系统的启动分为两个阶段。首先,带有最少但是必要的驱动(这些驱动是在配置内核时选择嵌入方式)的内核启动。然后,其它需要的模块将从 initrd 中根据实际需要加载(使用udev 机制,最重要的根文件系统所在硬盘的控制器接口module)。这样就可以不必将所有的驱动都编译进内核,而根据实际情况有选择地加载。对于启动较慢的设备如 usb 设备等,如果将驱动编译进内核,当内核访问其上的文件系统时,通常设备还没有准备好,就会造成访问失败。所以,通常在 initrd 中加载 usb 驱动,然后休眠几秒钟,带设备初始化完成后,再挂载其中的文件系统。
5)等待必要的驱动安装好之后,Kernel此时已经知道了文件系统,那么此时Kernel就会去呼叫init程序 ,init程序是系统用户空间的第一个程序,其他的程序都是由这个程序生出来的额,init也会去取的run- level等信息。
6) Init执行/etc/rc.d/rc.sysinit文件准备软件执行的作业环境(如一些网络和始终等)
7) Init去执行run-level的各种服务
8) Init执行/etc/rc.d/rc.local档案;
9) Init执行终端的仿真程序mingetty来启动登录程序(login),等待用户的登录。
2. 上面说了一下启动的大概过程,那么有些具体的细节接下来陈述喽。
1)记录一下运行等级吧,这个事很重要的,windows有安全模式能够修复一些由于错误操作的等带来的问题。那么同理linux也有运行级别可以来解决一些问题。
运行级别:
0:halt 这个是很暴力的停机。
1:single user mode ,这个是直接用管理员身份登录,丝毫不需要密码的方式。当然在登录的时候就是grub引导的时候选择运行级别可以用S,s,single等标示。
2:mutil user mode,no NFS 你懂的,有时候由于NFS服务器的原因,导致不能开机啦,这可怎么办,运行级别2是最好的选择。
3:multi user mode,text mode 这个是很标准的运行级别了,很常用。
4:reserved 保留
5:multi user mode,graphic mode 这个是图形界面啦
6:reboot:重启
介绍几个有用的查询命令:
runlevel 这个命令会有两个结果,第一个结果是上次的运行等级,第二个是本次的运行等级。
who –r 同上
查询内核
uname –r
这里补充一下:实际上在哪个运行级别上运行,都是在运行/etc/rc.d/sysinit 之后,然后根据/etc/inittab 中的内容设置默认的运行级别,实质也就是运行了不同的/etc/rc#.d脚本中的K和S而已。/etc/rc#.d知识对应/etc/rc.d/rc#.d的一个符号链接。
如果要是切换运行等级:init # #是对应的等级(init 0关机,init 6重启),过程是如下:(此处拿运行等级3和运行等级5之间切换)
1.先对比/etc/rc3.d和/etc/rc5.d的K和S文件;
2.切换到的等级中如果有多的K则关闭,少的S就打开。
2)linux的bootloader种类;
1.LILO:linux loader(8GB的限制)
2.GRUB:Grand Unified Bootloader
Stage1:第一阶段是为了引导第二阶段,第一阶段就是为了知道第二阶段的文件系统,如何去读取相关的配置文件。/boot下有很多的stage
*_stage1_5:文件系统的解释代码,根据/boot分区(或/boot所在分区)的具体文件系统类型 而异,如:ext3分区的话就是e2fs_stage1_5。在stage1_5没有被加载以前,系统无法识别任何文件系统(但是可以通过BIOS中断方式INT 13h读取磁盘指定扇区的内容)。
Stage2:GRUB的核心,运行的时候会把系统切换到保护模式,设置好C运行环境之后寻找menulist这个是grub.conf的链接文件。如果没有的话就执行一个shell等待我们输入命令。
总结:grub在第一阶段会加载相关的*_stage1_5文件,然后知道相应的文件系统,然后才能够从文件系统/boot中读取到grub.conf文件,后续加载Kernel和initrd等。
3)具体是什么是grup的配置文件?
grup.conf
default=0 # 设定默认启动的title的编号,从0开始编号
timeout=5 # 等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz # grub引导系统时的图片
hiddenmenu # 隐藏菜单
password redhat(这里是明文的密码,在加载操作系统的时候进行密码的验证)
password --md5 $1$HKXJ51$B9Z8A.X//XA.AtzU1.KuG. 这个可以用grub-md5-crypt 生成MD5加密后的密码,然后将加密后的密码放在这个地方就行了。
对于linux来说一个操作系统有几个不同版本的内核,所以一个title就对应一个内核。
title Red Hat Enterprise Linux Server (2.6.18-308.el5) # 内核标题,或操作系统名称,字符串,可自由修改
root (hd0,0) # 内核文件所在的设备;对grub而言,所有类型硬盘一律hd,格式为(hd#,N);hd#, #表示第几个磁盘;最后的N表示对应磁盘的分区;
kernel /vmlinuz-2.6.18-308.el5 ro root=/dev/vol0/root rhgb quiet # 内核文件路径,及传递给内核的参数
initrd /initrd-2.6.18-308.el5.img # ramdisk文件路径
password --md5 $1$HKXJ51$B9Z8A.X//XA.AtzU1.KuG. 加载内核的时候需要输入密码。
title Install Red Hat Enterprise Linux 5
root (hd0,0)
kernel /vmlinuz-5 ks=http://172.16.0.1/workstation.cfg ksdevice=eth0 noipv6
initrd /initrd-5
password --md5 $1$FSUEU/$uhUUc8USBK5QAXc.BfW4m.
4)下面说一下,那么如果grub坏掉怎么办。
1. 如何安装grub的stage1(在没有关机的情况下,grup损坏了,修复的过程,如果重启了,那么只能是用救援模式了)
# grub
grub> root (hd0,0)指定内核所在分区
grub> setup(hd0) 安装
注意这个命令使用完之后一定要sync同步到硬盘上之后再重启,否则只能救援模式了。
2.如果grub损坏怎么办?
grub.conf配置文件损坏之后就会在进入系统的是后进入到grup命令行模式
此时要做的几件事:
1.可以用root (hd#自动补全来探测大概/boot在哪个硬盘分区上,一般的0x83就可能是,但是0x82就不用想了,一般是交换分区。
2.先找到Kernel,initrd,根文件系统在哪里。利用find (hd#,#)/自动补全,查看对应设备分区中是不是有需要的文件。
3.指定Kernel,用Kernel命令 kernel /vm 自动补齐,属性是ro root=根文件系统所在的位置(磁盘分区)。
4.指定initrd,同样可以initrd /in 自动补全就行了。
5.boot引导内核。
注意:如果在引导过程中出现Kernel panic -not syncing:Attempted to kill init问题那么就在Kernel指定的时候添加selinux=0。
但是重启之后就又会出现进去grup命令行的模式。所以要想每次重启之后都能够顺利的引导要修复grub.conf文件。
5) 那么Kernel加载之后又是如何初始化的呢?
Kernel初始化的过程:
1、设备探测
2、驱动初始化(可能会从initrd(initramfs)文件中装载驱动模块)
3、以只读挂载根文件系统;
4、装载第一个进程init(PID:1)
那么init是什么东西?init是在/sbin/init 这个进程最主要就是准备软件执行需要的环 境,init程序都是靠/etc/inittab来规划的。
/etc/inittab这个文件中又涉及很多的脚本,主要有/etc/rc.d/rc.sysinit,这个文件的作用 有很多的作用,主要还是进行环境的准备。
/etc/rc这个主要是给不同执行rc1.d rc2.d等文件系统中文件,rc1.d等这下文件中有很多的 链接文件,这些文件都链接到init中的相应服务脚本,并且要启动的用S表示,后面的数字是说 明启动的顺序。K表示的是要关闭的服务,数字小的先关闭,数字大的则后关闭,同理S的相反。
/etc/rc.local这个文件主要是里面记录的是用户想要开机启动的除了init启动之后额外的启 动项目。
还有一个关于模块的/etc/modprobe.conf这里面记录的硬件所要用到的一些驱动模块。
开机过程中读取的一些服务的参数就是在/etc/sysconf/*下。这下面有哪些文件
例如:authconfig:规范身份认证的机制。
Clock:主机的时区等。
I18n 设定在一些语系方面的使用,
Keyboard&mouse:键盘和鼠标的形式。
Network:可以设定是否要启用网络的等。
这个目录中的文件都是很重要的文件,都是能够在开机的时候要读取到的文件。
6) 核心和核心模块
1.核心:/boot/vmlinuz
核心解压缩需要RAM Disk:/boot/initrd
核心模块:/lib/modules/version/kernel
核心原始码:/usr/src/linux
看一下这里的核心模块。如果我们要加入一个模块的话,我们需要找到驱动的依赖性, /lib/modules/$(uname -r)/modules.dep目录中记载着依赖性。这个目录如何去建立,depmod命令可以做到。
简单介绍一下depmod命令吧,不加任何参数的话,depmod会主动的去分析目前核心的模块,并且重新的写入/lib/modules/$(uname -r)/modules.dep –A参数则会去寻找比modules.dep内还要新的模块,如果有就会更新。
-n:不写入modul.dep,而是将结果输出到屏幕上
-e:显示出母亲已加载的不可执行的模块名称。
例如:如何将一个新的网卡驱动更行到依赖文件中。
先将驱动放入到/lib/modules/$(uname-r)/kernel/drivers/net下
然后执行depmod
注意一下:lsmod就是显示系统中已存在核心中的模块。
Modinfo是查询模块的信息:
-a列出作者名称;
-d:仅列出modules的说明
-l:仅列出授权。
-n:仅列出该模块的详细路径。
2.如何手动加载模块?
Modprobe会主动的去搜寻module.dep的内容,客服依赖性很方便啊。
Insmod则是完全由使用者加载一个完整文件名的模块,并不会去分析依赖性,但是会立即加载。例如:insmod /lib/modules/&(uname -r)/kernel/fs/vfat/vfat.ko
rmmod是移除模块的,-f强制移除,无论是不是在用。-w正在被使用就等待用完之后移除。
这两个命令有一定的问题就是要加上完整的路径和文件名,如果模块有一定的依赖性就无法完成。
所以有一个更好用的命令来处理这个问题。
Modprobe –c 列出目前系统所有的模块!(更详细的代号对应表)
-l 列出所有在/lib/modules/`uname –r`/kernel 当中所有模块的完整文件名。
-f强制加载该模块。
-r 这个类似rmmod
注意核心模块的额外参数设定在/etc/modprobe.conf.
7)/etc/init.d/下的文件。SysV风格
chkconfig –list所有的运行进程
启动优先次序,关闭优先次序
# chkconfig: runlevels SS KK
当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevels表示默认创建为S*开头的链接,-表示没有级别,默认为S*开头的链接;除此之外的级别默认创建为K*开头的链接;
S后面的启动优先级为SS所表示的数字;K后面关闭优先次序为KK所表示的数字;
# description: 用于说明此脚本的简单功能;\, 续行
使用chkconfig - –add service_name 加入到系统服务中,也就是要在对应的rc#.d文件中创建相应的文件。
Chkconfig– -del service_name 就是删除
Chkconfig–level 24 myservice off就是要关闭在2和4运行级别上的服务