文章目录
Linux启动流程
linux启动根据下边图片来进行说明
说明1:黑色的为主步骤,蓝色为分支步骤,绿色为注释。下面详解一下,也给自己加深印象
BIOS
BIOS(Basic Input Output System):基本输入输出系统。BIOS都存放在ROM(Read Only Memory,只读存储器)中。ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不能改,一旦烧录进去,用户只能验证写入的资料是否正确,不能再作任何修改。如果发现资料有任何错误,则只有舍弃不用。
1、上电自检:(POST:Power-On-Self-Test)是BIOS功能的一个主要部分。它负责完成对CPU、主板、内存、软硬盘子系统、显示子系统(包括显示缓存)、串并行接口、键盘、CD-ROM光驱等的检测。当我们计算机上的某一个硬件出现问题时,BIOS在这个阶段就会报错,导致无法启动。
2、Boot Squence:在完成POST自检后,ROM BIOS将按照系统CMOS设置中的启动顺序搜寻软硬盘驱动器及CDROM、网络服务器等有效的启动驱动器 ,读入操作系统引导记录,然后将系统控制权交给引导记录,由引导记录完成系统的启动。
BIOS完成这两个步骤后,就要交由MBR的bootloader来进行引导
读取MBR
MBR(Main Boot Record)称为主引导记录,它位于磁盘的0编号分区。大小为512bytes,其中446bytes中放置bootloader程序。64bytes放置分区表信息,2bytes用于MBR分区的有效检查
注意:bootloader引导加载器是一个程序,无法在逻辑卷上加载,只能是标准分区
对于bootloader来说,它的主引导程序分为两种:
LILO:LInux LOader,缺点:放到1024柱面之后的加载程序无法启动。现在已经用的很少
GRUB:Grand Uniform Bootloader,多系统启动程序。这里就以grub来进行说明:
grub的执行分为三个阶段:
stage1、存放在MBR分区,也就是bootloader。
stage1.5、MBR之后的扇区,让第1步中的bootloader能够识别出第3步的文件系统
stage2、存放在磁盘分区之上(/boot/grub),根据grub的配置文件(/boot/grub/grub.conf)查找内核信息,然后加载内核至内存中,并创建initrd(ramdisk)文件。而后把系统控制权交给内核。
initrd说明:
initrd:bootloader initialized RAM disk 是bootloader的初始化内存盘。该文件是在安装系统时自动产生的。并在stage2步骤同内核一起加载至内存中。在内核启动之后会先访问此文件系统,用来帮助挂载真正的根目录。centos5之前相对应的文件为initrd。centos6,7相对应的文件为initramfs
为什么要有这个文件?
由于linux面对的硬件架构不同,把所有市面上可见的硬件驱动写入内核中显然不太现实。所以内核中只保留了最基础的驱动。剩下的一部分驱动则在系统安装过程中写入了initrd中。
运行kernel
当内核接收到控制权后,会进行自身初始化:
1、探测可识别到的所有硬件设备
2、加载硬件驱动程序
3、以只读方式挂载根文件系统
4、运行用户空间的第一个程序/sbin/init
这时候系统的控制权全部交由init进程来管理
init
init进程是所有进程的父进程,在这一步,它主要根据配置文件、运行脚本来初始化系统。以便让用户以自己指定的某种方式运行系统。主要流程:
设置默认级别—>运行系统初始化脚本,完成系统初始化–>关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务–>设置登录终端[–> 启动图形终端]
1、init的运行级别
运行级别 | 解释 |
---|---|
0 | 关机 |
1 | 单用户模式,此级别会直接进入root用户,属于维护模式 |
2 | 多用户模式,此级别会启动网络功能,但不会启动NFS,属于维护模式 |
3 | 多用户模式,此级别只会启动文本界面,属于全功能模式 |
4 | 预留级别,此级别目前特别适用目的 |
5 | 多用户模式,此级别会启动图形界面,具有完全功能 |
6 | 重启 |
示例:
各级别之间的相互切换:
~# init #
级别查看:
[root@localhost ~]# who -r
运行级别 5 2019-04-02 17:04
init配置文件都在/etc/initab中,每行定义一种action以及与之对应的process
id:runlevels:action:process
#以下说明每个字符表示的含义
id:一个任务的标识符
runlevels:在哪些 级别下启动某些任务,如 #,###(代表级别数字) 也可以表示为空
action:在什么条件下启动任务、
process:任务,如启动程序、执行脚本等
# action的条件有如下几种:
wait:等待切换至此任务所在的级别时执行一次
respawn:一旦任务进行终止,就自动重新启动
indefault:设定默认级别,此时process为空,不能为0和6
sysinit:系统初始化,只有在系统重启或开始时,才会执行一次process
例如:
id:3:indefault: #表示设置默认级别为3
si::sysinit:/etc/rc.d/rc.sysinit #表示系统在重启或开机时,执行后面的rc.sysinit的脚本
2、系统初始化
系统初始化脚本放在/etc/rc.d/rc.sysinit文件中,该文件的主要功能:
1、设置主机名
2、设置欢迎信息
3、激活udev和selinux
4、挂载/etc/fstab文件中定义的所有文件系统
5、检测根文件系统,并以读写的方式重新挂载根文件系统
6、设置系统时钟
7、根据/etc/sysctl.conf文件中的配置来设置内核参数
8、激活LVM和raid设备
9、激活swap设备
10、加载额外的驱动程序
11、清理操作
系统初始化完成之后,系统开始执行关闭和开启一些服务脚本
3、关闭和开启相对应的服务
这一步系统会执行/etc/rc.d/rc #(#号代表运行级别,总共有7个级别) 下的脚本。其中K*是要关闭的服务,S*是要开启的服务。
#此处为rc0.d下的脚本
[root@ydong rc0.d]# ls
K01certmonger K15httpd K60crond K75blk-availability K84NetworkManager K89netconsole K99lvm2-monitor
K01libvirt-guests K15svnserve K60nfs K75netfs K84wpa_supplicant K89portreserve K99rngd
K01smartd K16abrt-ccpp K61nfs-rdma K75ntpdate K85mdmonitor K89rdisc K99sysstat
K02oddjobd K16abrtd K69rpcsvcgssd K75quota_nld K85messagebus K90network S00killall
K05atd K25sshd K72autofs K75udev-post K87irqbalance K92ip6tables S01halt
K05wdaemon K30postfix K73pcscd K76ypbind K87restorecond K92iptables
K10cups K30spice-vdagentd K73winbind K83bluetooth K87rpcbind K92pppoe-server
K10psacct K36mysqld K74acpid K83nfslock K88auditd K95firstboot
K10saslauthd K50dnsmasq K74haldaemon K83openct K88rsyslog K95rdma
K15htcacheclean K50kdump K74ntpd K83rpcgssd K88sssd K99cpuspeed
说明:
k*:要停止的服务;k##,优先级,数字越小,越先有限关闭;依赖的服务先关闭,而后关闭被依赖的服务
S*:要启动的服务;S##, 优先级,数字越小,越是优先启动;被依赖的服务先启动,而后启动依赖的服务
4、执行/etc/rc.d/rc.local脚本
此脚本功能主要放置用户需要开机就自动运行的命令
5、执行/sbin/login
最后一步执行/sbin/login,等待用户登录
说明:以上init的所有操作均是centos5上的操作,centos6上的init仍为/sbin/init,但是使用的upstart风格,centos7的init程序则变成了systemd。6和7同时兼容sysV init(也就是5的init程序)。
grub多系统引导程序
以上的grub只是作为centos启动流程里提了一下,此处将做详细说明。
grub作为一个引导程序,它的功能提供一个菜单,允许用户选择要启动的系统和不同的内核版本,把用户选择到的内核版本加载至内存中的特定空间,对其解压、展开。而后将控制权交给内核。
它目前有两个版本:
grub 0.x:grub legacy(centos6使用)
grub 1.x:grub2(centos7使用)
grub执行的步骤
stage1:即写入MBR的bootloader程序。
stage1.5:执行mbr之后的扇区,让stage1中的bootloader程序能够识别磁盘分区/boot/grub上的文件并载入内存中。
注意:此处若是boot分区的文件系统类型不属于stage1_5的中的一个,则会借助ramdisk来加载在/lib64/moudles/下额外的文件系统驱动。
stage2:位于磁盘分区/boot/grub之上,该步骤主要给用户提供一个友好的菜单。并加载/boot下的内核文件至内存中。
grub的功用及配置文件
grub主要具有以下几种功用:
1、提供菜单、并提供交互式接口
e:编辑模式,用于编辑菜单
c:命令模式,交互式接口
2、加载用户选择的内核或操作系统
允许传递参数给内核
可隐藏此菜单
3、为菜单提供保护机制
为编辑菜单进行认证
为启动内核为操作系统进行认证
grub的配置文件:/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/sda3
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0 #设定默认启动的菜单项,编号从0开始
timeout=5 #指定菜单项等待用户选择的时长
splashimage=(hd0,0)/grub/splash.xpm.gz #指明菜单的背景图片
hiddenmenu #隐藏菜单,若要显式,在启动时按下ESC
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/sda2 rhgb quiet 启动的内核,指定根文件所在系统分区,后面为一些参数,下面会说明
initrd /initramfs-2.6.32-642.el6.x86_64.img #指明ramfs文件
~
注意:在一个正常的操作系统中查看/boot/grub/grub.conf文件,可以在NOTICE段看到提示,说你是否拥有一个独立的boot分区?如果有则意味着kernel和initrd的路径是从/开始的而不是/boot开始的,如/vmlinuz-xxx,如果没有独立的boot分区,则kernel和initrd的路径中需要指明boot路径,例如Boot没有分区而是在/文件系统下的一个目录,则/boot/vmlinuz-xxx。
root (hd0,0)定义grub识别的根。一般定义的都是boot所在的分区,grub只能识别hd,所以这里只能使用hd,hd0表示在第一块磁盘上,hd0,0的第二个0表示boot在第一个分区上,grub2在分区的计算上是从1开始的,这是传统grub和grub2不同的地方。
kernel定义内核文件的路径和启动参数,等价于grub2的linux命令或linux16命令。首先说明参数,ro表示只读,root=/dev/sda[N]或者root=UUID="device_uuid_num"指定根文件系统所在的分区,这是必须的参数。rhgb表示在操作系统启动过程中使用图形界面输出一些信息,将其省略可以加快启动速度,quiet表示启动操作系统时静默输出信息。再说明路径,如果是boot是独立分区的,则kernel的路径定义方式为/vmlinuz-xxx,如果没有独立分区,则指明其绝对路径,一般都是在根文件系统下的目录,所以一般为/boot/vmlinuz-xxx。
initrd定义init ramdisk的路径,路径的定义方式同kernel。除了路径之外没有任何参数。
grub的命令行接口
直接输入grub,将会出命令行接口。下面介绍常用选项
[root@ydong ~]# grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
grub> help
选项 | 说明 |
---|---|
help | 获取帮助 |
help KEYWORD | 详细帮助信息 |
find (hd#,#) /pah/to/somefile | 查找文件 |
root(hd#,#) | 设定grub的根 |
kernel /PATH/TO/SOMEFILE | 指定本次要启动的内核文件 |
initrd /PATH/TO/INITRAMFS_FILE | 设定为选定的内核提供额外文件的ramdisk,ramdisk必须与内核版本恩完全匹配 |
boot | 引导启动选定的内核 |
手动在grub命令行接口启动系统:
root (hd#,#)
kernel /vimlinuz-VERSION-RELEASE ro root=/dev/DEVICE
initrd /initramfs-VERSION-RELEASE.img
boot
进入单用户模式:
centos6:
1、编辑grub菜单(选定要编辑的title,然后使用e命令)
2、在选定的kernel后附加:
1,s,S或single都可以
3、在kernel所在行,键入"b"命令
CentOS 7:
centos7的grub2界面会有两个入口,正常系统入口和救援模式,
e 键进入edit 模式。
找到以 linux16 开头的行,注意:只在该行里面进行操作。
1:
(1)把 ro更改成 rw ;(把只读更改成可写)
(2)把 rhgb quiet 删除;(quiet静默模式,可以不删)
(3)增加 init=/bin/bash;(或init=/bin/sh,指定shell环境)
(4) 按下 ctrl+x 来启动系统。
.....修改操作......
(5)重启
2:
(1)该行最后输入 rd.break
(2)ctrl+x 启动系统
(3)进去后输入命令 mount,发现根为/sysroot/,并且不能写,只有ro=readonly权限;
mount -o remount,rw /sysroot/,重新挂载,之后mount,发现有了r,w权限;
(4)chroot /sysroot/ 改变根
.....修改操作......
(5)ctrl+d 或者 exit 退出
(6)重启
grub的安装
(1)grub-install 命令
使用格式:grub-install --root-directory=/PATH/TO/rootDIR DEVICE
~]# grub-install --root-directory=/ /dev/sda3
~]# sync
(2)grub命令(shell中输入)
~]# grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit
~]# sync
(3)如果mbr中的bootloader程序损坏
插入一个系统引导光盘,进入救援模式重新安装grub
grub练习
新加硬盘,提供直接单独运行bash系统;
1、首先,我们先新添加一块硬盘sdb。
[root@bogon ~]# fdisk -l
Disk /dev/sda: 128.8 GB, 128849018880 bytes
255 heads, 63 sectors/track, 15665 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000150b0
Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 15666 125316096 8e Linux LVM
Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
2、我们分别来创建3个分区,分别为作grub启动的sdb1、和作为grub根的sdb2,外加一个swap分区
[root@bogon ~]# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x63ffbd19.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-2610, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +500M
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (66-2610, default 66):
Using default value 66
Last cylinder, +cylinders or +size{K,M,G} (66-2610, default 2610): +5G
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (720-2610, default 720):
Using default value 720
Last cylinder, +cylinders or +size{K,M,G} (720-2610, default 2610): +2G
Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 82
Changed system type of partition 3 to 82 (Linux swap / Solaris)
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@bogon ~]# partx -a /dev/sdb
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
BLKPG: Device or resource busy
error adding partition 3
[root@bogon ~]# cat /proc/partitions
major minor #blocks name
8 0 125829120 sda
8 1 512000 sda1
8 2 125316096 sda2
8 16 20971520 sdb
8 17 522081 sdb1
8 18 5253255 sdb2
8 19 2104515 sdb3
253 0 52428800 dm-0
253 1 2031616 dm-1
253 2 70852608 dm-2
4、分别将sdb1、sdb2、sdb3的文件系统格式化为ext4、ext4和swap。
[root@bogon ~]# mke2fs -t ext4 /dev/sdb1
[root@bogon ~]# mke2fs -t ext4 /dev/sdb2
[root@bogon ~]# mkswap /dev/sdb3
5、安装grub时,grub会自动的去寻找boot目录来进行安装,所以我们创建一个/mnt/boot的目录,并将sdb1挂载至此处。
[root@bogon ~]# mkdir /mnt/boot
[root@bogon ~]# mount /dev/sdb1 /mnt/boot
[root@bogon boot]# ls
lost+found
##以下这步为grub安装。
[root@bogon 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
6、创建一个grub的根,并将sdb2挂载至此处。
[root@bogon ~]# mkdir /mnt/sysroot
[root@bogon ~]# mount /dev/sdb2 /mnt/sysroot/
#此根需要与当前系统根上的目录一样,如果需要运行程序或者运行某些命令的话,只需将同等路径下的命令程序复制到相对应Grub根上的目录即可。
[root@bogon sysroot]# mkdir -pv root dev proc sys tmp mnt home var bin sbin lib lib64 etc
[root@bogon sysroot]# cp /bin/bash ./bin
#复制完命令还不行,我们需要将它依赖的动态库也复制到相对应的路径目录里。
[root@bogon sysroot]# ldd /bin/bash
linux-vdso.so.1 => (0x00007ffcd30af000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f47d96ca000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f47d94c6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f47d9131000)
/lib64/ld-linux-x86-64.so.2 (0x00007f47d98f6000)
[root@bogon sysroot]# cd
[root@bogon ~]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/libc.so.6 /mnt/sysroot/lib64
[root@bogon ~]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64
##切换根来尝试是否成功
[root@bogon ~]# chroot /mnt/sysroot/
bash-4.1# hklj
7、将当前系统下的内核和initrd文件复制到/mnt/boot目录下。并编写grub配置文件(grub安装好之后需要自己现写配置文件)。
[root@bogon ~]# cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/vmlinuz
[root@bogon ~]# cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot/initramfs
#以下为配置文件内容
default=0
timeout=10
title mycentos
root (hd0,0)
kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash
initrd /initramfs
~
8、将做好的此块硬盘添加至新虚拟机里即可。
练习:分别用while、for循环检测10.0.0.1/24网段存活的IP地址
10.0.0.1/24网段的IP地址范围为:10.0.0.1-10.0.0.254,以下演示为前两个ip地址。
while循环:
#!/bin/bash
declare -i ip=1;
while [ $ip -ne 3 ]; do
{
ping -c 1 10.0.0.$ip >/dev/null
if [ $? -eq 0 ];then
echo "ipaddress is : 10.0.0.$ip running"
elif [ $? -ne 0 ];then
echo "ipaddress is : 10.0.0.$ip down"
fi
}
let ip++
done
[root@localhost ~]# bash ipaddr.sh
ipaddress is : 10.0.0.1 down
ipaddress is : 10.0.0.2 down
for循环:
#!/bin/bash
for ip in {1..3};do
ping -c 1 10.0.0.$ip >/dev/null
if [ $? -eq 0 ];then
echo "address 10.0.0.$ip is running"
else
echo "address 10.0.0.$ip is down"
fi
let ip++
done
~
[root@localhost ~]# bash ipaddr-for.sh
address 10.0.0.1 is down
address 10.0.0.2 is down
address 10.0.0.3 is down
练习:while循环打印出乘法口诀
1 #!/bin/bash
2 declare -i i=1
3 while [ $i -lt 10 ];do
4 {
5 declare -i j=1
6 while [ $j -le $i ];do
7 echo -n "$j * $i "
8 let j++
9 done
10 }
11 echo " "
12 let i++
13 done
~
[root@localhost ~]# bash chengfa.sh
1 * 1
1 * 2 2 * 2
1 * 3 2 * 3 3 * 3
1 * 4 2 * 4 3 * 4 4 * 4
1 * 5 2 * 5 3 * 5 4 * 5 5 * 5
1 * 6 2 * 6 3 * 6 4 * 6 5 * 6 6 * 6
1 * 7 2 * 7 3 * 7 4 * 7 5 * 7 6 * 7 7 * 7
1 * 8 2 * 8 3 * 8 4 * 8 5 * 8 6 * 8 7 * 8 8 * 8
1 * 9 2 * 9 3 * 9 4 * 9 5 * 9 6 * 9 7 * 9 8 * 9 9 * 9
内核
内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。它的设计分为两大流派:单内核和双内核。
内核的主要功能:
内核的组成部分:
kernel:内核核心,一般为bzimage,通常位于/boot目录下,其名称为vmlinuz-VERSION-release
kernel object:内核对象,即内核模块,一般放置于/lib/modules/VERSION-release/
注意: 内核模块和内核核心版本一定要严格匹配
systemd、upstart和sysv的区别
https://www.cnblogs.com/baiyw/p/3504419.html
网络内核参数以及相关问题解释
https://help.aliyun.com/knowledge_detail/52868.html