arm linux 从入口到start_kernel 代码分析 - 2

发布者:张延强最新更新时间:2016-07-25 来源: eefocus关键字:arm  linux  start_kernel  代码分析 手机看文章 扫描二维码
随时随地手机看文章
 

1. 确定 processor type
 


    arch/arm/kernel/head.S中:
00075:  mrc p15, 0, r9, c0, c0  @ get processor id        
00076:  bl __lookup_processor_type  @ r5=procinfo r9=cpuid    
00077:  movs r10, r5    @ invalid processor (r5=0)?
00078:  beq __error_p   @ yes, error 'p'          

75行: 通过cp15协处理器的c0寄存器来获得processor id的指令. 关于cp15的详细内容可参考相关的arm手册

76行: 跳转到__lookup_processor_type.在__lookup_processor_type中,会把processor type 存储在r5中
77,78行: 判断r5中的processor type是否是0,如果是0,说明是无效的processor type,跳转到__error_p(出错)

__lookup_processor_type 函数主要是根据从cpu中获得的processor id和系统中的proc_info进行匹配,将匹配到的proc_info_list的基地址存到r5中, 0表示没有找到对应的processor type.

下面我们分析__lookup_processor_type函数
 arch/arm/kernel/head-common.S中:
 
00145:  .type __lookup_processor_type, %function
00146: __lookup_processor_type:
00147:  adr r3, 3f
00148:  ldmda r3, {r5 - r7}
00149:  sub r3, r3, r7   @ get offset between virt&phys
00150:  add r5, r5, r3   @ convert virt addresses to
00151:  add r6, r6, r3   @ physical address space
00152: 1: ldmia r5, {r3, r4}   @ value, mask
00153:  and r4, r4, r9   @ mask wanted bits
00154:  teq r3, r4
00155:  beq 2f
00156:  add r5, r5, #PROC_INFO_SZ  @ sizeof(proc_info_list)
00157:  cmp r5, r6
00158:  blo 1b
00159:  mov r5, #0    @ unknown processor
00160: 2: mov pc, lr
00161:
00162:
00165: ENTRY(lookup_processor_type)
00166:  stmfd sp!, {r4 - r7, r9, lr}
00167:  mov r9, r0
00168:  bl __lookup_processor_type
00169:  mov r0, r5
00170:  ldmfd sp!, {r4 - r7, r9, pc}
00171:
00172:
00176:  .long __proc_info_begin
00177:  .long __proc_info_end
00178: 3: .long .
00179:  .long __arch_info_begin
00180:  .long __arch_info_end
 
   
145, 146行是函数定义
147行: 取地址指令,这里的3f是向前symbol名称是3的位置,即第178行,将该地址存入r3.
        这里需要注意的是,adr指令取址,获得的是基于pc的一个地址,要格外注意,这个地址是3f处的"运行时地址",由于此时MMU还没有打开,也可以理解成物理地址(实地址).(详细内容可参考arm指令手册)
       
148行: 因为r3中的地址是178行的位置的地址,因而执行完后:
        r5存的是176行符号 __proc_info_begin的地址;
        r6存的是177行符号 __proc_info_end的地址;
        r7存的是3f处的地址.
        这里需要注意链接地址和运行时地址的区别. r3存储的是运行时地址(物理地址),而r7中存储的是链接地址(虚拟地址).
       
         __proc_info_begin和__proc_info_end是在arch/arm/kernel/vmlinux.lds.S中:
        00031:  __proc_info_begin = .;
        00032:   *(.proc.info.init)
        00033:  __proc_info_end = .;

        这里是声明了两个变量:__proc_info_begin 和 __proc_info_end,其中等号后面的"."是location counter(详细内容请参考ld.info)
        这三行的意思是: __proc_info_begin 的位置上,放置所有文件中的 ".proc.info.init" 段的内容,然后紧接着是 __proc_info_end 的位置.

        kernel 使用struct proc_info_list来描述processor type.
         在 include/asm-arm/procinfo.h 中:
        00029: struct proc_info_list {
        00030:  unsigned int  cpu_val;
        00031:  unsigned int  cpu_mask;
        00032:  unsigned long  __cpu_mm_mmu_flags; 
        00033:  unsigned long  __cpu_io_mmu_flags; 
        00034:  unsigned long  __cpu_flush;  
        00035:  const char  *arch_name;
        00036:  const char  *elf_name;
        00037:  unsigned int  elf_hwcap;
        00038:  const char  *cpu_name;
        00039:  struct processor *proc;
        00040:  struct cpu_tlb_fns *tlb;
        00041:  struct cpu_user_fns *user;
        00042:  struct cpu_cache_fns *cache;
        00043: };
       
        我们当前以at91为例,其processor是926的.
                在arch/arm/mm/proc-arm926.S 中:
        00464:  .section ".proc.info.init", #alloc, #execinstr
        00465:
        00466:  .type __arm926_proc_info,#object
        00467: __arm926_proc_info:
        00468:  .long 0x41069260   @ ARM926EJ-S (v5TEJ)
        00469:  .long 0xff0ffff0
        00470:  .long   PMD_TYPE_SECT | \
        00471:   PMD_SECT_BUFFERABLE | \
        00472:   PMD_SECT_CACHEABLE | \
        00473:   PMD_BIT4 | \
        00474:   PMD_SECT_AP_WRITE | \
        00475:   PMD_SECT_AP_READ
        00476:  .long   PMD_TYPE_SECT | \
        00477:   PMD_BIT4 | \
        00478:   PMD_SECT_AP_WRITE | \
        00479:   PMD_SECT_AP_READ
        00480:  __arm926_setup
        00481:  .long cpu_arch_name
        00482:  .long cpu_elf_name
        00483:  .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
        00484:  .long cpu_arm926_name
        00485:  .long arm926_processor_functions
        00486:  .long v4wbi_tlb_fns
        00487:  .long v4wb_user_fns
        00488:  .long arm926_cache_fns
        00489:  .size __arm926_proc_info, . - __arm926_proc_info
       
        从464行,我们可以看到 __arm926_proc_info 被放到了".proc.info.init"段中.
        对照struct proc_info_list,我们可以看到 __cpu_flush的定义是在480行,即__arm926_setup.(我们将在"4. 调用平台特定的__cpu_flush函数"一节中详细分析这部分的内容.)
       
从以上的内容我们可以看出: r5中的__proc_info_begin是proc_info_list的起始地址, r6中的__proc_info_end是proc_info_list的结束地址.

149行: 从上面的分析我们可以知道r3中存储的是3f处的物理地址,而r7存储的是3f处的虚拟地址,这一行是计算当前程序运行的物理地址和虚拟地址的差值,将其保存到r3中.

150行: 将r5存储的虚拟地址(__proc_info_begin)转换成物理地址
151行: 将r6存储的虚拟地址(__proc_info_end)转换成物理地址
152行: 对照struct proc_info_list,可以得知,这句是将当前proc_info的cpu_val和cpu_mask分别存r3, r4中
153行: r9中存储了processor id(arch/arm/kernel/head.S中的75行),与r4的cpu_mask进行逻辑与操作,得到我们需要的值
154行: 将153行中得到的值与r3中的cpu_val进行比较
155行: 如果相等,说明我们找到了对应的processor type,跳到160行,返回
156行: (如果不相等) , 将r5指向下一个proc_info,
157行: 和r6比较,检查是否到了__proc_info_end.
158行: 如果没有到__proc_info_end,表明还有proc_info配置,返回152行继续查找
159行: 执行到这里,说明所有的proc_info都匹配过了,但是没有找到匹配的,将r5设置成0(unknown processor)
160行: 返回

关键字:arm  linux  start_kernel  代码分析 引用地址:arm linux 从入口到start_kernel 代码分析 - 2

上一篇:ARM Linux从入口到Start_kernel代码分析 - (1)
下一篇:arm linux 从入口到start_kernel 代码分析 - 3

推荐阅读最新更新时间:2024-03-16 15:01

ARM程序状态寄存器
ARM体系结构包含一个当前程序状态寄存器(CPSR)和五个备份的程序状态寄存器(SPSRs)。备份的程序状态寄存器用来进行异常处理,其功能包括: ─ 保存ALU中的当前操作信息 ─ 控制允许和禁止中断 ─ 设置处理器的运行模式 条件码标志(Condition Code Flags) N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。 在ARM状态下,绝大多数的指令都是有条件执行的。 在Thumb状态下,仅有分支指令是有条件执行的。 控制位 PSR的低8位(包括I、F、T和M )称为控制位,当发生异常时这些位可以被改变。如果处理器运行特权模式,这些位也可以由程序修改。 ─ 中断
[单片机]
ARM mbed平台WIZwiki-W7500使用说明
ARM mbed IDE 是ARM内核微控制器的在线开发工具,其网站是: http://developer.mbed.org 。网站提供了在线编译器,不需要本地安装编译器即可进行开发,因此没有地点、时间和编译器版本的限制,只要有网络随时随地可进行开发。 下面开始使用ARM mbed IDE 进行WIZwiki-W7500的开发。 1. 如图1所示,首先在 developer.mbed.org 上创建一个帐号,在此帐号下可以添加和使用一些在线软件。登陆注册的账号开始使用IDE,如图2所示。 图1 ARM mbed首页 图2 账号登陆后的界面 2. Mbed.org 提供了不同厂商的不同平台,直接选择需要的厂
[单片机]
<font color='red'>ARM</font> mbed平台WIZwiki-W7500使用说明
基于ARM开发板的车辆检测系统控制单元设计
引言 由于交通需求的不断增加,有越来越多的环形感应线圈检测器用于交通检测。这些埋设在道路表面下的线圈可以检测到车辆通过时的电磁变化进而精确地算出交通流量。交通流量是交通统计和交通规划的基本数据,通过这些检测结果可以用来计算占用率(表征交通密度),在使用双线圈模式时还可以提供速度、车辆行驶方向、车型分类等数据,这些数据对于交通管理和统计是极为重要的。通常高速公路车辆检测系统由多通道环形检测单元LD4和控制单元CCU组成,本文采用PHILIPS公司最新推出的ARM7内核微处理器LPC2114设计实现了车辆检测系统控制单元部分,并且和5个LD4环形检测器一起构成10通道高速公路车辆检测系统。 LPC2114和电子硬盘连线示意图
[单片机]
基于<font color='red'>ARM</font>开发板的车辆检测系统控制单元设计
嵌入式linux启动信息完全注释
作者: yut616@sohu.com 摘要 我们在这里讨论的是对嵌入式linux系统的启动过程的输出信息的注释,通过我们的讨论,大家会对嵌入式linux启动过程中出现的、以前感觉熟悉的、但却又似是而非的东西有一个确切的了解,并且能了解到这些输出信息的来龙去脉。 嵌入式linux的启动信息是一个很值得我们去好好研究的东西,它能将一幅缩影图呈现在我们面前,来指导我们更加深入地理解linux内核。 关键字:linux,嵌入式,启动,bootloader 正文 作为一名嵌入系统开发者,你一定遇到过下面的情景: 在某论坛上看到一篇帖子,上面贴着嵌入式linux开发板启动时的有关信息,然后大家在帖子里讨论着这个启动过程中出
[嵌入式]
微软Windows再度拥抱ARM 突破英特尔、AMD双寡头
微软(Microsoft)曾尝试让Windows RT运行ARM(ARM)处理器,最后以失败告终,如今微软再结盟高通(Qualcomm),推出搭载高通ARM架构Snapdragon 835芯片的随时连结PC(Always Connected PC),这等于打破多年来由英特尔(Intel)及AMD(AMD) x86架构盘据的全球PC中央处理器(CPU)市场格局,让这块市场终于出现非x86架构新选择,另也是微软在面临苹果(Apple) iPad入侵NB市场下,借由推常时连网PC以期抵挡来自iPad对企业PC市场的持续入侵。   根据The Motley Fool网站报导,微软于2012年试图让Windows RT支援ARM处理器运行,
[半导体设计/制造]
linux内核中的IS_ERR
在看内核源码的时候,经常会遇到IS_ERR,比如在 linux/arch/arm/kernel/sys_arm.c中 view plain copy print ? asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv, char __user * __user *envp, struct pt_regs *regs) { int error; char * filename; filename = getname(filenamei); err
[单片机]
arm7 LPC2103 中断的处理方法
向量中断控制器(VIC)具 有 32 个中断请求输入,可将其编程分为3 类:FIQ 、向量IRQ和非向量IRQ 。可编程分配机制意味着不同外设的中断优先级可以动态分配并调整。 快速中断请求(FIQ )要求具有最高优先级。如果分配给 FIQ 的请求多于1 个,VIC 将中断请求“相或”后向ARM处理器产生 FIQ 信号。当只有一个中断被分配为 FIQ 时可实现 最短的FIQ 等待时间,因为FIQ 服务程序只要简单地启动器件的处理就可以了。但如果分配给FIQ 级的中断多于1 个,FIQ 服务程序从 VIC 中读出一个字来识别产生中断请求的 FIQ中断源是哪一个。 向量IRQ 具有中等优先级。该级别可分配32 个请求中的
[单片机]
IAR推出新版IAR Embedded Workbench for Arm功能安全版,该版本配备经过认证的静态代码分析功能
IAR推出新版IAR Embedded Workbench for Arm功能安全版,该版本配备经过认证的静态代码分析功能 瑞典乌普萨拉,2024年2月20日 – 全球领先的嵌入式系统开发软件解决方案供应商IAR宣布 :推出其旗舰产品IAR Embedded Workbench for Arm功能安全版的最新版本9.50.3。此次发布进一步加强了IAR支持开发人员创建安全、可靠和符合标准的嵌入式应用程序的承诺,涵盖了汽车、医疗设备、工业自动化和消费电子等多个行业。该版本中最重要的新功能是经过认证的C-STAT,这是专为安全关键应用程序设计的静态代码分析工具。 IAR Embedded Workbench for Ar
[嵌入式]
IAR推出新版IAR Embedded Workbench for <font color='red'>Arm</font>功能安全版,该版本配备经过认证的静态<font color='red'>代码</font><font color='red'>分析</font>功能
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved