系统启动流程


CentOS 5和6的启动流程
服务管理
Grub管理
自制Linux
启动排错
编译安装内核

系统启动流程:

 POST --> 读取BootSequence (BIOS),决定引导次序 -->读取引导设备的Bootloader(MBR grubstage1-->stage1.5/boot/filkeststem--> boot-->/boot/grub.conf/-->磁盘分区上读取 kernel(ramdisk来完成对真正根文件所在设备的加载) -->挂载rootfs(只读)到根设备上 --> 开始运行/sbin/init-->(/etc/inittab /etc/init/*.conf)-->设置默认运行级别-->运行系统初始化脚本,完成系统初始化-->关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务.-->rc.local-->设置登录终端[-->图形终端]

概论

1.linux组成部分:kernel(内核)+rootfs(GUN,根文件系统)
    kernel:进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能
        IPC:Inter process communication
            消息队列,semerphor,shm
            socket
    rootfs:程序和库文件glibc
        程序:二进制执行文件
        glibc:函数集合,function,调用接口
            过程调用:prpcedure,无返回值
            函数调用:function
2.kernel设计流派
    微内核:(monolithic kernel):Linux
        把所有工具集成与同一个程序
    单内核:(micro kernel): Windows, Solaris
        每种功能使用一个单独子系统实现(模块化)

3.Linux内核特点:
    支持模块化: .ko(内核对象)
        如:文件系统,硬件驱动,网络协议等
    支持内核模块的动态装载和卸载
4.linux内核组成部分:
        核心文件: /boot/vmlinuz-VERSION-release  vmlinuz的字母表示内核是压缩文件
            辅助的伪根系统:ramdisk
                启动操作系统,需要驱动,但驱动在根文件系统上,开机时挂载不了根文件系统,就需要一个第三方来辅助,生成一个虚拟的根文件系统,生成专用用户的专用驱动,来加载真正的根文件系统上的驱动.


                CentOS 5: /boot/initrd-VERSION-release.img
                CentOS6,7: /boot/initramfs-VERSION-release.img
        模块文件: /lib/modules/VERSION-release(内核版本号)
            注意:安装多版本的内核,有多个模块目录

5.模块文件目录: /lib/modules/2.6.32-431.el6.x86_64/kernel 
    arch :与平台相关的特有代码(x86 x64)
    crypto  :加密解密的组件
    drivers  :    驱动
    fs  :文件系统
    kernel  :内核追踪用到的组件
    lib  :库
    mm  :内存管理
    net  :网络管理
    sound:声音驱动

6.运行中的系统环境可分为两层:内核空间,用户空间
    用户空间:应用代码(进程或线程)
    内核空间(内核模式):内核代码(系统调用)
        任何应用程序在运行过程中,有可能需要不断发起模式转换,两种空间不断转换.转换的速率决定系统的性能.
7.建议在生产环境里面,将ctrl+alt+del里面重启的快捷键禁用

启动流程

仅适用于MBR类型架构的PC主机

1.centos6启动流程
系统启动流程

1.POST加电自检
2.加载BIOS的硬件信息,获取第一个启动设备。
3.读取第一个启动设备MBR的引导加载程序(grub)的启动信息
4.加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备。
5.核型执行init程序并获取运行信息。
6.Init执行/etc/rc.d/rc.sysinit文件。
7.启动核心的外挂模块(/etc/modprobe.conf)。
8.Init执行运行的各个批处理文件(scripts).
9.Init执行/etc/rc.d/rc.local.
10.执行/bin/login程序,等待用户登录。
11.登录之后开始以Shell控制主机。
1. POST: Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、 串并行接口、键盘、 CD-ROM光驱等硬件情况的检测。

 post(加电自检) 其实就是按开机键的那个过程,检测你的系统硬件信息 ,通过什么检测(cpu) 什么都不会干,执行事先编排好的指令和程序,cpu从哪加载指令和程序,能从硬盘拿数据吗?去内存拿数据 刚系统初始化过程中内存是空白的,没有数据,  
 这就要求系统自己完成这个的过程,通常内存有两种:ROM RAM ,计算机识别的内存和我们平时说的内存是不一样的 设备寻址时 不光识别物理4G内存条,还有一个低地址空间(BIOS的空间)在主板上有一个ROM芯片,里面嵌入了一段程序,(叫BIOS 基本输入输出系统)程序的作用就是扫描计算机的硬件, 开机过程中计算机会将他的指针指向内存低地址空间    自动在开机过程中CPU的指挥下将某个特殊的硬件的设备内容装在进内存,将BOis中的程序和指令映射进(物理地址空间)ROM 中,cpu就能读取指令,检测设备是否完整不需要任何额外指令,是硬件内置的,这个过程就是加电自检。
 bios 还要完成启动设备的次序决定,决定哪个设备先启动(USB装系统)

    ROM: BIOS, Basic Input and Output System,保存着有关计算机系统最重要的基本输入输出程序,系统信息设置、 开机加电自检程序和系统启动自举程序等。
    RAM: CMOS互补金属氧化物半导体,保存各项参数的设定按次序查找引导设备,第一个有引导程序的设备为本次启动设备

2.bootloader: 引导加载器,引导程序
    从BISO中按次序查找各引导设备,第一个有引导程序的设备即为本次启动要用到的设备.
    程序类型:
        windows: ntloader,仅是启动OS
        Linux:功能丰富,提供菜单,
            LILO: LInux LOader(缺陷:无法支持大硬盘分区)
            GRUB: GRand Unified Bootloader(统一引导加载器)
                centos 5,6: GRUB 0.X: GRUB Legacy(经典版), 各种安卓手机使用
                centos 7:   GRUB 1.X: GRUB2(跟0.X版本比,完全重写)
    功能:提供一个菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核
    MBR:Master Boot Record 
        512字节: 446byts: bootloader; 64byts: 分区表; 2byts: 55AA
            bootloader空间太小,446字符的代码只能实现最基本的功能
    GRUB:
       为向用户提供更好的开机体验,加入开机菜单,开机图片等更多功能,bootloader的小空间不能满足,grub分成三个阶段,第一阶段放在bootloader,bootloader不再直接加载内核,而是加载grub的第二阶段,第二阶段是一个虚拟操作系统,在磁盘分区内,有大的容量.相当于在启动操作系统前,启动一个虚拟操作系统(程序),不受MBR的限定,提供复杂的功能(阵列图,菜单,交互式接口),选定操作系统后,再由第二阶段加载内核文件.在第二阶段之前,还有第1.5阶段,提供文件系统驱动,方便虚拟系统的生成.

       第一阶段: primary boot loader : 1st stage, 1.5 stage
       第1.5阶段 :Partition:filesystem driver,1.5stage 文件系统驱动接口
       第二阶段 :Partition /boot/grub/ : 2nd stage,分区文件

    不支持复杂逻辑的软raid,内核分件只能放在基本磁盘分区上
   UEFI:可扩展固件接口(Extensible Firmware Interface,EFI)是 Intel 为 PC 固件的体系结构、接口和服务提出的建议标准。其主要目的是为了提供一组在 OS 加载之前(启动前)在所有平台上一致的、正确指定的启动服务,被看做是有近20多年历史的 BIOS 的继任者。
   GPT: GUID磁碟分割表(GUID Partition Table,缩写:GPT)其含义为“全局唯一标识磁盘分区表”,是一个实体硬盘的分区表的结构布局的标准。它是可扩展固件接口(EFI)标准(被Intel用于替代个人计算机的BIOS)的一部分,被用于替代BIOS系统中的一32bits来存储逻辑块地址和大小信息的主开机纪录(MBR)分区表。
3.kernel:
    有gurb中选定内核,把内核文件展开后,kernel自身初始化,然后接管系统的控制权,开始完成复杂的操作.
    自身初始化操作(按顺序操作):
        A.探测可识别到的所有硬件设备
        B.加载硬件驱动程序(有可能借助于ramdisk加载驱动)
        C.以只读方式挂载根文件系统(只读挂载,以防内核的错误操作,操作过程出错)
        D.运行用户空间的第一个应用程序: /sbin/init

     init程序的类型:
         CentOS 5之前: SysV init 
            配置文件: /etc/inittab
        CentOS 6: Upstart init (支持并发启动服务)
            配置文件: /etc/inittab(只是定义系统启动级别)
            /etc/init/*.conf(ntOS 7主要使用)
        Ce: Systemd systemd 
            配置文件: /usr/lib/systemd/system, /etc/systemd/system
    ramdisk:
        不在发行版系统光盘上事先存在,而是在装系统后,扫描硬件设备后动态生成的
         内核中的特性之一:使用缓冲和缓存来加速对磁盘上的文件访问
            ramdisk 转换成 ramfs(文件系统) 提高速度
            centos 5: initrd, 创建工具程序: mkinitrd
            CentOS 6,7initramfs,创建工具程序: mkinitrd, dracut
        系统初始化过程:
        POST --> 读取BootSequence (BIOS),决定引导次序 -->读取引导设备的Bootloader(MBR) -->磁盘分区上读取 kernel(ramdisk来完成对真正根文件所在设备的加载) -->挂载rootfs(只读)到根设备上 --> 开始运行/sbin/init( systemd

4.init程序(sbin/init)

centos5:SysV init
    运行级别:为了系-统的运行或维护等目的而设定的机制;
        0-6 :7个级别    
            0:关机 shutdowm
            1:单用户模式(root自动登录), single, 维护模式
            2: 多用户模式,启动网络功能,但不会启动NFS;维护模式
            3:多用户模式,正常模式;文本界面
            4:预留级别;,目前无特别适用目的, 可同3级别
            5:多用户模式(multi user),完全功能模式;图形界面
            6:重启
        默认级别: 3, 5
        切换级别: init #
        查看级别: runlevel ; who -r
   配置文件: /etc/inittab
        每一行定义一种action以及与之对应的process
            id:runlevel:action:process
                id:一个任务的标识符
                runlevels:在哪些级别启动此任务;#,###,也可以为空,表示所有级别
                action:在什么条件下启动此任务
                    wait: 等待切换至此任务所在的级别时运行一次
                    respawn:此任务终止时,就重新启动之
                    initdefault:设定默认运行级别; process省略
                    sysinit:设定系统初始化方式,此处一般为指定/etc/rc.drc.sysinit
                    ca::ctrlaltdel:/sbin/shutdown -t3 -r now
                    process:具体任务 ,通常是应用程序,或脚本,或二进制程序
            例:
                id:3:initdefault:  表示设定默认启动级别(centos6兼容)
                si::sysinit:/etc/rc.d/rc.sysinit 表示所有级别利用/etc/rc.d/rcsysinit设定系统初始化
                l3:3:wait:/etc/rc.d/rc 3 表示当切换到3级别时运行/etc/rc.d/rc脚本,往脚本里传递参数为3,意味着去启动或关闭/etc/rc.d/rc3.d/目录下的服务脚本所控制的服务,不同级别,数字不同.
                6:2345:respawn:/usr/sbin/mingetty tty6(定义终端1-6):表示在2345运行级别启动mingetty指令,给指令传递参数tty1,一旦该程序停止,要自动重启。mingetty会调用login程序,打开虚拟终端的程序,除了minget ty之外,还有诸如getty等
                x:5:respawn:/etc/X11/prefdm -nodaemon 表示在5运行级别启动时,打开图形化终端    
    系统初始化脚本:/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) 清理操作

     运行级别的相关服务:
       init在利用/etc/inittab配置文件,进行用户空间系统初始化时,会有关于默认运行级别的定义,当定义好默认运行级别,利于/etc/rc.d/rc.sysinit完成系统
初始化后,就会按照运行级别,来关闭、打开相应级别下的服务

    /etc/rc:规定关闭启动服务机制
         rc脚本接受一个运行级别数字为参数,/etc.rc.d/有rc+运行级别的目录,有K和S开头+运行级别+服务名的文件,每个文件链接/etc/init.d相应的程序文件.
          各种服务的控制脚本程序是存放在/etc/rc.d/init.d/目录下,然后各个对应级别下要关闭或开的程序以软连接的方式存放在/etc/rc.d/rc运行级别.d/目录下
                以K开头的表示要关闭的服务,K##*:关闭优先级,##数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的;
                以S开头的表示要开启的服务,##*:启动优先级,##数字越小,越是优先启动;被依赖的服务先关闭,依赖别人的服务后启动

                一般是先关闭相关服务后,再开启相关服务

         /etc/rc.d/rc.local 该脚本为正常行级别运行后的最后一个脚本,可以将一些希望开机时自动启动,但又不合适编辑成服务脚本的一些命令或程序,写在该文件中,
单独成行,即可完成开机自动启动;正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向了/etc/rc.d/rc.local脚本

    对应的文件在/etc/init/control-alt-delete.conf里,可通过/etc/inittab获知其定义信息

  /etc/rc.d/init.d/下的脚本的格式:
     这类脚本都需要在开头注释段标明:一般要接受至少start、stop、restart、status四个参数
         #!/bin/bash
          # crond    start/stop the cron daemon 标明脚本功能 ,此项可以不写 
          # chkconfig:LLL NN MM  标明该服务脚本初始状态下的运行级别,启动优先级,关闭优先级,必须要写
             LLL:自动为on级别
             NN:自动为on的优先级
             MM:自动为OFF的优先级   例:# chkconfig:2345 11 88
         # description:  描述
         功能代码段 …

 /etc/init.d/*(/etc/rc.d/init.d/*)服务脚本执行方式:
        #/etc/init.d/服务脚本 {start/restart/stop/status}
        #service SRV_SCRIPT {start/restart/stop/status}

为了统一管理服务关闭启动,设置服务脚本机制.利用chkconfig命令自动在各级别目录下创建对应的K或S的服务管理链接文件,且可以管理服务脚本的开机启动或关闭等,要想利用chkconfig进行管理,脚本必须要满足上述注释段的要求,然后将脚本放到/etc/init.d/目录下

    chkconfig命令:管控/etc/init.d/每个服务脚本在各级别下的启动或关闭状态;
         查看:chkconfig --list [服务名]
         添加:chkconfig --add 服务名
             SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)
         删除:chkconfig --del 服务名    
         修改执行的连接类型:
             chkconfig [--level LEVELS] name <on|off|reset>
                 --level LEVELS:指定级别,默认为234

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

总结(用户空间的启动流程):/sbin/init(/etc/inittab)            
    设置默认运行级别-->运行系统初始化脚本,完成系统初始化-->关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务.-->设置登录终端[-->图形终端]

  centos6:
        init程序:upstart,但依然为/sbin/init,其配置文件:/etc/init/*.conf
            为了兼容centos5,仍然有/etc/inittab,但仅仅是定义系统默认运行级别

系统启动流程

        /etc/rcs.conf:定义系统初始化脚本
        /etc/rc.conf:主配置文件,
        /etc/start-tty.conf:定义启动虚拟终端
        /etc/init-system-dbus.conf: 定义启动服务
            注意:*.confwei为upstar风格的配置文件.
        GRUB:完全一样

 centos7:
    init程序:systemd,配置文件:/usr/lib/systemd/system/*,/etc/systemd/system/*
    与centos5,6的开机启动服务相比,centos7开机时不启动任何服务,当访问某种服务时,才会启动服务,不访问的服务保持沉默状态

    完全兼容SycV脚本机制;因此,server命令依然可用,不过,建议使用systemctl命令来控制服务.
        systemctl {start|stop|restart|status} name[.service]
    设定默认系统运行级别:(不再是修改/etc/inittab,此文件指明更改方法)
        命令:systemctl set-default TARGET.target
        查看当期的运行平台: systemctl get-default
        常用的运行平台:
            # multi-user.target: analogous to runlevel 3
            # graphical.target: analogous to runlevel 5
        没有运行级别的概念,为了兼容centos5.6,设定不同的运行平台,来对应0-6的运行级别

2.详解GRUB(BOOT Loader)

grub legacy:主要运行分三个阶段
    stage1(第一阶段):安装在mbr中
    stage1.5(第1.5阶段):存放在mbr之后的扇区中,让stage1中的bootloader能识别stage2所在的分区上的文件系统(否则他是没办法加载第二阶段的)
    stage2(第2阶段):这个就是我们开机能看到提供菜单,让我们能够编辑时的加载界面的那个阶段,第二阶段是存放在磁盘分区上的,一般都在/boot/grub/目录下
    =====以上就是grub的组织格式======

    grub也有配置文件:/boot/grub.conf通常有个符号连接文件在/etc/grub.conf
    配置文件:/boot/grub/grub.conf <-- /etc/grub.conf
    因此当我们系统启动的时候如果要加载grub所在的磁盘时,会读取这个磁盘上的Mbr,从此能加载到stage1,stage1加载完以后会尝试去加载stage1.5,stage1.5阶段读到以后,从而就能够驱动stage2所在的磁盘分区;其实这个磁盘分区上不但有第二阶段,还有内核文件和ramdisk等等,都在这个分区上放置着,这就是为什么grub能够加载内核文件的原因。注意:主板bios必须能够识别硬盘。然后bios才能去加载硬盘上的boot loader,磁盘上boot loader加载完以后就能够直接识别当前主机能识别到的硬盘设备了,但是,硬盘设备能够识别,并不以为着能够识别硬盘中的文件系统,因为文件系统是额外附加的一层软件组织的文件结构。所有要想能够对接某种文件系统,必须要用到文件系统驱动。所谓的stage1.5阶段也就是给grub提供了文件系统驱动,从而grub就能够访问对应的stage2和内核所在的分区了,这通常应该是一个基本磁盘分区,毕竟stage1.5不可能做的过于复杂。所以grub的第二阶段,以及内核以及ramdisk文件通常都会放在一个基本磁盘分区
    stage2及内核等通常放置于一个基本磁盘分区(就是一般的磁盘分区,不是lvm和软raid;因为grub根本就驱动不了逻辑卷)
    功用:
        (1)提供菜单,并提供交互式接口
            e:编辑模式,用于编辑菜单
            c:命令模式,交互式接口(命令行接口)
        (2)加载用户选择的内核或操作系统
            允许用户传递参数给内核
            可隐藏菜单
        (3)    为菜单提供保护机制    
                为编辑菜单进行认证
                为启动内核或操作系统进行认证    

    如何识别硬盘设备:
        (hd#,#)第几块硬盘的第几个分区
            hd#: 磁盘编号,用数字表示;从0开始编号
            #: 分区编号,用数字表示; 从0开始编号
        (hd0,0) 第一块硬盘,第一个分区

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: 引导启动选定的内核

cat /proc/cmdline 显示/boot/grub/grub.conf中内核的参数

内核参数文档:/usr/share/doc/kernel-doc-2.6.32/Documentation/kernel-parameters.txt

手动在grub命令行接口启动系统:
    grub> root (hd#,#) 指明根设备
    grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE(只读方式启动根文件系统)
    grub> initrd /initramfs-VERSION-RELEASE.img 指明ramdisk文件
    grub> boot  引导内核

配置文件: /boot/grub/grub.conf

系统启动流程

    default=#: 设定默认启动的菜单项;落单项(title)编号从0开始
    timeout=#:指定菜单项等待选项选择的时长(用户在规定时间内不操作,自动跳过菜单)
    splashimage=(hd#,#)/PATH/TO/XPM_FILE:菜单背景图片文件路径,支持颜色很少
    hiddenmenu:隐藏菜单
    password [--md5] STRING: 启动菜单编辑认证 STRING:加密密码串 重启生效
    title TITLE:定义菜单项“标题” , 可出现多次
        root (hd#,#): grub查找stage2及kernel文件所在设备分区;为grub“根”
        kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核   ,这里的根是指root指向的第一个硬盘,第一个分区(hd0,0).  
            删除rhgb quiet选项,取消开机图形界面,查看内核启动消息
        initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件
        password [--md5] STRING: 启动选定的内核或操作系统时进行认证
        Max_loop=100 增加loop设备的数量(内核参数)

            独立分区的boot    kernel和initrd 可以写成 (hd0,0)/vimlinuz-
            非独立分区的boot kernrl      (hd0.0)/boot/vimlinuz-


grub加密:
    1.openssl passwd -1 或 指定盐: openssl passwd -salt "weds" -1
    2grub-md5-crypt命令,生成密码串,

     编辑/boot/grub/grub.conf  把生成的密码串放到password字段后 
        #password --md5 $1$8xzRy$xKj1/D5nb.9flfTfSRl5x.

系统启动流程

进入单用户模式:(可破解root密码)
    启动系统时,设置其运行级别1
    进入单用户模式:
    (1) 编辑grub菜单(选定要编辑的title,而后使用e命令);
    (2) 在选定的kernel后附加
        1, s, S或single都可以;编辑好敲回车
    (3) 在kernel所在行,键入“ b”命令
安装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#)

系统启动流程

3.自制linux系统

1.分区并创建文件系统
        fdisk /dev/sdb
    分两个必要的分区
        /dev/sdb1对应/boot /dev/sdb2对应根 /
        mkfs.ext4 /dev/sdb1
2.挂载boot
    mkdir /mnt/boot
    mount /dev/sdb1 /mnt/boot
3.安装grub
    grub-install --root-directory=/mnt /dev/sdb
4.. 恢复内核和initramfs文件
    cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/
    cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot
5.建立grub.conf文件
    Vim /mnt/boot/grub.conf
        kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2 selinux=0 init=/bin/bash
    chroot /mnt/sysroot
6. 创建一级目录
    mkdir /mnt/sysroot
    mount /dev/sdb2 /mnt/sysroot
    mkdir –pv/mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,dev,mnt,media}
7. 复制bash和相关库文件

4.救援模式

5.内核 Kernel

centos系统启动流程:POST-->biso-->bootloaer
加电自检后,读取bootloader中某个磁盘的MBR,kernel ,rootfs,init都是bootloader引导.

ldd命令:打印二进制程序文件的依赖库,没有对应文件的库,是真正的二进制程序入口.
    ldd /bin/ls | grep -o "lib[^[:space:]]*"

系统启动流程

内核设计体系:单内核,微内核
    linux:单内核,但充分借鉴微内核体系设计的优点:为内核引入了模块化机制
        内核的组成部分:
            kernel:内核核心,一般为bzimage,通常位为/boot目录,一般我们看到这个文件,就说明内核文件没用了,在系统启动时已经被加载过,开机后不在被使用,放在目录里,方便我们后期管理.
            kernel object:内核对象,即内核模块,一般放置于/lib/modules/VERSION-release/.
                A.内核模块与内核核心版本一定要严格匹配;
                B.内核模块化的主要动因:为了能够支持第三方厂商的硬件设备及其驱动程序,可以引进内核模块化的方式设计,这样每一个厂商都可以把自己的设备驱动写成内核模块,当用到这个设备时,单独编译这个内核模块.针对于当前内核的源码树,编译这个模块,并装载到内核上就可以使用了;

                C.在对内核的编译中,定义某个内核的功能,分为三种选择:
                     [ ]:N 编译时不启动功能,留空
                    [M]:Module 编译成内核模块,用到时临时装载,只占用磁盘空间,不占用内核内存空间
                    [*]:Y 直接编译进内核核心,只要内核在,功能就在,不用装载.
                D.内核:动态装载和卸载
            ramdisk:辅助性文件,并非必须,这取决于内核是否能直接驱动rootfs所在的设备;能直接驱动,ramdisk就不需要;不能驱动,就需要借助ramdisk封装驱动,不仅包括设备的驱动程序,也可以包括设备上的格式化所提供的逻辑设备,比如说lVM,文件系统;如果都编译成模块的话,都可以加载到内核中.
                借助于ramdisk,能加载的驱动,包括为:
                    目标设备驱动,例如:ISCSI设备的驱动
                    逻辑设备驱动,例如:LVM设备的驱动
                    文件系统,例如:XFS文件系统
                ramdksk:是一个简装版的根文件系统;不能作为一个操作系统使用,因为运行在内存中,缺少长久性,所以操作系统必须在持久性存储设备上,这也是做根切换的原因.提供设备驱动,仅仅是为了能够让内核找到真正的根文件系统.
        内核信息查看:
            uname命令:
               -a, --all 全部显示
               -s, --kernel-name 内核名称
               -n, --nodename  节点名称(主机名)    
               -r, --kernel-release  内核发行号
               -v, --kernel-version  内核编译版本号
               -m, --machine   硬件架构类型
               -p, --processor   cpu类型
               -i, --hardware-platform  硬件平台名称
               -o, --operating-system   操作系统类型

系统启动流程

        模块信息查看:
             lsmod命令:显示当前内核已加载的模块名,模块大小,被引用次数,被什么模块所引用
                 抽取/proc/modules的信息,lsmod抽取内核自己的输出接口的信息,以人性化的方式输出.
             modinfo命令:显示指定模块文件的详细信息
                    无论模块是否被装载,都可以用modinfo查看,modinfo就是通过获取/lib/modules目录下与当前内核版本同名的目录下的模块原数据文件,加以显示的.模块原数据文件类似于rpm包的元数据数据库,可以支持查询操作,需要专门的命令.每个文件都是经过hash格式编码,文件里面的都是键值对,从中查找数据的性能是O1(恒定)的,衡量一个算法的标准,O1,On,Olocaln.. 

                    选项:
                        -F:只显示指定字段的信息
                        -a:
                        -n:显示文件路径,相当于 -F filename,
                        -k:默认显示当前内核信息,要想显示其他内核的相关模块,使用-k选项指明kernel,和模块名

系统启动流程

         模块信息管理:
             modprobe命令:模块动态装载和卸载
                modpobe [-r] mod_name
                模块动态装卸载也可以基于文件实现,-c指明配置文件,默认是/etc/modprobe.d/*.conf文件
                选项:
                    装载模块: modprobe 模块名          被依赖的模块也会被装载
                    卸载模块: modprobe- r 模块名    正在使用的和默认装载的模块千万不要卸载,会影响系统使用

系统启动流程

             depmod命令:生成模块依赖关系
                内核模块依赖关系文件及系统信息映射文件的生成工具
                大多数命令选项,不使用;只有在新增模块时,这个模块依赖于其他模块,不得不手动改写模块文件.自己手动执行drpmod命令
                在对另外一个的内核文件生成依赖关系,并且保存文件也不放在/boot目录下,才有必要使用-b,-F,-E 选项指明内核文件,和内核模块
             模块装载和卸载的另一组命令:
                insmod命令:
                    insmod [filename][module options...]
                            filename:模块文件的文件路径,配合modinfo -n 查看模块文件路径

系统启动流程

                rmmod命令:
                    rmmod [module_name(模块名)]

系统启动流程

        ramdisk文件的管理:
            不是直接生成的,而是由命令管理的
            (1)mkinitrd命令: centos5 但6,7也有连接
                为当前使用中的内核重新制作ramdisk文件
                文件名:
                    centos5:initrd-2.6.32-504.30.3.el6.x86_64kdump.img
                    centos6,7:initramfs-2.6.32-504.30.3.el6.x86_64.img 
                命令格式:
                    mkinitrd [OPTION...] [<initrd-image>] <kernel-version>
                        --with=<module>:除了默认的模块之外需要装载至initramfs中的模块,重新制作ramdisk的重要原因,添加新的模块.
                        --preload=<module>:initramfs所提供的模块需要预先装载的模块;

                    示例: mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
            (2)dracut命令 centos 6,7
                    较为底层的生成ramdisk文件的工具
                    #dracut  [OPTION...] [<initrd-image>] <kernel-version>
                    示例:dracut /boot/initramfs-$(uname -r).img $(uname -r)

        内核信息输出的伪文件系统:
            /proc/:内核状态和统计信息的输出接口.可以通过各种文件系统直接管理.同时,还提供一个配置接口,/proc/sys;
                参数:
                    只读:信息输出;/proc下以数字命名的目录,只是用来输出某进程的相关信息./例如:/proc/#/*
                    可写:可接受用户指定一个"新值"来实现对内核某功能或特性的配置;写权限只有管理员拥有./proc/sys/
                            专门用来修改用于支持修改其值的参数,从而能够让我们实现配置内核参数的
                    伪文件系统的参数与/proc/sys/目录下的每个文件有映射关系,都相对与/proc/sys/目录而言,每个参数对应着我们所看到的/proc/sys/目录下的每个文件, 文件路径中的斜杠分隔符替换成点号,就成为参数名;
                        示例:net/ipv4/ip_forward相当于net.ipv4.ip_forward

                修改方式:    
                    (1)sysclt命令
                        专用于查看或设定/proc/sys/目录下参数的值
                        命令使用格式:
                            sysclt [options] [variable[=value]]
                                查看:
                                    #sysclt -a 查看全部信息
                                    #sysclt variable 指定参数名称 variable为文件目录的简装路径,以点分隔
                                修改其值:
                                    #sysclt -w variable=value

系统启动流程

                    (2)文件系统命令(cat,echo)
                        伪文件系统,不能使用文本编辑器去直接编辑,而应该使用重定向的方式覆盖原值
                        查看:
                            #cat /proc/sys/PATH/TO/SOME_KERNEL_FILE    
                        设定:使用覆盖重定向修改内核参数
                            echo "node1" > /proc/sys/kernel/hostname

系统启动流程

                        注意:上述两种方式的设定仅当前内核有效,内核或系统重启,配置失效
                    (3)配置文件
                        有可能是两种文件,
                        centos 5,6: /etc/sysctl.conf 
                        centos7:    /etc/sysctl.d/*.conf 分隔成多段配置
                        修改配置文件,不会立即生效,下次启动系统
                        立即有效:重读此配置文件,通知让sysctl命令重读此文件,并根据此文件的设定,来修改内核参数相关值即可
                            sysctl -p [/PATH/TO/CONFLG_FILE] 从指定文件中加载内核参数的相关设定,默认读取/etc/sysctl.conf,可指定其他文件,但最好在/etc/sysctl.d/目录下.
                内核参数:
                    1.net.ipv4.ip_forward,核心路由转发功能
                    2./proc/sys/vm/drop_caches:回收内存
                        0:
                        1:
                        2:
                    3./proc/sys/kernel.hostname:主机名
                    4./proc/sys/net/ipv4/icmp_exho_ignore_all 忽略别人ping自己,自己可以ping 别人
         /sys/目录:
                挂载的是sysfs:输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的可设定参数;对此些参数的修改,即可定制硬件设备工作特性;
                    [root@Wencx ~]# ls /sys
                    block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power
                    块设备,总线,
                    不同目录,通过不同视角对各设备划分的类别;根据总线划分,根据类别划分等等,另外也会根据某些特殊内容做些不同类的输出,或者说很多文件,很多设备所输出的位置不止一个目录,但是在多个目录下指向的同一个文件或设备.

                对一个linux主机来讲,每一个硬件设备被访问就要有设备文件,设备文件在/dev/目录下,内核怎么知道不同用户会有哪些硬件设备呢?事先不得而知.那应该准备怎样的设备文件来让内核识别呢?不知道的情况下,只能全部列出所有的设备文件,linux内核2.4以后在/dev/目录下有两万多个设备文件,无法预测用户用到哪些设备,所以把用户但凡用到的全创建出来,那么有两个问题?一.用户使用的很少,大多数文件浪费,虽不占用磁盘空间,但文件数量过大,二,没办法通过设备文件判断某个设备的存在./sys/目录在linux2.6内核引入后,使得我们能够按需创建设备文件,意思是说,每一次当内核系统完成自身初始化的时候,它会自动探测识别出每一个硬件设备信息,而后在把设备信息在系统启动完后,在内核初始化完后,在根文件系统挂载后,在重新探测输出到/sys/目录下,有多少硬件都在/sys/目录下显示.但是有些设备没有设备文件,就会临时读取/sys/目录下的设备信息,给它按需创建设备文件.对/dev/目录来说至关重要.

                udev:通过读取/sys/目录下的硬件设备信息按需为各硬件设备创建设备文件.是用户空间程序,不能直接跟硬件打交道,/sys/目录的存在才让udev读取硬件设备信息.专用命令:devadmin,hotplug;

                当根文件挂载完成后,系统初始化已经结束,系统就不会输出硬件信息./sys/目录的存在就会强制内核重新输出一遍内核信息,把内核中的各硬件设备信息输出至/sys/目录下,而这时候udev就会通过读取/sys/目录下的硬件设备信息按需为各硬件设备创建设备文件.

                /dev/目录下许多文件是Udev创建的,还有一些是内核创建的,比如说内核还要识别/sda硬盘,如果不能识别sda硬盘,标识为一个设备的话,怎么挂载设备?为了让设备访问正常,内核自动通过devtmpfs(设备临时文件系统),为每个内核必须用到的设备创建一个设备文件,这些设备文件可以在根文件系统挂载以后,从内核直接移到/dev/目录下,但不是完全移动,剩下的拷到udev,

                udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在/etc/udev/rules.d目录下,以及在/usr/lib/rules.d/目录下;

                /etc/udev/rules.d/70-persistent-net.rules文件,更改网卡配置文件的定义,并更改

原创文章,作者:wencx,如若转载,请注明出处:http://www.178linux.com/45996