ELF格式:是一种可执行文件的群体格式,是一种可执行的、可连接的文件类型。
系统启动:POST——>BIOS——>MBR——>kernel——>initramfs——>(Rootfs)/sbin/init
首先是POST(POST-on Self Test),加电自检的过程是什么?cpu本身啥也不会干,只会执行用户实现编排好的指令,指令在内存中,但是刚开机那一刻,内存中什么也没有,所以就要再cpu的指挥下将某个特殊的硬件设备的内容装载进内存,这个过程就是BIOS。
ROM:不需要加电就能够实现数据保存的,cpu在刚开机的时候就能够实现将ROM中的某些程序映射至RAM中(或者称为将RAM和ROM拼接起来,使CPU能够找到内存空间),由此,cpu就可以读取到ROM中配置好的指令信息.这些指令第一段主要就是完成硬件健康状况检查的.
根据BIOS中的配置信息,BIOS中配置了系统的启动次序(Boot sequence),依次按照启动顺序去寻找那个启动设备的MBR,①MBR中有一个Boot Loader(主引导记录),bootloader主要根据MBR中的分区表查找活动分区,也就是找到操作系统所在的那个分区,并加载那个系统的内核的。当找到bootloader之后,就将控制权交给了bootloader,BIOS基本上就退出了,如果第一个设备上没有MBR,或者MBR中没有bootloader,那就要寻找第二个bootloader,但是如果第一个bootloader损坏了,不会去寻找第二个MBR。②bootloader就要去装载用户选定(双系统)的那个磁盘分区上的操作系统的内核,内核一般也是压缩存放的,将内核加载进内存,在内存中完成解压缩,然后将控制权交给内核,然后bootloader又退出了。③而此时,内核获得了整个系统的控制权,他要识别每一个硬件,而且要让每一个硬件都能工作。通过驱动程序探测硬件是否正常。④启动init进程,所有在用户空间启用的进程都由init进行管理的,除非需要跟硬盘打交道,才从用户空间切换至内核空间。
但是内核启动之前,文件系统并没有装载,内核只是探测硬件是否正常,内核只是从某一个磁盘分区上装载上来的,而这个分区是由bootloader识别的分区,
文件系统是从根开始的,根下有很多一级目录(usr,boot,home),这是文件系统的层次结构,但是有很多目录就可以单独挂载一个分区的,但是有的目录一定是不能关联出去的,因为这些目录与根完成初始化有关的。因为所有的目录都要通过根来访问,根所在的分区通常就是kernel能够完成进入用户空间的最核心的位置,所以根所在的分区称为根文件系统(rootfs),像/bin,/sbin这些目录下的二进制程序,是系统启动就要用到的,所以不能独立分区的,像/usr和操作系统启动没有关系,可以独立分区,所以/usr这个目录本身要在根所在的分区下,但是它下边的文件就可以在其他分区上。
所有的访问都要通过根文件系统作为入口进行访问
那么去哪找根?
去根所在的那个分区上,那根在什么分区上?我们必须告诉内核,根在哪,也就是root=。。。但是现在如果内核驱动不了这个分区,他就不能挂载rootfs,那就意味着内核必须能够通过驱动程序探测并访问那个分区,但是每个用户用的硬盘可能都不同,那么光加载驱动都需要好的M。
所以内核有两种设计风格:一种是单内核结构,将所有功能(文件系统、进程管理、内存管理、网络管理、驱动程序)做进内核中,第二种是微内核结构,将所有功能作为子系统,需要用到那个子系统,由内核负责调度子系统使其工作起来。微内核更安全,因为某一个子系统坏了并不会影响其他子系统,但是单内核工作方式更加简单,微内核工作起来子系统之间的协调很复杂。但是单内核在设计上却有着微内核的优势,却避免了单内核的劣势。Linux属于单内核的,对多线程的支持并不是很好,在Linux中线程称为轻量级进程(LWP);windows、Solaris属于微内核,在根本上来讲支持是多线程的。
但是虽然Linux在制作的时候解压出来的文件非常大,但并非每个功能我们都需要,比如:Linux为了支持更多的平台,内置了很多架构支持(ARM:手机的Android底层就是Linux,只不过这个Linux运行在ARM机构上的,现在的手持终端机属于ARM架构的,省电、X86:PC机、PowerPC:苹果),但是运行在我们平台上只要一种就够了。所以内核在设计上采用了模块化设计,不管是RedHat、SUSE、Fedora,内核可以有核心(ko)和模块,内核的核心做的很小,但是这个核心上布满了孔,任何一个模块在使用的时候,装载进相应的位置就可以了,这就是内核的动态加载。
在RedHat系列的系统上,内核模块在/lib/modules/内核版本号,而且系统上可以有多个内核共存的,在该目录下都有一个与内核版本号相同的目录,但是好多模块都是由依赖关系的,insert命令可以装载指定的内核模块文件,但无法自动解决模块间的依赖关系,modprobe命令可以自动识别和解决依赖关系。
so(share object):共享对象,在用户空间中的那些进程所用到的共享模块。
vmlinuz:这是内核名称。
[root@localhost ~]# cd /lib/modules/3.10.0-693.el7.x86_64/kernel/
arch:跟平台相关的,驱动CPU等的
arypto:加密相关的
drivers:驱动(下边还有一个net目录,才是网卡驱动)
fs:文件系统
kernel:内核
lib:库
mm:内存管理
net:网络管理
sound:声卡
.map结尾的是映射表文件
内核要想访问一个目录,都要先装载根文件系统,但是根文件系统在一个设备上,要想访问这个设备,就要驱动这个设备,但是驱动这个设备的驱动程序在/lib/modules下(也就是在这个设备上),就尴尬了。。。
所以妥协,找个中间人,在内核和访问的设备中间加一个中间人,这个中间人就是向内核提供该设备的驱动,这个文件是安装系统后来生成的。利用一些脚本或者程序动态生成内核需要访问这个设备所需要的驱动程序。
那内核又怎么访问这个中间人呢?
内核访问任何文件都必须通过文件系统来访问,所以这个中间人要是一个文件系统,而且文件系统要有根,所以这个中间人就是一个根文件系统。这个根是虚根,也就是切换根过程。
这个切根过程会将有的文件直接从虚根搬运到实根上边,例如/proc(内核映射文件)/sys、/dev。
切根过程:随便建一个目录就可以当作根来用,根下必须要有一个/bin/bash文件,使用chroot切换过去发现报错,因为bash还要依赖很多库文件才能运行,使用命令ldd /bin/bash可以查看该文件依赖于那些库文件。
Linux是有运行级别的,启动级别的区别的核心就是运行的服务不同。6以前的系统启动级别的配置文件是/etc/inittab,7的运行级别都在/lib/systemd/system下,将某个启动文件的级别软连接到/etc/systemd/system/default.target即可修改系统运行级别,或者通过systemctl set-default multi-user.target修改系统运行级别。
如果没有安装Xwindows服务,将系统级别修改为5,系统也可以按照命令行模式正常启动。
0:关机
1:单用户模式,直接以管理员身份登陆系统,密码都不需要。
2:多用户模式,不启用NFS。
3:多用户模式。(默认)
4:保留
5:X windows
6:重启
bootloader(MBR):微软只引导自己的,不引导别人的。如果先装的linux,在安装的windows,windows将直接覆盖Linux的MBR。更可恶的是,win8之后,windows将直接锁定MBR,也就是安了win8之后,并存Linux不可能实现了。windows不引导别人也不允许别人来引导windows。
Linux中常用的bootloader有两种:,一种是LILO(Linux loader),第二个是grub,grub本身也是一个程序,他需要装在MBR中,来引导操作系统的。但是它只有446字节,没办法展示丰富的特性,所以它分了三段:第一段叫做Stage1,他装在了MBR中,第一阶段的主要目的是为了引导第二阶段,Stage2,第二阶段位于跟内核所在的同一个分区的一个目录里边,/boot/grub/。所以第一阶段就要访问这个目录,这个目录是一个基本磁盘分区,是一定能够访问的,但是这个分区上要装文件系统,文件系统可能不一样,所以就还有一个阶段叫Stage1.5:说白了,就是来识别常见的不同类型的文件系统的。
LILO、grub这些常见的引导程序都直接安装在MBR中。
对grub而言,所有类型硬盘都是hd。
内核文件路径和传递给内核参数可在/proc/cmdline文件中。
linux一启动有一个红色的背景图,那个图就是/boot/grub/splash.xpm.gz
为什么在grub配置文件中内核文件写的是/vmlinuz和虚拟文件系统时/initrd,他们两个不应该是boot下嘛?(boot独立分区)
因为在grub启动的时候,文件系统还没有挂载,grub不能通过根作为入口来访问,grub(Stage1.5阶段)可以直接进行访问该分区的该文件。而boot下的内核文件在另外一个分区上,所以对于这个分区而言,这个分区就是根了,所以就是根下的这个文件。虚拟文件系统一样道理。
如果boot没有独立分区:/boot/vmlinuz
dd if=/dev/zero of=/dev/sda(系统所在磁盘) count=1 bs=400(不能超过446)
dd命令可以用来备份磁盘
MBR坏了怎么办?
cpu亲和性:进程运行在一个CPU上有缓存,那么就让他一直运行在这个CPU上
MBR和GPT分区表有什么区别
用Fdisk分GPT
将boot目录下的所有东西全部删除进行修复:
重启电源进入固件,使用光盘启动
选择Troubleshooting(故障排除),然后选择Rescue a CentOS system(修复Centos系统)
选择continue进入
输入chroot /mnt/sysimage切根
挂载光盘mount /dev/sr0 /mnt
rpm安装内核rpm -ivh /mnt/Packages/kernel-3 --force
安装grub:grub2-install /dev/sda
生成grub.cfg文件:grub2-mkconfig -o /boot/grub2/grub.cfg
同步磁盘sync
关机重新在硬盘中启动系统