Linux系統(tǒng)啟動流程

2017年2月3日13:54:11 發(fā)表評論 4,102 ℃

Linux系統(tǒng)啟動流程

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以上的分區(qū)引導

GRUB:GRand Unified Bootloader

Stage1:MBR

Stage1_5:識別常見的不同的文件系統(tǒng)

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) #內核標題,或操作系統(tǒng)名稱,字符串,可以自由修改
root (hd0,0)  #內核文件所在的設備:對grub而言,所有類型硬盤一律hd:(hd#,N),#表示第幾個磁盤;最后的N表示對應的磁盤分區(qū)
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  #內核文件路徑,及傳遞給內核的參數(shù)
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

系統(tǒng)啟動缺少grub.conf文件:

grub>find (查找內核文件)

grub>root (hd#,N)   (root (hd0,然后按tab鍵,會有顯示,把type 0x83的分區(qū)位置都得試一下)

grub>kernel /path/to/kernel_file   ( kernel /vmlinuz-2.6.32-573.el6.x86_64   [如果出現(xiàn) 報錯,就重啟加上根分區(qū)磁盤 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、以只讀掛載根文件系統(tǒng)

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:系統(tǒng)初始化

wait:等待級別切換完成

respawn:一旦程序終止,會重新啟動

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

1、激活udev和selinux
2、根據(jù)/etc/sysctl.conf文件,來設定內核參數(shù)
3、設定時鐘時區(qū)
4、裝載鍵盤映射
5、啟用交換分區(qū)
6、設置主機名
7、根文件系統(tǒng)檢測,并以讀寫方式重新掛載
8、激活RAID和LVM設置
9、啟用磁盤配額
10、根據(jù)/etc/fstab ,檢查并掛載其他文件系統(tǒng)
11、清理過期的鎖和PID文件
for I in /etc/rc3.d/K*;do

$I stop

done

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

$I  start

done
##:關閉或啟動的優(yōu)先次序,數(shù)據(jù)越小越優(yōu)先被選定
先關閉以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目錄創(chuàng)建鏈接時,runlevels表示默認創(chuàng)建為S*開頭的連接,-表示沒有級別默認為S*開頭的連接;除此之外的級別默認創(chuàng)建K*開頭的鏈接:

S后面的啟動優(yōu)先級為SS所表示的數(shù)字;K后面關閉的優(yōu)先次序為KK所表示的數(shù)字

# description:用于說明此腳本的簡單功能;\,續(xù)行符

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:系統(tǒng)最后啟動的一個服務,準確說:執(zhí)行的一個腳本

/etc/inittab的任務(redhat5):

1、設定默認運行級別

2、運行系統(tǒng)初始化腳本( /etc/rc.d/rc.sysinit)

3、運行指定運行級別對應目錄下的腳本

/etc/rc.d/init.d/

/etc/rc.d/rc#.d

4、設定Ctrl+Atl+Del組合鍵的操作

5、定義UPS電源在電源故障/恢復時執(zhí)行的操作

6、啟動虛擬終端(2345級別)

7、啟動圖形終端(5級別)

守護進程的類型:

獨立守護進程

xinetd:超級守護進程,代理人

瞬時守護進程:不需要關聯(lián)之運行級別

核心:/boot/vmlinux-version

內核模塊(ko):/lib/modules/version

內核設計:

單內核:模塊化設計

微內核

裝載模塊

insmod

modprobe

www.kernel.org

用戶空間訪問、監(jiān)控內核的方式:

/proc, /sys

偽文件系統(tǒng)

/proc/sys:此目錄中的文件很多是可讀寫的

/sys/: 某些文件可寫

設定內核參數(shù)值的方法:

echo VALUE > /proc/sys/to/somefile

sysctl -w kernel.hostname=

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

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

修改文件完成之后,執(zhí)行如下命令可立即生效:

sysctl -p

sysctl -a:顯示所有的內核參數(shù)及其值

內核模塊管理:

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桌面環(huán)境使用,需要安裝圖形開發(fā)庫

make kconfig : KDE桌面環(huán)境使用,需要安裝圖形開發(fā)

make menuconfig(出錯,安裝yum install ncursesyum install ncurses-devel)

make

make modules_install

make install

如何實現(xiàn)部分編譯:

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`

制作一個精簡系統(tǒng):

步驟:

1、mkdir 創(chuàng)建一個boot分區(qū)  一個根分區(qū),并格式化分區(qū) 

2、dev/sda1 掛載到 /test/boot/ dev/sda2 掛載到/test/sysroot

3、創(chuàng)建內核文件

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

4、創(chuàng)建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、創(chuàng)建必要目錄

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、創(chuàng)建etc/inittab

vim /test/myroot/etc/inittab

id:3:initdefault:

8、創(chuàng)建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

精簡系統(tǒng)功能完善

#/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 中定義的其他文件系統(tǒng)

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、設定內核參數(shù):/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下載源文件解壓

②進入解壓目錄,執(zhí)行 make menuconfig編譯,然后保存退出 執(zhí)行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}

創(chuàng)建兩個必要的設備文件:
# mknod  dev/console  c  5  1
# mknod  dev/null  c  1  3

④modinfo ext3 復制ext3庫和依賴的庫到 busybox/lib/modules目錄

⑤在busybox目錄創(chuàng)建init文件 ,給執(zhí)行權限

添加如下內容:

#!/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 創(chuàng)建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

⑩建立系統(tǒng)初始化腳本文件# 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

?為系統(tǒng)準備一個“文件系統(tǒng)表”配置文件/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文件系統(tǒng)模塊) + ROOTFS (busybox制作)

make arch/

arch/x86/bootbzImage

硬件驅動:initrd

initrd:僅需要提供內核訪問真正的根文件系統(tǒng)所在設備需要的驅動

存儲設備和文件系統(tǒng)相關的模塊

系統(tǒng)初始化rc.sysinit :初始其他硬件的驅動程序;

ROOTFS:bushbox  ,init 不支持運行級別

/etc/inittab 格式也不盡相同

ash,bush

bash

內核設計風格:

RedHat,SUSE

核心:動態(tài)加載 內核模塊
內核:/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/ 創(chuàng)建光盤鏡像

【騰訊云】云服務器、云數(shù)據(jù)庫、COS、CDN、短信等云產品特惠熱賣中

發(fā)表評論

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