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 rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全