linux内核启动解析(二)_第1页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、linux内核启动解析(二)话说内核映像解压后,又跳到c0008000这个地址。这个地址指向内核代码的什么地方,我们绝对很想知道。在arch/arm/kernel/vmlinux.lds.s中,可以发觉这样的代码:sectionsifdef config_xip_kernel. = xip_virt_addr(config_xip_phys_addr);else. = page_offset + text_offset;endif.text.head : _stext = .;_sinittext = .;*(.text.head)普通内核都不配置成xip方式的,所以这段脚本等同于:secti

2、ons. = page_offset + text_offset;.text.head : _stext = .;_sinittext = .;*(.text.head)这段脚本告知我们sections的起始地址是 .text.head的起始地址_stext,且_stext= page_offset + text_offset;page_ofset在.config文件中设置:page_offset=0xc0000000;text_offset在主名目下的makefile文件中设置:textofs-y := 0x00008000text_offset := $(textofs-y)结合arch/

3、arm/kernel/head.s,会发觉如下代码:.section ".text.head", "ax"entry(stext)msr cpsr_c, psr_f_bit | psr_i_bit | svc_mode ensure svc mode and irqs disabledmrc p15, 0, r9, c0, c0 get processor idbl _lookup_processor_type r5=procinfo r9=cupidendproc(stext)第一句代码的意思是表示下面的内容都属于.text.head 段的,”ax”表

4、示这段内容是可分配且可执行的(allocable and executable) 。所以c0008000处放的代码就是stext的入口地址。接下来的msr cpsr_c, psr_f_bit | psr_i_bit | svc_mode就是把fiq_mask(迅速中断屏蔽位)和irq_mask(迅速中断屏蔽位)都置位,同时把处理器模式设置为svc模式。这就是要告知闲杂人等不要来打搅,这里要办重要的事。cpsr_c 代表当前状态寄存器;鉴于当前状态寄存器的重要性,arm特意开发了msr命令,特地用来设置当前状态寄存器。mrc p15, 0, r9, c0, c0是将协处理器cp15 c0的值赋值

5、到r9中。接下来的bl _lookup_processor_type是长跳转到_lookup_processor_type,查看processor id是否被内核支持。_lookup_processor_type:adr r3, 3fldmda r3, r5 - r7sub r3, r3, r7 get offset between virt&physadd r5, r5, r3 convert virt addresses toadd r6, r6, r3 physical address space1: ldmia r5, r3, r4 value, maskand r4, r4,

6、 r9 mask wanted bitsteq r3, r4beq 2fadd r5, r5, proc_info_sz sizeof(proc_info_list)cmp r5, r6blo 1bmov r5, 0 unknown processor2: mov pc, lrendproc(_lookup_processor_type)adr是条伪命令,作用就是把标号为3位置的地址赋值给r3寄存器。3后面加f是表示这是个长距离(far)的标号。有学生可能就要问了,ldr也能起到这个作用,为什么不用ldr?首先 ldr r3, 3f取的是标号3这个地址的内容,而不是地址本身;第二,可以用ldr

7、 r3,=3f来取地址本身,但这是一个肯定地址;而adr取得的是相对地址。假如要保证程序在任何内存都能运行,就必需保证代码是地址无关的,也就是(position independent code)。明显adr伪命令很对pic的胃口,它的取相对地址方式符合pic的设定。.long _proc_info_begin.long _proc_info_end3: .long .long _arch_info_begin.long _arch_info_end我们接着往下看。ldmda r3, r5 - r7sub r3, r3, r7 get offset between virt&physa

8、dd r5, r5, r3 convert virt addresses toadd r6, r6, r3 physical address space1: ldmia r5, r3, r4 value, maskand r4, r4, r9 mask wanted bitsteq r3, r4beq 2fadd r5, r5, proc_info_sz sizeof(proc_info_list)cmp r5, r6blo 1bmov r5, 0 unknown processor2: mov pc, lrldmada r3,(r5-r7) 是把标签3所指的地址的内容(也就是标签3的虚拟地址

9、)赋值给r7,把比标签3所指的地址小4的地址的内容(也就是_proc_info_end)赋值给r6,把比标签3所指的地址小8的地址的内容(_proc_info_begin)赋值给r5。这里的虚拟地址是线性规律地址,它和物理地址之间有着一一映射关系。由于_proc_info_begin 和_proc_info_end都是虚拟地址,此时我们mmu还没有打开,就必需要用法物理地址。这就需要我们先把它们转换为物理地址。接下来的三句代码就是完成这样的工作。_proc_info_begin和_proc_info_end是在vlinux.lds.s中定义的。_proc_info_begin = .;*(.p

10、.init)_proc_info_end = .;这解释在_proc_info_begin和_proc_info_end之间的是全部的..init段。我们可以在arch/arm/mm/proc_*.s中找到相应的..init段。smdk6410属于armv6,我们可以在proc_v6.s找到armv6处理器的id和id掩码。之后的代码就是把处理器的id和id掩码赋值到r3,r4中;把r9与处理器掩码做与操作,然后与处理器id(r3)比较,看是否相等;如不相等,就取下一个处理器id举行比较;假如到最后都没有处理器id相符,就将r5赋值为0:1: ldmia r5, r3, r4 value, maskand r4, r4, r9 mask wanted bitsteq r3, r4beq 2fadd r5, r5, proc_info_sz sizeof(proc_info_list)cmp r5, r6blo 1bmov r5, 0 unknown processor2: mov pc, lr最后一句是跳出_lookup_processor_type函数。跳出之后会对处理器id是否

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论