當前位置:學者齋 >

IT認證 >Linux認證 >

Linux系統啟動的詳細過程和步驟

Linux系統啟動的詳細過程和步驟

Linux作業系統藉助於Internet網路,並通過全世界各地計算機愛好者的共同努力,已成為今天世界上使用最多的一種UNIX 類作業系統,並且使用人數還在迅猛增長。下面小編準備了關於Linux系統啟動的詳細過程和步驟,提供給大家參考!

Linux系統啟動的詳細過程和步驟

  第一階段:

系統上電開機後,主機板BIOS(Basic Input / Output System)執行POST(Power on self test)程式碼,檢測系統外圍關鍵裝置(如:CPU、記憶體、顯示卡、I/O、鍵盤滑鼠等)。硬體配置資訊及一些使用者配置引數儲存在主機板的CMOS( Complementary Metal Oxide Semiconductor)上(一般64位元組),實際上就是主機板上一塊可讀寫的RAM晶片,由主機板上的電池供電,系統掉電後,資訊不會丟失。

執行POST程式碼對系統外圍關鍵裝置檢測通過後,系統啟動自舉程式, 根據我們在BIOS中設定的啟動順序搜尋啟動驅動器(比如的硬碟、光碟機、網路伺服器等)。選擇合適的啟動器,比如通常情況下的硬碟裝置,BIOS會讀取硬碟裝置的第一個扇區(MBR,512位元組),並執行其中的程式碼。實際上這裡BIOS並不關心啟動裝置第一個扇區中是什麼內容,它只是負責讀取該扇區內容、並執行,BIOS的任務就完成了。此後將系統啟動的控制權移交到MBR部分的程式碼。

注: 在我們的現行系統中,大多關鍵裝置都是連在主機板上的。因此主機板BIOS提供了一個作業系統(軟體)和系統外圍關鍵裝置(硬體)最底級別的介面,在這個階段,檢測系統外圍關鍵裝置是否“準備好”,以供作業系統使用。

  第二階段:

BIOS通過下面兩種方法之一來傳遞引導記錄:

第一, 將控制權傳遞給initial program loader(IPL),該程式安裝在磁碟主引導記錄(MBR)中

第二, 將控制權傳遞給initial program loader(IPL),該程式安裝在磁碟分割槽的啟動引導扇區中

無論上面的哪種情況中,IPL都是MBR的一部分並應該儲存於一個不大於446位元組的磁碟空間中,因為MBR是一個不大於512位元組的空間。

因此IPL僅僅是GRUB的第一個部分(stage1),他的作用就是定位和裝載GRUB的第二個部分(stage2);stage2對啟動系統起關鍵作用,該部分提供了GRUB啟動選單和互動式的GRUB的shell。啟動選單在啟動時候通過/boot/grub/檔案所定義的內容生成。在啟動選單中選擇了kernel之後,GRUB會負責解壓和裝載kernel image並且將initrd裝載到記憶體中。最後GRUB初始化kernel啟動程式碼。

完成之後後續的引導權被移交給kernel。

假設Boot Loader為grub (grub-0.97),其引導系統的過程如下:

grub分為stage1 (stage1_5) 和stage2兩個階段。stage1可以看成是initial program loaderI(IPL),而stage2則實現了grub的主要功能,包括對特定檔案系統的支援(如ext2,ext3,reiserfs等),grub自己的shell,以及內部程式(如:kernrl,initrd,root)等。

stage 1:MBR(512 位元組,0頭0道1扇區),前446位元組存放的是 stage1,後面存放硬碟分割槽表資訊,BIOS將stag1載入記憶體中0x7c00處並跳轉執行。stage1(/stage1/start.S)的任務非常單純,僅僅是將硬碟0頭0道2扇區讀入記憶體。0頭0道2扇區內容是原始碼中的/stage2/start.S,編譯後512位元組,它是stage2或者stage1_5的入口。

注:此時stage1是沒有能力識別檔案系統的,其定位硬碟0頭0道2扇區過程如下:

BIOS將stage1載入記憶體0x7c00處並執行,然後呼叫BIOS INIT13中斷,將硬碟0頭0道2扇區內容載入記憶體0x7000處,然後呼叫copy_buffer將其轉移到記憶體0x8000處。定位0頭0道2扇區有兩種定址方式:LBA、CHS。

start.S的主要功能是將stage2或stage1_5從硬碟載入記憶體,如果是stage2,則載入0x820處;如果是 stage1_5,則載入0x2200處。

注:這裡的stage2或者stage1_5不是/boot分割槽/boot/grub目錄下的檔案,這個時候grub還沒有能力識別任何檔案系統。分以下兩種情況:

(1)假如start.S讀取的是stage1_5,它存放在硬碟0頭0道3扇區向後的位置,stage1_5作為stage1和stage2中間的橋樑,stage1_5有識別檔案系統的能力,此後grub才有能力去訪問/boot分割槽/boot/grub目錄下的 stage2檔案,將stage2載入記憶體並執行。

(2)假如start.S讀取的是stage2,同樣,這個stage2也不是/boot分割槽/boot/grub目錄下的stage2,這個時候start.S讀取的是存放在/boot分割槽Boot Sector的stage2。這種情況下就有一個限制:因為start.S通過BIOS中斷方式直接對硬碟定址(而非通過訪問具體的檔案系統),其定址範圍有限,限制在8GB以內。因此這種情況需要將/boot分割槽分在硬碟8GB定址空間之前。

假如是情形(2),我們將/boot/grub目錄下的內容清空,依然能成功啟動grub;假如是情形(1),將/boot/grub目錄下stage2刪除後,則系統啟動過程中grub會啟動失敗。

這個地方經常要進行的操作:

是關於grub常用的幾個指令對應的函式:

grub>root (hd0,0) --root指令為grub指定了一個根分割槽

grub>kernel /5 --kernel指令將作業系統核心載入記憶體

grub>module /5xen ro root=/dev/sda2 --module指令載入指定的模組

grub>module / --指定initrd檔案

grub>boot --boot 指令呼叫相應的啟動函式啟動OS核心

  第三階段:

如階段2所述,grub>boot指令後,系統啟動的控制權移交給kernel。Kernel會立即初始化系統中各裝置並做相關配置工作,其中包括CPU、I/O、儲存裝置等。

關於裝置驅動載入,有兩部分:一部分裝置驅動編入Linux Kernel中,Kernel會呼叫這部分驅動初始化相關裝置,同時將日誌輸出到kernel message buffer,系統啟動後dmesg可以檢視到這部分輸出資訊。另外有一部分裝置驅動並沒有編入Kernel,而是作為模組形式放在initrd(ramdisk)中。

在2.6核心中,支援兩種格式的initrd,一種是2.4核心的檔案系統映象image-initrd,一種是cpio格式。以 cpio 格式為例,核心判斷initrd為cpio的檔案格式後,會將initrd中的內容釋放到rootfs中。

initrd是一種基於記憶體的檔案系統,啟動過程中,系統在訪問真正的.根檔案系統/時,會先訪問initrd檔案系統。將initrd中的內容開啟來看,會發現有bin、devetc、lib、procsys、sysroot、init等檔案(包含目錄)。其中包含了一些裝置的驅動模組,比如scsi ata等裝置驅動模組,同時還有幾個基本的可執行程式 insmod, modprobe, lvm,nash。主要目的是載入一些儲存介質的驅動模組,如上面所說的scsi ideusb等裝置驅動模組,初始化LVM,把/根檔案系統以只讀方式掛載。

initrd中的內容釋放到rootfs中後,Kernel會執行其中的init檔案,這裡的init是一個指令碼,由nash直譯器執行。這個時候核心的控制權移交給init檔案處理,我們檢視init檔案的內容,主要也是載入各種儲存介質相關的裝置驅動。

驅動載入後,會建立一個根裝置,然後將根檔案系統/以只讀的方式掛載。這步結束後釋放未使用記憶體並執行switchroot,轉換到真正的根/上面去,同時執行/sbin/init程式,開啟系統的1號程序,此後系統啟動的控制權移交給 init 程序。關於switchroot是在nash中定義的程式。

Linux Kernel需要適應多種不同的硬體架構,但是將所有的硬體驅動編入Kernel又是不實際的,而且Kernel也不可能每新出一種硬體結構,就將該硬體的裝置驅動寫入核心。實際上Linux Kernel僅是包含了基本的硬體驅動,在系統安裝過程中會檢測系統硬體資訊,根據安裝資訊和系統硬體資訊將一部分裝置驅動寫入 initrd 。這樣在以後啟動系統時,一部分裝置驅動就放在initrd中來載入。

  第四階段:

init程序起來後,系統啟動的控制權移交給init程序。

/sbin/init程序是所有程序的父程序,當init起來之後,它首先會讀取配置檔案/etc/inittab,進行以下工作:

1)執行系統初始化指令碼(/etc/rc.d/nit),對系統進行基本的配置,以讀寫方式掛載根檔案系統及其它檔案系統,到此係統基本算執行起來了,後面需要進行執行級別的確定及相應服務的啟動;

2)確定啟動後進入的執行級別;

3) 執行/etc/rc.d/rc,該檔案定義了服務啟動的順序是先K後S,而具體的每個執行級別的服務狀態是放在/etc/rc.d/rcn.d(n=0~6)目錄下,所有的檔案均連結至/etc/init.d下的相應檔案。

4)有關key sequence的設定

5) 有關UPS的指令碼定義

6)啟動虛擬終端/sbin/mingetty

7)在執行級別5上執行X

這時呈現給使用者的就是最終的登入介面。

至此,系統啟動過程完畢:)

說明:

1)/etc/rc.d/nt -- System Initialization Tasks

它的主要工作有:

配置selinux,

系統時鐘,

核心引數(/etc/),

hostname,

啟用swap分割槽,

根檔案系統的檢查和二次掛載(讀寫),

啟用RAID和LVM裝置,

啟用磁碟quota

檢查並掛載其它檔案系統

等等。

GRUB的基本原理以及對GRUB的操作控制方法:

GRUB全稱為Grand Unified Boot Loader,是Linux作業系統主流的啟動引導管理器。主要作用是啟動和裝載Linux作業系統。系統啟動過程中一旦完成了BIOS自檢,GRUB會被立刻裝載。在GRUB裡面包含了可以載入作業系統的程式碼以及將作業系統引導權傳遞給其他啟動引導管理器的程式碼。GRUB可以允許使用者選擇使用不同的kernel啟動系統,或者在啟動系統的過程中設定不同的啟動引數。

而通常BIOS會以下面兩種方法之一來呼叫啟動引導管理器:

將控制權移交給於驅動器主引導記錄的initial program loader(IPL);

將控制權移交給其他啟動引導管理器,再由他們將控制權移交給安裝在分割槽引導扇區的IPL

通常情況下啟動引導管理器GRUB由兩部分組成(stage1和stage2):

stage1比較小,通常可以駐留在MBR或者各個磁碟分割槽的啟動扇區中,主要作用是裝載stage2。

stage2比較大,從磁碟的啟動引導分割槽讀取

至於在stage1和stage2之間存在一個stage1.5,是因為starge1.5具有識別檔案系統的能力。

在Linux系統中對GRUB的配置有兩種方法:

主要引導管理器:

會將啟動引導管理器的stage1安裝在MBR上,這時啟動引導管理器必須被配置為可以傳遞控制權到其他作業系統;

次要引導管理器:

會將啟動引導管理器的stage1安裝在一些分割槽的引導扇區上,而其他的啟動引導管理器會被安裝在MBR上,由他們來向Linux啟動引導管理器傳遞控制權。

GRUB在啟動過程中可以提供命令列互動介面,可以從ext系列,reiserfs,fat等多種檔案系統引導系統,並且可以提供密碼加密功能,其內容在/boot分割槽下,系統啟動過程中由配置檔案/boot/grub/來定義啟動方式,對該配置檔案的更改會立即生效。

在配置檔案/boot/grub/檔案中定義的內容包括:

grub所在的分割槽,引導系統所使用的kernel檔案位置,硬體初始化使用的initrd檔案位置,以及啟動引數。

例如:

grub>root (hd0,0) --root指令為grub指定了一個根分割槽

grub>kernel /5 --kernel指令將作業系統核心載入記憶體

grub>module /5xen ro root=/dev/sda2 --module指令載入指定的模組

grub>module / --指定initrd檔案

grub>boot --boot 指令呼叫相應的啟動函式啟動OS核心

可見其指定的內容大多數在/boot分割槽,如果切換到/boot分割槽之後會看到這些內容:

/boot/vmlinuz-* linux kernel的一個copy;

/boot/initrd* 初始化的ram disk檔案

/boot/grub/ linux裝置名和grub裝置名的對映檔案

/boot/grub/ 主配置檔案

通常GRUB出錯機率不是很大,但一旦出現問題恐怕採用最多的方式是重灌grub到MBR中。

在這種時候需要注意的問題有:

首先,裝置對映關係:

GRUB裡面對裝置名稱的定義和系統中對裝置名稱的定義方法不一樣:

(fd0) /dev/fd0

(hd0) /dev/sda /dev/hda

(hd1) /dev/sdb /dev/hdb

如夠進入系統或者救援模式,可執行命令/sbin/grub-install /dev/sda(或者hda)進行GRUB重灌:

# /sbin/grub-install device

處於某種原因MBR中資訊出錯可以使用上面的命令將其重灌到磁碟主引導記錄中;但是如果在不能進入系統的情況下就需要通過grub的命令列介面進行手動設定,這個時候就要注意上面所提到的對映關係。

同時,在grub命令列中對grub進行手動設定的時候需要注意所使用的命令:

# root (hd0,0) --指定啟動分割槽

# setup(hd0) --表示將grub安裝在主引導記錄上

# quit --退出grub shell

下面是一個完整的檔案內容:

[root@dhcp-0-195 ~]# cat /etc/

# 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/VolGroup001/LogVol00

# initrd /

#boot=/dev/sda

default=0

timeout=30

splashimage=(hd0,0)/grub/

hiddenmenu

password --md5 $1$apEcJWbA$DTJ8a6mKn/3yrTTSXBtdH0

title Red Hat Enterprise Linux Client (5)

root (hd0,0)

kernel /5 ro root=/dev/VolGroup001/LogVol00 crashkernel=128M@16M

initrd /

系統啟動執行級別的概念以及服務的定製方法;

當initrd可以正常檢測和裝載之後,最後的工作就基本上由作業系統來進行了。當系統的init程序起來之後系統啟動的控制權移交給init程序。

/sbin/init程序是所有程序的父程序,當init起來之後,它首先會讀取配置檔案/etc/inittab,進行以下工作:

1)執行系統初始化指令碼(/etc/rc.d/nit),對系統進行基本的配置,以讀寫方式掛載根檔案系統及其它檔案系統,後面需要進行執行級別的確定及相應服務的啟動,(從這個角度可以看出如果要定義系統的init動作,需要修改/etc/rc.d/nit指令碼)

2)通過對/etc/inittab檔案的讀取確定啟動後進入的執行級別;

3) 在相應的執行級別中執行/etc/rc.d/rcx.d目錄下的指令碼名稱,該檔案定義了服務啟動的順序是先K後S,而具體的每個執行級別的服務狀態是放在/etc/rc.d/rcn.d(n=0~6)目錄下,但這些檔案均是到/etc/init.d下的相應檔案的連結。

系統會按照在該目錄下的檔名稱和優先順序執行對應執行級別目錄下的指令碼:

在某個執行級別的對應目錄下,K開頭的服務被關閉,S開頭的服務被開啟,K在S開始之前執行,在執行過程中按照數字來定義優先順序,數字越低優先順序越高。

4)按照/etc/rc.d/rcX.d目錄中的定義,系統會於後臺啟動相應的服務,如果要對某個執行級別中的服務進行更具體的定製,通過chkconfig命令來操作,或者通過setup/ntsys/system-config-services來進行定製。

5)在/etc/inittab檔案中存在有關key sequence,UPS的指令碼定義,啟動虛擬終端/sbin/mingetty的設定,這時呈現給使用者的就是最終的登入介面。

也就是說後臺啟動的服務完畢之後,如果系統預設進入字元介面,則執行mgetty進入1-6號終端控制檯,如果系統預設進入圖形介面,則開啟gdm服務進入7號虛擬圖形控制檯。

至此,系統啟動過程完畢。

對於/etc/rc.d/nit檔案的說明:

/etc/rc.d/nt -- System Initialization Tasks 執行系統初始化任務的指令碼。

它的主要工作有:

配置selinux,

系統時鐘,

核心引數(/etc/),

hostname,

啟用swap分割槽,

根檔案系統的檢查和二次掛載(讀寫),

啟用RAID和LVM裝置,

啟用磁碟quota

檢查並掛載其它檔案系統

這是其基本要實現的工作內容:

#!/bin/bash

#

# /etc/rc.d/nit - run once at boot time

#

# Taken in part from Miquel van Smoorenburg's bcheckrc.

# Check SELinux status

# Because of a chicken/egg problem, init_crypto must be run twice. /var may be

# encrypted but /var/lib/random-seed is needed to initialize swap.

# Only read this once.

# Initialize hardware

# Set default affinity

# Load other user-defined modules

# Load modules (for backward compatibility with VARs)

# Start the graphical boot, if necessary; /usr may not be mounted yet, so we

# may have to do this again after mounting

# Configure kernel parameters

# Set the hostname.

# Initialize ACPI bits

# RAID setup

# Device mapper & related initialization

# Update quotas if necessary

# Remount the root filesystem read-write.

# Clean up SELinux labels

# Clear mtab

# Remove stale backups

# Enter mounted filesystems into /etc/mtab

# Mount all other filesystems (except for NFS and /proc, which is already

# mounted). Contrary to standard usage,

# filesystems are NOT unmounted in single user mode.

# Check to see if a full relabel is needed

# Start the graphical boot, if necessary and not done yet.

# Initialize pseudo-random number generator

# Use the hardware RNG to seed the entropy pool, if available

# Configure machine if necessary.

# Clean out /.

# Do we need (w|u)tmpx files? We don't set them up, but the sysadmin might...

# Clean up /var. I'd use find, but /usr may not be mounted.

# Reset pam_console permissions

# Clean up utmp/wtmp

# Clean up various /tmp bits

# Make ICE directory

# Start up swapping.

標籤: 系統啟動 LINUX
  • 文章版權屬於文章作者所有,轉載請註明 https://xuezhezhai.com/zh-tw/itrz/linux/pmerlv.html