arm-linux内核start_kernel之前启动分析(3)-开启MMU,走进新时代

本文详细分析了ARM Linux内核启动过程中开启MMU的步骤,包括proc_info_list结构体的解析、CPU特定处理代码的执行、MMU的启用以及后续的__mmap_switched函数。通过理解这一过程,可以深入掌握ARM内核启动进入虚拟地址阶段的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在忙一款PPC处理器的芯片验证和内核移植工作,导致arm-linux启动分析最后一部一直没有写,今天将arm-linux start_kernel之前的最后一部分分析记录下。之前2篇文章链接如下:
http://blog.youkuaiyun.com/skyflying2012/article/details/41344377
http://blog.youkuaiyun.com/skyflying2012/article/details/41447843

kernel版本号:3.4.55

之前分析到__create_page_tables在内核代码区TEXT_OFF下部的16KB区域内进行页表的配置,完成turn_mmu_on的平映射以及kernel image的线性映射。接下来就需要开启MMU,让整个CPU进入虚拟地址运行的新阶段。head.S中stext最后一段代码如下:

   /*
     * 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_processor_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, =__mmap_switched       @ address to jump to after
                        @ mmu has been enabled
    adr lr, BSYM(1f)            @ return (PIC) address
    mov r8, r4              @ set TTBR1 to swapper_pg_dir
 ARM(   add pc, r10, #PROCINFO_INITFUNC )
 THUMB( add r12, r10, #PROCINFO_INITFUNC    )
 THUMB( mov pc, r12             )
1:  b   __enable_mmu
ENDPROC(stext)

看注释也可以明白接下来要完成的2件工作:执行CPU特定处理代码,开启MMU。
在第一篇分析中我们知道r10中存储着本CPU的proc_info_list首地址。到这里需要再详细解释下内核的proc
info机制。在kernel image中定义有一个.proc.info.init的段。在arch/arm/kernel/vmlinux.lds.S中,如下:

#define PROC_INFO                           \
    . = ALIGN(4);                           \
    VMLINUX_SYMBOL(__proc_info_begin) = .;              \
    *(.proc.info.init)                      \
    VMLINUX_SYMBOL(__proc_info_end) = .;

__proc_info_begin和__pro_info_end分别代表该段的头尾。.proc.info.init段中存储的数据是在arch/arm/mm/proc-xxx.S中定义的。到底使用哪个proc-xxx.S则由处理器的指令集版本号决定。
以我的cortex-A8处理器为例,是armv7指令集,根据arch/arm/mm/Makefile。

obj-$(CONFIG_CPU_V6)        += proc-v6.o
obj-$(CONFIG_CPU_V6K)       += proc-v6.o
obj-$(CONFIG_CPU_V7)        += proc-v7.o

编译的是proc-v7.S,在该文件中有如下一段汇编:

   .section ".rodata"

    string  cpu_arch_name, "armv7"
    string  cpu_elf_name, "v7"
    .align

    //接下来定义的数据都在.proc.info.init段中
    .section ".proc.info.init", #alloc, #execinstr

    /*
     * Standard v7 proc info content
     */
    //定义了宏定义__v7_proc,这个宏定义非常重要!
.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0
    ALT_SMP(.long   PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
            PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
    ALT_UP(.long    PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
            PMD_SECT_AF | PMD_FLAGS_UP | \mm_mmuflags)
    .long   PMD_TYPE_SECT | PMD_SECT_AP_WRITE | \
        PMD_SECT_AP_READ | PMD_SECT_AF | \io_mmuflags
    W(b)    \initfunc
    .long   cpu_arch_name
    .long   cpu_elf_name
    .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
        HWCAP_EDSP | HWCAP_TLS | \hwcaps
    .long   cpu_v7_name
    .long   v7_processor_functions
    .long   v7wbi_tlb_fns
    .long   v6_user_fns
    .long   v7_cache_fns
.endm
     //没有选择LPAE
#ifndef CONFIG_ARM_LPAE
    /*
     * ARM Ltd. Cortex A5 processor.
     */
    .type   __v7_ca5mp_proc_info, #object
__v7_ca5mp_proc_info:
    .long   0x410fc050
    .long   0xff0ffff0
    __v7_proc __v7_ca5mp_setup
    .size   __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info

    /*
     * ARM Ltd. Cortex A9 processor.
     */
    .type   __v7_ca9mp_proc_info, #object
__v7_ca9mp_proc_info:
    .long   0x410fc090
    .long   0xff0ffff0
    __v7_proc __v7_ca9mp_setup
    .size   __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
#endif  /* CONFIG_ARM_LPAE */

    /*
     * ARM Ltd. Cortex A7 processor.
     */
    .type   __v7_ca7mp_proc_info, #object
__v7_ca7mp_proc_info:
    .long   0x410fc070
    .long   0xff0ffff0
    __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
    .size   __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info

    /*
     * ARM Ltd. Cortex A15 processor.
     */
    .type   __v7_ca15mp_proc_info, #object
__v7_ca15mp_proc_info:
    .long   0x410fc0f0
    .long   0xff0ffff0
    __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV
    .size   __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info

    /*
     * Match any ARMv7 processor core.
     */
    .type   __v7_proc_info, #object
__v7_proc_info:
    .long   0x000f0000      @ Required ID value
    .long   0x000f0000      @ Mask for ID
    __v7_proc __v7_setup
    .size   __v7_proc_info, . - __v7_proc_info

这段汇编看出,指定.proc.info.init段中存储的是一些结构体,定义了V7指令集特定处理器的属性和处理函数。在C文件中我们找到了这些结构体的定义&

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值