国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

Linux內(nèi)核啟動(dòng)流程-迅為IMX6ULL開(kāi)發(fā)板(一)

發(fā)布時(shí)間:2020-7-17 10:30    發(fā)布者:就是塔塔
在前面的章節(jié)介紹了ubootLinux內(nèi)核的一些相關(guān)內(nèi)容。在來(lái)看Linux內(nèi)核的大致啟動(dòng)流程,Linux內(nèi)核的啟動(dòng)流程要比uboot復(fù)雜的多,涉及到的內(nèi)容也更多,因此在本章節(jié)大致簡(jiǎn)單的了解一下Linux內(nèi)核的啟動(dòng)流程。有興趣的用戶可以參考其他書(shū)籍或資料進(jìn)行深入了解。
嵌入式linux內(nèi)核的啟動(dòng)全過(guò)程主要分為三個(gè)階段。第一階段為內(nèi)核自解壓過(guò)程,第二階段主要工作是設(shè)置ARM處理器工作模式、使能MMU、設(shè)置一級(jí)頁(yè)表等,而第三階段則主要為C代碼,包括內(nèi)核初始化的全部工作。下面分別進(jìn)行簡(jiǎn)單介紹。
基于迅為-IMX6ULL開(kāi)發(fā)板
30.1 Linux內(nèi)核啟動(dòng)(一):Linux內(nèi)核自解壓過(guò)程
Linux內(nèi)核有兩種映像格式:一種是非壓縮內(nèi)核,叫Image,另一種是它的壓縮版本,叫zImage。zImage是Image經(jīng)過(guò)壓縮形成的,所以它的大小比Image小。但為了能使用zImage,必須在它的開(kāi)頭加上解壓縮的代碼,將zImage解壓縮之后才能執(zhí)行,因此它的執(zhí)行速度比Image要慢一些
內(nèi)核壓縮和解壓縮代碼都在目錄kernel/arch/arm/boot/compressed,編譯完成后將產(chǎn)生head.omisc.opiggy.gzip.ovmlinuxdecompress.o這幾個(gè)文件,head.o是內(nèi)核的頭部文件,負(fù)責(zé)初始設(shè)置;misc.o將主要負(fù)責(zé)內(nèi)核的解壓工作,它在head.o之后;piggy.gzip.o是一個(gè)中間文件,其實(shí)是一個(gè)壓縮的內(nèi)核(kernel/vmlinux),只不過(guò)沒(méi)有和初始化文件及解壓文件鏈接而已;vmlinux是沒(méi)有(zImage是壓縮過(guò)的內(nèi)核)壓縮過(guò)的內(nèi)核,就是由piggy.gzip.ohead.omisc.o組成的,而decompress.o是為支持更多的壓縮格式而新引入的。
uboot完成系統(tǒng)引導(dǎo)將Linux內(nèi)核加載到內(nèi)存之后,調(diào)用do_bootm_linux(),這個(gè)函數(shù)將跳轉(zhuǎn)到kernel的起始位置。如果kernel沒(méi)有被壓縮,就可以啟動(dòng)了。如果kernel被壓縮過(guò),則要進(jìn)行解壓,在壓縮過(guò)的kernel頭部有解壓程序。壓縮過(guò)的kernel入口第一個(gè)文件源碼位置在arch/arm/boot/compressed/head.S。它將調(diào)用函數(shù)decompress_kernel(),這個(gè)函數(shù)在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又調(diào)用arch_decomp_setup()進(jìn)行設(shè)置,然后調(diào)用gunzip()將內(nèi)核放于指定的位置。
函數(shù)decompress_kernel實(shí)現(xiàn)的功能:解壓縮代碼位于kernel/lib/inflate.cinflate.c是從gzip源程序中分離出來(lái)的,包含了一些對(duì)全局?jǐn)?shù)據(jù)的直接引用,在使用時(shí)需要直接嵌入到代碼中。gzip壓縮文件時(shí)總是在前32K字節(jié)的范圍內(nèi)尋找重復(fù)的字符串進(jìn)行編碼, 在解壓時(shí)需要一個(gè)至少為32K字節(jié)的解壓緩沖區(qū),它定義為window[WSIZE]inflate.c使用get_byte()讀取輸入文件,它被定義成宏來(lái)提高效率。輸入緩沖區(qū)指針必須定義為inptrinflate.c中對(duì)之有減量操作。inflate.c調(diào)用flush_window()來(lái)輸出window緩沖區(qū)中的解壓出的字節(jié)串,每次輸出長(zhǎng)度用outcnt變量表示。在flush_window()中,還必須對(duì)輸出字節(jié)串計(jì)算CRC并且刷新crc變量。在調(diào)用gunzip()開(kāi)始解壓之前,調(diào)用makecrc()初始化CRC計(jì)算表。最后gunzip()返回0表示解壓成功。在內(nèi)核啟動(dòng)時(shí)一般會(huì)看到這樣的輸出:
UncompressingLinux...done, booting the kernel.
當(dāng)然有的內(nèi)核沒(méi)有這樣的輸出,是沒(méi)有這一條打印語(yǔ)句。
30.2 Linux內(nèi)核啟動(dòng)(二):ARM處理器相關(guān)設(shè)置
當(dāng)Linux內(nèi)核自解壓完成后,開(kāi)始執(zhí)行內(nèi)核代碼。內(nèi)核的入口函數(shù)由鏈接腳本vmlinux.lds決定,需要編譯內(nèi)核源碼,才會(huì)生成腳本文件。
首先分析Linux內(nèi)核的鏈接腳本文件arch/arm/kernel/vmlinux.lds,通過(guò)鏈接腳本可以找到Linux內(nèi)核的第一行程序是從哪里開(kāi)始執(zhí)行的。vmlinux.lds文件部分代碼如下:
492 OUTPUT_ARCH(arm)
493 ENTRY(stext)
494 jiffies = jiffies_64;
495 SECTIONS
496 {
497 /*
498 * XXX: The linker does not define how output sections are
499 * assigned to input sections when there are multiple statements
500 * matching the same input section name. There is no documented
501 * order of matching.
502 *
503 * unwind exit sections must be discarded before the rest of the
504 * unwind sections get included.
505 */
506 /DISCARD/ : {
507 *(.ARM.exidx.exit.text)
508 *(.ARM.extab.exit.text)
509
......
645 }
第493行的 ENTRY 指明了Linux內(nèi)核入口函數(shù)為stext,因此要分析Linux內(nèi)核第二階段的啟動(dòng)流程,就得先從文件 arch/arm/kernel/head.S 的stext處開(kāi)始分析。
30.2.1 Linux內(nèi)核入口函數(shù)stext
stextLinux內(nèi)核的入口地址,在文件arch/arm/kernel/head.S中有如下內(nèi)容:
/*
* Kernel startup entry point.
* ---------------------------
*
* This is normally called from the decompressor code. The requirements
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
* r1 = machine nr, r2 = atags or dtb pointer.
.....
*/
以上代碼中的內(nèi)容顯示。Linux內(nèi)核啟動(dòng)之前要求如下:
① 關(guān)閉MMU
② 關(guān)閉D-cache
③ 不用關(guān)心I-cache
④ r0 = 0
⑤ r1 = machine nr(機(jī)器ID號(hào))
⑥ r2 = atags或者設(shè)備樹(shù)(dts)首地址
Linux內(nèi)核的入口點(diǎn)stext其實(shí)相當(dāng)于內(nèi)核的入口函數(shù),stext函數(shù)代碼如下:
80 ENTRY(stext)
......
91 @ ensure svc mode and all interrupts masked
92 safe_svcmode_maskall r9
93
94 mrc p15, 0, r9, c0, c0 @ get processor id
95 bl __lookup_processor_type @ r5=procinfo r9=cpuid
96 movs r10, r5 @ invalid processor (r5=0)?
97 THUMB( it eq ) @ force fixup-able long branch encoding
98 beq __error_p @ yes, error 'p'
99
......
107
108 #ifndef CONFIG_XIP_KERNEL
......
113 #else
114 ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case
115 #endif
116
117 /*
118 * r1 = machine no, r2 = atags or dtb,
119 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
120 */
121 bl __vet_atags
......
128 bl __create_page_tables
129
130 /*
131 * The following calls CPU specific code in a position independent
132 * manner. See arch/arm/mm/proc-*.S for details. r10 = base of
133 * xxx_proc_info structure selected by __lookup_processor_type
134 * above. On return, the CPU will be ready for the MMU to be
135 * turned on, and r0 will hold the CPU control register value.
136 */
137 ldr r13, =__mmap_switched @ address to jump to after
138 @ mmu has been enabled
139 adr lr, BSYM(1f) @ return (PIC) address
140 mov r8, r4 @ set TTBR1 to swapper_pg_dir
141 ldr r12, [r10, #PROCINFO_INITFUNC]
142 add r12, r12, r10
143 ret r12
144 1: b __enable_mmu
145 ENDPROC(stext)
第92行,調(diào)用函數(shù)safe_svcmode_maskall確保CPU處于SVC模式,并且關(guān)閉了所有的中斷。safe_svcmode_maskall定義在文件arch/arm/include/asm/assembler.h 中。
第94行,讀處理器ID,ID值保存在r9寄存器中。
第95行,__lookup_processor_type調(diào)用結(jié)束返回原程序時(shí),會(huì)將返回結(jié)果保存到寄存器中。其中r5寄存器返回一個(gè)用來(lái)描述處理器的結(jié)構(gòu)體地址,并對(duì)r5進(jìn)行判斷,如果r5的值為0則說(shuō)明不支持這種處理器,將進(jìn)入__error_p procinfo proc_info_list類(lèi) 結(jié) 構(gòu) Linux內(nèi)核將每種處理器都抽象為一個(gè) proc_info_list 結(jié)構(gòu)體,每種處理器都對(duì)應(yīng)一個(gè)procinfo。proc_info_list在文件arch/arm/include/asm/procinfo.h 中的定義如下:
struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mm_mmu_flags; /* used by head.S */
unsigned long   __cpu_io_mmu_flags; /* used by head.S */
unsigned long __cpu_flush; /* used by head.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
const char *cpu_name;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
struct cpu_cache_fns *cache;
};
121 行,調(diào)用函數(shù)__vet_atags 驗(yàn)證 atags 或設(shè)備樹(shù)(dtb)的合法性。函數(shù)__vet_atags 定義在文件 arch/arm/kernel/head-common.S 中。
128 行,調(diào)用函數(shù)__create_page_tables 創(chuàng)建頁(yè)表。
137 行,將函數(shù)__mmap_switched 的地址保存到 r13 寄存器中。__mmap_switched 定義在文件 arch/arm/kernel/head-common.S,__mmap_switched 最終會(huì)調(diào)用 start_kernel 函數(shù)。
144 ,調(diào)用 __enable_mmu 數(shù) 使 MMU __enable_mmu arch/arm/kernel/head.S 中。__enable_mmu 最終會(huì)通過(guò)調(diào)用__turn_mmu_on 來(lái)打開(kāi) MMU,__turn_mmu_on 最后會(huì)執(zhí)行 r13 里面保存的__mmap_switched 函數(shù)。
30.2.2 _mmap_switched 函數(shù)
__mmap_switched 函數(shù)定義在文件arch/arm/kernel/head-common.S中,函數(shù)代碼如下:
81 __mmap_switched:
82 adr r3, __mmap_switched_data
83
84 ldmia r3!, {r4, r5, r6, r7}
85 cmp r4, r5 @ Copy data segment if needed
86 1: cmpne r5, r6
87 ldrne fp, [r4], #4
88 strne fp, [r5], #4
89 bne 1b
90
91 mov fp, #0 @ Clear BSS (and zero fp)
92 1: cmp r6, r7
93 strcc fp, [r6],#4
94 bcc 1b
95
96 ARM( ldmia r3, {r4, r5, r6, r7, sp})
97 THUMB( ldmia r3, {r4, r5, r6, r7} )
98 THUMB( ldr sp, [r3, #16] )
99 str r9, [r4] @ Save processor ID
100 str r1, [r5] @ Save machine type
101 str r2, [r6] @ Save atags pointer
102 cmp r7, #0
103 strne r0, [r7] @ Save control register values
104 b start_kernel
105 ENDPROC(__mmap_switched)
104 行最終調(diào)用 start_kernel 來(lái)啟動(dòng) Linux 內(nèi)核,start_kernel 函數(shù)定義在文件 init/main.c中。
從start_kernel 函數(shù)開(kāi)始Linux內(nèi)核啟動(dòng)進(jìn)入到下一個(gè)階段。
下面內(nèi)容請(qǐng)關(guān)注:Linux內(nèi)核啟動(dòng)流程-迅為IMX6ULL開(kāi)發(fā)板(二)

本文地址:http://m.qingdxww.cn/thread-596614-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專(zhuān)區(qū)
  • 利用SAM E54 Xplained Pro評(píng)估工具包演示CAN轉(zhuǎn)USB橋接器以及基于CAN的主機(jī)和自舉程序應(yīng)用程序
  • 使用SAM-IoT Wx v2開(kāi)發(fā)板演示AWS IoT Core應(yīng)用程序
  • 使用Harmony3加速TCP/IP應(yīng)用的開(kāi)發(fā)培訓(xùn)教程
  • 集成高級(jí)模擬外設(shè)的PIC18F-Q71家族介紹培訓(xùn)教程
  • 貿(mào)澤電子(Mouser)專(zhuān)區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日本不卡一区二区三区四区 | 一级黄色大毛片 | 国产国产成人精品久久 | 91久久夜色精品国产九色 | 中国一级毛片特级毛片 | 欧美ab在线 | 亚洲一级视频在线观看 | 免费观看黄色在线视频 | 亚洲国产欧洲精品路线久久 | 亚洲精品手机在线观看 | 蜜桃精品视频 | 国产高清一级在线观看 | 91在线 在线播放 | 欧美在线视频一区二区 | 黄毛片一级毛片 | 欧美一级黄色片在线观看 | 亚洲三级在线观看 | 久久久一区二区三区不卡 | 日本高清在线视频www色下载 | 亚洲欧美91 | 日韩欧美日本 | 不卡免费在线视频 | 草莓视频app下载站长统计 | 午夜在线观看视频在线播放版 | 国产区香蕉精品系列在线观看不卡 | 1024香蕉国产在线视频 | 99久久中文字幕伊人 | 窝窝午夜看片成人精品 | 日本黄色网站大全 | 一级做a爱片就在线看 | 99热这里只有精品首页精品 | 99视频国产热精品视频 | 青青草手机在线观看 | 青青国产成人久久激情911 | 岛国片免费在线观看 | 久久久免费精品 | 成人亚洲欧美日韩中文字幕 | 91av视频在线观看 | 日韩拍拍拍 | 91福利在线视频 | 全国最大色 |