Linux启动流程

  • 操作系统的启动流程
  • 操作系统启动的流程:post-->BIOS(Boot Sequence)--->MBR(boot loader,446)-->kernel---> initrd ---> 查找根文件系统,启动根文件系统-->init(用户空间的第一个进程);
  • post加电自检:将BIOS 中的程序映射进CPU可以查找的内存中的地址空间, ROM 映射进RAM里面,这些指令用于完成硬件设备的检查;
  • 关于bootloader:
    • 对于不同的操作系统来说是不同的,LinuxWindowsbootloader是不同的,windows默认是锁定MBR的,不允许其他的操作来替换;Linux支持的bootloader包括LILO(Linux Loader),不支持大硬盘或者分区,嵌入式一般使用这个;
    • GRUB(Grand Unified bootloader):包含两个阶段;
      这里写图片描述
      • stage1 :装载在MBR中了,目的是用来引导第二个阶段的;
      • stage1.5:其中为了识别常用的stage2的文件系统,引入stage1.5,用于支持常见的文件系统;
      • stage2:第二个阶段在/boot/grub/stage2里面,MBR 第一阶段所访问的/boot/grub/是一个基本磁盘设备,可以进行硬访问,第二个阶段是不受 446字节的大小限制的设别,可以进行硬访问;
        这里写图片描述
      • grubstage2阶段的配置文件/boot/grub/grub.conf:
        • default=0:表示默认启动第一个操作系统;
        • timeout:等待用户选择的超时时长
        • splashimage=:用于指定背景图图片;
        • Hiddenmenu:表示隐藏菜单;
        • title:表示内核标题,操作系统标题;
        • root:表示内核文件所在的设备,如果grub找不到kernel的位置,需要进入救援模式来手动探测内核所在的位置;grub识别硬盘都是按照 hd开头,第一个为hd0;
        • kernel:一行表示kernel文件路径以及传递给内核的参数;这一行和/proc/cmdline文件是一致的;这个knernel是直接通过访问内核所在的分区来访问的,并不铜鼓根文件系统,因为i这时,根文件系统还没有被识别;如果没有进行单独分区,就需要使用/boot/
        • initrd:表示ram disk文件路径,是在操作系统安装的最后生成的,里面各种文件,除了内核文件之外都有;
        • /boot:是一个独立的分区,grub访问内核时,文件系统还没有加载,所以直接访问磁盘上的/boot,就不需要根来查找对应目录,也就不需要加载内核文件系统这个操作;
      • grub的应用:编辑界面:在系统启动过程中,按e进入编辑界面;a可以用于修改内核参数;c:可以用于进入命令行界面;b:用于进行重新启动;
        • 如果需要添加grub密码:在title上面添加password,使用命令grub-MD5-crypt:可以用于添加grub加密后的密码,格式为password --md5;
        • 如果密码文件放在了title下面.表示在装载内核时,需要输入密码;
  • BIOS:里面设置这操作系统的顺序,一次去查找这些设备的MBR,bootloader查找操作系统所在的分区,并且加载内核,转载进入内存;最后kernel 获得控制权,识别文件系统,探测内核,识别关键设备;
  • 查看系统的运行级别:
    • who -r:用于查看当前系统的运行级别;
    • runlevel:也是用于查看当前系统的运行级别的,前面的N表示没有进行级别切换;
      这里写图片描述
  • grub的损坏和修复:
    • 使用命令破坏前446个字节, dd if/dev/zero of=/dev/sda count=1 bs=400,建议使用虚拟机进行测试,不要再真机上面进行测试;
    • 使用 sync进行同步;
    • root(hd0,0)硬盘等设备,通常被grub识别为hd开头的设备,通常MBR位置0分区;
    • setup(hd0)安装:
    • 或者直接使用grub-install –root-directory=/grub所在的位置;往其他硬盘上装载grub;
    • 创建三个分区:创建一个boot目录,挂载一块磁盘,使用命令grub-install-root-directory=/mnt/dev/hda;
    • 编辑/mnt/boot/grub/grub.conf
    • 添加:
defaultlt=0
timeout=5
title Fake linux
root(hd0,0)
kernel /vmlinux
initrd /initrd.img
  • 再次强调一下千万不要拿grub.conf开玩笑,不然系统就毁了;否则就得自己写一个;使用 find (hd0,0)/ 来查找内核所在的位置;首先指定root (hd0,0) 在执行 kernel/vmlinux-2.6-补全文件所在的位置;在指定 initrd /initrd-2.6-补全,然后使用boot 进行重启;

  • 内核初始化的过程:

    • 1.设备探测;
    • 2.驱动初始化,需要从initrd 文件中装在驱动模块,redhat6 称为initramfs
    • 3.以只读方式挂载根文件系统;
    • 4.装载第一个进程init,PID1的进程;
  • /sbin/init:通常读取的文件是/etc/inittab

    • upstart:一个可执行程序,速度比较快redhat6.0以后开始使用,可以用于并行启动进程;
    • systemd:并行启动多个进程的init进程,并行能力更强,但是可能不太稳定,基于事件启动;redhat5redhat6上面的init进程是不相同的,配置文件也不相同;init 都是inittaab切割后的各种片,每一个文件都是基于事件驱动的方式来启动的;
  • redhat5/etc/inittab文件:
    这里写图片描述

    • 三个冒号分开的四段:
      • ID:表示标识符,必须与每一行都不相同;
      • runlevel:表示在那个级别下执行这个动作;
      • action:表示执行的动作,什么时候执行这个动作;
        • sysinit:表示系统初始化;
        • wait:表示级别切换到次级别时,执行一次;
        • respawn:一旦程序终止,会重新启动;
      • process:要运行的进程程序;如果不指定级别,表示的就是所有级别;
    • K开头的表示停止,S开头的表示启动,文件里面的大多数表示的是链接文件,其实各个执行的级别后面代表的都是一个个服务或者脚本文件,然后通过一个脚本来同一控制这些脚本的执行;
    • /etc/inittab执行的任务:
      • 1.设定默认的运行级别;
      • 2.运行系统的初始化脚本;
      • 3.运行指定运行级别对应目录下的脚本;
      • 4.设定 Ctrl+Alt+delete 组合键的操作;
      • 5.启动虚拟终端(2345);
      • 6.启动图形终端(5级别);
      • 7.定义UPS电源在电源故障时,恢复时执行的脚本
  • /etc/rc.d/rc.sysinit完成的任务:

#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.
#

HOSTNAME=$(/bin/hostname)

set -m

if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
    HOSTNAME=localhost
fi

if [ ! -e /proc/mounts ]; then
	mount -n -t proc /proc /proc
	mount -n -t sysfs /sys /sys >/dev/null 2>&1
fi
if [ ! -d /proc/bus/usb ]; then
	modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
else
	mount -n -t usbfs /proc/bus/usb /proc/bus/usb
fi

#remount /dev/shm to set attributes from fstab #669700
mount -n -o remount /dev/shm >/dev/null 2>&1
#remount /proc to set attributes from fstab #984003
mount -n -o remount /proc >/dev/null 2>&1

. /etc/init.d/functions
* 1.激活`udev` 和 `selinux`;
* 2.根据`/etc/systl.conf`文件来设置内核参数;
* 3.设定时区时钟;
* 4.装载键盘映射;
* 5.启用交换分区;
* 6.设置主机名;
* 7.根文件系统检测,并且以只读方式重新挂载;
* 8.激活`RAID`设备和`LVM`设备;
* 9.启用磁盘配额;
* 10.根据`/etc/fstab`,检查并挂载其他文件系统;
* 11.清理过期的的锁和`PID`文件;
  • init:用户空间的主导程序,用户空间的管理都由init管理;

  • 内核的设计风格

  • 在内核启动之前,文件系统是没有启动的,内核所在的分区是由bootloader来识别的,所以bootloader需要来识别文件系统;根文件系统是访问其他目录或者文件的入口,根文件系统是自引用的,这个过程由内核完成,内核必须可以探测访问内核所在的分区,但是由于磁盘硬件的不同,这些驱动不可以全部做入内核,所以存在两种内核设计理念;

  • 单内核设计:把所有功能都做进内核,文件系统,进程管理等功能,逻辑上简单,但是导致内核系统十分庞大;

  • 微内核设计:将上述功能做成一个子系统,驱动程序,文件系统作为子系统,一个子系统坏掉,不影响正常启动,彼此之间的协调很复杂;

  • Linux 是单内核设计支持LWP轻量级进程,Linux对于线程的支持并不是很好;内核代码十分庞大,按照自己的实际需要进行编译安装,Linux同时也引入了微内核的思想;内核的设计是模块化的,有核心和其他模块组成,内核核心可以动态的加载所需要的内核模块,在/lib/modules/里面内核版本号命名的目录/模块之间是有依赖关系,有一个文件来解决依赖;命令一般为 vmlunuz-2.6.32目录在里面有文件系统,驱动程序,加密解密程序等;

  • linux采用模块化设计,由核心模块和外为模块组成;

    • 内核的核心功能称为ko,内核核心本身很小,在需要使用的时候,如果已经完成过编译,就只需要进行加载就可以了;
    • 外围模块: 大多数模块都在目录/lib/modules/内核版本号码里面,也就是内核所需要的模块在某个设备上,而访问该设备的驱动程序也在这个设备上;
    • 所以需要在内核和需要访问的是设备之间添加一个程序文件,这个文件不是事先编译好的,而这个程序文件,也就是这个文件并不是事先在编译内核是就提供的,而是根据内核和BISO生成的相关硬件配置信息,在安装操作系统时生成的一个文件,这个设备可以成为桥接设备;
      • 这个设备文件提供一个独立的文件系统,用于内核来访问,这是一个伪文件系统,用于临时的根切换,同时将该文件系统的/proc, /sys , /dev,转到真正的根文件系统;
    • redhat6bash-shell使用的是命令chroot,但是在rhel5上面使用的是nash提供的命令switch-root,
  • /lib/modules/内核版本号码:
    这里写图片描述

    • dep:表示的都是内核依赖文件;
    • alias:表示的是内核别名文件;
    • map:表示的是内核映射关系;
    • kernel:
      这里写图片描述
      • arch:表示和平台相关的文件;
      • crypto:表示和加解密相关的文件;
      • drivers:表示和驱动相关的文件;
      • fs:表示和文件系统相关的文件;
      • lib:表示依赖的库文件;
      • mm:表示的是内存管理相关的文件;
      • net:表示网络相关的文件,通常是驱动协议,不是驱动程序;
      • sound:表示和声音相关的文件;
  • nash shell 中提供了一个switch root来完成根切换;伪文件系统里面的文件可以讲内存中的一段空间模拟成硬盘来使用,这段空间称为ramdisk 或者 ram filesystem,使用这段空间来展开伪文件系统中的文件,内核访问根文件系统需要驱动程序和文件系统来进行访问;

  • 这段地址空间在rhel5上面称为ramdisk--->initrd,在rhel6上面ramfs-->initramfs

  • 用户空间的命令用于实现根切换的命令是chroot;

    • 首先创建一个目录chroot
    • 然后创建/bin/bash,在chroot里面的目录,也就是./bin/bash
    • 使用ldd /bin/bash依赖的库文件,并且建立库文件的相对目录,复制库文件到对应的目录里面;
    • 按照上面的过程同时还可以复制一些常见的命令文件过去,在这个目录底下,就可以执行这些文件;
      这里写图片描述
  • bootloader是完成kernelinitrd的加载的,最后将initrd交给kernel使用;

  • Init的功能:

    • 定义操作系统的运行级别:
      • 0:表示halt,表示停止操作系统,但是不关闭电源;
      • 1:single user root表示单用户模式,直接登录管理员,不适用密码登录,使用s或者 S或者single都可以进入单用户模式;
      • 2: multi user root:表示多用户模式,启用网络功能,但是不启用NFS等网络文件系统;
      • 3:multi user root:多用户模式,启用正常的系统功能,但是是文本模式;
      • 4:reserved:保留级别,暂时没有定义;
      • 5:multi user root:多用户启动图形界面;
      • 6:reboot:重启,如果定义为这个级别,系统会一直重新启动;
  • /etc/rc.d/rc.sysinit文件的内容:

    • Si::sysinit:/etc/rc.d/rc.sysinit.完成OS的初始化,里面对应的K开头的文件和S开头的文件,都是按照级别等级需要执行的,这些脚本都是Linux执行的服务脚本,对于这些脚本至少需要接受四个参数:start stop restart status,以及reload configtest;
    • 脚本的规范:
      • 服务脚本都有相同意义的两行chkconfig:用来定义定义这个脚本来创建一个链接,三组数字分别表示为:
        • 启动的运行级别:也就是这些程序在哪些运行级别下面运行;
        • SS启动的优先顺序:表示相对于其他应用程序的启动优先级;
        • KK关闭的优先顺序:表示相对于其他应用程序的关闭优先级别;
        • description:这个脚本文件完成的工作的一个大致的介绍;
    • chkconfig命令为此脚本来创建链接时,runlevels表示创建默认为S开头的连接,除此之外的级别默认创建为K开头的链接;S后面的启动优先级为SS所表示的数字,K后面关闭优先顺序为KK所代表的数字;runlevel后面可以为表示默认没有开头为S的链接;
    • chkconfig命令:
      • --list:用于列出所有独立守护进程的启动设定,可以使用chkconfig –list SERVICE_NAME查看某个具体的服务;
      • --add SERVICE_NAME:用于自动创建服务脚本所使用的链接;
      • --del SERVICE_NAME:用于删除服务的链接文件;
      • --level runlecvels SERVICE_NAME {on | off}:用于指定在那个级别开启或者关闭,如果省略级别指定默认为2345级别;
    • /etc/rc.d/rc.local文件,本质上是一个链接文件
      • 系统最后执行的一个脚本,可以用于自定义一些自己需要的服务,不方便写成脚本的
        服务,感觉很有用;
  • 使用chkconfig管理的服务通常称为独立守护服务,就是自己来管理自己应该在那些级别下面启动,在那些情况下开启;

  • 守护进程类型

  • 独立守护进程:服务的关闭启动等是自己进行管理,这种类型的进程适合于长时在线的服务;

  • 瞬时守护进程:不需要关联至运行级别;由xinetd来负责进行管理,xinetd也称为超级守护进程,但是超级守护进程xinetd是需要关联至运行级别的,超级守护进程是记录自己守护的瞬时守护进程是按需进行开启的,当需要访问时,xinetd通知相关的瞬时守护进程,完成服务后,瞬时守护进程就会关闭;
    这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值