ARM+Linux启动分析----head-armvS内幕.doc
上传人:sy****28 上传时间:2024-09-13 格式:DOC 页数:8 大小:52KB 金币:16 举报 版权申诉
预览加载中,请您耐心等待几秒...

ARM+Linux启动分析----head-armvS内幕.doc

ARM+Linux启动分析----head-armvS内幕.doc

预览

在线预览结束,喜欢就下载吧,查找使用更方便

16 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

ARMLinux启动分析----head-armv.S内幕Linux启动后执行的第一个文件是arch/arm/kernel下的head-($PROCESSOR).S文件,processor代表的是该cpu的类型。ARM6及其以后的处理器核心支持32位地址空间。这些处理器可以在26位和32位PC的模式下操作。在26位PC模式下,R15寄存器的表现如同在以前的处理器上,代码只能运行在地址空间的最低的64M字节空间中。在32位PC模式下,32位的R15寄存器被用做程序计数器。使用独立的状态寄存器来存储处理器模式和状态标志。对于26位的arm处理器类型,linux用armo来表示;对于32位的arm处理器,使用armv表示。在include/linux/autoconf.h文件中通过#defineCONFIG_CPU_321将处理器类型设置为支持32位PC模式。然后在arch/arm/Makefile中通过ifeq($(CONFIG_CPU_32),y)PROCESSOR=armvTEXTADDR=0xC0008000LDSCRIPT=arch/arm/vmlinux-armv.lds.inendif设置处理器类型为armv,这样linux运行所执行的第一个文件就是head-armv.S。接着,Makefile定义了内核中代码和数据所使用的虚拟地址TEXRADDR,最后,定义了链接器所使用的脚本文件,这个文件也是与处理器类型相关的。在执行head-armv.S文件之前,有一点需要注意的是,bootloader已经在处理器的R1寄存器中存放了机器体系结构的类型号。由于在文件的执行过程中将要针对当前的机器体系结构设置相关的参数,如果没有这个步骤,系统将显示“ERROR:a”,同时停止执行。当然,也可以在head-armv.S文件的开头添加代码,手工对R1赋值,具体的机器类型号在arch/arm/tools/mach-types文件中。好了,接下来我们可以开始阅读head-armv.S文件了,看看它到底作了些什么事情。由于篇幅的限制,对一些不是很关键的代码和英文注释予以省略,但是在每段代码后,我会根据自己的理解给出解释。#if(TEXTADDR&0xffff)!=0x8000#errorTEXTADDRmuststartat0xXXXX8000#endif.globlSYMBOL_NAME(swapper_pg_dir).equSYMBOL_NAME(swapper_pg_dir),TEXTADDR-0x4000.macropgtbl,reg,rambaseadr\reg,stextsub\reg,\reg,#0x4000.endm.macrokrnladr,rd,pgtable,rambasebic\rd,\pgtable,#0x000ff000.endm首先,系统确保TEXTADDR的地址是以0x8000结尾的,前面已经提到过,TEXTADDR的地址是0xC0008000,是内核所使用的虚拟地址,而我所使用的PXA255处理器上支持的SDRAM空间是从0xA0000000开始的,这就需要通过MMU进行虚拟地址到实际物理地址的转换,也就是说将0xC0008000映射到0xA0008000。地址转换所使用的页表将存放在从0xA0008000网上的16K空间中,即从0xA0004000到0xA0008000这一段。因此,系统必须空出0xA0000000到0xA0008000这一段,存放页表和其它的一些内核将使用到的数据结构。虽然上面的代码判断的是TEXTADDR的地址是否以0x8000结尾,但从效果上说是一样的。接着,代码定义了全局变量swapper_pg_dir,它是页表目录项的虚拟地址。前面用SYMBOL_NAME()修饰,这是因为在有的系统中,C编绎器对.C文件中的符号名有"_"前缀,SYMBOL_NAME()可以使汇编代码也适应这种变化。但是在当前的Linux中,SYMBOL_NAME实际上不起任何作用。大家可以参考include/linux/linkage.h中对该修饰符的定义。然后,代码定义了pgtbl和krnladr两个宏。Pgtbl宏得到的是与位置无关的页表目录项地址,值为0xA000800往上16k的地址,即0xA0004000。stext所代表的也是内核的起始地址,通过arch/arm/vmlinux-armv.lds.in的链接脚本可以发现它在内核中的链接地址和TEXTADDR一致。那么为什么页表地址不是0xC0004000呢?因为我们在定义/reg寄存器时使用的adr指令,adr指令是在当前的PC值上+/-一个标号的偏移得到的,所以得到的地址只跟PC和标号到PC的偏移相关,跟编译地址无关。在MMU打开前,代码要是地址