Linux系统启动流程

2017年2月3日13:54:11 发表评论 2,868 ℃

Linux系统启动流程

PC:OS(Linux)POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-->initrd-->(ROOTFS)/sbin/init(/etc/inittab)启动的服务不同:

运行级别:0-6

0:关机(halt)1:单用户模式(single user mode)启动以后不需要root密码,直接以管理员登录根(s ,S ,single ,1都表示1级别)2:多用户模式(multi user mode),不启用NFS3:正常多用户模式(multi user mode text mode)文本模式4:保留级别5:图形终端模式(multi user mode ,graphic mode)6:重启(reboot)

详解启动过程

bootloader(MBR)

LILO:Linux Loader 不支持8G以上的分区引导

GRUB:GRand Unified Bootloader

Stage1:MBR

Stage1_5:识别常见的不同的文件系统

Stage2:/boot/grub

grub.conf文件:

default=0  #设定默认启动的title的编号,从0开始
timeout=5  #等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz  #grub的背景图片
hiddenmenu   #隐藏菜单

password --md5 $1$nTXq0/$87SaMxaKgOo.QWCGjA4FP. #此选项设置以后,启动编辑grub.conf需要输入此密码
title CentOS (2.6.32-642.3.1.el6.i686) #内核标题,或操作系统名称,字符串,可以自由修改
root (hd0,0)  #内核文件所在的设备:对grub而言,所有类型硬盘一律hd:(hd#,N),#表示第几个磁盘;最后的N表示对应的磁盘分区
kernel /vmlinuz-2.6.32-642.3.1.el6.i686 ro root=UUID=7a707d58-36d1-4f7e-8f59-d306f79b96dc rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD quiet(屏蔽内核初始化大部分信息) SYSF rhgb crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM  #内核文件路径,及传递给内核的参数
initrd /initramfs-2.6.32-642.3.1.el6.i686.img  #ramdisk文件路径

password --md5 $1$nTXq0/$87SaMxaKgOo.QWCGjA4FP.  #此选项设置以后,启动内核需要输入密码

安装grub stage1

#grub

grub>root (hd0,0)

grub>setup (hd0)

安装grub第二种方式

#grub-install --root-directory=/path/to/boot's_parent_dir  /PATH/TO/DEVICE

系统启动缺少grub.conf文件:

grub>find (查找内核文件)

grub>root (hd#,N)   (root (hd0,然后按tab键,会有显示,把type 0x83的分区位置都得试一下)

grub>kernel /path/to/kernel_file   ( kernel /vmlinuz-2.6.32-573.el6.x86_64   [如果出现 报错,就重启加上根分区磁盘 ro root=/dev/sda2])

grub>initrd /path/to/initrd_file  (initrd /initramfs-2.6.32-573.el6.x86_64.img)

grub>boot

Kernel初始的过程:

1、设备探测

2、驱动初始化(可能会从initrd (initramfs))

3、以只读挂载根文件系统

4、装载第一个进程init (PID:1)

/sbin/init:(/etc/inittab)

upstart:Ubuntu 、redhat6.0+ 

/etc/inittab 

/etc/init/*.conf

systemd:

id:runlevels:action:process

id:3:initdefault:

id:标识符

runlevels:在哪个级别运行此行

process:要运行的程序

ACTION:

initdefault:设定默认运行级别

sysinit:系统初始化

wait:等待级别切换完成

respawn:一旦程序终止,会重新启动

/etc/rc.d/rc.sysinit完成的任务:

1、激活udev和selinux
2、根据/etc/sysctl.conf文件,来设定内核参数
3、设定时钟时区
4、装载键盘映射
5、启用交换分区
6、设置主机名
7、根文件系统检测,并以读写方式重新挂载
8、激活RAID和LVM设置
9、启用磁盘配额
10、根据/etc/fstab ,检查并挂载其他文件系统
11、清理过期的锁和PID文件
for I in /etc/rc3.d/K*;do

$I stop

done

for I in /etc/rc3.d/S*;do

$I  start

done
##:关闭或启动的优先次序,数据越小越优先被选定
先关闭以K开头的服务,后启动以S开头的服务

OS初始化

10:0:wait:/etc/rc.d/rc 0

rc0.d/

K*

stop

S*

start

/etc/rc.d/init.d , /etc/init.d
服务类脚本:

start
SysV:/etc/rc.d/init.d

start|stop|restart|status
reload(不重启重新加载配置文件)|configtest(检查配置文件的语法是否有错误)

chkconfig

# chkconfig :runlevels SS KK 

当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevels表示默认创建为S*开头的连接,-表示没有级别默认为S*开头的连接;除此之外的级别默认创建K*开头的链接:

S后面的启动优先级为SS所表示的数字;K后面关闭的优先次序为KK所表示的数字

# description:用于说明此脚本的简单功能;\,续行符

chkconfig命令:

chkconfig --list :查看所有独立守护服务的启动设定:独立守护进程

chkconfig --list SERVICE_NAME 单独查看某个服务的启动设定

chkconfig --add SERVICE_NAME 添加到服务列表

chkconfig --del SERVICE_NAME 删除服务链接

chkconfig [--level RUNLEVELS] SERVICE_NAME {on|off}

如果省略级别指定,默认为2345级别

/etc/rc.d/rc.local:系统最后启动的一个服务,准确说:执行的一个脚本

/etc/inittab的任务(redhat5):

1、设定默认运行级别

2、运行系统初始化脚本( /etc/rc.d/rc.sysinit)

3、运行指定运行级别对应目录下的脚本

/etc/rc.d/init.d/

/etc/rc.d/rc#.d

4、设定Ctrl+Atl+Del组合键的操作

5、定义UPS电源在电源故障/恢复时执行的操作

6、启动虚拟终端(2345级别)

7、启动图形终端(5级别)

守护进程的类型:

独立守护进程

xinetd:超级守护进程,代理人

瞬时守护进程:不需要关联之运行级别

核心:/boot/vmlinux-version

内核模块(ko):/lib/modules/version

内核设计:

单内核:模块化设计

微内核

装载模块

insmod

modprobe

www.kernel.org

用户空间访问、监控内核的方式:

/proc, /sys

伪文件系统

/proc/sys:此目录中的文件很多是可读写的

/sys/: 某些文件可写

设定内核参数值的方法:

echo VALUE > /proc/sys/to/somefile

sysctl -w kernel.hostname=

能立即生效,但无法永久有效

永久有效,但不能立即生效/etc/sysctl.conf

修改文件完成之后,执行如下命令可立即生效:

sysctl -p

sysctl -a:显示所有的内核参数及其值

内核模块管理:

lsmod:查看

modprobe MOD_NAME:装载某模块

modprobe -r MOD_NAME:卸载某模块

modinfo MOD_NAME:查看模块的具体信息

insmod /PATH/TO/MODULE_FILE 装载模块

rmmod MOD_NAME 卸载模块

depmod /PATH/TO/MODLIES_DIR 保存依赖关系

内核中的功能除了核心功能之外,在编译时,大多功能都有三种选择

1、不使用此功能

2、编译成内核模块

3、编译进内核

如何手动编译内核:

make gconfig:Gnome桌面环境使用,需要安装图形开发库

make kconfig : KDE桌面环境使用,需要安装图形开发

make menuconfig(出错,安装yum install ncursesyum install ncurses-devel)

make

make modules_install

make install

如何实现部分编译:

1、只编译某子目录下的相关代码:

make dir/

make arch/

kake drivers/net/

2、只编译部分模块

make M=drivers/net/

3、只编译某一模块

make drivers/net/pcnet32.ko

4、将编译完成的结果放置于别的目录中

make O=/tmp/kernel

5、交叉编译

make ARCH=

screen命令:

screen -ls :显示已经建立的屏幕

screen:直接打开一个新的屏幕

Ctrl+a ,d:拆除屏幕

screen -r ID :还原回某屏幕

二次编译时清理,清理前,如果有需要,请备份配置文件.config

make clean

make mrproper

mkinitrd initrd文件路径 内核版本号

mkinitrd /boot/initrd-`uname -r`.img `uname -r`

制作一个精简系统:

步骤:

1、mkdir 创建一个boot分区  一个根分区,并格式化分区 

2、dev/sda1 挂载到 /test/boot/ dev/sda2 挂载到/test/sysroot

3、创建内核文件

cp /boot/vmlinuz-2.6.32-573.el6.x86_64 /test/boot/vmlinuxz  

4、创建initrd文件

①cd /tmp/test

②zcat /boot/initramfs-2.6.32-573.el6.x86_64.img | cpio -id 展开归档

③vim init 自定义修改

④find . | cpio -H newc --quiet -o | gzip -9 > /test/boot/initrd.gz 归档压缩

5、安装grub

①grub-install --root-directory=/test /dev/sda

②vim /test/boot/grub/grub.conf

default=0

timeout=5

title My Linux (2.6.32-573.el6.x86_64)

root (hd0,0)

kernel /vmlinuz

initrd /initramfs.gz

6、创建必要目录

mkdir -pv etc/rc.d/init.d bin sbin proc sys dev lib root mnt media /var/{log,run,lock/subsys,tmp} usr/{bin,shbin,local} tmp home opt boot

7、创建etc/inittab

vim /test/myroot/etc/inittab

id:3:initdefault:

8、创建etc/rc.d/rc.sysinit

vim /test/myroot/etc/rc.d/rc.sysinit

#!/bin/bash
#
echo -e "Welcome to \033[32m TangCongJiang\033[0m Linux"
/bin/bash

9、复制/sbin/init 和/bin/bash 到新根目录

cp /sbin/init /test/myroot/sbin/

cp /bin/bash /test/myroot/bin/

10、利用脚本copy命令以及命令依赖的库文件到新的根目录

#!/bin/bash

MYROOT=/www/myroot

cplib(){

  libdir=${1%/*}

  newlib=$MYROOT$libdir

  [ ! -d $newlib ] && mkdir -p $newlib

  [ ! -e $MYROOT$1 ] && cp $1 $newlib && echo -e "\033[35m$1 copy finished!\033[0m"

}

cpcmd(){

  cmddir=${1%/*}

  newcmd=$MYROOT$cmddir

  [ ! -d $newcmd  ]  && mkdir -p $newcmd

  [ ! -e $MYROOT$1 ] && cp $1 $newcmd

  for i in  `ldd $1 | grep -o "/.*lib\(64\)\?/[^[:space:]]\+"`;do

    cplib $i

  done

}

echo -ne "\033[34mPlease input Command:\033[0m"

read CMD

until [ $CMD == 'q' ];do

  ! which $CMD &>/dev/null && echo -ne "\033[31mCommand not exist,Please again input:\033[0m" && read CMD && continue

  COMMAND=`which $CMD | grep -v "alias" | grep  -o "[^[:space:]]\+"`

  cpcmd $COMMAND

  echo -e "\033[32m$COMMAND copy finished!\033[0m"

  echo -ne "\033[33mPlease input Command:\033[0m"

  read CMD

done

精简系统功能完善

#/etc/rc.d/init.d/functions

SCREEN=`stty -F /dev/console size 2>/dev/null`

COLUMNS=${SCREEN#* }

[ -z $COLUMNS ]&& COLUMNS=80

SPA_COL=$[$COLUMNS-14]

RED='\033[1;31m'

GREEN='\033[1;32m'

BLUE='\033[1;34m'

NORMAL='\033[0m'

success(){

  string=$1

  RT_SPA=$[$SPA_COL-${#string}]

  echo -n $string

  for i in `seq 1 $RT_SPA`;do

    echo -n " "

  done

    echo -e "[   ${GREEN}OK${NORMAL}   ]"

}

failde(){

  string=$1

  RT_SPA=$[$SPA_COL-${#string}]

  echo -n $string

  for i in `seq 1 $RT_SPA`;do

    echo -n " "

  done

    echo -e "[ ${RED}FAILED${NORMAL} ]"
}

1、关机重启;

#!/bin/bash

case $0 in

*reboot)

   COMMAND='/sbin/halt -p';;
*halt)
   COMMAND='/sbin/reboot';;
*)
   echo "Only call this script by *reboot OR *halt";;
esac
exec $COMMAND

/etc/rc.d/rc

#!/bin/bash

RUNLEVEL=$1

for i in /etc/rc.d/rc$RUNLEVEL.d/K*;do

    $i stop

done

for i in /etc/rc.d/rc$RUNLEVEL.d/S*;do

   $i start

done

2、主机名

/etc/rc.d/rc.sysinit 

#!/bin/bash

echo "Welcome to linux"

echo "Remount rootfs"

mount -n -o remount,rw /

mount -a

[  $? -eq 0 ] && success "Mount others filesystem"

echo "Set the hostname"

[  -f /etc/sysconfig/network  ] && .  /etc/sysconfig/network

[  -z $HOSTNAME -o $HOSTNAME == '(none)' ] && HOSTNAME=localhost

/bin/hostname $HOSTNAME

3、运行对应服务脚本

(服务样例脚本)

 /etc/rc.d/init.d/myservice

#!/bin/bash

#

# chkconfig:2345 45 55

# description:This is my services!

. /etc/rc.d/init.d/functions

NAME=myservice

FILE=/var/lock/subsys/$NAME

STATUS(){

if [  -e $FILE ];then

  echo -e "\033[32m$NAME is running... \033[0m"

else

  echo -e "\033[31m$NAME is stoped\033[0m"

fi 

}

START(){

  touch $FILE

  [ $? -eq 0 ] && success "Staring $NAME" || failed "Staring $NAME" 

}

STOP(){

  rm -f $FILE $>/dev/null

  [ $? -eq 0 ] && success "Stoping $NAME" || failed "stoping $NAME"   

}

USAGE(){

  echo "/etc/init.d/$NAME {start|stop|restart|status}"

}

case $1 in

start)

  START;;

stop)

  STOP;;

restart)

  echo "restarting...";;

status)

  STATUS ;;

*)

  USAGE;;
esac

4、启动终端;

/etc/inittab

1:2345:respawn:/sbin/agetty -n -1 /bin/bash 38400 tty1

1:2345:respawn:/sbin/agetty -n -1 /bin/bash 38400 tty2

终端提示信息:

/etc/issue文件的内容

5、定义单用户级别

/etc/init.d/single

. /etc/init.d/functions

if [ "$1" != "start" ]; then

   exit 0

fi

# this looks nicer

[ -x /usr/bin/clear ] && /usr/bin/clear

# Now go to the single user level.

echo $"Telling INIT to go to single user mode."

exec init -t1 S

6、装载网卡驱动,启用网络功能

/etc/rc.d/rc.sysinit 

  ....

 echo " Initializing network device..."

/sbin/inmod /lib/modules/mii.ko

/sbin/inmod /lib/modules/pcnet32.ko

ifconfig lo 127.0.0.1/8

[ $? -eq 0 ] && success "Activating loopback network device" || failed "

Activating loopback network device"

/etc/rc.d/init.d/network

#!/bin/bash

#chkconfig: 35 10 90

#description:network services

prog=network

. /etc/rc.d/init.d/functions

C>

. $CONF

start(){

  ifconfig eht0 $IPADDR/24 up

  [  -z $GATEWAY  ] && route add default gw $GATEWAY

}

 stop(){

  ifconfig eth0 down

}

status(){

  ifconfig eth0

}

usage(){

  echo "$prog:{start|stop|restart|status}"

}

case $1 in

start)

   start

   success "config network eht0";;

stop)

   success "Stop network eht0";;

restart)

   stop

   start

   success  "Restart network card eht0";;

status)

   status;;

*)

   usge;;

   exit 6

esac

7、rc.sysinit:挂载/etc/fstab 中定义的其他文件系统

grep -v -E "^$|^#" /etc/fstab | grep -E -v "\<swap|proc|sysfs\>" | awk '{print $1}' | while read LINE;do awk '{print $1}' /proc/mounts | grep  "^$LINE";done

8、设定内核参数:/etc/sysctl.conf

/etc/rc.d/rc.sysinit

sysctl -p &> /dev/null

[  $? -eq 0  ] && success "Set kernel parameter" || failed "

Set kernel parameter"

9、用户

PAM :pluggable Authentication Module

/etc/pam.d/*

绕过pam

/bin/login

nsswitch:Network Service Switch

框架:/etc/passwd , /etc/shadow , /etc/group
库: libnss_file.so , libnss_nis.so ,libnsss_ldap.so
配置文件:/etc/nsswitch.conf
NIS ,LDAP ,MYSQL

/etc/inittab

1:2345:respawn:/sbin/mingetty tty1

2:2345:respawn:/sbin/mingetty tty2

.bash_profile

PS1='[\u@\h \W]\$'

u:用户名

h:主机名

W:路径基名

export  PS1

busybox :1M

kernel+initrd(busybox)-->rootfs(busybox)

查看本机硬件设备信息:

1、cat /proc/cpuinfo

2、lsusb

3、lspci

4、hal-device

Hardware Abstract Layer

如何编译busybox(busybox-1.21.1  kernel-2.6.39.3):

①www.busybox.net下载源文件解压

②进入解压目录,执行 make menuconfig编译,然后保存退出 执行make install(glibc报错需要yum install glibc-static -y;kernel版本较低,需要下载高版本的kernel,复制include/mtd/ubi-user.h 到busybox/include/mtd目录)

③cp -a _install/* /tmp/busybox  mkdir -pv /tmp/busybox/{proc,sys,etc,dev,mnt/sysroot,lib/modules,tmp}

创建两个必要的设备文件:
# mknod  dev/console  c  5  1
# mknod  dev/null  c  1  3

④modinfo ext3 复制ext3库和依赖的库到 busybox/lib/modules目录

⑤在busybox目录创建init文件 ,给执行权限

添加如下内容:

#!/bin/sh

mount -t proc proc /proc

mount -t sysfs sysfs /sys

insmod /lib/modules/jbd.ko

insmod /lib/modules/ext3.ko

mdev -s

mount -t ext3 /dev/hda2  /mnt/sysroot
exec  switch_root  /mnt/sysroot  /sbin/init

制作initrd : find  .  | cpio  --quiet  -H newc  -o  | gzip  -9 -n > /test/boot/initrd.gz

⑥cp /boot/vmlinux  /mnt/boot/vmlinuz 

⑦安装grub  grub-install --root-directory=/test /dev/sda 创建grub.conf 

vim /test/boot/grub/grub.conf

default=0

timeout=5

title My Linux (2.6.32-573.el6.x86_64)

root (hd0,0) ro root=/dev/sda2

kernel /vmlinuz

initrd /initrd.gz

⑧cp _install/* /test/sysroot/ -a  

    rm linuxrc

    cd /test/sysroot/

    mkdir -pv  proc  sys  etc/rc.d/init.d  tmp  dev/pts  boot  var/{log,lock,run}  usr/lib root mnt media

   mknod  dev/console  c  5  1
   mknod  dev/null  c  1  3

⑨为init进程提供配置文件:

# vim  etc/inittab

添加如下内容:

::sysinit:/etc/rc.d/rc.sysinit

console::respawn:-/bin/sh

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount -a -r

⑩建立系统初始化脚本文件# vim  etc/rc.d/rc.sysinit

添加如下内容:

#!/bin/sh

echo -e "\tWelcome to  \033[31mMageEdu\033[0m Linux"

echo -e "Remounting the root filesystem ..."

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -o  remount,rw  / 

echo -e "Creating the files of device ..."

mdev -s 

echo -e "Mounting the filesystem ..."

mount -a

swapon -a

#echo -e "Starting the log daemon ..."

#syslogd

#klogd

#echo -e "Configuring loopback interface ..."

#ifconfig  lo  127.0.0.1/24

#ifconfig eth0 172.16.100.9/16

⑪为系统准备一个“文件系统表”配置文件/etc/fstab

# vim  etc/fstab

添加如下内容:

sysfs                   /sys                    sysfs   defaults        0 0

proc                    /proc                   proc    defaults        0 0

/dev/hda1               /boot                   ext3    defaults        0 0

/dev/hda2               /                       ext3    defaults        1 1

Kernel + initrd( busybox 制作 ,不提供ext3文件系统模块) + ROOTFS (busybox制作)

make arch/

arch/x86/bootbzImage

硬件驱动:initrd

initrd:仅需要提供内核访问真正的根文件系统所在设备需要的驱动

存储设备和文件系统相关的模块

系统初始化rc.sysinit :初始其他硬件的驱动程序;

ROOTFS:bushbox  ,init 不支持运行级别

/etc/inittab 格式也不尽相同

ash,bush

bash

内核设计风格:

RedHat,SUSE

核心:动态加载 内核模块
内核:/lib/modules/“内核版本号命名的目录”

vmlinuz-2.6.32
/lib/modules/2.6.32/
RedHat5:ramdisk-->initrd
RedHat6:ramfs-->initramfs

单内核:Linux(LWP)

核心:ko(kernel object 内核对象)

微内核:Windows ,Solaris(线程)

chroot命令:切换根目录

chroot /PATH/TO/TEMPROOT

chroot /test/virroot /bin/bash

ldd命令:查看命令支持的库文件

ldd /bin/bash  ldd /bin/mv

kickstart:三部分

命令段

必备命令

keyboard

lang

timezone 

rootpw --iscrpted

selinux  --disabled|--permissive

authconfig --useshadow

bootloader --location

clearpart --initlabel --linux

driverdisk --source=

firewail --disabled 

firstboot --disabled

test|graphical 

key  --skip

network --botoproto= --ip= --netmask= --geteway= --nameserver=

install|upgrade

可选命令

软件包 选择段,%packages

@package_group_name

package_name

-package_name

脚本段

%pre

%post

安装过程中,boot提示符中可以使用的命令  :

askmethod

dd

ip=

netmask=

geteway=

dns=

ks=http://
ks=cdrom:/
rescue:进入紧急救援模式

ksvalidator /bash/to/anaconda-ks.cfg 检查语法错误

system-config-kickstart & 启用图形化调试

mkisofs -R -b isolinux/isolinux.bin -no-emul-boot  -boot-load-size 4 -boot-info-table -o boot.iso  iso/ 创建光盘镜像

【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: