IMX6Solo启动流程-Linux 内核启动 七
来源:互联网 发布:19的网络语啥意思 编辑:程序博客网 时间:2024/06/05 17:45
写在前头
*.版权声明:本篇文章为原创,可随意转载,转载请注明出处,谢谢!另我创建一个QQ群82642304,欢迎加入!
*.目的:整理一下RIotBoard开发板的启动流程,对自己的所学做一个整理总结,本系列内核代码基于linux-3.0.35-imx。
*.备注:整个系列只是对我所学进行总结,记录我认为是关键的点,另我能力有限,难免出现疏漏错误,如果读者有发现请多指正,以免我误导他人!
接上篇分析:
/* * 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_mmuENDPROC(stext)
注释里解释的十分清楚。
1. 将__mmap_switched的地址保存在r13,然后将返回地址设置成
b __enable_mmu
然后保存页表地址到r8,跳转到struct proc_info_list->__cpu_flush。
2. struct proc_info_list->__cpu_flush的定义在arch/arm/mm/proc-**.S,对我来说就是arch/arm/mm/proc-v7.S:
/* * Match any ARMv7 processor core. */ .type __v7_proc_info, #object__v7_proc_info: .long 0x000f0000 @ Required ID value .long 0x000f0000 @ Mask for ID ALT_SMP(.long \ PMD_TYPE_SECT | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ | \ PMD_FLAGS_SMP) ALT_UP(.long \ PMD_TYPE_SECT | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ | \ PMD_FLAGS_UP) .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ W(b) __v7_setup .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS .long cpu_v7_name .long v7_processor_functions .long v7wbi_tlb_fns .long v6_user_fns .long v7_cache_fns .size __v7_proc_info, . - __v7_proc_info
即跳转到__v7_setup,它的作用注释里面页解释清楚:
Initialise TLB, Caches, and MMU state ready to switch the MMU
arm V7内核,架构相关,我没有继续研究。
执行完__v7_setup后,由于之前我们已经赋值好lr寄存器的值,所以跳转之后,就是继续跳转到__enable_mmu函数。
3. __enable_mmu函数在head.S中定义,它的作用就是开启MMU,在该函数的最后汇编代码片段为
mov r3, r13 mov pc, r3
我们可以看到跳转到里r13寄存器里面保存的值,在之前r13寄存器保存的值是__mmap_switched,这是一个链接地址,跳转到这边后就跳出平等映射代码区域。
4. __mmap_switched的定义在head-common.S中:
/* * 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 * r2 = atags/dtb pointer * r9 = processor ID */ __INIT__mmap_switched: adr r3, __mmap_switched_data ldmia r3!, {r4, r5, r6, r7} cmp r4, r5 @ Copy data segment if needed1: 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 ARM( ldmia r3, {r4, r5, r6, r7, sp}) THUMB( ldmia r3, {r4, r5, r6, r7} ) THUMB( ldr sp, [r3, #16] ) str r9, [r4] @ Save processor ID str r1, [r5] @ Save machine type str r2, [r6] @ Save atags pointer bic r4, r0, #CR_A @ Clear 'A' bit stmia r7, {r0, r4} @ Save control register values b start_kernelENDPROC(__mmap_switched)
清除BSS段,跳转到start_kernel。
start_kernel定义在init/main.c中,就是内核启动的第二阶段(C语言)。
在该函数里面做着大量的初始化工作,是一个非常重要的函数。
网络上有许多关于该函数的分析。我后续也会慢慢分析,但是我打算不按照它的执行流程来分析,而是尽量按照功能/模块来分析。
如果需要研究它的执行流程,建议参考网络上其他文章。
总结
创建页表之后的代码理解起来比较容易,我就没有详细分析。
参考
暂无
- IMX6Solo启动流程-Linux 内核启动 七
- IMX6Solo启动流程-Linux 内核启动 一
- IMX6Solo启动流程-Linux 内核启动 二
- IMX6Solo启动流程-Linux 内核启动 三
- IMX6Solo启动流程-Linux 内核启动 四
- IMX6Solo启动流程-Linux 内核启动 五
- IMX6Solo启动流程-Linux 内核启动 六
- IMX6Solo启动流程-从上电到Uboot
- linux内核启动流程
- Linux内核启动流程
- linux内核启动流程
- linux内核启动流程
- linux内核启动流程
- Linux内核启动流程
- Linux内核启动流程
- linux内核启动流程
- linux内核启动流程
- linux内核启动流程
- google test 例子 & coding style
- Hbase helloworld
- 二叉树的非递归遍历
- fopen函数和fread函数、fwrite函数
- 事务基础知识-->Spring事务管理
- IMX6Solo启动流程-Linux 内核启动 七
- HDU 5493 Queue (线段树) 2015合肥网络赛
- 如何在项目中引入.h、.lib和dll、以及.cpp
- 国际化信息-->MVC
- 使用GO语言开发 Redis数据监控程序
- CoordinatorLayout与快速返回的实现
- AndroidUI ToolBar
- 【Visual C++ 2010】WM_PAINT消息产生的条件
- Html5离线缓存详细讲解