衡阳派盒市场营销有限公司

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

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

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

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

h1654155971.7688 ? 來源:未知 ? 作者:易水寒 ? 2018-06-10 11:03 ? 次閱讀

對(duì)于ARM處理器,內(nèi)核第一個(gè)啟動(dòng)的文件是arc/arm/kernel下面的head.S文件。當(dāng)然arc/arm/boot/compress下面也有這個(gè)文件,這個(gè)文件和上面的文件略有不同,當(dāng)要生成壓縮的內(nèi)核時(shí)zImage時(shí),啟動(dòng)的是后者,后者與前者不同的時(shí),它前面的代碼是做自解壓的,后面的代碼都相同。我們這里這分析arc/arm/kernel下面的head.S文件。當(dāng)head.S所作的工作完成后它會(huì)跳到init/目錄下跌的main.c的start_kernel函數(shù)開始執(zhí)行。

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

第一階段

首先截取部分head.S文件,將后面重點(diǎn)要分析的代碼高亮顯示。

ENTRY(stext)

msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode

@ and irqs disabled

mrc p15, 0, r9, c0, c0 @ get processor id

bl __lookup_processor_type @ r5=procinfo r9=cpuid

movs r10, r5 @ invalid processor (r5=0)?

beq __error_p @ yes, error 'p'

bl __lookup_machine_type @ r5=machinfo

movs r8, r5 @ invalid machine (r5=0)?

beq __error_a @ yes, error 'a'

bl __create_page_tables

/*

* The following calls CPU specific code in a position independent

* manner. See arch/arm/mm/proc-*.S for details. r10 = base of

* xxx_proc_info structure selected by __lookup_machine_type

* above. On return, the CPU will be ready for the MMU to be

* turned on, and r0 will hold the CPU control register value.

*/

ldr r13, __switch_data @ address to jump to after

@ mmu has been enabled

adr lr, __enable_mmu @ return (PIC) address

第一步,執(zhí)行的是__lookup_processor_type,這個(gè)函數(shù)是檢查處理器型號(hào),它讀取你的電路板的CPU型號(hào)與內(nèi)核支持的處理器進(jìn)行比較看是否能夠處理。這個(gè)我們不關(guān)心它的具體實(shí)現(xiàn)過程,因?yàn)楝F(xiàn)在主流處理器內(nèi)核都提供了支持。

第二步,執(zhí)行的是__lookup_machine_type,這個(gè)函數(shù)是來檢查機(jī)器型號(hào)的,它會(huì)讀取你bootloader傳進(jìn)來的機(jī)器ID和他能夠處理的機(jī)器ID進(jìn)行比較看是否能夠處理。內(nèi)核的ID號(hào)定義在arc/arm/tool/mach_types文件中MACH_TYPE_xxxx宏定義。內(nèi)核究竟就如何檢查是否是它支持的機(jī)器的呢?實(shí)際上每個(gè)機(jī)器都會(huì)在/arc/arm/mach-xxxx/smdk-xxxx.c文件中有個(gè)描述特定機(jī)器的數(shù)據(jù)結(jié)構(gòu),如下

MACHINE_START(S3C2440, "SMDK2440")

/* Maintainer: Ben Dooks */

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,

.map_io = smdk2440_map_io,

.init_machine = smdk2440_machine_init,

.timer = &s3c24xx_timer,

MACHINE_END

MACHINE_START 和 MACHINE_END實(shí)際上被展開成一個(gè)結(jié)構(gòu)體

#define MACHINE_START(_type,_name) \

static const struct machine_desc __mach_desc_##_type \

__used \

__attribute__((__section__(".arch.info.init"))) = { \

.nr = MACH_TYPE_##_type, \

.name = _name,

#define MACHINE_END \

};

于是上面的數(shù)據(jù)結(jié)構(gòu)就被展開為

static const struct machine_desc __mach_desc_S3C2440 \

__used \

__attribute__((__section__(".arch.info.init"))) = { \

.nr = MACH_TYPE_S3C2440, \

.name =” SMDK2440”,};

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,

.map_io = smdk2440_map_io,

.init_machine = smdk2440_machine_init,

.timer = &s3c24xx_timer,

}

每個(gè)機(jī)器都會(huì)有一個(gè)machine_desc __mach_desc結(jié)構(gòu),內(nèi)核通過檢查每個(gè)machine_desc __mach_desc的nr號(hào)和bootloader傳上來的ID進(jìn)行比較,如果相同,內(nèi)核就認(rèn)為支持該機(jī)器,而且內(nèi)核在后面的工作中會(huì)調(diào)用該機(jī)器的machine_desc __mach_desc_結(jié)構(gòu)中的方法進(jìn)行一些初始化工作。

第三步,創(chuàng)建一級(jí)頁表。

第四步,在R13中保存__switch_data 這個(gè)函數(shù)的地址,在第四步使能mmu完成后會(huì)跳到該函數(shù)執(zhí)行。

第五步,執(zhí)行的是__enable_mmu,它是使能MMU,這個(gè)函數(shù)調(diào)用了__turn_mmu_on函數(shù),讓后在_turn_mmu_on在最后將第三步賦給R13的值傳給了PC指針 (mov pc, r13),于是內(nèi)核開始跳到__switch_data這個(gè)函數(shù)開始執(zhí)行。

我們?cè)賮砜碼rch/arm/kenel/head-common.S這個(gè)文件中的__switch_data函數(shù)

__switch_data:

.long __mmap_switched

.long __data_loc @ r4

.long __data_start @ r5

.long __bss_start @ r6

.long _end @ r7

.long processor_id @ r4

.long __machine_arch_type @ r5

.long cr_alignment @ r6

.long init_thread_union + THREAD_START_SP @ sp

/*

* The following fragment of code is executed with the MMU on in MMU mode,

* and uses absolute addresses; this is not position independent.

*

* r0 = cp#15 control register

* r1 = machine ID

* r9 = processor ID

*/

.type __mmap_switched, %function

__mmap_switched:

adr r3, __switch_data + 4

ldmia r3!, {r4, r5, r6, r7}

cmp r4, r5 @ Copy data segment if needed

1: cmpne r5, r6

ldrne fp, [r4], #4

strne fp, [r5], #4

bne 1b

mov fp, #0 @ Clear BSS (and zero fp)

1: cmp r6, r7

strcc fp, [r6],#4

bcc 1b

ldmia r3, {r4, r5, r6, sp}

str r9, [r4] @ Save processor ID

str r1, [r5] @ Save machine type

bic r4, r0, #CR_A @ Clear 'A' bit

stmia r6, {r0, r4} @ Save control register values

b start_kernel

這個(gè)函數(shù)做的工作是,復(fù)制數(shù)據(jù)段清楚BBS段,設(shè)置堆在指針,然后保存處理器內(nèi)核和機(jī)器內(nèi)核等工作,最后跳到start_kernel函數(shù)。于是內(nèi)核開始執(zhí)行第二階段。

第二階段

我們?cè)賮砜磇nit/目錄下的main.c的start_kernel函數(shù),這里我只截圖了部分。

asmlinkage void __init start_kernel(void)

{

…………………….

……………………..

printk(KERN_NOTICE);

printk(linux_banner);

setup_arch(&command_line);

setup_command_line(command_line);

parse_early_param();

parse_args("Booting kernel", static_command_line, __start___param,

__stop___param - __start___param,

&unknown_bootoption);

……………………

…………………………

init_IRQ();

pidhash_init();

init_timers();

hrtimers_init();

softirq_init();

timekeeping_init();

time_init();

profile_init();

…………………………

……………………………

console_init();

………………………………

………………………………

ssssss;

}

從上面可以看出start_kernel首先是打印內(nèi)核信息,然后對(duì)bootloader傳進(jìn)來的一些參數(shù)進(jìn)行處理,再接著執(zhí)行各種各樣的初始化,在這其中會(huì)初始化控制臺(tái)。最后會(huì)調(diào)用rest_init();這個(gè)函數(shù)會(huì)啟動(dòng)掛接根文件系統(tǒng)并且啟動(dòng)init進(jìn)程。

綜上,內(nèi)核啟動(dòng)的過程大致為以下幾步:

1.檢查CPU和機(jī)器類型

2.進(jìn)行堆棧、MMU等其他程序運(yùn)行關(guān)鍵的東西進(jìn)行初始化

3.打印內(nèi)核信息

4.執(zhí)行各種模塊的初始化

5.掛接根文件系統(tǒng)

6.啟動(dòng)第一個(gè)init進(jìn)程

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

    關(guān)注

    6

    文章

    361

    瀏覽量

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

    關(guān)注

    1

    文章

    316

    瀏覽量

    21742

原文標(biāo)題:ARM處理器上的linux內(nèi)核是怎么啟動(dòng)的

文章出處:【微信號(hào):weixin21ic,微信公眾號(hào):21ic電子網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)核啟動(dòng)過程和Bootloader(總述)

    Bootloader的執(zhí)行過程,這樣才能對(duì)嵌入式系統(tǒng)的整個(gè)啟動(dòng)過程有清晰的掌握2.2 Bootloader的執(zhí)行過程 不同的處理器電或復(fù)
    發(fā)表于 08-18 17:35

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

    Linux內(nèi)核啟動(dòng)流程。有興趣的用戶可以參考其他書籍或資料進(jìn)行深入了解。  嵌入式linux內(nèi)核
    發(fā)表于 12-29 07:35

    瑞芯微芯片處理器詳細(xì)資料

    瑞芯微芯片處理器詳細(xì)資料分享
    發(fā)表于 01-15 06:41

    瑞芯微芯片處理器詳細(xì)資料

    瑞芯微芯片處理器詳細(xì)資料分享
    發(fā)表于 12-28 10:33

    Linux內(nèi)核文檔:ARM-啟動(dòng)

    Linux內(nèi)核文檔:ARM-啟動(dòng)
    發(fā)表于 10-30 10:15 ?6次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>文檔:<b class='flag-5'>ARM</b>-<b class='flag-5'>啟動(dòng)</b>

    詳解bootloader的執(zhí)行流程與ARM Linux啟動(dòng)過程分析

    S3C2410 ARM處理器為例,詳細(xì)分析了系統(tǒng)電后 bootloader的執(zhí)行流程及 ARM Lin
    的頭像 發(fā)表于 12-21 09:24 ?1.1w次閱讀
    詳解bootloader的執(zhí)行流程與<b class='flag-5'>ARM</b> <b class='flag-5'>Linux</b><b class='flag-5'>啟動(dòng)過程</b>分析

    ARM處理器AM1806的英文原版資料詳細(xì)概述

    本文的主要內(nèi)容是TI的產(chǎn)品ARM處理器AM1806的英文原版資料詳細(xì)概述
    發(fā)表于 04-24 15:30 ?0次下載
    <b class='flag-5'>ARM</b>微<b class='flag-5'>處理器</b>AM1806的英文原版<b class='flag-5'>資料</b><b class='flag-5'>詳細(xì)</b><b class='flag-5'>概述</b>

    KeyStone處理器的硬件系統(tǒng)設(shè)計(jì)詳細(xì)資料概述

    本文的主要內(nèi)容介紹的是KeyStone處理器的硬件系統(tǒng)設(shè)計(jì)的詳細(xì)資料概述
    發(fā)表于 04-28 10:38 ?8次下載
    KeyStone<b class='flag-5'>處理器</b>的硬件系統(tǒng)設(shè)計(jì)<b class='flag-5'>詳細(xì)資料</b><b class='flag-5'>概述</b>

    用于工業(yè)自動(dòng)化的ARM處理器AM335x的詳細(xì)資料概述

    本文檔介紹的主要內(nèi)容是TI用于工業(yè)自動(dòng)化的ARM處理器AM335x系列產(chǎn)品的詳細(xì)資料概述
    發(fā)表于 05-10 08:42 ?10次下載
    用于工業(yè)自動(dòng)化的<b class='flag-5'>ARM</b>微<b class='flag-5'>處理器</b>AM335x的<b class='flag-5'>詳細(xì)資料</b><b class='flag-5'>概述</b>

    如何在Linux下如何刪除大量文件的詳細(xì)資料概述

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何在Linux下刪除大量文件的過程詳細(xì)資料概述免費(fèi)下載。
    發(fā)表于 11-14 17:10 ?7次下載

    Linux內(nèi)核處理器體系結(jié)構(gòu)的詳細(xì)資料說明

    Linux 4.x內(nèi)核已經(jīng)支持幾十種的處理器體系結(jié)構(gòu),目前市面上最流行的兩種體系結(jié)構(gòu)是x86和ARM。x86體系結(jié)構(gòu)以Intel公司的PC和服務(wù)
    發(fā)表于 05-28 17:58 ?3次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>處理器</b>體系結(jié)構(gòu)的<b class='flag-5'>詳細(xì)資料</b>說明

    嵌入式系統(tǒng)及應(yīng)用教程之ARM體系結(jié)構(gòu)及處理器內(nèi)核詳細(xì)資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式系統(tǒng)及應(yīng)用教程之ARM體系結(jié)構(gòu)及處理器內(nèi)核詳細(xì)資料說明包括了: 體系結(jié)構(gòu),編程模型,指令集介紹,
    發(fā)表于 10-14 17:14 ?7次下載
    嵌入式系統(tǒng)及應(yīng)用教程之<b class='flag-5'>ARM</b>體系結(jié)構(gòu)及<b class='flag-5'>處理器</b><b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>詳細(xì)資料</b>說明

    ARM處理器內(nèi)核詳細(xì)資料概述

    本文檔的主要內(nèi)容詳細(xì)介紹的是ARM處理器內(nèi)核詳細(xì)資料概述包括了:
    發(fā)表于 10-14 17:14 ?15次下載
    <b class='flag-5'>ARM</b><b class='flag-5'>處理器</b><b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>詳細(xì)資料</b><b class='flag-5'>概述</b>

    ARM處理器的工作模式詳細(xì)資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是ARM處理器的工作模式詳細(xì)資料說明。
    發(fā)表于 10-21 17:40 ?10次下載
    <b class='flag-5'>ARM</b><b class='flag-5'>處理器</b>的工作模式<b class='flag-5'>詳細(xì)資料</b>說明

    ARM處理器詳細(xì)資料介紹

    本文檔的主要內(nèi)容詳細(xì)介紹的是ARM處理器詳細(xì)資料介紹。
    發(fā)表于 03-14 17:04 ?17次下載
    <b class='flag-5'>ARM</b>微<b class='flag-5'>處理器</b>的<b class='flag-5'>詳細(xì)資料</b>介紹
    百家乐博娱乐网| 百家乐官网记算| 大中华百家乐的玩法技巧和规则| 百家乐官网楼梯缆 | 百家乐官网代打公司| 女优百家乐的玩法技巧和规则| 运城百家乐官网蓝盾| 鸿博娱乐| 百家乐前四手下注之观点| 百家乐官网最好的平台是哪个| 大发888 备用6222.co| 租nongcun房看风水做生意的| 棋牌百家乐官网怎么玩| 威尼斯人娱乐信誉| 免费百家乐官网缩水工具| 百家乐官网玩法秘决| 太阳城地址| 博彩乐百家乐平台| 百家乐官网赢钱公式冯耕| 大发888中文官网| 木棉百家乐官网的玩法技巧和规则 | 百家乐霸王闲| 百家乐官网博弈之赢者理论坛| 足球下注| 扑克百家乐麻将筹码防伪| 有看做生意风水的大师吗| 百家乐官网怎么推算| 大发888账号申请| 玩百家乐去哪个平台好| 百家乐官网赌博策略论坛| 盈丰国际博彩网| 威尼斯人娱乐城网络百家乐| 怎么看百家乐官网走势| 澳门赌场图片| 威尼斯人娱乐城老lm0| 娱乐城百家乐技巧| 百家乐官网娱乐备用网址| 汕头市| 大发888易发| 稳赢百家乐的玩法技巧| 大发百家乐官网的玩法技巧和规则|