Linux 啓動流程梳理 - 思維導圖 - 流程圖

Linux 啓動流程總的來說可以分成三個階段

Linux 啓動流程圖

第一步:上電

Ø 在 x86 系統中,將 1M 空間最上面的 0xF0000 到 0xFFFFF 這 64K 映射給 ROM。

Ø 當電腦剛加電的時候,會做一些重置的工作,將 CS 設置爲 0xFFFF,將 IP 設置爲 0x0000,所以第一條指令就會指向 0xFFFF0,正是在 ROM 的範圍內。

Ø 在這裏,有一個 JMP 命令會跳到 ROM 中做初始化工作的代碼,於是,BIOS 開始進行初始化的工作

第二步:BIOS 啓動

固件初始化:計算機開機後,UEFI 固件會進行初始化,包括硬件初始化、自檢和加載 UEFI 固件驅動程序等。

啓動設備選擇:UEFI 固件會檢測並識別可啓動的設備,如硬盤、光盤、USB 設備等。它會根據預設的啓動順序或用戶設置的啓動選項,選擇一個可啓動的設備作爲啓動介質。

UEFI 固件驅動程序加載:UEFI 固件會加載設備上的 UEFI 固件驅動程序,這些驅動程序負責與硬件設備進行交互,以便後續的啓動過程能夠正常進行。

UEFI 應用程序加載:UEFI 固件會加載位於啓動介質上的 UEFI 應用程序,如引導加載程序(Bootloader)或操作系統的引導管理器。這些應用程序通常位於 EFI 系統分區中,以. efi 文件格式存在。

引導加載程序執行:加載的引導加載程序會接管控制權,負責加載操作系統內核或其他引導組件。常見的引導加載程序有 UEFI Shell、GRUB、rEFInd 等。

第三步:Linux 啓動

Linux 啓動 - 引導

Ø 我們可以通過 BIOS 界面選擇硬盤啓動項進入 OS,那 BIOS 是怎麼發現這個硬盤裏有 OS?

Ø 答案就是 MBR(Master Boot Record),

ØMBR 是放在硬盤的第一個扇區,一共 512 字節,

Ø 可以分成兩部分:

Ø 主引導記錄:安裝啓動引導程序的地方,446 字節,

Ø 分區表:記錄整個硬盤分區的的狀態此外,64 字節

Linux 啓動 - 引導 EBR/VBR

Ø 找到 MBR 後下一步做啥?

Ø(1) 如果查找分區表時發現操作系統裝在主分區,然後執行已載入的 MBR 中的 boot loader 代碼,加載該激活主分區的 VBR 中的 boot loader,至此,控制權就交給了 VBR 的 boot loader

Ø(2) 如果操作系統不是裝在主分區,那麼肯定是裝在邏輯分區中,所以查找完主分區表後會繼續查找擴展分區表,直到找到 EBR 所在的分區,然後 MBR 中的 boot loader 將控制權交給該 EBR 的 boot loader

Linux 啓動 - 引導 GRUB2 介紹

ØGNU GRUB(GRand Unified Bootloader 簡稱 “GRUB”)是一個來自 GNU 項目的多操作系統啓動程序。GRUB 是多啓動規範的實現,它允許用戶可以在計算機內同時擁有多個操作系統,並在計算機啓動時選擇希望運行的操作系統。GRUB 可用於選擇操作系統分區上的不同內核,也可用於向這些內核傳遞啓動參數。

Ø 生成配置文件:grub2-mkconfig -o /boot/grub2/grub.cfg

Ø 安裝:grub2-install /dev/sda

Linux 啓動 - 引導 GRUB2 加載

ØGrub2 第一個安裝的就是 boot.img,BIOS 完成任務後,會將 boot.img 從硬盤加載到內存中的 0x7c00 來運行。boot.img 會加載 core.img。如果從硬盤啓動的話,這個扇區裏面是 diskboot.img,diskboot.img 的任務就是將 core.img 的其他部分加載進來,先是解壓縮程序 lzma_decompress.img,再往下是 kernel.img,最後是各個模塊 module 對應的映像。這裏需要注意,它不是 Linux 的內核,而是 grub 的內核。

Ø 隨着我們加載的東西越來越大,實模式這 1M 的地址空間實在放不下了,所以在真正的解壓縮之前,lzma_decompress.img 做了一個重要的決定,就是調用 real_to_prot,切換到保護模式,這樣就能在更大的尋址空間裏面,加載更多的東西。

Linux 啓動 - 0/1 號進程

Øset_task_stack_end_magic(&init_task)。這裏面有一個參數 init_task,它的定義是 struct task_struct init_task = INIT_TASK(init_task)。

Ø 它是系統創建的第一個進程,我們稱爲 0 號進程。這是唯一一個沒有通過 fork 或者 kernel_thread 產生的進程,是進程列表的第一個。

Ø1.trap_init() 中斷初始化

Ø2.mm_init() 內存初始化

Ø3.sched_init() 調度策略初始化

Ø4.vfs_caches_init() 基於內存文件系統 rootfs 初始化

Ø5.start_kernel()->rest_init() 其他方面的初始化

Ørest_init 的第一大工作是,用 kernel_thread(kernel_init, NULL, CLONE_FS) 創建第二個進程,這個是 1 號進程。1 號進程對於操作系統來講,有 “劃時代” 的意義。

Linux 啓動 - ramdisk

Øinit 程序是在文件系統上的,文件系統一定是在一個存儲設備上的,例如硬盤。Linux 訪問存儲設備,要有驅動才能訪問。如果存儲系統數目很有限,那驅動可以直接放到內核裏面,但是文件系統的格式有很多,全都放進內核那內核就太大了。

Ø 這該怎麼辦呢?

Ø 我們只好先弄一個基於內存的文件系統。內存訪問是不需要驅動的,這個就是 ramdisk。這個時候,ramdisk 是根文件系統。

Ø 運行 ramdisk 上的 /init,等它運行完了就已經在用戶態了。/init 這個程序會先根據存儲系統的類型加載驅動,有了驅動就可以設置真正的根文件系統了。有了真正的根文件系統,ramdisk 上的 /init 會啓動文件系統上的 init。

Linux 啓動 - init 介紹

Ø 前面 0/1 進程都屬於內核線程,ps pid=1 的是 init 進程

Ø if (ramdisk_execute_command) {

Øret = run_init_process(ramdisk_execute_command);

Ø...... }

Ø......

Øif (!try_to_run_init_process("/sbin/init") ||

Ø!try_to_run_init_process("/etc/init") ||

Ø !try_to_run_init_process("/bin/init") ||

Ø!try_to_run_init_process("/bin/sh")) return 0

Ø 它會嘗試運行 ramdisk 的 “/init”,或者普通文件系統上的 “/sbin/init”“/etc/init”“/bin/init”“/bin/sh”。不同版本的 Linux 會選擇不同的文件啓動,但是隻要有一個起來了就可以。

ØInit 類型:

ØSysV:CentOS 5 之前, 配置文件 / etc/inittab

ØUpstart:CentOS 6,配置文件 / etc/inittab,/etc/init/*.conf

ØSystemd:CnetOS7, 配置文件 / usr/lib/system/syste,/etc/systemd/system

Linux 啓動 - 運行級別

Linux 啓動 - fstab

Ø 任何硬件設備連接後,操作系統使用硬件,即需要掛載。windows 只不過是自動 “掛載” 了,linux 需要手動自己搞。在 Linux 系統下,例如每次掛載 / dev/sdb1(例如 U 盤設備文件)需要手動使用命令 mount。當然,每次重啓,開啓時,硬盤一般也是被自動掛載的,而自動掛載的信息,就記錄在 / etc/fstab 文件中。

Ø 系統每次啓動都會讀取 / etc/fstab 中的配置內容,自動掛載該文件中被記錄的設備和分區。

Ø 第一列:設備文件或 UUID 或 label(三者的區別看下面)

Ø 第二列:設備的掛載點(空目錄)

Ø 第三列:該分區文件系統的格式(可以使用特殊的參數 auto,自動識別分區的分區格式)

Ø 第四列:文件系統的參數,設置格式的選項

Ø 第五列:dump 備份的設置(0 表示不進行 dump 備份,1 代表每天進行 dump 備份,2 代表不定日期的進行 dump 備份)

Ø 第六列:磁盤檢查設置(其實是一個檢查順序,0 代表不檢查,1 代表第一個檢查,2 後續. 一般根目錄是 1,數字相同則同時檢查)

Linux 啓動 - 用戶登錄

一般來說:用戶登錄方式有三種

  1. 命令行登錄

2.ssh 登錄

  1. 圖形登錄

Linux 是多任務多用戶的操作系統,它允許多人同時在線工作。但每個人都必須要輸入用戶名和密碼才能驗證身份並最終登錄。但登陸時是以圖形界面的方式給用戶使用,還是以純命令行模式給用戶使用呢?這是終端決定的,也就是說在登錄前需要先加載終端。

現代 Linux 上,console 終端已經和原始的意義不太一樣了,其設備映射在 / dev/console 上,所有內核輸出的信息都輸出到 console 終端,而其他用戶程序輸出的信息則輸出到虛擬終端或僞終端。

總結下:

/dev/console:控制檯終端

/dev/ttyN:虛擬終端,ctrl+alt+f[1-6] 切換的就是虛擬終端

/dev/ttySN:串行終端

/dev/pts/N:僞終端,ssh 等工具連接過去的活着圖形終端下開啓的命令行終端就是僞終端。

Linux 啓動 - 用戶切換

Linux 預設提供了六個命令窗口終端機讓我們來登錄。

默認我們登錄的就是第一個窗口,也就是 tty1,這個六個窗口分別爲 tty1,tty2 … tty6,你可以按下 Ctrl + Alt + F1 ~ F6 來切換它們

Ø

Ø 針對我的 VM Virtual BOX ctrl+alt + F1 是圖形終端, ctrl+alt + F2~F6 命令行終端

Linux 啓動流程思維導圖

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/t4PCY8N64X_NJvZDUFTWFA