嵌入式 arm平台kernel启动第二阶段分析
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中找到,参数
嵌入式arm平台kernel启 相关文章:
- 嵌入式 arm平台kernel启动第一阶段汇编head.s分析(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)