嵌入式 arm平台kernel启动第二阶段分析
LB,指令TLB无效。
#endif
adrr5,arm920_crval//获取arm920_crval的地址,并存入r5。
ldmiar5,{r5,r6}//获取arm920_crval地址处的连续8字节分别存入r5,r6。
mrcp15,0,r0,c1,c0//获取CP15下控制寄存器的值,并存入r0。
bicr0,r0,r5//通过查看arm920_crval的值可知该行是清除r0中相关位,为以后对这些位的赋值做准备
orrr0,r0,r6//设置r0中的相关位,即为mmu做相应设置。
movpc,lr//上面有操作adrlr,__enable_mmu,此处将跳到程序段__enable_mmu处。
.size__arm920_setup,.-__arm920_setup
.typearm920_crval,#object
arm920_crval:
crvalclear=0x00003f3f,mmuset=0x00003135,ucset=0x00001130
//
__arm920_setup函数的具体解析结束(\arch\arm\mm\proc-arm920.S)
//
ENDPROC(stext)
接着往下分析linux/arch/arm/kernel/head-common.S中:
.type__switch_data,%object@定义__switch_data为一个对象
__switch_data:
.long__mmap_switched
.long__data_loc@r4
.long_data@r5
.long__bss_start@r6
.long_end@r7
.longprocessor_id@r4
.long__machine_arch_type@r5
.long__atags_pointer@r6
.longcr_alignment@r7
.longinit_thread_union+THREAD_START_SP@sp
/*
*ThefollowingfragmentofcodeisexecutedwiththeMMUoninMMUmode,
*andusesabsoluteaddresses;thisisnotpositionindependent.
*r0=cp#15controlregister
*r1=machineID
*r2=atagspointer
*r9=processorID
*/
/*其中上面的几个段的定义是在文件arch/arm/kernel/vmlinux.lds中指定*/
vmlinux.lds开始*
SECTIONS
{
……………………
#ifdefCONFIG_XIP_KERNEL
__data_loc=ALIGN(4);/*locationinbinary*/
.=PAGE_OFFSET+TEXT_OFFSET;
#else
.=ALIGN(THREAD_SIZE);
__data_loc=.;
#endif
.data:AT(__data_loc){//此处数据存储在上面__data_loc处。
_data=.;/*addressinmemory*/
*(.data.init_task)
…………………………
.bss:{
__bss_start=.;/*BSS*/
*(.bss)
*(COMMON)
_end=.;
}
………………………………
}
init_thread_union是init进程的基地址.在arch/arm/kernel/init_task.c中:
unionthread_unioninit_thread_union__attribute__((__section__(".init.task")))={INIT_THREAD_INFO(init_task)};
对照vmlnux.lds.S中,我们可以知道inittask是存放在.data段的开始8k,并且是THREAD_SIZE(8k)对齐的*/
vmlinux.lds结束*
__mmap_switched:
adrr3,__switch_data+4
ldmiar3!,{r4,r5,r6,r7}
……………………
………………………………
movfp,#0@清除bss段
1:cmpr6,r7
strccfp,[r6],#4
bcc1b
ARM(ldmiar3,{r4,r5,r6,r7,sp})/*把__machine_arch_type变量值放入r5中,把__atags_pointer变量的值放入r6中*/
strr9,[r4]@SaveprocessorID保存处理器id到processor_id所在的地址中
strr1,[r5]@Savemachinetype保存machineid到__machine_arch_type中
strr2,[r6]@Saveatagspointer保存参数列表首地址到__atags_pointer中
bicr4,r0,#CR_A@ClearAbit
stmiar7,{r0,r4}@Savecontrolregistervalues
bstart_kernel@程序跳转到函数start_kernel进入C语言部分。
ENDPROC(__mmap_switched)
到处我们的启动的第二阶段分析完毕。
后面会接着分析第三阶段。第三阶段完全是C语言代码,从start_kernel函数开始。
嵌入式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)