微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 嵌入式 arm平台kernel启动第二阶段分析

嵌入式 arm平台kernel启动第二阶段分析

时间:11-09 来源:互联网 点击:

ch_info_end

//

__lookup_processor_type函数的具体解析结束(\arch\arm\kernel\head-common.S)

//

movsr10,r5@invalidprocessor(r5=0)?

beq__error_p@yes,errorp

/*机器ID是由u-boot引导内核是通过thekernel第二个参数传递进来的,现在保存在r1中,在__arch_info_begin开始的段中进行查找,如果找到,则返回machine对应相关结构体在物理地址空间的首地址到r5,最后保存在r8中。

bl__lookup_machine_type@r5=machinfo

//

__lookup_machine_type函数的具体解析开始(\arch\arm\kernel\head-common.S)

//

每一个CPU平台都可能有其不一样的结构体,描述这个平台的结构体是machine_desc。

这个结构体在文件arch/arm/include/asm/mach/arch.h中定义:

structmachine_desc{

unsignedintnr;/*architecturenumber*/

unsignedintphys_io;/*startofphysicalio*/

………………………………

};

对于平台smdk2410来说其对应machine_desc结构在文件linux/arch/arm/mach-s3c2410/mach-smdk2410.c中初始化:

MACHINE_START(SMDK2410,"SMDK2410")

.phys_io=S3C2410_PA_UART,

.io_pg_offst=(((u32)S3C24XX_VA_UART)>>18)&0xfffc,

.boot_params=S3C2410_SDRAM_PA+0x100,

.map_io=smdk2410_map_io,

.init_irq=s3c24xx_init_irq,

.init_machine=smdk2410_init,

.timer=&s3c24xx_timer,

MACHINE_END

对于宏MACHINE_START在文件arch/arm/include/asm/mach/arch.h中定义:

#defineMACHINE_START(_type,_name)/

staticconststructmachine_desc__mach_desc_##_type/

__used/

__attribute__((__section__(".arch.info.init")))={/

.nr=MACH_TYPE_##_type,/

.name=_name,

#defineMACHINE_END/

};

__attribute__((__section__(".arch.info.init")))表明该结构体在并以后存放的位置。

在链接文件链接脚本文件arch/arm/kernel/vmlinux.lds中

SECTIONS

{

#ifdefCONFIG_XIP_KERNEL

.=XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);

#else

.=PAGE_OFFSET+TEXT_OFFSET;

#endif

.text.head:{

_stext=.;

_sinittext=.;

*(.text.head)

}

.init:{/*Initcodeanddata*/

INIT_TEXT

_einittext=.;

__proc_info_begin=.;

*(.proc.info.init)

__proc_info_end=.;

__arch_info_begin=.;

*(.arch.info.init)

__arch_info_end=.;

………………………………

在__arch_info_begin和__arch_info_end之间存放了linux内核所支持的所有平台对应的machine_desc结构体。

/*

*r1=machinearchitecturenumber

*Returns:

*r5=mach_infopointerinphysicaladdressspace

*/

__lookup_machine_type:

adrr3,4b@把标号4处的地址放到r3寄存器里面

ldmiar3,{r4,r5,r6}@R4=标号4处的虚拟地址,r5=__arch_info_begin,r6=__arch_info_end

subr3,r3,r4@getoffsetbetweenvirt&phys计算出虚拟地址与物理地址的偏移

/*利用offset,将r5和r6中保存的虚拟地址转变为物理地址*/

addr5,r5,r3@convertvirtaddressesto

addr6,r6,r3@physicaladdressspace

/*读取machine_desc结构的nr参数,对于smdk2410来说该值是MACH_TYPE_SMDK2410,这个值在文件linux/arch/arm/tools/mach-types中:

smdk2410ARCH_SMDK2410SMDK2410193*/

1:ldrr3,[r5,#MACHINFO_TYPE]@getmachinetype

teqr3,r1@matchesloadernumber?把取到的machineid和从uboot中传过来的machineid(存放r1中)相比较

beq2f@found如果相等,则跳到标号2处,返回

addr5,r5,#SIZEOF_MACHINE_DESC@nextmachine_desc没有找到,则继续找下一个,加上该结构体的长度

cmpr5,r6@判断是否已经到该段的末尾

blo1b@如果没有,则跳转到标号1处,继续查找

movr5,#0@unknownmachine如果已经到末尾,并且没找到,则返回值r5寄存器赋值为0

2:movpc,lr@返回原函数,且r5作为返回值

ENDPROC(__lookup_machine_type)

.align2

3:.long__proc_info_begin

.long__proc_info_end

4:.long.@“.”表示当前这行代码编译连接后的虚拟地址

.long__arch_info_begin

.long__arch_info_end

//

__lookup_machine_type函数的具体解析结束(\arch\arm\kernel\head-common.S)

//

movsr8,r5@invalidmachine(r5=0)?

beq__error_a@yes,errora

/*检查bootloader传入的参数列表atags的合法性*/

bl__vet_atags

//

__vet_atags函数的具体解析开始(\arch\arm\kernel\head-common.S)

//

关于参数链表:

内核参数链表的格式和说明可以从内核源代码目录树中的\arch\arm\include\asm\setup.h中找到,参数

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top