stm32uclinuxstartkernel之前的汇编代码分析.docx

上传人:b****0 文档编号:12811639 上传时间:2023-04-22 格式:DOCX 页数:15 大小:23.80KB
下载 相关 举报
stm32uclinuxstartkernel之前的汇编代码分析.docx_第1页
第1页 / 共15页
stm32uclinuxstartkernel之前的汇编代码分析.docx_第2页
第2页 / 共15页
stm32uclinuxstartkernel之前的汇编代码分析.docx_第3页
第3页 / 共15页
stm32uclinuxstartkernel之前的汇编代码分析.docx_第4页
第4页 / 共15页
stm32uclinuxstartkernel之前的汇编代码分析.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

stm32uclinuxstartkernel之前的汇编代码分析.docx

《stm32uclinuxstartkernel之前的汇编代码分析.docx》由会员分享,可在线阅读,更多相关《stm32uclinuxstartkernel之前的汇编代码分析.docx(15页珍藏版)》请在冰豆网上搜索。

stm32uclinuxstartkernel之前的汇编代码分析.docx

stm32uclinuxstartkernel之前的汇编代码分析

Boot中执行下面两句话之后,进入uclinux内核。

theKernel=(void(*)(int,int,unsignedint))((uint32_t)0x08003001);

theKernel(0,2189,((uint32_t)0x20000100));

1start_kernel之前的汇编代码分析

首先来到0x08003000处,此时携带有三个参数,R0、R1、R2,分别是0,2189,0x20000100.

0x08003000对应着下面stext的汇编代码。

代码阅读说明:

@后面的内容标示是注释语句

ARM或者THUMB指令的选取,在\include\asm-arm\unified.h中,定义了使用ARM,THUMB为空

偏移量#PROC_INFO_SZ等,在\include\asm\asm-offset.h中宏定义

1.1head-mommu.S

文件在arch\arm\kernel\head-nommu.S,text.head段,有stext、__after_proc_init两段组成,内核从这里开始启动,然后通过各种调用,最终进入C语言的start_kernel函数,这段代码执行流程如下:

(1)调用__lookup_processor_type,传入R9(CPU基址寄存器的值),成功后获得当前的proc_info结构体信息,地址放入R10;

(2)调用__lookup_machine_type,BootLoader传给内核的R1值,成功后获得当前的machine_desc结构体信息,地址放入R8;

(3)执行__v7m_setup,进行必要的初始化;

(4)执行__switch_data,并最终跳转到C语言的start_kernel函数。

.section".text.head","ax"

ENTRY(stext)

cpsidi@disableinterrupts//cortex-M3特殊指令,关闭所有中断

ldrr9,=0xe000ed00@CPUIDregisteraddress

ldrr9,[r9]//CPUID基址寄存器,参考手册(周立功)-P80

bl__lookup_processor_type@r5=procinfor9=cupid//head-common.S

movsr10,r5@invalidprocessor(r5=0)?

beq__error_p@yes,error'p'

bl__lookup_machine_type@r5=machinfo

movsr8,r5@invalidmachine(r5=0)?

beq__error_a@yes,error'a'

badrlr,__after_proc_init@return(PIC)address//提前暂存lr的值

ARM(addpc,r10,#PROCINFO_INITFUNC)//R10处偏移16个字节,然后赋给PC

//相当于跳转到下面的__v7m_setup

ENDPROC(stext)

__after_proc_init:

ldrpc,__switch_data//将PC指针赋值到__switch_data标号地址处,实际执行的

ENDPROC(__after_proc_init)//是在__mmap_switched这个标号处

.ltorg

#include"head-common.S"//末尾包含下面的文件

1.2head-common.S

文件在arch\arm\kernel\head-common.S,有__switch_data、__mmap_switched、__error_p、__error_a、__error、__lookup_processor_type、C语言的lookup_processor_type、__lookup_machine_type、C语言的lookup_machine_type、__vet_atags等组成,这里只列出上面调用要使用的查找处理器类型和查找机器类型。

_lookup_processor_type:

//r9是刚从CPU基址寄存器中取出的值

ARM(adrr3,3f)//执行此句后,r3的地址是后面标号3处的地址

ARM(ldmdar3,{r5-r7})//r5,r6,r7依次变为,__proc_info_begin,end,以及

//标号3处的末尾链接地址

subr3,r3,r7@getoffsetbetweenvirt&phys//这三行执行虚实地址转换

addr5,r5,r3@convertvirtaddressesto//r5是proc_info_list结构体地址

addr6,r6,r3@physicaladdressspace//__proc_info_end的自己

1:

ldmiar5,{r3,r4}@value,mask//r3是结构体的val变量

andr4,r4,r9@maskwantedbits//r4是结构体的mask变量

teqr3,r4

beq2f//相等转到后面的2标号处

addr5,r5,#PROC_INFO_SZ@sizeof(proc_info_list)//宏定义在asm-offset.h

cmpr5,r6//结构体可能是个数组,需要全部查找,若r5的地址没有超出end

blo1b//的地址,则继续转到1处理,若最后没找到,r5变为空

movr5,#0@unknownprocessor

2:

movpc,lr

ENDPROC(__lookup_processor_type)

ENTRY(lookup_processor_type)

stmfdsp!

{r4-r7,r9,lr}

movr9,r0//提供C语言的API结构,r0是传入的参数

bl__lookup_processor_type

movr0,r5//此处的R0是函数的返回值,即传出的参数

ldmfdsp!

{r4-r7,r9,pc}

ENDPROC(lookup_processor_type)

.long__proc_info_begin//arch/arm/kernel/vmlinux.lds.s中定义

.long__proc_info_end

3:

.long.

.long__arch_info_begin

.long__arch_info_end

/*

*Lookupmachinearchitectureinthelinker-buildlistofarchitectures.

*Notethatwecan'tusetheabsoluteaddressesforthe__arch_info

*listssincewearen'trunningwiththeMMUon(andtherefore,weare

*notinthecorrectaddressspace).Wehavetocalculatetheoffset.

*

*r1=machinearchitecturenumber

*Returns:

*r3,r4,r6corrupted

*r5=mach_infopointerinphysicaladdressspace

*/

__lookup_machine_type:

adrr3,3b

ldmiar3,{r4,r5,r6}//r5是__arch_info_begin,r6是end

subr3,r3,r4@getoffsetbetweenvirt&phys//虚实地址转换

addr5,r5,r3@convertvirtaddressesto

addr6,r6,r3@physicaladdressspace

1:

ldrr3,[r5,#MACHINFO_TYPE]@getmachinetype//结构体偏移字节数,见上面的注释

teqr3,r1@matchesloadernumber?

//与传递给内核的r1相同

beq2f@found//r3就是结构体中第一个变量nr

addr5,r5,#SIZEOF_MACHINE_DESC@nextmachine_desc

cmpr5,r6

blo1b

movr5,#0@unknownmachine

2:

movpc,lr

ENDPROC(__lookup_machine_type)

/*

*ThisprovidesaC-APIversionoftheabovefunction.

*/

ENTRY(lookup_machine_type)

stmfdsp!

{r4-r6,lr}

movr1,r0//提供C语言的API结构,r0是传入的参数

bl__lookup_machine_type

movr0,r5//此处的R0是函数的返回值,即传出的参数

ldmfdsp!

{r4-r6,pc}

ENDPROC(lookup_machine_type)

1.2.1lookup_processor_type

(1)vmlinux.lds.s

文件在arch\arm\kernel\vmlinux.lds.s

__proc_info_begin=.;//include/asm-arm/procinfo.h中定义

*(.proc.info.init)

__proc_info_end=.;

__arch_info_begin=.;//include/asm-arm/mach/arch.h 中定义

*(.arch.info.init)

__arch_info_end=.;

(2)procinfo.h

文件在include/asm-arm/procinfo.h

structproc_info_list{//pro-v7m.S对其实例化

unsignedintcpu_val;

unsignedintcpu_mask;

unsignedlong__cpu_mm_mmu_flags;/*usedbyhead.S*/

unsignedlong__cpu_io_mmu_flags;/*usedbyhead.S*/

unsignedlong__cpu_flush;/*usedbyhead.S*/

constchar*arch_name;

constchar*elf_name;

unsignedintelf_hwcap;

constchar*cpu_name;

structprocessor*proc;

structcpu_tlb_fns*tlb;

structcpu_user_fns*user;

structcpu_cache_fns*cache;

};

(3)pro-v7m.S

文件在arch\arm\mm\pro-v7m.S,内容很多,核心就是.section".proc.info.init",其它的都是它这个结构体中得成员,如__v7m_setup、cpu_arch_name、cpu_elf_name、cpu_v7m_name、v7m_processor_functions等。

cpu_v7m_name:

.ascii"ARMv7-MProcessor"

.align

.section".text.init",#alloc,#execinstr

.typev7m_processor_functions,#object

ENTRY(v7m_processor_functions)

.wordv7m_early_abort

.wordcpu_v7m_proc_init

.wordcpu_v7m_proc_fin

.wordcpu_v7m_reset

.wordcpu_v7m_do_idle

.wordcpu_v7m_dcache_clean_area

.wordcpu_v7m_switch_mm

.wordcpu_v7m_set_pte_ext

.wordpabort_noifar

.sizev7m_processor_functions,.-v7m_processor_functions

.typecpu_arch_name,#object

cpu_arch_name:

.asciz"armv7m"

.sizecpu_arch_name,.-cpu_arch_name

.typecpu_elf_name,#object

cpu_elf_name:

.asciz"v7m"

.sizecpu_elf_name,.-cpu_elf_name

.align

.section".proc.info.init",#alloc,#execinstr

/*

*MatchanyARMv7-Mprocessorcore.

*/

.type__v7m_proc_info,#object

__v7m_proc_info:

//E000ED00是CPUID基址寄存器,其中[19:

16]读作常量F

.long0x000f0000@RequiredIDvalue

.long0x000f0000@MaskforID

.long0@proc_info_list.__cpu_mm_mmu_flags

.long0@proc_info_list.__cpu_io_mmu_flags

b__v7m_setup@proc_info_list.__cpu_flush

.longcpu_arch_name

.longcpu_elf_name

.longHWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP

.longcpu_v7m_name

.longv7m_processor_functions@proc_info_list.proc

.long0@proc_info_list.tlb

.long0@proc_info_list.user

.long0@proc_info_list.cache

.size__v7m_proc_info,.-__v7m_proc_info

1.2.2lookup_machine_type

(1)arch.h

文件在include/asm-arm/mach/arch.h 

structmachine_desc{//在stm3210e_eval.c中实例化

/*

*Note!

Thefirstfourelementsareused

*byassemblercodeinhead.S,head-common.S

*/

unsignedintnr;/*architecturenumber*/

unsignedintphys_io;/*startofphysicalio*/

unsignedintio_pg_offst;/*byteoffsetforio

*pagetabeentry*/

constchar*name;/*architecturename*/

unsignedlongboot_params;/*taggedlist*/

unsignedintvideo_start;/*startofvideoRAM*/

unsignedintvideo_end;/*endofvideoRAM*/

unsignedintreserve_lp0:

1;/*neverhaslp0*/

unsignedintreserve_lp1:

1;/*neverhaslp1*/

unsignedintreserve_lp2:

1;/*neverhaslp2*/

unsignedintsoft_reboot:

1;/*softreboot*/

void(*fixup)(structmachine_desc*,

structtag*,char**,

structmeminfo*);

void(*map_io)(void);/*IOmappingfunction*/

void(*init_irq)(void);

structsys_timer*timer;/*systemticktimer*/

void(*init_machine)(void);

};

/*

*Setofmacrostodefinearchitecturefeatures.Thisisbuiltinto

*atablebythelinker.

*/

#defineMACHINE_START(_type,_name)\

staticconststructmachine_desc__mach_desc_##_type\

__used\

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

.nr=MACH_TYPE_##_type,\

.name=_name,

#defineMACHINE_END\

};

(2)stm3210e_eval.c

文件在arch\arm\mach-stm3210e_eval\stm3210e_eval.c

MACHINE_START(STM3210E_EVAL,"STM3210E-EVAL")

/*Maintainer:

MCDApplicationTEAM*//*Status*/

.fixup=stm3210e_eval_fixup,//OK

.boot_params=CONFIG_EXTERNAL_RAM_BASE+0x100,//OK

.init_irq=nvic_init_irq,//OK

.timer=&stm3210e_eval_timer,//OK

.init_machine=stm3210e_eval_init,//OK

MACHINE_END

(3)match-type.h

文件在include/asm-arm/mach-type.h

#defineMACH_TYPE_STM3210E_EVAL2189

1.3__v7m_setup

文件在arch\arm\mm\pro-v7m.S

/*

*__v7m_setup

*

*InitialiseTLB,Caches,andMMUstatereadytoswitchtheMMU

*on.Returninr0thenewCP15C1controlregistersetting.

*

*WeautomaticallydetectifwehaveaHarvardcache,andusethe

*Harvardcachecontrolinstructionsinseadoftheunifiedcache

*controlinstructions.

*

*ThisshouldbeabletocoverallARMv7-Mcores.

*

*Itisassumedthat:

*-cachetyperegisterisimplemented

*/

__v7m_setup:

@Configurethevectortablebaseaddress//配置中断向量偏移

ldrr0,=0xe000ed08@vectortablebaseaddress

ldrr12,=vector_table

strr12,[r0]

@LowerthepriorityoftheSVCandPendSVexceptions

ldrr0,=0xe000ed1c//设置SVC、PendSV的中断优先级都为128

movr5,#0x80000000

strr5,[r0]@setSVCpriority

ldrr0,=0xe000ed20

movr5,#0x00800000

strr5,[r0]@setPendSVpriority

@SVCtorunthekernelinthismode

badrr0,1f

ldrr5,[r12,#11*4]@readtheSVCvectorentry

strr0,[r12,#11*4]@writethetemporarySVCvectorentry

movr6,lr@saveLR

movr7,sp@saveSP

#if!

defined(CONFIG_XIP_KERNEL)

ldrsp,=__v7m_setup_stack_top

#endif

cpsiei

svc#0//呼叫系统服务,权威指南-P182,暂时没找到?

1:

cpsidi

strr5,[r12,#11*4]@restoretheoriginalSVCvectorentry

movlr,r6@restoreLR

m

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1