Linux组成

Linux: kernel+rootfs

kernel: 进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能
rootfs:程序和glibc(库)
库:函数集合, function, 调用接口(头文件负责描述)
程序:二进制执行文件

内核设计流派:

  • 单内核(monolithic kernel):Linux
    把所有功能集成于同一个程序
  • 微内核(micro kernel):Windows, Solaris
    每种功能使用一个单独子系统实现

Centos6(5)启动流程1

image

详细过程

  1. 加载BIOS的硬件信息,获取第一个启动设备
  2. 读取第一个启动设备MBR的引导加载程序(grub)的启动信息
  3. 加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备
  4. 核心执行init程序,并获取默认的运行信息
  5. init程序执行/etc/rc.d/rc.sysinit文件
  6. 启动核心的外挂模块
  7. init执行运行的各个批处理文件(scripts)
  8. init执行/etc/rc.d/rc.local
  9. 执行/bin/login程序,等待用户登录
  10. 登录之后开始以Shell控制主机

  11. POST:Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测
    • ROM:BIOS,Basic Input and OutputSystem,保存着有关计算机系统最重要的基本输入输出程序,系统信息设置、 开机加电自检程序和系统启动自举程序等
    • RAM:CMOS互补金属氧化物半导体,保存各项参数的设定按次序查找引导设备,第一个有引导程序的设备为本次启动设备
  12. bootloader: 引导加载器,引导程序
    windows: ntloader,仅是启动OS
    Linux:功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核
    • LILO:LInux LOader :早期的,现在不用了
    • GRUB: GRand Unified Bootloader
      GRUB 0.X: GRUB Legacy, GRUB2

GRUB相关

  1. MBR:第一个扇区
    前446字节 bootloader
    中间64字节 分区表
    最后2字节 55AA
  2. GRUB
    primary boot loader : 1st stage,1.5 stage
    secondary boot loader :2nd stage,分区文件
  3. kernel
    自身初始化:
    探测可识别到的所有硬件设备
    加载最核心的硬件驱动程序(借助于ramdisk或者ramfs加载驱动
    以只读方式挂载根文件系统
    (然后再加载lib下的各种驱动,包括根分区/文件系统驱动等等,重新加载,不再用img中的驱动。当然此过程也是按需加载)
    运行用户空间的第一个应用程序:/sbin/init
    (init会根据它的配置文件进行初始化,比如启动各种服务,并重新RW挂载根/等)

内核相关

  • Linux内核特点:
    支持模块化:.ko(内核对象) kernel object
    如:文件系统,硬件驱动,网络协议等
    支持内核模块的动态装载和卸载
  • 内核组成部分:
    核心文件:/boot/vmlinuz-VERSION-release
    ramdisk:辅助的伪根系统
    CentOS 5 /boot/initrd-VERSION-release.img
    CentOS 6,7/boot/initramfs-VERSION-release.img
    模块文件:/lib/modules/VERSION-release

ramdisk管理

  • ramdisk:
    内核中的特性之一:使用缓冲和缓存来加速对磁盘上的文件访问,并加载相应的硬件驱动
    ramdisk --> ramfs 提高速度
    CentOS 5 initrd.img
    工具程序:mkinitrd
    CentOS 6,7 initramfs.img
    工具程序:mkinitrd, dracut
  • ramdisk文件的制作:
    (1) mkinitrd命令
    为当前正在使用的内核重新制作ramdisk文件
    mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
    (2) dracut命令
    为当前正在使用的内核重新制作ramdisk文件
    dracut /boot/initramfs-$(uname -r).img $(uname -r)

注意点:

  1. 第一步POST它是属于BIOS里面的一个功能,第一步实际上直接先运行BIOS,然后直接再运行POST。它就是对各种硬件进行检测,如果没有问题就运行下一步,有问题就会报错。任何计算机(包括linux,windows,unix)系统都会运行这一步,它和系统无关。
  2. BIOS里进行的各种设置(比如启动引导的选择)它是通过RAM来进行修改的,它断电即丢失。但平常我们电脑关机了之后开机它仍未丢失只是因为BIOS里面自带电池,会让它不断电。但是如果一台电脑长时间未插电,电池电量耗光,则所有的设置就会丢失乱套。
  3. 引导设备包括硬盘,U盘,光盘,网卡(从网络中下载引导的资源)
  4. GRUB不仅能引导,还能加密等进行其他操作,实质是软件,在linux里面它就是一个软件包(6之前叫grub,7上就grub2)。 GRUB和LILO不仅可以启动linux,还可以启动windows.(它可以装多系统,启动时选择)
  5. GRUB分别存放在了不同的部分,第一部分就在MBR的0扇区(512字节)中的前446字节中。后面的存放在boot目录下的grub(grub2)文件夹中。注意了第一部分的0扇区部分没有文件系统,它不是文件,就是以01方式存储的二进制。因此它的第一阶段446字节并不是文件,后面的第二阶段才是文件保存的。(1.5阶段
  6. GRUB引导之后想要启动什么系统就把控制权交给什么系统的内核。比如linux kernel.
  7. init启动之后会根据它的配置文件进行初始化,启动各种服务(比如ssh等等)而且会将根/重新RW方式挂载
  8. linux内核也是一个包,它集成了各种文件。除了boot下的文件,在etc下还有配置文件,包括一个调用第三方库的配置文件,剩下的就是各种驱动模块在lib/modules
  9. lsmod 可以查看已经加载到内存中的模块文件,由此也可以看出驱动模块是按需加载而非全部加载。只有有需要的时候才会加载它。cat /var/log/messages可以查看相关驱动日志等信息(当然也包括其他的各种信息)。 lsusb可以查看USB设备。
  10. boot下的vmlinuz文件很小,它只存储了最核心的驱动相关等文件。而那些次要的按需加载的驱动模块就存放在了lib/modules/VERSION目录中了(主要就在lib/modules下对应的内核版本VERSION文件夹中的kernel文件夹中)。这样做的好处就是减少了最核心的内核文件(驱动等)的大小,开机加载的时候也不会加载那些按需加载的驱动模块,如果都放在此文件里,不仅文件很大,而且开机加载浪费资源加载很多没有必要的驱动文件。
  11. modinfo MODULE_NAME 命令可查看驱动的相关信息,包括所在位置等。
  12. 因为各种文件系统的驱动模块不在boot下的vmlinuz文件中(按需加载文件系统,不可能都加载),因此开机经过各种步骤之后,将控制权交给内核之后,它检测完硬件设备然后加载驱动模块的时候,必须要知道驱动模块所在的路径,(此时经过grub的1.5阶段已经知道了找到了各种磁盘和挂载对应等)但是想要找磁盘内的文件必须得利用文件系统来寻找(因为分区之后挂载并使用时必须要指定文件系统)。
    • 但是此时因为没有加载根分区文件系统驱动,便无法挂载根分区(虽然磁盘和分区能找到,他们是根据在grub阶段中的分区表64字节来找的,现在已经是内核阶段了,没有文件系统驱动,所以就没办法加载根分区文件系统,便无法挂载),因此也无法找到各种文件系统的驱动模块包括其他各种驱动等(在根下的lib中,更别说后面的挂载根目录等操作了(总结就是要挂载根目录必须要知道它的文件系统才能挂载,然后根据路径找到各种驱动所在的目录才能加载lib下的各种驱动),造成了相互矛盾。
    • 因此此时需要一个伪文件系统,把某些特定的驱动和文件(计算机启动时需要的)放在了initranfs-VERSION.img文件中(老版本命名为initrd),而根分区的文件系统就在这个伪文件系统img的打包文件中,这个伪文件系统在grub启动时会和内核一并被grub加载到内存中,因此此时内核便可以重新挂载根并且进行初始化,启动服务等操作了。
    • 可以用下面的方式打开查看img文件(6中需要先解压,它是gzip格式,7中不用直接就是cpio压缩格式).
Centos6:
 gzip -d -c initramfs-2.6.32-754.el6.x86_64.img >initramfs.img :gzip文件类型,这里如果不用-c的话会显示后缀不对,用-c可直接重定向不用管后缀的问题
 ls
 file initramfs.img  : cpio文件类型
 cpio --help
 cpio -tv < initramfs.img  |less :查看里面的文件
  1. 注意vmlinuz文件是官方编译完成后的的二进制文件,出厂即给出的,在光盘中直接就存在的(isolinux目录中)。而initramfs文件是根据自己的根的文件系统等等其他信息安装操作系统的时候后期临时生成的文件,并非出厂即带的文件。
  2. 其中光盘中的isolinux中的initrd文件是ramdisk方式的虚拟磁盘(包括centos5),因为不管怎样只要使用磁盘中的文件都需要文件系统,因此从6之后开始就直接改为了虚拟文件系统ramfs,不需要再多此一举先虚拟磁盘,然后挂文件系统驱动,然后再找文件。
  3. 不论是哪一种img(ramfs或者rd)文件,如果被破坏,则计算机启动时无法加载驱动模块,则无法挂载根分区便会导致无法启动。

系统启动流程

  1. 系统初始化:
    POST --> BootSequence (BIOS) --> Bootloader(MBR) -->kernel(ramdisk) --> rootfs(只读) --> init(systemd)
  2. init程序的类型:
    • SysV: init, CentOS 5之前
      配置文件:/etc/inittab
    • Upstart: init,CentOS 6
      配置文件:/etc/inittab, /etc/init/*.conf
    • Systemd:systemd, CentOS 7
      配置文件:/usr/lib/systemd/system
      /etc/systemd/system

注意点:

  1. 5 6 7版本的init进程分别来自三个不同的rpm包,5中是redhat所写,6中是ubuntu所写,7中是红帽员工所写。
  2. 5之前版本的/etc/inittab中定义了许多功能,都放在了这个文件中,6中它只有控制开机进入的runlevel功能(其他的功能分散放在了其他位置的文件中),而7中完全不用这个文件了。
  3. 单用户模式只能一个终端一个用户(root)登陆使用,它可以破解root口令。开机的时候按a进入选择模式然后直接输入1(或者S s single) 进入单用户模式即可(centos 6中)。然后此时便可以用passwd命令修改口令或者直接改shadow文件把口令删掉。
  4. cat /etc/rc.d/rc.sysinit:此文件中(5中6中都有)就是开机之后运行的初始化配置脚本
  5. 以5中的/etc/inittab为例, 其中第一行设定好初始runlevel之后,然后设置初始化/etc/rc.d/rc.sysinit脚本,然后按照默认的启动runlevel编号来执行一次性任务/etc/rc.d/rc # 脚本,其中#就是编号。对应编号就会进入到对应/etc/rc#.d/文件夹中执行里面的K*和S*开头的脚本.
    • 这些脚本其实都是软链接,它们指向了真正的服务脚本在/etc/init.d/文件夹中(注意/etc/init.d也是个软链接,它指向/etc/rc.d/init.d文件夹)。只不过这里用K*和S*开头代表在这个模式下以K开头的脚本服务停止服务,而以S开头的脚本中的服务启动服务.(这个配置就写在/etc/rc.d./rc脚本中),只要第一次开机启动或者说用init命令切换模式,就会根据此相对应的模式编号文件夹中的KS软链接来关闭或者启动相对应的守护进程。
    • 在/etc/init.d/文件夹中的脚本 后面加上参数 stop 就相当于停止此服务,start就是启动此服务(正好符合rc脚本中的命令)
    • 注意:在这里K开头和S开头的脚本是按照ls的顺序来一个一个执行的,有些服务具有关联性的要先启动某个服务再启动它就要放到后面的顺序中启动,当然关闭的时候就要放到前面来关闭。也就是说K后面的排序越小,S后面的排序就越大。反之亦然。(注意排序是按照ls的排序,也就是先数字,再字母;字母按照字符串比较大小的方式来排序)
  6. 接上,如果自己要设置并编写启动脚本,放在/etc/init.d/文件夹中,同时在相对应的想要启动和关闭这个服务的/etc/rc#.d/文件夹中设置软链接,但是尽量吧自己的服务K编号写的比较靠前同时把S编号的脚本写的比较靠后用于避免依赖性的问题比较好。
    • 注意了针对同一个脚本服务的软链接文件K和S在一个rc#.d中不可能同时存在,不然K开头的就相当于没用了(先执行K然后S将它覆盖启动了)

ntsysv 和chkconfig 在下面有详细介绍用于更改启动守护进程

  1. service 服务 status , 就相当于 /etc/init.d/服务 status; 这两个命令等价,只是前面的命令避免了再书写服务路径。status,stop,start等等都是服务脚本的参数。
  2. 这些init.d里面的服务被叫做deamon(守护进程),它和终端以及用户无关,开机即可以设置启动或者不启动。
  3. 参考init.d中的文件格式,可以自己书写服务脚本放在init.d文件夹中并加上执行权限。
#!/bin/sh
# chkconfig: 345 99 2   :这一项最前面的数字代表此项服务第一次加入本机的时候在哪些模式下启动(也就是S的模式,没写的就是K,它只在第一次加入服务时有效,后面用chkconfig更改后就无效了),第二个数字代表启动的S编号数字,第三个代表关闭的K编号数字。
:如果所有模式都是S则写上0123456,所有模式都是off写上-(第一位的数字);后面的两个数字是SK的顺序和它无关
# description: testservice   :这一项在5中必须有,在centos6中可以不写了。不过chkconfig在5 6中都必须有。
  • 注意init.d中的脚本不一定都在chgconfig --list中显示出来,有function,还有killall都没有在里面显示,因为它们都不符合格式要求。
  • 因此自己编写的服务脚本一定要符合格式要求才可以。
  1. 如果想要实现自己编写的脚本可以用service 脚本 start|status|stop|restart 等命令,可以参考init中其他脚本所写的方式,也可以自己定义函数然后在自己所写的服务脚本里面引用。则就可以用这种命令的格式了。(service命令就相当于执行init.d里面的脚本,把路径给加上了而已,至于命令参数什么的都得自己在脚本中写)
  2. 写完脚本加上执行权限之后就可以直接“service 脚本名” 的方式来执行脚本了,但是chkconfig列表中仍未显示,用“chkconfig -add 脚本名” 加入服务列表中,它就会按照所写的模式加入。然后可以再用chkconfig [--level 345] 脚本名 on|off 来调整。
  3. 删除的话同理用chkconfig -del 脚本名的方式来删除,这样才能删除干净,把软链接和--list中都去除。此时脚本还保留在init.d目录中,如果不想要了也可以删掉。
  4. 更简单的方式是把想要运行的简单配置或者程序直接写在/etc/rc.d/rc.local文件中即可,它在2345模式中都被S99Local软链接指向。因此它会开机运行所有服务之后自己再运行。

    • Centos6上直接写入此文件中即可,centos7上面因为它没有执行权限,所以必须自己加上执行权限
  5. 注意了,centos6中 /etc/rc.d/文件夹中的才是真正的文件,而/etc/下面也有和etc/rc.d文件夹中一模一样的文件,不过/etc下的文件全部都是软链接,指向/etc/rc.d下的文件(或者文件夹)
  6. 复习知识点:软链接文件夹里面的软链接其实就是这个软连接文件夹对应的原文件夹内的存储的软链接。如果删除掉这个软连接文件夹内的软链接则原始文件夹内的软链接也会被删除。 虽然路径在软连接文件夹内和原文件夹内不相同,但是里面的任何文件包括链接文件其实都是同一个。
  7. service --status-all 可以看到所有的服务(不论运行不运行)的状态,注意和chkconfig --list的区别。
  8. 继续解释/etc/inittab(centos5中为例)的下一行,其中解释了ctrl+alt+delete三个按键的操作结果就是3秒后关机,而在6则不在这个文件中,在/etc/init/control+alt+delete.conf中。这三个键的功能最好注释掉以免错误操作导致系统自动重启(字符界面3模式直接重启,图形界面5模式弹出对话框选择是否重启)
  9. centos5中还有断电关机以及来电取消关机的设置。(非正常断电基本上有UPS电池,它会供电一段时间然后完成必要的工作再关机,如果在这个阶段来电了则取消关机命令)
  10. 接着就是重启6个终端的命令(这也是为何之前kill mingetty命令并不能关掉它的原因,在这里规定了自动重启)。如果想再多开终端,可以继续添加(按ctrl+alt+F1-6,自己添加的话可以更多,其中tty后面的字符代表ctrl+alt后面的FN的数字)
  11. 最后一个是图形界面模式为5,如果改为其他模式则其他模式也可以变成图形模式(注意各种模块rc#.d中的驱动启动情况)。5和3的区别就是在这里,多运行了一个X11协议守护进程。

启动流程2

  • /sbin/init CentOS6之前
    运行级别:为系统运行或维护等目的而设定;0-6:7个级别
    0:关机
    1:单用户模式(root自动登录), single, 维护模式,只能一个终端登陆
    2: 多用户模式,启动网络功能,但不会启动NFS;维护模式
    3:多用户模式,正常模式;文本界面
    4:预留级别;可同3级别
    5:多用户模式,正常模式;图形界面
    6:重启
  • 默认级别:3, 5
  • 切换级别:init #
  • 查看级别:runlevel ; who -r

init初始化(早期版本)

init读取其初始化文件:/etc/inittab
初始运行级别(RUN LEVEL)
系统初始化脚本
对应运行级别的脚本目录
捕获某个关键字顺序
定义UPS电源终端/恢复脚本
在虚拟控制台生成getty
在运行级别5初始化X

CentOS 5 的inittab文件

  • 配置文件:/etc/inittab
  • 每一行格式:
    id:runlevel:action:process
    id:是惟一标识该项的字符序列
    runlevels: 定义了操作所使用的运行级别
    action: 指定了要执行的特定操作

    wait: 切换至此级别运行一次
    respawn:此process终止,就重新启动之
    initdefault:设定默认运行级别;process省略
    sysinit:设定系统初始化方式,后面跟文件表明按照此文件配置进行初始化
    process:定义了要执行的进程

示例:CentOS 5 的inittab文件

id:5:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down”
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled”
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
x:5:respawn:/etc/X11/prefdm -nodaemon

CentOS 6 /etc/inittab和相关文件

  • /etc/inittab
    只设置系统默认的运行级别
    id:3:initdefault:
  • 示例:
    破解CentOS 6 的root口令操作

/etc/init/control-alt-delete.conf
/etc/init/tty.conf
/etc/init/start-ttys.conf
/etc/init/rc.conf
/etc/init/prefdm.conf

  • 启动流程
  • /etc/rc.d/rc.sysinit: 系统初始化脚本
    (1) 设置主机名
    (2) 设置欢迎信息
    (3) 激活udev和selinux
    (4) 挂载/etc/fstab文件中定义的文件系统
    (5) 检测根文件系统,并以读写方式重新挂载根文件系统
    (6) 设置系统时钟
    (7) 激活swap设备
    (8) 根据/etc/sysctl.conf文件设置内核参数
    (9) 激活lvm及software raid设备
    (10) 加载额外设备的驱动程序
    (11) 清理操作

  • 说明:rc N --> 意味着读取/etc/rc.d/rcN.d/
    K*: K##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务
    S*: S##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务

for srv in /etc/rc.d/rcN.d/K; do
$srv stop
done
for srv in /etc/rc.d/rcN.d/S
; do
$srv start
done

启动过程总结centos6(5):

BIOS中POST加电自检-->BIOS选择启动设备(Cmos设置)-->寻找启动设备MBR分区标头以及启动信息bootloader(前446字节)并加载它(grub)-->bootloader(grub)选择指定的内核加载(同时加载initramfs),并移交控制权-->内核结合initramfs.img文件识别文件系统并挂载根目录-->内核加载第一个进程/sbin/init --> init根据配置文件(/etc/inittab)运行rc.sysinit脚本(包括设置默认运行级别、完成系统初始化等等)--> (关闭对应下需要关闭的服务)启动需要启动服务(rc#.d各种开启关闭服务,以及最后的rc.loacl服务脚本) --> 设置登录终端

CentOS 6 init程序为: upstart, 其配置文件:

/etc/inittab, /etc/init/*.conf,配置文件的语法 遵循 upstart配置文件语法格式,和CentOS5不同

利用ntsysv命令可以来控制服务开机启动或者不启动,以及调整启动顺序。不过它默认设置的是当前模式下的服务,星号代表启动,空代表不启动,用空格键设置。可以用ntsysv --level=#(编号)来修改特定模式下的启动服务等

它本质上改的也就是/etc/rc#.d/文件夹中的软链接标志将K和S互换。不过需要注意它必须下次启动才能生效,当前已经启动的不会有影响。

chkconfig命令

ntsysv命令
chkconfig命令

  • 查看服务在所有级别的启动或关闭设定情形:
    chkconfig [--list] [name]
  • 添加:
    SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)
    chkconfig --add name
    #!/bin/bash
    #LLLL 表示初始在哪个级别下启动,-表示都不启动
    chkconfig: LLLL nn nn
  • 删除:
    chkconfig --del name
  • 修改指定的链接类型
    chkconfig [--level levels] name <on|off|reset>
    --level LLLL: 指定要设置的级别;省略时表示2345
    例子: chkconfig atd on :一般都是这样写
  • 注意:chkconfig 服务 on|off ; 代表下次开机启动或者关闭
  • service 服务 start|stop|status 代表当前关闭或者启动 (7中类似用systemctl)

xinetd管理的服务

  • service 命令:手动管理服务
    service 服务 start|stop|restart
    service --status-all
  • 瞬态(Transient)服务被xinetd进程所管理
    进入的请求首先被xinetd代理
    配置文件:/etc/xinetd.conf、 /etc/xinetd.d/<service>
    与libwrap.so文件链接
    用chkconfig控制的服务:
    示例:chkconfig tftp on

超级守护进程xinetd

  1. 比如安装telnet-server服务的时候就会顺便关联这个超级守护进程一并安装。并且在chkconfig --list中可以查看到。如果是off状态,说明xinted无法激活telnet服务也无法关闭它,相当于没有开启监控功能。必须在/etc/xinetd.d/文件夹下的telnet配置文件中修改disabled 为 no之后才可以开启xinetd监护telnet的功能。
    • 当然用chkconfig telnet on|off 也可以直接开启关闭telnet,但这里的开启关闭也是对于xinetd服务来说的开启关闭监听telnet功能,本质上也就相当于更改了上面写的配置文件。
  2. 但此时新装好的xinetd服务并没有开启,需要service xinetd start开启xinetd服务之后才可以真正监听telnet服务。(注意它和1的区别以及chkconfig xinetd on|off的区别
  3. 此时当由用户访问telnet服务的时候它就会开启telnet服务,当没有用户访问的时候就会自动关闭telnet服务。可用ss -ntlp 或者lsof -i :23来查看是否是xinetd服务在监听此23端口。
  4. Centos7中已经用systemd服务来监听了。xinetd就被淘汰使用了(当然也可以用,不过没必要了)

注意点:

  1. 注意BIOS中按照引导设置找到引导设备(硬盘,光盘,U盘,网卡等)之后,然后根据里面的MBR表头的前446字节中的引导信息来进行操作系统的加载引导。这里面目前常用的就是gurb的第一阶段。
  2. 注意了grub是一个引导操作系统的程序,用来启动操作系统,而BIOS也是一个启动引导程序,它包含POST,找到引导硬件等等(详情看其他博客介绍)。BIOS开机就会启动,而后面用不用grub则要看BIOS找到的引导硬件里的引导信息中的bootloader是不是grub程序,注意它俩的区别。
  3. BIOS是和UEFI相对应的,一个16位寻址,一个64位寻址,分别主要用于MBR分区和GPT分区格式的系统引导。 MBR分区格式中,BIOS引导必须将系统装在MBR分区格式的硬盘分区(中,BIOS会找这个硬盘的活动分区(记载了引导程序,也就是ntloader,grub。winloader.exe这种启动程序的分区),然后根据它的设置来启动操作系统。UEFI则是另外的方式,BCD文件夹(windows中用winload.efi)
  4. grub则是和ntloader等引导程序对应的,包含于BIOS下面,属于bootloader,不是和BIOS属于同一个级别的。它在linux中grub作用于MBR分区格式下,作用阶段在BIOS寻找启动设备,然后在硬盘启动(其实其他方式启动用GRUB也是类似这样的MBR过程)的活动分区MBR中找启动信息(前512字节,第一个扇区),它只是用来引导启动操作系统内核,内核启动之后就没它的事情了,就靠内核来运行第一个进程init来进行各种模块驱动等的初始化了。

grub legacy

CentOS 6启动流程:
POST --> Boot Sequence(BIOS) --> Boot Loader --> Kernel(ramdisk) -->rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 系统初始化脚本rc.sysinit --> 关闭或启动对应级别的服务 --> 启动终端
参看:https://s4.51cto.com/wyfs02/M02/87/20/wKiom1fVBELjXsvaAAUkuL83t2Q304.jpg

grub: GRand Unified Bootloader
grub 0.97: grub legacy
grub 2.x: grub2

  • grub legacy:
    stage1: mbr
    stage1_5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统,从而能找到stage2中的grub文件夹以及内核,img文件
    stage2:磁盘分区(/boot/grub/)

grub安装(修复)

安装grub:

(1) grub-install:非交互式
安装grub stage1和stage1_5到/dev/DISK磁盘上,并复制GRUB相关文件到 DIR/boot目录下
命令:grub-install --root-directory=DIR /dev/DISK
(2) grub:交互式
grub> root (hd#,#)
grub> setup (hd#)

grub legacy

  1. 配置文件:/boot/grub/grub.conf <—— /etc/grub.conf
    stage2及内核等通常放置于一个基本磁盘分区

    • 功用:
      (1) 提供启动菜单、并提供交互式接口
      a:内核参数
      e: 编辑模式,用于编辑菜单
      c: 命令模式,交互式接口
      (2) 加载用户选择的内核或操作系统
      允许传递参数给内核
      可隐藏启动菜单
      (3) 为菜单提供了保护机制
      为编辑启动菜单进行认证
      为启用内核或操作系统进行认证
  2. grub的命令行接口
    help: 获取帮助列表
    help KEYWORD: 详细帮助信息
    find (hd#,#)/PATH/TO/SOMEFILE:
    root (hd#,#)
    kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可添加许多内核支持使用的cmdline参数
    例如:max_loop=100 selinux=0 init=/path/to/init
    initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk
    boot: 引导启动选定的内核
  3. cat /proc/cmdline 内核参数
    内核参数文档:/usr/share/doc/kernel-doc-2.6.32/Documentation/kernelparameters.txt

  4. 识别硬盘设备
    (hd#,#)
    hd#: 磁盘编号,用数字表示;从0开始编号
    #: 分区编号,用数字表示; 从0开始编号
    (hd0,0) 第一块硬盘,第一个分区
  5. 手动在grub命令行接口启动系统
    grub> root (hd#,#)
    grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE
    grub> initrd /initramfs-VERSION-RELEASE.img
    grub> boot

grub legacy配置文件

配置文件:/boot/grub/grub.conf
default=#: 设定默认启动的菜单项;落单项(title)编号从0开始
timeout=#:指定菜单项等待选项选择的时长
splashimage=(hd#,#)/PATH/XPM_FILE:菜单背景图片文件路径
password [--md5] STRING: 启动菜单编辑认证
hiddenmenu:隐藏菜单
title TITLE:定义菜单项“标题” , 可出现多次
root (hd#,#):查找stage2及kernel文件所在设备分区;为grub的根
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核
initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件
password [--md5|--encrypted ] STRING: 启动选定的内核或操作系统时进行认证

grub加密

生成grub口令
grub-md5-crypt
grub-crypt

  • 破解root口令:
    启动系统时,设置其运行级别1
  • 进入单用户模式:
    (1) 编辑grub菜单(选定要编辑的title,而后使用a 或 e 命令)
    (2) 在选定的kernel后附加1, s, S,single 都可以
    (3) 在kernel所在行,键入“b” 命令

注意点:

  1. 如果grub1阶段找不到或者错误,BIOS会自动寻找下一个可以启动的硬盘引导设备(按照启动顺序设置一个一个找设备)。
  2. grub-install命令,后面直接跟上想要修复的硬盘或者设备(比如/dev/sda)
    • 注意如果boot文件夹和不在根文件夹下面,也就是说不是boot不是/boot 而是在其他的文件夹下,则要写上boot文件夹所在的上级目录,如果就在根下面则不用写了。这一点别忘了.
    • 更多的详细信息关于--root-directory=DIR直接查看man帮助(6和7不同,7是2代grub,且可以GPT EUFI启动)
  3. 重要注意点1:只有启动设备(比如第一个硬盘/dev/sda)的前446字节才会有bootloader,也就是grub的信息,它会在安装系统的时候自动写上grub的信息。而后面添加的新硬盘的MBR(比如/dev/sdb,sdc等)则前面446字节为0,只有后面64字节有分区信息。
    • 当然可以装多个grub,一个硬盘装一个,则这每一个硬盘都能够作为启动设备来使用并启动计算机。
  4. 重要注意点2:grub的作用只是引导启动操作系统内核,启动完内核它便会移交控制权,结束本身的工作。同时根据3中可以看出,如果硬盘MBR前446字节错误,只是说它不能作为启动引导设备,但是它的硬盘分区表64字节如果并未损害,仍然可以被识别分区并且挂载(挂载前里面的各个分区要有文件系统),注意分区表和bootloader的区别。
    • 因此,在光盘救援模式下,只要系统通过光盘引导并加载到内存中启动了一个小型LINUX系统,则损坏了446字节但64字节分区表没被损坏的硬盘就相当于3中后加的硬盘一样,直接挂载使用即可(然后就可以用光盘对其进行grub的安装和修复)
  5. 交互式安装grub时候,指定grub所需要的恢复文件的boot所在的目录位置时,root(hd#,#),第一个代表硬盘,第二个代表此硬盘内的哪个分区。一般boot单独分离出来挂载一个分区的时候(系统安装时)会自动把它排在硬盘第一个分区。因此/dev/sda1 (boot的挂载目录),就是root(hd0,0)
    • 注意这个交互式安装时是按照/boot 所在的目录的stage1 1.5 2等备份文件来进行恢复的,如果没有这些备份文件则不能用交互式。
    • 交互式内还可以输入一些其他命令,比如help查看帮助
    • setup(hd0)指定安装MBR446字节的硬盘位置。由此可见/boot文件夹和启动设备硬盘可以不在一个硬盘上,也就是这个硬盘只用来引导启动而另外一个硬盘装内核和grunstage2来启动系统。
  6. 重要注意点3:注意grub操作完毕的时候要用sync命令(多输入几次)让命令从缓冲区写入磁盘中,以免并没有保存。(也可以重新挂载硬盘设备让它直接写入磁盘的方式,在前面所学的mount中可见此命令)
  7. 在启动过程中boot目录grub下的grub2.conf配置文件是最重要的必要文件,而其他的文件即使丢失或者不存在计算机也能够正常启动。
    • 它保存了grub第二阶段1.操作系统内核位置2.操作系统根相关的挂载配置设置3.initramfs.img伪文件系统的位置。
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password=
title CentOS 6 (2.6.32-754.el6.x86_64)
    root (hd0,0)
    kernel /vmlinuz-2.6.32-754.el6.x86_64 ro root=UUID=d5db5e08-dc6d-4b6e-84fc-7e490e44ba0c rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /initramfs-2.6.32-754.el6.x86_64.img
  • 由分析可知 root (hd#,#) 就是代表了第几块硬盘的第几个分区,它是grub程序所找的根(狭义上可以理解为boot文件夹所在的硬盘分区,因为默认内核和img文件就装在这里,)在这里这个根就代表着boot这个文件夹,或者说代表root (hd#,#) 所指的分区的挂载的文件夹(因为它就是boot 所以 / 符号在这里就是代表/boot这个文件夹)
  • 而内核挂载后 root=/dev/sda2 才是操作系统的根,对其进行各种挂载配置
  • 此项也可不写,不过下面的kernel 和 initrd两项就要写成(hd0,0)/##### 的形式了
  • 重要注意4: grub1阶段完成之后,因为446字节很小不可能放得下文件系统的驱动,虽然分区表能找到分区/dev/sda1,但是grub程序是如何找到/boot目录以及它里面的grub,conf文件的?(寻找文件需要挂载时加载相应的文件系统驱动才可,只找到分区没有文件系统不行)。这里就是靠的1扇区后面的更多扇区的grub1.5阶段来实现的。
  • grub 1.5阶段就记载了boot目录的文件系统驱动(且只记载了它的驱动,没有记载其他的),它的扇区数量不固定,根据文件系统驱动的大小和安装时的设定来动态分配的。经过grub1.5阶段,识别了boot分区的文件系统,才能找到boot目录以及它的grub.conf文件
  • 重要注意5:操作系统根分区的虚拟文件系统驱动(第一次只读挂载时),就是靠grub.conf中写的initramfs.img文件来加载的(grub1.5只记载了boot的,不然这个img文件缺失了为何根就挂载不了了?,说明grub只管boot,img只管操作系统根,img缺失了机器能用grub硬盘启动但是无法挂载根)。
  1. 注意内核kernel和initrd两行顺序不能写反。title代表了标题栏选项,每一项就是一个选择内核的标题栏。

    • quiet表示内核安静模式启动,不显示内核启动的各种信息。这两项可以去掉。
    • rhgb项代表图形界面显示(转圈等待的那个图形界面),在这个界面按esc键才能看到被它遮盖的启动信息;
    • default代表默认启动选择哪一个菜单的内核,timeout就是相对应的多少秒内没有操作就会启动默认菜单的时长。
    • hiddenmenu 如果不敲任意键,则默认隐藏菜单
    • splashimage(=(hd0,0)/grub/splash.xpm.gz)代表启动的时候后面的背景图片,可以自己更改。*(大小就是640480像素图片,后缀为xpm,并且要压缩为gz)**
      可在linux里安装ImageMagick包,然后用convert命令转换它:convert -resize 640x480 -colors 14 win.jpg win.xpm , 然后路径写上即可。
      之后再对其进行压缩,放到boot目录中,在grub.conf中指定它即可更改启动时菜单栏的背景图片了(注意不是rhgb的那个,这个是菜单栏背景图)
    • 重要注意6:当规定了root (hd0,0) 之后,经测试要把所有相关文件都放在这个分区内才可。可放在这个分区不同的文件夹,但是必须在这个分区内。原因就是因为grub一次只能识别一个分区和它相应的文件系统。
  2. 前面也提到过grub交互式只是恢复备份文件,如果没有这些文件则无法用这个命令。因此用grub-install命令更加常用:

    • grub-insatall /dev/sda :注意直接写硬盘不要写分区,因为grub就是在MBR中,它在硬盘的第一个扇区和分区无关。
    • 如果boot文件夹挂载点不直接在操作系统根目录下,则要加上boot挂载的文件夹目录--root-directory=DIR.
    • 这个命令不仅能修复grubstage1 ,还能修复grubstage1.5 以及grub文件夹下的各个备份文件(其实就是文件系统驱动等),但是不能修复grub.conf文件和图片文件
  3. 重要注意7:grub-install /dev/sda命令执行过之后,如果只留下grub.conf文件,机器这次不能像之前那样正常启动了,会出现error 15的错误。说明此命令和原装的系统grubstage2的文件还是略有区别的,虽然表面上看起来是修复成功了。此时只能光盘救援模式(想要用此命令必须切换根才可)
  4. 为了避免启动过程中root口令被破解(按a切换1模式),因此可以在grub.conf中加一行password=### 来加口令,这样开机进入选择界面时就需要输入密码了。
    • 当然要用加密的方式进行书写,利用命令 grub-crypt 或者 grub-md5-crypt 生成密码然后复制进去暗文即可。(最好用grub-crypt,$6加密)不过需要注意指明加密的方式 :
      password --md5 $1#####
      password --encrypt $6######

/proc目录

  • /proc目录:
    内核把自己内部状态信息及统计信息,以及可配置参数通过proc伪文件系统加以输出
  • 帮助:man proc
  • 参数:
    只读:输出信息
    可写:可接受用户指定“新值”来实现对内核某功能或特性的配置
  • /proc/sys目录
    (1) sysctl命令用于查看或设定此目录中诸多参数
    sysctl -w path.to.parameter=VALUE
    sysctl -w kernel.hostname=mail.magedu.com
    (2) echo命令通过重定向方式也可以修改大多数参数的值
    echo "VALUE" > /proc/sys/path/to/parameter
    echo “websrv” > /proc/sys/kernel/hostname

sysctl命令

  • sysctl命令:
    默认配置文件:/etc/sysctl.conf
    (1) 设置某参数
    sysctl -w parameter=VALUE
    (2) 通过读取配置文件设置参数
    sysctl -p [/path/to/conf_file]
    (3) 查看所有生效参数
    sysctl -a
  • 常用的几个参数:
    net.ipv4.ip_forward :数据包转发
    net.ipv4.icmp_echo_ignore_all :是否忽略icmp的请求,如果改为1则忽略,便禁止了ping本机的功能
    vm.drop_caches :清空buffer/cache,要设置为3

/sys目录

  • /sys目录:
    sysfs:为用户使用的伪文件系统,输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的设定信息;有些参数是可以修改的,用于调整硬件工作特性
    udev通过此路径下输出的信息动态为各设备创建所需要设备文件,udev是运行用户空间程序
  • 专用工具:udevadmin, hotplug
    udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在/etc/udev/rules.d及/usr/lib/udev/rules.d目录下

注意

  1. sysctl命令就是通过修改/etc/sysctl.conf文件来永久保存开机之后写入proc/sys文件夹中的各种配置。直接修改proc/sys的方式只能临时修改(比如echo 1修改网卡的数据转发)。
  2. 在这个配置文件中的每一项都省略了/proc/sys标头,这里面的每一项的/标志被换为了.符号
    • 修改之后不会立即生效,使用sysctl -p命令让它立即生效。
    • 如果文件中没有默认写入的配置,则可以手写进去,就比如禁止ping功能的项。不过要注意格式。
  3. 但是要注意如果生效的项被删除了,则用sysctl -p命令重新载入的时候不会修改被删除的这一项的值。因为它只是读入此文件并加载到内存中配置,如果不相同的设置才会覆盖掉。
    删除掉某一项相当于没有配置,因此只能修改文件中每一项后面的值而不是删除这一项。
  4. 利用sysctl -a命令查看所有正在生效的配置,也可以利用sysctl -w 直接修改文件中的每一项的值(也是永久修改保存)。格式也是按照文件中的格式来写的,都是点.的符号
  5. Centos7中此文件为空,只能自己全部手写配置。可先用sysctl -a|grep来查询然后再书写。
  6. 利用man proc来查看各种设置的功能和选项,比如drop_caches,因为许多内核默认设置都比较保守,因此需要更改它

内核编译

  • 单内核体系设计、但充分借鉴了微内核设计体系的优点,为内核引入模块化机制
  • 内核组成部分:
    kernel:内核核心,一般为bzImage,通常在/boot目录下名称为 vmlinuz-VERSION-RELEASE
    kernel object:内核对象,一般放置于/lib/modules/VERSION-RELEASE/
  • 辅助文件:ramdisk
    initrd
    initramfs

内核版本

  • 运行中的内核:
    uname命令:
    uname - print system information
    uname [OPTION]...
    -n: 显示节点名称
    -r: 显示VERSION-RELEASE
    -a:显示所有信息

内核模块命令

lsmod命令:

显示由核心已经装载的内核模块
显示的内容来自于: /proc/modules文件(cat /proc/modules)

  • 其中各项代表模块名,大小(以K为单位),被使用的次数,以及当前模块被by下面的模块所依赖

modinfo命令:

显示模块的详细描述信息
modinfo [ -k kernel ] [ modulename|filename... ]
-n:只显示模块文件路径
-p:显示模块参数
-a:作者
-d:描述
示例:
lsmod |grep xfs
modinfo xfs
复习知识点:ethtool -i eth0

内核模块管理

modprobe命令:

装载或卸载内核模块
modprobe [ -C config-file ] [ modulename ] [ module parame-ters... ]
modprobe [ -r ] modulename… :-r 卸载 不写-r 加载

  • 配置文件:/etc/modprobe.conf,或/etc/modprobe.d/*.conf
  • 有些模块需要某些参数设置,则就会在上面所写的配置文件中写入,modprobe装载模块时会自动装载对应的这些配置文件
  • 此命令不需要写模块路径只需要写名字,同时也可以自动解决模块的依赖性,会把相关模块也同时加载

depmod命令:

内核模块依赖关系文件及系统信息映射文件的生成工具

装载或卸载内核模块:

insmod命令:指定模块文件,不自动解决依赖模块

  • (install mod)insmod必须指定模块的全路径且不能解决依赖性
    insmod [ filename ] [ module options... ]
    insmod `modinfo –n exportfs`
    lnsmod `modinfo –n xfs`

rmmod命令:卸载模块,直接写模块名即可

rmmod [ modulename ]
rmmod xfs
rmmod exportfs

附加知识点:NTFS文件格式的支持在epel源中有包可以进行操作。会多一个mount.ntfs命令,对NTFS格式文件系统的分区进行挂载之后便可可读可写。

启动流程图