arm linux 启动过程
时间:11-09
来源:互联网
点击:
- ype__arm920_proc_info,#object
- __arm920_proc_info:
- .long0x41009200
- .long0xff00fff0
- .longPMD_TYPE_SECT|\
- PMD_SECT_BUFFERABLE|\
- PMD_SECT_CACHEABLE|\
- PMD_BIT4|\
- PMD_SECT_AP_WRITE|\
- PMD_SECT_AP_READ
- .longPMD_TYPE_SECT|\
- PMD_BIT4|\
- PMD_SECT_AP_WRITE|\
- PMD_SECT_AP_READ
- /*__arm920_setup函数在stext的未尾被调用,请往回看。*/
- b__arm920_setup
- .longcpu_arch_name
- .longcpu_elf_name
- .longHWCAP_SWP|HWCAP_HALF|HWCAP_THUMB
- .longcpu_arm920_name
- .longarm920_processor_functions
- .longv4wbi_tlb_fns
- .longv4wb_user_fns
- #ifndefCONFIG_CPU_DCACHE_WRITETHROUGH
- .longarm920_cache_fns
- #else
- .longv4wt_cache_fns
- #endif
- .size__arm920_proc_info,.-__arm920_proc_info
[cpp]view plaincopyprint?
- /*
- *ReadprocessorIDregister(CP#15,CR0),andlookupinthelinker-built
- *supportedprocessorlist.Notethatwecantusetheabsoluteaddresses
- *forthe__proc_infolistssincewearentrunningwiththeMMUon
- *(andtherefore,wearenotinthecorrectaddressspace).Wehaveto
- *calculatetheoffset.
- *
- *r9=cpuid
- *Returns:
- *r3,r4,r6corrupted
- *r5=proc_infopointerinphysicaladdressspace
- *r9=cpuid(preserved)
- */
- __lookup_processor_type:
- /*adr是相对寻址,它的寻计算结果是将当前PC值加上3f符号与PC的偏移量,
- *而PC是物理地址,因此r3的结果也是3f符号的物理地址*/
- adrr3,3f
- /*r5值为__proc_info_bein,r6值为__proc_ino_end,而r7值为.,
- *也即3f符号的链接地址。请注意,在链接期间,__proc_info_begin和
- *__proc_info_end以及.均是链接地址,也即虚执地址。
- */
- ldmdar3,{r5-r7}
- /*r3为3f的物理地址,而r7为3f的虚拟地址。结果是r3为虚拟地址与物理地址的差值,即PHYS_OFFSET-PAGE_OFFSET。*/
- subr3,r3,r7@getoffsetbetweenvirt&phys
- /*r5为__proc_info_begin的物理地址,即r5指针__proc_info数组的首地址*/
- addr5,r5,r3@convertvirtaddressesto
- /*r6为__proc_info_end的物理地址*/
- addr6,r6,r3@physicaladdressspace
- /*读取r5指向的__proc_info数组元素的CPUID和mask值*/
- 1:ldmiar5,{r3,r4}@value,mask
- /*将当前CPUID和mask相与,并与数组元素中的CPUID比较是否相同
- *若相同,则找到当前CPU的__proc_info定义,r5指向访元素并返回。
- */
- andr4,r4,r9@maskwantedbits
- teqr3,r4
- beq2f
- /*r5指向下一个__proc_info元素*/
- addr5,r5,#PROC_INFO_SZ@sizeof(proc_info_list)
- /*是否遍历完所有__proc_info元素*/
- cmpr5,r6
- blo1b
- /*找不到则返回NULL*/
- movr5,#0@unknownprocessor
- 2:movpc,lr
- ENDPROC(__lookup_processor_type)
- .long__proc_info_begin
- .long__proc_info_end
- 3:.long.
- .long__arch_info_begin
- .long__arch_info_end
4 __lookup_machine_type 函数
__lookup_machine_type 和__lookup_processor_type像对孪生兄弟,它们的行为都是很类似的:__lookup_machine_type根据r1寄存器的机器编号到.arch.info.init段的数组中依次查找机器编号与r1相同的记录。它使了与它孪生兄弟同样的手法进行虚拟地址到物理地址的转换计算。
在介绍函数,我们先分析tqs3c2440开发板的机器信息的定义:
[cpp]view plaincopyprint?
- 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\
- };
MACHINE_START宏用于定义一个.arch.info.init段的数组元素。.nr元素就是函数要比较的变量。Tqs3c2440开发板相应的定义如下:
[cpp]view plaincopyprint?
- MACHINE_START(S3C2440,"TQ2440")
- .phys_io=S3C2410_PA_UART,
- .io_pg_offst=(((u32)S3C24XX_VA_UART)>>18)&0xfffc,
- .boot_params=S3C2410_SDRAM_PA+0x100,
- .init_irq=s3c24xx_init_irq,
- .map_io=tq2440_map_io,
- .init_machine=tq2440_machine_init,
- .timer=&s3c24xx_timer,
- MACHINE_END
这是一个struct machine_desc结构,在后面的C代码(start_kernel开始执行的代码)会使用该变量对象。在tqs3c2440开发中的__lookup_machine_type函数就是返回该对象指针。
这里涉及很多函数指针,它们都是在start_kernel函数里在各种阶段进行初始化的回函数。如map_io指向的tq2440_map_io就是在建立好内核页表后,再调用它来针对开发板的各种IO端口来建立相关的映射和页表。
至于__loopup_machine_type的代码就不作详细分析,请对比__lookup_processor_type来自行分析。代码如下:
armlinux启动过 相关文章:
- ARM Linux 的启动过程(11-09)
- ARM Linux启动过程学习(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)