新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > arm linux 從入口到start_kernel 代碼分析 - 5

        arm linux 從入口到start_kernel 代碼分析 - 5

        作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
        4. 調(diào)用平臺(tái)特定的 __cpu_flush 函數(shù)

        當(dāng) __create_page_tables 返回之后

        本文引用地址:http://www.104case.com/article/201611/317209.htm

        此時(shí),一些特定寄存器的值如下所示:
        r4 = pgtbl (page table 的物理基地址)
        r8 = machine info (struct machine_desc的基地址)
        r9 = cpu id (通過cp15協(xié)處理器獲得的cpu id)
        r10 = procinfo (struct proc_info_list的基地址)


        在我們需要在開啟mmu之前,做一些必須的工作:清除ICache, 清除 DCache, 清除 Writebuffer, 清除TLB等.
        這些一般是通過cp15協(xié)處理器來實(shí)現(xiàn)的,并且是平臺(tái)相關(guān)的. 這就是 __cpu_flush 需要做的工作.

        在 arch/arm/kernel/head.S中
        00091: ldrr13, __switch_data@ address to jump to after
        00092: @ mmu has been enabled
        00093: adrlr, __enable_mmu@ return (PIC) address
        00094: addpc, r10, #PROCINFO_INITFUNC

        第91行: 將r13設(shè)置為 __switch_data 的地址
        第92行: 將lr設(shè)置為 __enable_mmu 的地址
        第93行: r10存儲(chǔ)的是procinfo的基地址, PROCINFO_INITFUNC是在 arch/arm/kernel/asm-offset.c 中107行定義.
        則該行將pc設(shè)為 proc_info_list的 __cpu_flush 函數(shù)的地址, 即下面跳轉(zhuǎn)到該函數(shù).
        在分析 __lookup_processor_type 的時(shí)候,我們已經(jīng)知道,對(duì)于 ARM926EJS 來說,其__cpu_flush指向的是函數(shù) __arm926_setup


        下面我們來分析函數(shù) __arm926_setup

        在 arch/arm/mm/proc-arm926.S 中:
        00391: .type__arm926_setup, #function
        00392: __arm926_setup:
        00393: movr0, #0
        00394: mcrp15, 0, r0, c7, c7@ invalidate I,D caches on v4
        00395: mcrp15, 0, r0, c7, c10, 4@ drain write buffer on v4
        00396: #ifdef CONFIG_MMU
        00397: mcrp15, 0, r0, c8, c7@ invalidate I,D TLBs on v4
        00398: #endif
        00399:
        00400:
        00401: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
        00402: movr0, #4@ disable write-back on caches explicitly
        00403: mcrp15, 7, r0, c15, c0, 0
        00404: #endif
        00405:
        00406: adrr5, arm926_crval
        00407: ldmiar5, {r5, r6}
        00408: mrcp15, 0, r0, c1, c0@ get control register v4
        00409: bicr0, r0, r5
        00410: orrr0, r0, r6
        00411: #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
        00412: orrr0, r0, #0x4000@ .1.. .... .... ....
        00413: #endif
        00414: movpc, lr
        00415: .size__arm926_setup, . - __arm926_setup
        00416:
        00417:
        00423: .typearm926_crval, #object
        00424: arm926_crval:
        00425: crvalclear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134

        第391, 392行: 是函數(shù)聲明
        第393行: 將r0設(shè)置為0
        第394行: 清除(invalidate)Instruction Cache 和 Data Cache.
        第395行: 清除(drain) Write Buffer.
        第396 - 398行: 如果有配置了MMU,則需要清除(invalidate)Instruction TLB 和Data TLB

        接下來,是對(duì)控制寄存器c1進(jìn)行配置,請(qǐng)參考 ARM926 TRM.

        第401 - 404行: 如果配置了Data Cache使用writethrough方式, 需要關(guān)掉write-back.

        第406行: 取arm926_crval的地址到r5中, arm926_crval 在第424行

        第407行: 這里我們需要看一下424和425行,其中用到了宏crval,crval是在 arch/arm/mm/proc-macro.S 中:

        00053: .macrocrval, clear, mmuset, ucset
        00054: #ifdef CONFIG_MMU
        00055: .wordclear
        00056: .wordmmuset
        00057: #else
        00058: .wordclear
        00059: .worducset
        00060: #endif
        00061: .endm

        配合425行,我們可以看出,首先在arm926_crval的地址處存放了clear的值,然后接下來的地址存放了mmuset的值(對(duì)于配置了MMU的情況)

        所以,在407行中,我們將clear和mmuset的值分別存到了r5, r6中

        第408行: 獲得控制寄存器c1的值
        第409行: 將r0中的 clear (r5) 對(duì)應(yīng)的位都清除掉
        第410行: 設(shè)置r0中 mmuset (r6) 對(duì)應(yīng)的位

        第411 - 413行: 如果配置了使用 round robin方式,需要設(shè)置控制寄存器c1的 Bit[16]
        第412行: 取lr的值到pc中.
        而lr中的值存放的是 __enable_mmu 的地址(arch/arm/kernel/head.S 93行),所以,接下來就是跳轉(zhuǎn)到函數(shù) __enable_mmu



        關(guān)鍵詞: armlinuxstart_kernel代碼分

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 平昌县| 朝阳县| 玉林市| 鲁甸县| 旺苍县| 玛纳斯县| 民权县| 磴口县| 商河县| 西乡县| 泾阳县| 黄陵县| 临泽县| 津南区| 盱眙县| 金湖县| 依安县| 邳州市| 佛教| 彰化市| 疏勒县| 广安市| 博湖县| 商都县| 西安市| 耒阳市| 西盟| 九龙坡区| 柳江县| 阿拉善左旗| 新竹县| 石首市| 平山县| 武宁县| 修文县| 巴青县| 曲松县| 澳门| 阜新| 甘洛县| 威远县|