前提知识点:
内核最初启动的时候,没有启动MMU,这样导致CPU只认物理地址(又称运行地址),不认虚拟地址(又称链接地址)。
所以,地址操作在内核汇编中普遍存在,基于内核编译时,是用链接脚本进行定位的。基于无MMU的CPU运行时,是依据PC地址进行定位的。所以,运行内核时,需要将虚拟地址转为物理地址以供运行。
最常见的方法即是,adr获取物理地址,ldr获取虚拟地址,两者相减得偏移值,后续虚拟地址加偏移得物理地址。
分析依据:
1.硬件imx6
2.内核3.0.35
大纲:
1.汇编部分:
1.1SVC模式、禁止中断
1.2.获取CPU架构ID,匹配CPU架构信息(协处理器读取)
1.3.内核启动参数确认
1.4.创建页表(16K一级初始页表区、内核镜像、atag)
1.5.ICACHE/DCACHE
1.6.MMU启动(协处理器设置)
1.7.映射(数据、bss、内核接口需求)
2.C语言部分
2.1初始化系统(时钟等)
2.2匹配CPU芯片并初始化
....
uboot引导过后,经过判断MMU = off, D-cache = off, I-cache = dont care, r0 = 0,* r1 = machine nr, r2 = atags or dtb pointer,全部符合才跳转到以下入口
arch/arm/kernel/head.S
一、CPU确认:
/arch/arm/kernel/head-common.S
IMX6为ARMv7架构,所以定义文件在/arch/arm/mm/proc-v7.S
地址转换过程:
因为在判定CPU架构时未开启系统的MMU功能,所以均使用物理地址,
而内核代码在连接时是以虚拟地址来实现的,因此要想用proc_info_list 结构,该结构表示的是内核所支持的CPU架构
__lookup_processor_type使用该元素的前两个字段cpuid和mask来匹配当前CPUID,如果满足CPUID & mask == cpuid,则找到当前cpu的定义并返回
二、内核启动参数确认
三、SMP调整
四、页表(16K一级初始页表、内核Image、atags、串口地址重定位)
五、MMU使能
协处理器介绍:
六、映射(数据、bss、入口需求)
arch/arm/kernel/setup_arch.c
内核2.6.39.rc1之前的__lookup_machine_type被改为setup_machine_tags
/arch/arm/include/asm/mach/arch.h
/arch/arm/kernel/vmlinux.lds
/arch/arm/include/asm/mach/arch.h
/arch/arm/mach-mx6/board-mx6q_sabresd.c
include/generated/mach-types.h +1109