0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核自解壓過程分析

Linux愛好者 ? 來源:Linux愛好者 ? 2023-12-08 14:00 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux內(nèi)核自解壓過程

uboot完成系統(tǒng)引導(dǎo)以后,執(zhí)行環(huán)境變量bootm中的命令;即,將Linux內(nèi)核調(diào)入內(nèi)存中并調(diào)用do_bootm函數(shù)啟動內(nèi)核,跳轉(zhuǎn)至kernel的起始位置。如果內(nèi)核沒有被壓縮,則直接啟動;如果內(nèi)核被壓縮過,則需要進(jìn)行解壓,被壓縮過的kernel頭部有解壓程序。

壓縮過的kernel入口第一個文件源碼位置在/kernel/arch/arm/boot/compressed/head.S。它將調(diào)用decompress_kernel()函數(shù)進(jìn)行解壓,解壓完成后,打印出信息“Uncompressing Linux...done,booting the kernel”。解壓縮完成后,調(diào)用gunzip()函數(shù)(或unlz4()、或bunzip2()、或unlz())將內(nèi)核放于指定位置,開始啟動內(nèi)核。

2. Linux內(nèi)核啟動準(zhǔn)備階段

由內(nèi)核鏈接腳本/kernel/arch/arm/kernel/vmlinux.lds可知,內(nèi)核入口函數(shù)為stext(/kernel/arch/arm/kernel/head.S)。內(nèi)核解壓完成后,解壓縮代碼調(diào)用stext函數(shù)啟動內(nèi)核。

ENTRY(stext)
setmodePSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode@ and irqs disabled
mrcp15, 0, r9, c0, c0            @ 獲得處理器ID,并存儲在r9寄存器中
bl__lookup_processor_type        @ 結(jié)果返回:描述處理器結(jié)構(gòu)體的地址 r5=procinfo ,處理器ID號 r9=cpuid
movsr10, r5                      @ invalid processor (r5=0)?判斷內(nèi)核是否支持該處理器
beq__error_p                     @ yes, error 'p'
bl__lookup_machine_type          @結(jié)果返回:描述機(jī)器(開發(fā)板)的結(jié)構(gòu)體地址  r5=machinfo
movsr8, r5                       @ invalid machine (r5=0)?判斷內(nèi)核是否支持該機(jī)器(開發(fā)板)
beq__error_a                     @ yes, error 'a'
bl__vet_atags                    @檢查uboot給內(nèi)核的傳參ATAGS格式是否正確
bl__create_page_tables           @建立虛擬地址映射頁表

ldrr13, __switch_data            @ address to jump to after

(1)關(guān)閉IRQ、FIQ中斷,進(jìn)入SVC模式。調(diào)用setmode宏實(shí)現(xiàn);

(2)校驗處理器ID,檢驗內(nèi)核是否支持該處理器;若不支持,則停止啟動內(nèi)核。調(diào)用__lookup_processor_type函數(shù)實(shí)現(xiàn);

(3)校驗機(jī)器碼,檢驗內(nèi)核是否支持該機(jī)器;若不支持,則停止啟動內(nèi)核。調(diào)用__lookup_machine_type函數(shù)實(shí)現(xiàn);

(4)檢查uboot向內(nèi)核傳參ATAGS格式是否正確,調(diào)用__vet_atars函數(shù)實(shí)現(xiàn);

(5)建立虛擬地址映射頁表。此處建立的頁表為粗頁表,在內(nèi)核啟動前期使用。Linux對內(nèi)存管理有更精細(xì)的要求,隨后會重新建立更精細(xì)的頁表。調(diào)用__create_page_tables函數(shù)實(shí)現(xiàn)。

(6)跳轉(zhuǎn)執(zhí)行__switch_data函數(shù),其中調(diào)用__mmap_switched完成最后的準(zhǔn)備工作。

    1)復(fù)制數(shù)據(jù)段、清除bss段,目的是構(gòu)建C語言運(yùn)行環(huán)境;

    2)保存處理器ID號、機(jī)器碼、uboot向內(nèi)核傳參地址;

    3)b   start_kernel跳轉(zhuǎn)至內(nèi)核初始化階段。
__switch_data:
.long__mmap_switched
..........................................................
__mmap_switched:
adrr3, __switch_data + 4

ldmiar3!, {r4, r5, r6, r7}
cmpr4, r5@ Copy data segment if needed
1:cmpner5, r6
ldrnefp, [r4], #4
strnefp, [r5], #4
bne1b

movfp, #0@ Clear BSS (and zero fp)
1:cmpr6, r7
strccfp, [r6],#4
bcc1b

 ARM(ldmiar3, {r4, r5, r6, r7, sp})
 THUMB(ldmiar3, {r4, r5, r6, r7})
 THUMB(ldrsp, [r3, #16])
strr9, [r4]@ Save processor ID
strr1, [r5]@ Save machine type
strr2, [r6]@ Save atags pointer
bicr4, r0, #CR_A@ Clear 'A' bit
stmiar7, {r0, r4}@ Save control register values
bstart_kernel
ENDPROC(__mmap_switched)

3. Linux內(nèi)核初始化階段

此階段從start_kernel函數(shù)開始。start_kernel函數(shù)是所有Linux平臺進(jìn)入系統(tǒng)內(nèi)核初始化的入口函數(shù)。它的主要工作是完成剩余與硬件平臺相關(guān)的初始化工作,在進(jìn)行一系列與內(nèi)核相關(guān)的初始化之后,調(diào)用第一個用戶進(jìn)程init并等待其執(zhí)行。至此,整個內(nèi)核啟動完成。

3.1 start_kernel函數(shù)的主要工作

start_kernel函數(shù)主要完成內(nèi)核相關(guān)的初始化工作。具體包括以下部分:
(1)內(nèi)核架構(gòu) 、通用配置相關(guān)初始化

(2) 內(nèi)存管理相關(guān)初始化

(3)進(jìn)程管理相關(guān)初始化

(4)進(jìn)程調(diào)度相關(guān)初始化

(5)網(wǎng)絡(luò)子系統(tǒng)管理

(6)虛擬文件系統(tǒng)

(7)文件系統(tǒng)

3.2 start_kernel函數(shù)流中的關(guān)鍵函數(shù)

12d8148e-958d-11ee-8b88-92fbcf53809c.png

(1)setup_arch(&command_line)函數(shù)

內(nèi)核架構(gòu)相關(guān)的初始化函數(shù),是非常重要的一個初始化步驟。其中,包含了處理器相關(guān)參數(shù)的初始化、內(nèi)核啟動參數(shù)(tagged list)的獲取和前期處理、內(nèi)存子系統(tǒng)的早期初始化。

command_line實(shí)質(zhì)是uboot向內(nèi)核傳遞的命令行啟動參數(shù),即uboot中環(huán)境變量bootargs的值。若uboot中bootargs的值為空,command_line = default_command_line,即為內(nèi)核中的默認(rèn)命令行參數(shù),其值在.config文件中配置,對應(yīng)CONFIG_CMDLINE配置項。

(2)setup_command_line、parse_early_param以及parse_args函數(shù)

這些函數(shù)都是在完成命令行參數(shù)的解析、保存。譬如,cmdline = console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3;解析為一下四個參數(shù):

console=ttySAC2,115200 //指定控制臺的串口設(shè)備號,及其波特率
root=/dev/mmcblk0p2 rw //指定根文件系統(tǒng)rootfs的路徑
init=/linuxrc //指定第一個用戶進(jìn)程init的路徑
rootfstype=ext3 //指定根文件系統(tǒng)rootfs的類型

(3)sched_init函數(shù)

初始化進(jìn)程調(diào)度器,創(chuàng)建運(yùn)行隊列,設(shè)置當(dāng)前任務(wù)的空線程。

(4)rest_init函數(shù)

rest_init函數(shù)的主要工作如下:

1)調(diào)用kernel_thread函數(shù)啟動了2個內(nèi)核線程,分別是:kernel_init和kthreadd。kernel_init線程中調(diào)用prepare_namespace函數(shù)掛載根文件系統(tǒng)rootfs;然后調(diào)用init_post函數(shù),執(zhí)行根文件系統(tǒng)rootfs下的第一個用戶進(jìn)程init。用戶進(jìn)程有4個備選方案,若command_line中init的路徑錯誤,則會執(zhí)行備用方案。第一備用:/sbin/init,第二備用:/etc/init,第三備用:/bin/init,第四備用:/bin/sh。

2)調(diào)用schedule函數(shù)開啟內(nèi)核調(diào)度系統(tǒng);

3)調(diào)用cpu_idle函數(shù),啟動空閑進(jìn)程idle,完成內(nèi)核啟動。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19843

    瀏覽量

    234091
  • SVC
    SVC
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    12411
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    317

    瀏覽量

    22287
  • FIQ
    FIQ
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    2400

原文標(biāo)題:linux 內(nèi)核啟動流程分析

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 0人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    Linux內(nèi)核的編譯主要過程

    Linux內(nèi)核的編譯主要過程: 配置、編譯、安裝 。
    發(fā)表于 08-08 16:02 ?877次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的編譯主要<b class='flag-5'>過程</b>

    Linux內(nèi)核自解壓過程

    Linux內(nèi)核的啟動流程。有興趣的用戶可以參考其他書籍或資料進(jìn)行深入了解?! ∏度胧?b class='flag-5'>linux內(nèi)核的啟動全過程主要分為三個階段。第一階段為
    發(fā)表于 12-29 07:35

    嵌入式Linux主要有哪幾部分呢

    嵌入式Linux主要有這幾部分:Bootloader:主要用于引導(dǎo)Linux內(nèi)核到內(nèi)存中,讓內(nèi)核進(jìn)行自解壓并運(yùn)行zImage:帶
    發(fā)表于 10-27 08:40

    嵌入式linux內(nèi)核啟動流程是怎樣的

    內(nèi)核構(gòu)成分析uImage構(gòu)成:arm linux內(nèi)核映像uImage生成過程圖解:u-boot認(rèn)為zImage為
    發(fā)表于 12-20 08:15

    Linux內(nèi)核啟動全過程解析

    當(dāng)u-boot開始執(zhí)行bootcmd命令,就進(jìn)入Linux內(nèi)核啟動階段,與u-boot類似,普通Linux內(nèi)核的啟動過程也可以分為兩個階段,
    發(fā)表于 10-26 17:20

    linux內(nèi)核啟動內(nèi)核解壓過程分析

    linux啟動時內(nèi)核解壓過程分析,一份不錯的文檔,深入了解內(nèi)核必備
    發(fā)表于 03-09 13:39 ?1次下載

    基于Linux 2.6內(nèi)核Makefile分析

    基于2.4內(nèi)核的,可以說關(guān)于2.6內(nèi)核Makefile相關(guān)的文章鳳毛麟角,筆者抽時間完成了這篇分析文章,讓讀者迅速熟悉Linux最新Makefile體系,從而加深對
    發(fā)表于 09-18 19:09 ?0次下載
    基于<b class='flag-5'>Linux</b> 2.6<b class='flag-5'>內(nèi)核</b>Makefile<b class='flag-5'>分析</b>

    關(guān)于Linux 2.6內(nèi)核Makefile的分析

    的介紹文章都是基于2.4內(nèi)核的,可以說關(guān)于2.6內(nèi)核Makefile相關(guān)的文章鳳毛麟角,筆者抽時間完成了這篇分析文章,讓讀者迅速熟悉Linux最新Makefile體系,從而加深對
    發(fā)表于 11-02 10:12 ?1次下載

    Linux內(nèi)核移植相關(guān)代碼解析

    本文通過整理之前研發(fā)的一個項目(ARM7TDMI +uCLinux),分析內(nèi)核啟動過程及需要修改的文件,以供內(nèi)核移植者參考。整理過程中也同時
    發(fā)表于 11-07 11:29 ?0次下載

    ARM處理器上的linux內(nèi)核啟動的過程詳細(xì)資料概述

    壓縮的內(nèi)核時zImage時,啟動的是后者,后者與前者不同的時,它前面的代碼是做自解壓的,后面的代碼都相同。我們這里這分析arc/arm/kernel下面的head.S文件。當(dāng)head.S所作的工作完成后它會跳到init/目錄下跌
    的頭像 發(fā)表于 06-10 11:03 ?5127次閱讀
    ARM處理器上的<b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>啟動的<b class='flag-5'>過程</b>詳細(xì)資料概述

    嵌入式Linux內(nèi)核移植相關(guān)代碼分析

    不需要帶有自解壓功能,而使用Bootloader中的解壓程序代替內(nèi)核自解壓程序。其工作過程內(nèi)核
    發(fā)表于 04-02 14:37 ?332次閱讀

    Linux內(nèi)核GPIO操作函數(shù)的詳解分析

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux內(nèi)核GPIO操作函數(shù)的詳解分析免費(fèi)下載。
    發(fā)表于 01-22 16:58 ?28次下載

    STM32MP157 Linux系統(tǒng)移植開發(fā)篇8:Linux內(nèi)核配置方法及編譯

    Linux內(nèi)核配置及編譯解壓內(nèi)核建立源碼目錄該目錄下以patch結(jié)尾的文件為ST官方提供的補(bǔ)丁文件,linux-5.4.31.tar.xz為
    發(fā)表于 12-04 21:06 ?9次下載
    STM32MP157 <b class='flag-5'>Linux</b>系統(tǒng)移植開發(fā)篇8:<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>配置方法及編譯

    從軟件角度分析linux內(nèi)核USB子系統(tǒng)的熱插拔過程

    本文從軟件角度分析linux內(nèi)核USB子系統(tǒng)的熱插拔過程,以實(shí)際分析思路和過程行文,基于
    的頭像 發(fā)表于 01-15 09:28 ?6325次閱讀

    Linux內(nèi)核啟動速度優(yōu)化的幾個方法

    符合實(shí)際情況的,以此進(jìn)行優(yōu)化。 加載位置 內(nèi)核鏡像可以由 kernel 自解壓,也可以由 uboot 進(jìn)行解壓。 對于 kernel 自解壓的情況,如果壓縮過的 kernel 與
    的頭像 發(fā)表于 10-04 15:07 ?1273次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品