技术标签: 启动 mmu kernel 内核 linux内核启动之谜 linux kernel arm
最近在忙一款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 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文件中我们找到了这些结构体的定义&
文章浏览阅读1k次。在cocos2d-x中一切可视化的元素都集成自Node,zhe's_cococs cocos2d::node 使用
文章浏览阅读74次。20180806 考试记录 T1 【NOIP2013模拟联考8】最短路(path)Solution设s为第0个标记点,t为k+1个跑k+1次最短路然后全排列暴力求解qwq注意最大值要设为long long范围最大值CodePS:各种修改qwq//By Menteur_Hxy#include<queue>#include..._i <= 3000000000u
文章浏览阅读190次。点击关注公众号,实用技术文章及时了解作者:LanceToBigDatacnblogs.com/zhangyinhua/p/7620964.html说起MySQL的查询优化,相信大家积累...
文章浏览阅读921次。云函数/云函数本地调试云函数是云开发其中一项基础能力,在云端运行的代码,微信私有协议天然鉴权,开发者只需编写自身业务逻辑代码。云函数个数免费版云函数数量上限为 50写完自己的原函数后,可以通过云函数的本地调试来进行调试,调试没有问题了就可以上传云端,对于解决bug查找bug是很好用的使用像调试自己的哪一个云函数就直接右键开启本地调试即可。就是这样一个页面此时运行自己的云函数就是在本地运行不是再云端给运行了。可以调试没问题后再传到云端,有时候会弹出一个错误解决方法:右键点击你_本地云函数调试并发数量限制
文章浏览阅读5.8k次。微软的解释:创建称为默认值的对象。当绑定到列或别名数据类型时,如果插入时没有显式提供值,则默认值将指定一个值,以便将其插入该对象所绑定的列中(或者,如果是别名数据类型,则插入所有列中)。后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。语法 ..._sql declare default
文章浏览阅读2.2k次。首先介绍一下背景知识:Linux主分区,扩展分区,逻辑分区的联系和区别Linux硬盘分区有三种,主磁盘分区、扩展磁盘分区、逻辑分区。一个硬盘主分区至少有1个,最多4个,扩展分区可以没有,最多1个。且主分区+扩展分区总共不能超过4个。逻辑分区可以有若干个。在linux下主分区和逻辑分区都可以用来放系统,引导os开机。分出主分区后,其余的部分可以分成扩展分区,一般情况是剩余磁盘空间全部配成扩展分区,..._sdb7这个分区的具体含义
文章浏览阅读72次。1、将数据库和监听程序关闭2、首先检查OPatch版本是否符合要求:$ORACLE_HOME/OPatch/opatch lsinventory3、若不符合要求,需先更新opatch:mv 掉原有的OPatch目录mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatchbakcp p6880880_112000_SOLARIS64-opatch11.2.0.3.12.z..._oracle9i 打补丁时ouihome设置
文章浏览阅读1.8k次,点赞4次,收藏18次。几个常见的问题:问题一:相关的几个软件下载地址Tesseract:Index of /tesseractjTessBoxEditor: VietOCR - Browse /jTessBoxEditor at SourceForge.net问题二:jTessBoxEditor下载是注意一下,中文的话要下载jTessBoxEditorFX问题三:mftraining执行时提示停止工作,一般是Tesseract版本的问题,可以选择Tesseract3验证过是好的,Tesser._jtessboxeditor训练英文和数字结合的图片
文章浏览阅读302次。题目:用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。如果只有5个砝码,重量分别是1,3,9,27,81则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。本题目要求编程实现:对用户给定的重量,给出砝码组合方案。例如:用户输入:5程序输出:9-3-1用户输入:19程序输出:27-9+1要求程序输出的组合总是大数在前小数在后。可以假设用户的输入的数字符合范围1~121。思路:观察输出,都是3的多少次方,所以我们可以把输入的值,转换成3进制的_天平称重(进制解法) python
文章浏览阅读954次。链接:https://pan.baidu.com/s/1w5_GTiWuAR_X2t8J7JIP4Q提取码:a0u1_druid-1.1.21.jar
文章浏览阅读8k次。看到一篇pthread_spinlock_t与pthread_mutex_t性能对比做的非常细致的博客,记录下来原文在此:http://www.cnblogs.com/diyunpeng/archive/2011/06/07/2074059.html_pthread 性能 效率
文章浏览阅读1.1k次。myisam:.frm: 存储表定义.myd(MYData):存储数据.MYI(MYindex):存储引擎innodb:.frm:存储表定义.idb:存储数据和索引,在同一个文件中_innodb和mylsam生成文件的区别