Linux系统启动及定制过程

Linux系统启动及定制

一、简述linux操作系统启动流程

1.1 Centos5、Centos6系统启动过程

Linux系统启动及定制过程

CentOS的启动流程总体顺序如下:

POST --> Boot Sequence --> bootloader(MBR) --> Kernel --> 加载rootfs --> switchroot --> /sbin/init --> (配置文件:/etc/inittab, /etc/init/*.conf) --> 根据init配置文件设置默认运行级别 --> 运行系统初始化脚本/etc/rc.d/rc.sysinit,完成系统初始化 --> 开启或关闭用户选定的对应运行级别下所对应的服务 --> 启动终端,打印登录提示符。

注:前面加粗部分代表内核空间的系统启动流程,后面未加粗部分代表用户空间的系统启动流程。

第一步:硬件启动过程

Linux系统启动及定制过程

  • POST加电自检

    主要实现的功能是检测各个外围硬件设备是否存在而且能够正常运行起来,实现这一自检功能的是固化在主板上的ROM(主要代表为CMOS)芯片上的BIOS(Basic Input/Output System)程序;例如BIOS会检测CPU、Memory以及I/O设备是否能够正常运行,如果是个人计算机的话可能还会检测一下显示器。只要一通电,CPU就会自动去加载ROM芯片上的BIOS程序,是这样来实现的。而检测完成之后就进行硬件设备的初始化。

  • 选择启动设备以加载MBR

    主要实现的功能是选择要启动的硬件设备,选择了之后就可以读取这个设备上位于MBR里头的bootloader了。这一步的实现是这样的:根据BIOS中对启动顺序的设定,BIOS自己会依次扫描各个引导设备,然后第一个被扫描到具有引导程序(bootloader)的设备就被作为要启动的引导设备。

Linux系统启动及定制过程

  MBR(Main Boot Record),是硬盘的0柱面,0磁道、1扇区(第一个扇区),称为主引导扇区,也称为主引导记录。它由三部分组 成:主引导程序(BootLoader)、硬盘分区表DPT(Disk Partition table)和硬盘有效标志(55AA)。
   注:硬盘默认一个扇区大小为512字节。
  第一部分,主引导程序(BootLoader)占446个字节,负责从活动分区中装载,并运行系统引导程序。
  第二部分,硬盘分区表DPT占64个字节,有4个分区表项,每个分区表项占16个字节,硬盘中分区有多少以及每一个分区的大小都记 录在其中。
  第三部分,硬盘有效标志,占2个字节,固定为55AA。如果这个标志位0xAA55,就认为这个是MBR。

第二步:GRUB引导阶段

Linux系统启动及定制过程

不同的系统有不同的主引导程序(BootLoader)。Windows使用的是NTLDR(NT Loader,Windows NT系列操作系统)、Bootmgr(Boot Manager,Windows Vista,7,8,10),Linux一般使用的是grub(也叫grub legacy)和grub2。GRUB程序加载执行并引导kernel(内核)程序,其中有三个阶段,Grub引导阶段的文件都在/boot/grub/目录下。

stage1:这一阶段执行的就是系统安装时预先写入到MBR的Bootloader程序,即是存放在MBR的前446字节里的程序。它的任务仅是读取(加载)硬盘的0柱面,0磁道,2扇区的内容(/boot/grub/stage1)并执行。

stage1.5:这一阶段是Stage1阶段和Stage2阶段的桥梁,功能是加载stage2所在分区的文件系统驱动,让stage1中的bootloader能识别stage2所在分区的文件系统,此后grub程序便有能力去访问/boot/grub/stage2。

stage2:这一阶段读取并解析grub的配置文件/boot/grub/grub.cnf,根据配置文件加载内核镜像到内存中,通过initrd程序建立虚拟根文件系统,最后调用(转交)内核。

[root@CentOS6 ~]# cat /boot/grub/grub.conf
# 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/mapper/vg_centos6-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0  //设置默认启动项为第一个内核
timeout=5  //菜单项等待选项时间为5秒
splashimage=(hd0,0)/grub/splash.xpm.gz  //菜单背景图片
hiddenmenu  //隐藏菜单
//这里有时候会有passwrod参数,意思是进入急救模式(单用户模式)的密码是多少,可以是明文密码,可以是加密密码
//例如password --md5 $1$1S9Xy$1MuGZSoPc2vAtkW.jvz0X/,这代表进入急救模式的password经过MD5加密,加密密码为$1$1S9Xy$1MuGZSoPc2vAtkW.jvz0X/
title CentOS 6 (2.6.32-642.el6.x86_64)  //菜单项名称
        root (hd0,0)  //grub查找stage2文件及kernel文件所在设备分区,grub的根。第一块硬盘的第一个分区
        //启动的内核
        kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/mapper/vg_centos6-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=vg_centos6/lv_swap crashkernel=128M LANG=zh_CN.UTF-8 rd_LVM_LV=vg_centos6/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-642.el6.x86_64.img  //内核匹配的ramfs文件,img是镜像文件

第三步:内部引导阶段

Linux系统启动及定制过程

加载内核,核心开始解压,启动一些最核心的程序。为了让内核足够的轻小,硬件驱动并没放在内核文件里面。系统仅探测可识别到的所有硬件设备,加载硬件驱动程序,即加载真正的根文件系统所在设备的驱动程序(有可能会借助于ramdisk加载驱动),以只读方式挂载根文件系统,运行用户空间的第一个应用程序:/sbin/init。

第四步:init初始化阶段(系统初始化阶段)

Linux系统启动及定制过程

虽然CentOS 5、CentOS 6以及CentOS 7的/etc/init配置文件内容各不相同,但总体的启动流程相同:/sbin/init --> 根据/etc/inittab配置文件设置默认运行级别 --> 运行系统初始化脚本/etc/rc.d/rc.sysinit,完成系统初始化 --> 关闭或启动用户选定的默认运行级别所对应的服务 。

对于CentOS 5来说,初始化程序init是SysV init,其配置文件为:/etc/inittab; 对于CentOS 6来说,初始化程序init是upstart,其配置文件为:/etc/inittab, /etc/init/*.conf,也就是upstart将配置文件拆分成多个,在/etc/init/目录下以conf结尾的都是upstart风格的配置文件,而/etc/inittab仅用于设置默认运行级别; 对于CentOS 7来说,初始化程序init是systemd,其配置文件:/usr/lib/system/systemd/, /etc/systemd/system/*;

具体执行过程:/sbin/init程序会读取/etc/inittab文件确认运行级别,然后执行/etc/rc.d/rc脚本,根据确认的运行级别启动对应/etc/rc.d/rc#.d/目录下的服务(#为0~6),与此同时执行系统初始化脚本/etc/rc.sysinit(软链接,指向/etc/rc.d/rc.sysinit),还会加载/etc/rc.local(软链接,指向/etc/rc.d/rc.local文件)用户自定义服务(脚本)。

CentOS7中初始化进程变为了systemd,systemd即为system daemon,是Linux下的一种init软件,开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell系统开销的效果,最终代替现在常用的System V与BSD风格的init程序。与多数发行版使用的System V风格的init相比,systemd采用了以下的新技术:A.采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;B.用Cgroup代替PID来追踪进程,即使是两次fork之后生成的守护进程也不会脱离systemd的控制。

系统初始化阶段涉及到的主要配置文件:

  • Centos5系统/etc/inittab配置文件说明

    id:3:initdefault:    //设置默认运行级别,此处设置为3;
    
    # System initialization.
    si::sysinit:/etc/rc.d/rc.sysinit    //指定系统初始化脚本;
    //根据前面获取到的运行级别信息,运行/etc/rc.d/rc脚本;
    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
    //因为默认运行级别为3,因此只会开启或关闭/etc/rc.d/rc3.d/目录下的脚本所控制的服务;而其它
    的/etc/rc.d/rc#.d/目录则别略过;
    l4:4:wait:/etc/rc.d/rc 4
    l5:5:wait:/etc/rc.d/rc 5
    l6:6:wait:/etc/rc.d/rc 6
    

    /etc/inittab每行定义一种action以及与之对应的process:
    格式:id:runlevel:action:process
    各字段解释:
    id:一个任务的标识符;
    runlevel:在哪些级别下启动该任务;格式可以是#,###,也可以为空(表示所有级别);
    action:在什么条件下启动该任务;
    process:任务;

    action种类:
    wait:等待切换至该任务所在的级别时执行一次;
    respawn:一旦该任务终止,就会重新启动这个任务;
    initdefault:设定默认运行级别;此时process是省略掉的;
    sysinit:设定系统初始化方式,这里一般指定为/etc/rc.d/rc.sysinit脚本文件。

  • Centos6配置文件/etc/inittab文件

    # inittab is only used by upstart for the default runlevel.
    #
    # ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
    #
    # System initialization is started by /etc/init/rcS.conf    # 系统初始化使用的配置文件
    #
    # Individual runlevels are started by /etc/init/rc.conf    # 个人运行级别使用的配置文件
    #
    # Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
    #
    # Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
    # with configuration in /etc/sysconfig/init.
    #
    # For information on how to write upstart event handlers, or how
    # upstart works, see init(5), init(8), and initctl(8).
    #
    # Default runlevel. The runlevels used are:
    #   0 - halt (Do NOT set initdefault to this)
    #   1 - Single user mode
    #   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
    #   3 - Full multiuser mode
    #   4 - unused
    #   5 - X11
    #   6 - reboot (Do NOT set initdefault to this)
    # 
    id:3:initdefault:    # 系统启动默认的运行级别
    
  • Centos7配置文件/etc/inittab文件

    # inittab is no longer used when using systemd.
    #
    # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
    #
    # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
    #
    # systemd uses 'targets' instead of runlevels. By default, there are two main targets:
    #
    # multi-user.target: analogous to runlevel 3
    # graphical.target: analogous to runlevel 5
    #
    # To view current default target, run:
    # systemctl get-default
    #
    # To set a default target, run:
    # systemctl set-default TARGET.target
    

    CentOS7首先执行默认target配置文件/etc/systemd/system/default.target(这是一个软链接,与默认运行级别有关)。然后执行sysinit.target来初始化系统和basic.target来准备操作系统。接着启动multi-user.target下的本机与服务器服务,并检查/etc/rc.d/rc.local文件是否有用户自定义脚本需要启动。最后执行multi-user下的getty.target及登录服务,检查default.target是否有其他的服务需要启动。

  • 系统初始化脚本/etc/rc.d/rc.sysinit

    运行初始化脚本是为了初始化系统环境,这一步初始化包括:

    ①设置主机名;

    ②设置欢迎信息;

    ③激活udev和selinux;

    ④挂载/etc/fstab文件中定义的所有文件系统;

    ⑤检测根文件系统,以读写方式重新挂载根文件系统;

    ⑥设置系统时钟;

    ⑦根据/etc/sysctl.conf文件来设置内核参数;

    ⑧激活lvm及软raid设备;

    ⑨激活swap设备;

    ⑩加载额外设备的驱动程序(因为内核只加载根文件系统所在分区的驱动程序);

    ![wKioL1iuv4axwD7kAAABMmWbSlw410.png](十二周 Linux系统启动相关.assets/170320141960022.png)清理操作

  • 关闭或启动用户选定的默认运行级别下所对应的服务

    要实现的功能是:根据前面用户通过init配置文件对默认运行级别的设定,关闭或启动这个运行级别下的服务。(注意:关闭在前,启动在后)

    具体实现方式:运行/etc/rc.d/rc这个脚本文件,而初始化程序init根据前面获取的默认运行级别信息,将这个运行级别数字以参数方式传递给/etc/rc.d/rc脚本中的变量\$runlevel;然后,这个脚本会以glob方式去把/etc/rc.d/rc\$runlevel.d/S匹配到的脚本所控制的服务开启,而把/etc/rc.d/rc$runlevel.d/K匹配到的脚本所控制的服务开启。

    /etc/rc.d/rc#.d/目录下的脚本文件命名格式:

    (1)K##:表示要停止的服务;'##'表示关闭优先级,数字越小,越是优先关闭;依赖到其他服务的服
    务会优先关闭,而被依赖的服务则后关闭;
    (2)S##:表示要启动的服务;'##'表示启动优先级,数字越小,越是优先启动;被依赖的服务会优先
    启动,而依赖到其他服务的服务则后启动。

第五步:启动终端

Linux系统启动及定制过程

根据前面获取的运行级别来启动终端,mingetty程序是用于启动终端的,它会调用登录程序login,这样就能显示出登录提示符了,类似mingetty这种用于打开终端的程序还有getty等。而如果默认运行级别为5,则会打开图形界面。

1.2 Centos7系统启动过程

第一步:硬件启动过程

这一步和CentOS6差不多,详细请看1.1内容。

第二步:GRUB引导阶段

从这一步开始,CentOS6和CentOS7的启动流程区别开始展现出来了。CentOS7的主引导程序使用的是grub2,执行过程是先加载boot.img、core.img两个镜像,再加载MOD模块文件,把grub2程序加载执行,接着解析配置文件/boot/grub/grub.cfg,根据配置文件加载内核镜像到内存,之后构建虚拟根文件系统,最后转到内核。

CentOS7中使用命令进行配置,而不直接去修改配置文件了。grub.cfg配置文件开头注释部分说明了由/etc/grub.d/目录下文件和/etc/default/grub文件组成。改好配置后都需要使用命令grub2-mkconfig -o /boot/grub2/grub.cfg,将配置文件重新生成。

第三步:内部引导阶段

这一步与CentOS6也差不多,加载驱动,切换到真正的根文件系统,唯一不同的是执行的初始化程序变成了/usr/lib/systemd/systemd。

第四步:init初始化阶段(系统初始化阶段)

  CentOS7中我们的初始化进程变为了systemd。执行默认target配置文件/etc/systemd/system/default.target(这是一个软链接,与默认运行级别有关)。然后执行sysinit.target来初始化系统和basic.target来准备操作系统。接着启动multi-user.target下的本机与服务器服务,并检查/etc/rc.d/rc.local文件是否有用户自定义脚本需要启动。最后执行multi-user下的getty.target及登录服务,检查default.target是否有其他的服务需要启动。

  注意:/etc/systemd/system/default.target指向了/lib/systemd/system/目录下的graphical.target或multiuser.target。而graphical.target依赖multiuser.target,multiuser.target依赖basic.target,basic.target依赖sysinit.target,所以倒过来执行。

  unit对象:unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其他与init相关的信息。(也就是CentOS6中的服务器启动脚本)

(1)/etc/systemd/system/default.target

  这是一个软链接,和默认运行级别相关。

[root@xuexi system]# ll /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 36 12月  9 15:47 /etc/systemd/system/default.target -> /lib/systemd/system/graphical.target

[root@xuexi system]# cd /lib/systemd/system/
[root@xuexi system]# ls *.target
anaconda.target            local-fs.target           runlevel2.target
basic.target               machines.target           runlevel3.target
bluetooth.target           multi-user.target         runlevel4.target
cryptsetup-pre.target      network-online.target     runlevel5.target
cryptsetup.target          network-pre.target        runlevel6.target
ctrl-alt-del.target        network.target            shutdown.target
default.target             nfs-client.target         sigpwr.target
emergency.target           nss-lookup.target         sleep.target
final.target               nss-user-lookup.target    slices.target
getty-pre.target           paths.target              smartcard.target
getty.target               poweroff.target           sockets.target
graphical.target           printer.target            sound.target
halt.target                rdma-hw.target            suspend.target
hibernate.target           reboot.target             swap.target
hybrid-sleep.target        remote-cryptsetup.target  sysinit.target
initrd-fs.target           remote-fs-pre.target      system-update.target
initrd-root-fs.target      remote-fs.target          timers.target
initrd-switch-root.target  rescue.target             time-sync.target
initrd.target              rpcbind.target            umount.target
iprutils.target            rpc_pipefs.target         virt-guest-shutdown.target
kexec.target               runlevel0.target
local-fs-pre.target        runlevel1.target

这里可以看到runlevel开头的target文件,对应着CentOS6的启动级别,不过一样是软链接,指向了同目录下的其他文件。

[root@xuexi system]# ll runlevel*.target
lrwxrwxrwx. 1 root root 15 4月   5 22:10 runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 4月   5 22:10 runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 4月   5 22:10 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 4月   5 22:10 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 4月   5 22:10 runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 4月   5 22:10 runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 4月   5 22:10 runlevel6.target -> reboot.target

可以看到default.target与runlevel5.target指向的是同一个文件,可以看出我的默认运行级别是5。

(2)/usr/lib/systemd/system/

  这个目录存储每个服务的脚本,类似CentOS6的/etc/init.d/。

(2)/run/systemd/system/

  系统执行过程中产生的脚本。

(3)/etc/systemd/system/

  类似于CentOS6的/etc/rc.d/rc#.d/SXX类文件的功能,管理员建立的执行脚本,大部分是软链接。

第五步:启动终端

systemd执行sysinit.target
systemd启动multi-user.target下的本机与服务器服务
systemd执行multi-user.target下面的/etc/rc.d/rc.local
Systemd执行multi-user.target下的getty.target及登录服务
getty.target是启动终端的systemd对象。如果到此步骤,系统没有指定启动图形桌面,到此就可以结束了,如果需要启动图形界面,要在此基础上启动桌面程序。

二、制作一个只运行shell的linux系统

2.1 测试环境

# uname -a
Linux CentOS6 2.6.32-754.el6.x86_64 #1 SMP Tue Jun 19 21:26:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@CentOS6 ~]# cat /etc/redhat-release
CentOS release 6.10 (Final)

2.2 为安装Centos6系统增加一块新的硬盘、分区并创建文件系统

# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk
├─sda1   8:1    0  300M  0 part /boot
├─sda2   8:2    0    3G  0 part [SWAP]
└─sda3   8:3    0 26.7G  0 part /
sr0     11:0    1 1024M  0 rom

# ls /sys/class/scsi_host
host0  host1  host2

# for ((i=0;i<=2;i++)); do echo '- - -' > /sys/class/scsi_host/host$i/scan; done

# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk
├─sda1   8:1    0  300M  0 part /boot
├─sda2   8:2    0    3G  0 part [SWAP]
└─sda3   8:3    0 26.7G  0 part /
sr0     11:0    1 1024M  0 rom
sdb      8:16   0   20G  0 disk

# fdisk /dev/sdb

# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk
├─sda1   8:1    0  300M  0 part /boot
├─sda2   8:2    0    3G  0 part [SWAP]
└─sda3   8:3    0 26.7G  0 part /
sr0     11:0    1 1024M  0 rom
sdb      8:16   0   20G  0 disk
├─sdb1   8:17   0    1G  0 part
└─sdb2   8:18   0   19G  0 part

# mkfs.ext4 /dev/sdb2
# mkfs.ext4 /dev/sdb2

2.3 挂载boot安装grub

# mkdir /mnt/boot
# mount /dev/sdb1 /mnt/boot

# grub-install --root-directory=/mnt/ /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt//boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)   /dev/fd0
(hd0)   /dev/sda
(hd1)   /dev/sdb
[root@CentOS6 ~]#

2.4 准备内核和initramfs文件

[root@CentOS6 boot]# ls /boot
config-2.6.32-754.el6.x86_64  initramfs-2.6.32-754.el6.x86_64.img  System.map-2.6.32-754.el6.x86_64
efi                           lost+found                           vmlinuz-2.6.32-754.el6.x86_64
grub                          symvers-2.6.32-754.el6.x86_64.gz

# cp /boot/vmlinuz-2.6.32-754.el6.x86_64 /mnt/boot/vmlinuz-2.6.32-754.el6.x86_64
# cp /boot/initramfs-2.6.32-754.el6.x86_64.img /mnt/boot/initramfs-2.6.32-754.el6.x86_64.img

# ls /mnt/boot
grub  initramfs-2.6.32-754.el6.x86_64.img  lost+found  vmlinuz-2.6.32-754.el6.x86_64

2.5 建立grub.conf

# vim /mnt/boot/grub/grub.conf
default=0
timeout=6
title Custom Linux6
root (hd0,0)
kernel /vmlinuz-2.6.32-754.el6.x86_64 root=/dev/sda2 selinux=0 init=/bin/bash
initrd /initramfs-2.6.32-754.el6.x86_64.img

2.6 准备命令及库文件脚本

# vim comcp.sh
#!/bin/bash                                                                                                                      
#
#********************************************************************
#Author:        xinshidong
#QQ:            6736080
#Date:          2021-02-24
#FileName:     comcp1.sh
#URL:            
#Description:      The test script
#Copyright (C):     2021 All rights reserved
#********************************************************************
ch_root="/mnt/sysroot"
[ ! -d $ch_root ] && mkdir $ch_root

bincopy() {
    if which $1 &>/dev/null; then

        local cmd_path=`which --skip-alias $1`   #bash的默认路径是/usr/bin/bash,复制/bin/bash时,此处直接赋值:local cmd_path=/bin/bash
        local bin_dir=`dirname $cmd_path` #复制/bin/bash时,此处直接赋值:local cmd_path=/bin
#        local cmd_path=/bin/bash
#        local bin_dir=/bin
        [ -d ${ch_root}${bin_dir} ] || mkdir -p ${ch_root}${bin_dir}
        [ -f ${ch_root}${cmd_path} ] || cp $cmd_path ${ch_root}${bin_dir}
        return 0
    else
        echo "Command not found."
        return 1
    fi
}

libcopy() {
    local lib_list=$(ldd `which --skip-alias $1` | grep -Eo '/[^[:space:]]+')
    for loop in $lib_list;do
        local lib_dir=`dirname $loop`
        [ -d ${ch_root}${lib_dir} ] || mkdir -p  ${ch_root}${lib_dir}
        [ -f ${ch_root}${loop} ] || cp $loop ${ch_root}${lib_dir}
    done
}

read -p "Please input a command: " command

while [ "$command" != "quit" ];do
    if bincopy $command ;then
        libcopy $command
    fi
    read -p "Please input a command or quit: " command
done                                      

2.5 准备根目录下面相关程序和库

# mount /dev/sdb2 /mnt/sysroot
# mkdir -pv /mnt/sysroot/{boot,dev,sys,proc,etc,lib,lib64,bin,sbin,tmp,var,usr,opt,home,root,mnt,media}
mkdir: created directory `/mnt/sysroot/boot'
mkdir: created directory `/mnt/sysroot/dev'
mkdir: created directory `/mnt/sysroot/sys'
mkdir: created directory `/mnt/sysroot/proc'
mkdir: created directory `/mnt/sysroot/etc'
mkdir: created directory `/mnt/sysroot/lib'
mkdir: created directory `/mnt/sysroot/lib64'
mkdir: created directory `/mnt/sysroot/bin'
mkdir: created directory `/mnt/sysroot/sbin'
mkdir: created directory `/mnt/sysroot/tmp'
mkdir: created directory `/mnt/sysroot/var'
mkdir: created directory `/mnt/sysroot/usr'
mkdir: created directory `/mnt/sysroot/opt'
mkdir: created directory `/mnt/sysroot/home'
mkdir: created directory `/mnt/sysroot/root'
mkdir: created directory `/mnt/sysroot/mnt'
mkdir: created directory `/mnt/sysroot/media'

# ./comcp.sh 
Please input a command: 
bash,ip,ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid,ps,fdisk,pstree,vim,vi,ethtool

# ethtool -i eth0
driver: e1000
version: 7.3.21-k8-NAPI
firmware-version:
bus-info: 0000:02:01.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no

# modinfo -n e1000
/lib/modules/2.6.32-754.el6.x86_64/kernel/drivers/net/e1000/e1000.ko

# cp /lib/modules/2.6.32-754.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/sysroot/lib

# chroot /mnt/sysroot
bash-4.1# ls
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  sbin  sys  tmp  usr  var

2.6 使用准备好的磁盘创建Linux系统

将准备好的磁盘文件(Centos6系统中新增加的磁盘设备/dev/sdb)拷贝到新的虚拟机文件夹下备用。

Linux系统启动及定制过程

新建虚拟机时,选择使用现有虚拟磁盘安装新的虚拟机

Linux系统启动及定制过程

Linux系统启动及定制过程

启动虚拟机

Linux系统启动及定制过程

Linux系统启动及定制过程

三、systemctl管理命令及system unit文件格式

从 CentOS 7 版本之后,系统开始用 systemd 实现init进程,系统启动和服务器守护进程管理器功能,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程。

unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息。

# uname -a
Linux localhost.localdomain 4.18.0-147.el8.x86_64 #1 SMP Wed Dec 4 21:51:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost ~]# cat /etc/redhat-release 
CentOS Linux release 8.1.1911 (Core) 

# systemctl -t help
Available unit types:
service
socket
target
device
mount
automount
swap
timer
path
slice
scope
  • service unit: 文件扩展名为.service, 用于定义系统服务
  • Socket unit: .socket, 定义进程间通信用的socket文件,也可在系统启动时,延迟启动服务,实现按需启动
  • Target unit: 文件扩展名为.target,用于模拟实现运行级别
  • Device unit: .device, 用于定义内核识别的设备
  • Mount unit: .mount, 定义文件系统挂载点
  • Snapshot unit: .snapshot, 管理系统快照
  • Swap unit: .swap, 用于标识swap设备
  • Automount unit: .automount,文件系统的自动挂载点
  • Path unit: .path,用于定义文件系统中的一个文件或目录使用,常用于当文件系统变化时,延迟激活服务,如:spool 目录
  • Timer unit: .timer,封装了一个由 systemd 管理的定时器, 以支持基于定时器的启动。
  • slice unit: .slice,用于封装管理一组进程资源占用的控制组的 slice 单元。 此类单元是通过在 Linux cgroup(Control Group) 树中创建一个节点实现资源控制的。 slice 单元用于包含其他管理进程的单元(一般是 scope 与 service 单元)。 对 slice 单元施加的资源限制,将会作用于此 slice 单元所包含的全部进程的集合。
  • scope unit: .scope,范围(scope)单元并不通过单元文件进行配置, 而是仅能以编程的方式通过 systemd D-Bus 接口创建。 范围单元的名称都以 ".scope" 作为后缀。 与服务(service)单元不同,范围单元用于管理 一组外部创建的进程, 它自身并不派生(fork)任何进程。

3.1 systemctl管理命令

命令格式:

systemctl COMMAND name.service

#启动:相当于service name start
systemctl start name.service
#停止:相当于service name stop
systemctl stop name.service
#重启:相当于service name restart
systemctl restart name.service
#查看状态:相当于service name status
systemctl status name.service
#禁止自动和手动启动:
systemctl mask name.service
#取消禁止
systemctl unmask name.service
#查看某服务当前激活与否的状态:
systemctl is-active name.service
#查看所有已经激活的服务:
systemctl list-units --type|-t service
#查看所有服务:
systemctl list-units --type service --all|-a
#设定某服务开机自启,相当于chkconfig name on
systemctl enable name.service
#设定某服务开机禁止启动:相当于chkconfig name off
systemctl disable name.service
#查看所有服务的开机自启状态,相当于chkconfig --list
systemctl list-unit-files --type service
#用来列出该服务在哪些运行级别下启用和禁用:chkconfig --list name
ls /etc/systemd/system/*.wants/name.service
#查看服务是否开机自启:
systemctl is-enabled name.service
#列出失败的服务
systemctl --failed --type=service
#开机并立即启动或停止
systemctl enable --now postfix
systemctl disable --now postfix
#查看服务的依赖关系:
systemctl list-dependencies name.service
#杀掉进程:
systemctl kill unitname

服务状态

#显示状态
systemctl list-unit-files --type service --all
  • loaded Unit配置文件已处理
  • active(running) 一次或多次持续处理的运行
  • active(exited) 成功完成一次性的配置
  • active(waiting) 运行中,等待一个事件
  • inactive 不运行
  • enabled 开机启动
  • disabled 开机不启动
  • static 开机不启动,但可被另一个启用的服务激活
  • indirect 重定向到别处

3.2 system unit文件格式

/usr/lib/systemd/system:发行版打包者使用,每个服务最主要的启动脚本设置,类似于之前的/etc/init.d/

/etc/systemd/system:系统管理员和用户使用,管理员建立的执行脚本,类似于/etc/rcN.d/Sxx的功能,比上面目录优先运行

/lib/systemd/system::ubutun的对应目录

/run/systemd/system:系统执行过程中所产生的服务脚本,比上面目录优先运行

unit 格式说明:

  • 以 “#” 开头的行后面的内容会被认为是注释

  • 相关布尔值,1、yes、on、true 都是开启,0、no、off、false 都是关闭
  • 时间单位默认是秒,所以要用毫秒(ms)分钟(m)等须显式说明

service unit file文件通常由三部分组成:

  • [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等
  • [Service]:与特定类型相关的专用选项;此处为Service类型
  • [Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项

Unit段的常用选项:

  • Description:描述信息
  • After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before相反
  • Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
  • Wants:依赖到的其它units,弱依赖
  • Conflicts:定义units间的冲突关系

Service段的常用选项:

  • Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
    • simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
    • forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止
    • oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中
    • dbus:与simple类似,但这个daemon必须要在取得一个D-Bus的名称后,才会继续运作。因此通常也要同时设定BusNname= 才行
    • notify:在启动完成后会发送一个通知消息。还需要配合 NotifyAccess 来让 Systemd 接收消息
    • idle:与simple类似,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的daemon通常是开机到最后才执行即可的服务
  • EnvironmentFile:环境配置文件
  • ExecStart:指明启动unit要运行命令或脚本的绝对路径
  • ExecStartPre: ExecStart前运行
  • ExecStartPost: ExecStart后运行
  • ExecStop:指明停止unit要运行的命令或脚本
  • Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务
  • PrivateTmp:设定为yes时,会在生成/tmp/systemd-private-UUID-NAME.service-XXXXX/tmp/目录

Install段的常用选项:

  • Alias:别名,可使用systemctl command Alias.service
  • RequiredBy:被哪些units所依赖,强依赖
  • WantedBy:被哪些units所依赖,弱依赖
  • Also:安装本服务的时候还要安装别的相关服务

注意:对于新创建的unit文件,或者修改了的unit文件,要通知systemd重载此配置文件,而后可以选择重启。

systemctl daemon-reload

四、破解centos7 密码

首先在启动界面按e编辑启动参数

Linux系统启动及定制过程

将ro参数更改为rw init=/sysroot/bin/sh,按ctr + x启动系统
Linux系统启动及定制过程

Linux系统启动及定制过程

按下图执行命令更改root密码

Linux系统启动及定制过程

猜你喜欢

转载自blog.51cto.com/12302225/2638803