单片机
返回首页

arm linux 从入口到start_kernel 代码分析 - 5

2016-07-25 来源:eefocus

4. 调用平台特定的 __cpu_flush 函数

当 __create_page_tables 返回之后

此时,一些特定寄存器的值如下所示:
r4 = pgtbl              (page table 的物理基地址)
r8 = machine info       (struct machine_desc的基地址)
r9 = cpu id             (通过cp15协处理器获得的cpu id)
r10 = procinfo          (struct proc_info_list的基地址)


在我们需要在开启mmu之前,做一些必须的工作:清除ICache, 清除 DCache, 清除 Writebuffer, 清除TLB等.
这些一般是通过cp15协处理器来实现的,并且是平台相关的. 这就是 __cpu_flush 需要做的工作.
       
        在 arch/arm/kernel/head.S中
00091:  ldr r13, __switch_data  @ address to jump to after
00092:       @ mmu has been enabled    
00093:  adr lr, __enable_mmu  @ return (PIC) address    
00094:  add pc, r10, #PROCINFO_INITFUNC           

第91行: 将r13设置为 __switch_data 的地址
第92行: 将lr设置为 __enable_mmu 的地址
第93行: r10存储的是procinfo的基地址, PROCINFO_INITFUNC是在 arch/arm/kernel/asm-offset.c 中107行定义.
        则该行将pc设为 proc_info_list的 __cpu_flush 函数的地址, 即下面跳转到该函数.
        在分析 __lookup_processor_type 的时候,我们已经知道,对于 ARM926EJS 来说,其__cpu_flush指向的是函数 __arm926_setup

       
        下面我们来分析函数 __arm926_setup
       
        在 arch/arm/mm/proc-arm926.S 中:
00391:  .type __arm926_setup, #function
00392: __arm926_setup:
00393:  mov r0, #0
00394:  mcr p15, 0, r0, c7, c7  @ invalidate I,D caches on v4
00395:  mcr p15, 0, r0, c7, c10, 4  @ drain write buffer on v4
00396: #ifdef CONFIG_MMU
00397:  mcr p15, 0, r0, c8, c7  @ invalidate I,D TLBs on v4
00398: #endif
00399:
00400:
00401: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
00402:  mov r0, #4    @ disable write-back on caches explicitly
00403:  mcr p15, 7, r0, c15, c0, 0
00404: #endif
00405:
00406:  adr r5, arm926_crval
00407:  ldmia r5, {r5, r6}
00408:  mrc p15, 0, r0, c1, c0  @ get control register v4
00409:  bic r0, r0, r5
00410:  orr r0, r0, r6
00411: #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
00412:  orr r0, r0, #0x4000   @ .1.. .... .... ....
00413: #endif
00414:  mov pc, lr       
00415:  .size __arm926_setup, . - __arm926_setup
00416:
00417:  
00423:  .type arm926_crval, #object
00424: arm926_crval:
00425:  crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134

 

第391, 392行: 是函数声明
第393行: 将r0设置为0
第394行: 清除(invalidate)Instruction Cache 和 Data Cache.
第395行: 清除(drain) Write Buffer.
第396 - 398行: 如果有配置了MMU,则需要清除(invalidate)Instruction TLB 和Data TLB

接下来,是对控制寄存器c1进行配置,请参考 ARM926 TRM.

第401 - 404行: 如果配置了Data Cache使用writethrough方式, 需要关掉write-back.
                
第406行: 取arm926_crval的地址到r5中, arm926_crval 在第424行
  
第407行: 这里我们需要看一下424和425行,其中用到了宏crval,crval是在 arch/arm/mm/proc-macro.S 中:

        00053:  .macro crval, clear, mmuset, ucset
        00054: #ifdef CONFIG_MMU
        00055:  .word \clear
        00056:  .word \mmuset
        00057: #else
        00058:  .word \clear
        00059:  .word \ucset
        00060: #endif
        00061:  .endm

        配合425行,我们可以看出,首先在arm926_crval的地址处存放了clear的值,然后接下来的地址存放了mmuset的值(对于配置了MMU的情况)               
       
所以,在407行中,我们将clear和mmuset的值分别存到了r5, r6中

第408行: 获得控制寄存器c1的值
第409行:  将r0中的 clear (r5) 对应的位都清除掉
第410行: 设置r0中 mmuset (r6) 对应的位

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

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章