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

2024-01-06 21:38

本文主要是介绍arm-linux内核start_kernel之前启动分析(3)-开启MMU,走进新时代,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在忙一款PPC处理器的芯片验证和内核移植工作,导致arm-linux启动分析最后一部一直没有写,今天将arm-linux start_kernel之前的最后一部分分析记录下。之前2篇文章链接如下:
http://blog.csdn.net/skyflying2012/article/details/41344377
http://blog.csdn.net/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 enabledadr lr, BSYM(1f)            @ return (PIC) addressmov r8, r4              @ set TTBR1 to swapper_pg_dirARM(   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 = 0ALT_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_mmuflagsW(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文件中我们找到了这些结构体的定义&

这篇关于arm-linux内核start_kernel之前启动分析(3)-开启MMU,走进新时代的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/577706

相关文章

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

springboot启动流程过程

《springboot启动流程过程》SpringBoot简化了Spring框架的使用,通过创建`SpringApplication`对象,判断应用类型并设置初始化器和监听器,在`run`方法中,读取配... 目录springboot启动流程springboot程序启动入口1.创建SpringApplicat