浅析eCos系统Redboot单元启动流程.docx_第1页
浅析eCos系统Redboot单元启动流程.docx_第2页
浅析eCos系统Redboot单元启动流程.docx_第3页
浅析eCos系统Redboot单元启动流程.docx_第4页
浅析eCos系统Redboot单元启动流程.docx_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

浅析eCos系统Redboot单元启动流程packages/hal/arm/arch/v2_0/src/vectors.Sinstall/lib/target.ld|1|STARTUP(vectors.o)/入口文件install/lib/target.ld|2|ENTRY(reset_vector)/入口段/packages/redboot/v2_0/src/main.c|178| cyg_start(void).code 32.section.vectors,ax#ifdefPLATFORM_PREAMBLEPLATFORM_PREAMBLE/而ep93xx恰好就定义了该宏packages/hal/arm/arm9/ep93xx/v2_0/include/hal_platform_setup.h/*#define PLATFORM_PREAMBLE _platform_preamble#if defined(CYG_HAL_STARTUP_ROM) | defined(CYG_HAL_STARTUP_ROMRAM).macro _platform_preambleb start_here./ Put the current literal pool here.ltorg/ Put a CRUS at offset 0x1000 so that the boot ROM will boot this image./ 在0或0x1000地址写入CRUS4个字符,是ep9312启动所必须 0x1000.long 0x53555243 / Put a CRUS in there so this is bootable.start_here:.endm*/#endif.global _exception_handlers_exception_handlers:ldr pc,.reset_vector/ 0x00ldr pc,.undefined_instruction/ 0x04ldr pc,.software_interrupt/ 0x08 start & software intldr pc,.abort_prefetch/ 0x0Cldr pc,.abort_data/ 0x10.word 0/ unusedldr pc,.IRQ/ 0x18ldr pc,.FIQ/ 0x1C.reset_vector:PLATFORM_SETUP1/对于ep93xx来说对应:packages/hal/arm/arm9/ep93xx/v2_0/include/hal_platform_setup.h/*#define PLATFORM_SETUP1 _platform_setup1.macro _platform_setup1b Setup/and r12, pc, #0xf0000000/获取flash的基地址,因为pc现在运行在flash中,并且flash的基地址含1数一定在最高8bit中/bl BuildPagetable /建立虚拟地址映射表/ Create a read-only mapping of FLASH at virtual address 0x6000_0000./add r1, r0, #0x00001800 /0x60000000 18 这样将作为虚拟地址入口#if defined(HAL_PLATFORM_EP9301) | defined(HAL_PLATFORM_EP9302)mov r2, #0x00000040#elsemov r2, #0x00000080#endiforr r3, r12, #0x0000001e/将r12中flash的物理地址存入PTE虚拟地址入口为0x60000000,这样对0x60000000访问将被线性MMU到物理地址map_flash_6:str r3, r1, #4add r3, r3, #0x00100000subs r2, r2, #4bne map_flash_6. / / Enable the MMU and branch to our equivalent virtual address. / ldr r0, =0xc0000079 ldr r1, =go_virtual ldr r2, =_rom_vectors_vma sub r1, r1, r2 /之所以进行sub操作,我的EP9312使用的是ROMRAM启动方式,/BootROM将直接跳转到flash处执行存储在flash中的代码,flash被映射到虚拟地址0x60000000之后,/为了还能够在0x60000000空间执行flash中的代码,那么就需要首先计算出go_virtual偏移地址,/然后加上flash的虚拟基地址0x60000000,这样代码才会从flash处继续顺利执行 bic r1, r1, #0xf0000000 orr r1, r1, #0x60000000 mcr p15, 0, r0, c1, c0, 0 mov pc, r1go_virtual: nop#ifdef CYG_HAL_STARTUP_ROMRAM/因为现在代码运行在rom中,所以可以安全的对整个SDRAM进行清0操作 / / Copy our image from FLASH to SDRAM. / ldr r0,=_rom_vectors_lma /值为0x60000000,就是flash的虚拟地址 ldr r1,=_rom_vectors_vma /值为0x8000 ldr r2,=_ram_data_endcopy_loop: ldmia r0!, r3-r10 /将flash中的数据取出来 stmia r1!, r3-r10 /转储到0x8000开始处 cmp r1, r2 blt copy_loop / / Zero fill the first portion of SDRAM. / mov r0, #0x00000000 mov r1, #0x00000000 mov r2, #0x00002000zero: str r0, r1, #4 /清零00x4000空间的数据 subs r2, r2, #4 /0x40000x8000空间用来存放MMU的PTE虚拟映射表 bne zero / / Branch to the copy in RAM. / ldr r0, =RamLocation /ok现在取出RamLocation编译地址0x8504 mov pc, r0 /执行完该句之后,程序就到被虚拟映射到0地址的SDRAM中跑了RamLocation:#endif./完成SDRAM初始化,将flash只读地址映射到虚拟地址0x60000000,将flash读写地址映射到虚拟地址0xe0000000,熄灭green led,点亮red led,打开PLL,使能200MHz处理器时钟,使能usb时钟/packages/hal/arm/arch/v2_0/src/arm.ld|105| _rom_vectors_lma = LOADADDR(.rom_vectors);/packages/hal/arm/arm9/ep93xx/v2_0/include/pkgconf/mlt_arm_arm9_edb9312_romram.ldi|15| SECTION_rom_vectors (ram, 0x8000, AT (0x60000000)/所以这样_rom_vectors_lma = 0x60000000; _rom_vectors_vma = 0x8000该地址为ram中地址/于是将根据下面的内容生成install/lib/target.ldMEMORYram : ORIGIN = 0, LENGTH = 0x10000000rom : ORIGIN = 0x60000000, LENGTH = 0x2000000 /这是rom的虚拟地址,flash物理地址将在b Setup中被映射到0x60000000这里SECTIONSSECTIONS_BEGINSECTION_fixed_vectors (ram, 0x20, LMA_EQ_VMA)SECTION_rom_vectors (ram, 0x8000, AT (0x60000000)/SECTION_text (ram, ALIGN (0x4), FOLLOWING (.rom_vectors)SECTION_fini (ram, ALIGN (0x4), FOLLOWING (.text)SECTION_rodata (ram, ALIGN (0x4), FOLLOWING (.fini)SECTION_rodata1 (ram, ALIGN (0x4), FOLLOWING (.rodata)SECTION_fixup (ram, ALIGN (0x4), FOLLOWING (.rodata1)SECTION_gcc_except_table (ram, ALIGN (0x4), FOLLOWING (.fixup)SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table)SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)_heap1 = ALIGN (0x8); /堆栈开始SECTIONS_ENDSetupReturn:.endm*/warm_reset:通过反汇编luthergliethttp:/vobs/tmp/luther$ arm-elf-objdump-DS-b binary-m arm install/bin/redboot.bin|more1000:53555243 cmpplr5,#805306372;0x300000041004:ea00000e b0x10441008:e59ff018 ldrpc,pc,#24;0x1028100c:e59ff018 ldrpc,pc,#24;0x102c/读取pc+24处的handler1010:e59ff018 ldrpc,pc,#24;0x10301014:e59ff018 ldrpc,pc,#24;0x10341018:00000000 andeqr0,r0,r0101c:e59ff018 ldrpc,pc,#24;0x103c1020:e59ff018 ldrpc,pc,#24;0x10401024:00000040 andeqr0,r0,r0,asr#321028:00009178 andeqr9,r0,r8,ror r1102c:0000919c muleqr0,ip,r11030:000091c8 andeqr9,r0,r8,asr#31034:000091e4 andeqr9,r0,r4,ror#31038:00000000 andeqr0,r0,r0103c:000092fc streqdr9,r0,-ip1040:000092c4 andeqr9,r0,r4,asr#51044:eafffc9f b0x2c8/对应PLATFORM_SETUP1宏展开,执行Setup操作1048:e3a00000 movr0,#0;0x0104c:e59f13d0 ldrr1,pc,#976;0x14241050:e5912008 ldrr2,r1,#8/软中断software interrupt1054:e5802008 strr2,r0,#8/将verctor存储到0地址处,因为其使用ldr pc绝对跳转,所以都能实现跳转1058:e3a00000 movr0,#0;0x0105c:e59f13a4 ldrr1,pc,#932;0x14081060:e5912028 ldrr2,r1,#40/将处理handler地址存储到0x28地址处,将由ldrpc, pc, #24读取1064:e5802028 strr2,r0,#401068:e5912018 ldrr2,r1,#24106c:e5802018 strr2,r0,#241070:e5912038 ldrr2,r1,#561074:e5802038 strr2,r0,#561078:e591201c ldrr2,r1,#28107c:e580201c strr2,r0,#281080:e591203c ldrr2,r1,#601084:e580203c strr2,r0,#601088:e591200c ldrr2,r1,#12108c:e580200c strr2,r0,#121090:e591202c ldrr2,r1,#441094:e580202c strr2,r0,#441098:e5912010 ldrr2,r1,#16109c:e5802010 strr2,r0,#1610a0:e5912030 ldrr2,r1,#4810a4:e5802030 strr2,r0,#4810a8:e3a00000 movr0,#0;0x010ac:e59f1354 ldrr1,pc,#852;0x140810b0:e5912000 ldrr2,r110b4:e5802000 strr2,r0/将reset追加到0地址处10b8:e59f2368 ldrr2,pc,#872;0x142810bc:e5802020 strr2,r0,#32/将reset的handler改变为warm_reset存储到0x20处,以等待直接跳转方式的reset来调用10c0:e59f3328 ldrr3,pc,#808;0x13f0/packages/hal/arm/arch/v2_0/src/arm.ld|238| _rom_data_start = LOADADDR (.data);10c4:e59f4328 ldrr4,pc,#808;0x13f410c8:e59f5328 ldrr5,pc,#808;0x13f810cc:e1540005 cmpr4,r510d0:0a000005 beq0x10ec10d4:e2433004 subr3,r3,#4;0x410d8:e2444004 subr4,r4,#4;0x410dc:e5b30004 ldrr0,r3,#4!/将_rom_data_start中的data数据段加载到_ram_data_start10e0:e5a40004 strr0,r4,#4!10e4:e1540005 cmpr4,r510e8:1afffffb bne0x10dc10ec:e59fd2e4 ldrsp,pc,#740;0x13d810f0:e3a000d2 movr0,#210;0xd210f4:e129f000 msrCPSR_fc,r010f8:e59fd2dc ldrsp,pc,#732;0x13dc10fc:e3a000db movr0,#219;0xdb1100:e129f000 msrCPSR_fc,r01104:e59fd2d0 ldrsp,pc,#720;0x13dc1108:e3a000d3 movr0,#211;0xd3110c:e129f000 msrCPSR_fc,r01110:e169f000 msrSPSR_fc,r01114:e59fd2bc ldrsp,pc,#700;0x13d81118:e59f12c4 ldrr1,pc,#708;0x13e4111c:e59f22c4 ldrr2,pc,#708;0x13e81120:e3a00000 movr0,#0;0x01124:e1510002 cmpr1,r21128:0a000002 beq0x1138112c:e4810004 strr0,r1,#4/对bbs段进行清0操作1130:e1510002 cmpr1,r21134:9afffffc bls0x112c1138:eb001eb6 bl0x8c18/bl hal_hardware_init 包含打开串口输出功能/*hal_virtual_vector_table这个表就像是linux下的syscall系统调用,直接调用hal_virtual_vector_table中的项就可以执行所要的功能函数比如:CYGACC_CALL_IF_DELAY_US_SET(delay_us);static voiddelay_us(cyg_int32 usecs)CYGARC_HAL_SAVE_GP();#ifdef CYGPKG_KERNEL.#else / CYGPKG_KERNEL#ifdef HAL_DELAY_USHAL_DELAY_US(usecs);/packages/hal/arm/arm9/ep93xx/v2_0/include/hal_diag.h = #define HAL_DELAY_US(n) hal_delay_us(n);/packages/hal/arm/arm9/ep93xx/v2_0/src/ep93xx_misc.c = void hal_delay_us(cyg_int32 usecs)#elsewhile (usecs- 0) int i;for (i = 0; i = _CTOR_LIST_; p-)(*p) ();/我打印p为000363a8,*p内容为000158e8,也就是他的跳转地址为000158e8经过反汇编luthergliethttp:/vobs/tmp/ep9312$ arm-elf-objdump -DS ./infra/v2_0/src/infra_diag.o |more.00000000 :0:e52de004 strlr, sp, -#4!4:e3a01d9d movr1, #10048; 0x27408:e2811034 addr1, r1, #52; 0x34c:e3a00001 movr0, #1; 0x110:e49de004 ldrlr, sp, #414:eafffffe b0 Disassembly of section .ctors.55435: /上面就是.ctors*段,所以将被添加到_CTOR_LIST_代表的KEEP (*(SORT (.ctors*)段空间.00000000 :0:00000000 andeqr0, r0, r0.luthergliethttp:/vobs/tmp/ep9312$ arm-elf-objdump -DS install/bin/redboot.elf |more发现158e8地址处的类构造函数地址:class Cyg_dummy_diag_init_class public:Cyg_dummy_diag_init_class() HAL_DIAG_INIT();static Cyg_dummy_diag_init_class cyg_dummy_diag_init_objCYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_HAL);/产生静态对象,将自己添加到_CTOR_LIST_构造函数空间区.000363a8 :363a8:000158e8 andeqr5, r1, r8, ror #17000158c8 :158c8:e3a03d9d movr3, #10048; 0x2740158cc:e2833034 addr3, r3, #52; 0x34158d0:e1510003 cmpr1, r3158d4:03500001 cmpeqr0, #1; 0x1158d8:e52de004 strlr, sp, -#4!158dc:149df004 ldrnepc, sp, #4158e0:e49de004 ldrlr, sp, #4158e4:eafffb17 b14548 /跳转到hal_if_diag_init()函数初始化diag,主要是完成gdb的控制函数/填充,CYGNUM_CALL_IF_SET_COMM_ID_MANGLER对应comm_channels0,也就是gdb使用的空间/cyg_hal_diag_mangler_gdb_init()就是完成comm_channels0控制函数填充的函数./如果想在这里开始就调用diag_printf(hellon);来打印数据,那还不行,必须调用diag_init_putc(_mon_write_char);设置/diag_printf的串口数据输出回调函数才行,如果想更早打印数据,那么可以这样修改:/static void _mon_write_char(char c, void *param)去掉static,然后/externC void _mon_write_char(char c, void *param);/void hal_hardware_init(void)/ diag_init_putc(_mon_write_char); 在该函数中追加此行/ plf_hardware_init();/ hal_if_init();/在执行完该句之后就可以安全使用diag_printf打印数据了.*/1160:eb003266 bl0xdb00/bl cyg_start /进入redboot的c主函数hal_if_init=CYGACC_CALL_IF_DELAY_US_SET(delay_us);/设置时间调用函数体CYGACC_CALL_IF_FLASH_CFG_OP_SET(flash_config_op);/设置flash配置调用函数体set_debug_comm(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm);CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(set_console_comm);CYGACC_CALL_IF_VERSION_SET(CYGNUM_CALL_IF_TABLE_VERSION_CALL|(CYG_ADDRWORD)CYGNUM_CALL_IF_TABLE_VERSION_COMMfun)();/do_flash_init/load_flash_config/net_initpackages/redboot/v2_0/src/flash.c|1235| RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST);/所以这些都是将会被自动执行的functionpackages/redboot/v2_0/src/flash.c|2118| RedBoot_init(load_flash_config, RedBoot_INIT_FIRST);packages/redboot/v2_0/src/fs/ide.c|489| RedBoot_init(ide_init, RedBoot_INIT_FIRST);packages/redboot/v2_0/src/decompress.c|104| RedBoot_init(_zlib_init, RedBoot_INIT_FIRST);packages/redboot/v2_0/src/net/net_io.c|575| RedBoot_init(net_init, RedBoot_INIT_LAST);packages/redboot/v2_0/include/redboot.h|251| #define RedBoot_init(_f_,_p_) _RedBoot_init(_f_,_p_)luthergliethttp:/vobs/tmp/ep9312$ arm-elf-objdump -DS ./redboot/v2_0/src/redboot_flash.o |more.Disassembly of section .ecos.table.FIS_cmds.data.fis_init:00000000 :0:00000004 andeqr0, r0, r44:0000000c andeqr0, r0, ip8:00000030 andeqr0, r0, r0, lsr r0.cyg_start= if (cmd = parse(&command, &argc, &argv0) != (struct cmd *)0)=return cmd_search(_RedBoot_CMD_TAB_, &_RedBoot_CMD_TAB_END_, argv0);/遍历_RedBoot_CMD_TAB_指向section为.ecos.table的存储节中的所有handler处理函数packages/redboot/v2_0/src/flash.c|173| RedBoot_nested_cmd(fis, /string名为fis/fis命令,其自身添加到命令为RedBoot_commands的_RedBoot_CMD_TAB_所在节Manage FLASH images,cmds,do_fis,_FIS_cmds_TAB_, &_FIS_cmds_TAB_END_);CYG_HAL_TABLE_BEGIN(_FIS_cmds_TAB_, FIS_cmds);/在.ecos.table.节中定义名为FIS_cmds的管理区,即.ecos.table.FIS_cmds节所有需要被do_fis函数使用的local_cmd_entry命令功能函数都需要将自己添加到名为FIS_cmds管理区,所以这样看起来就像是一个二维数组或者多维数组RedBoot fis load ramdisk对应的存储结构二维表为:_RedBoot_CMD_TAB_fis = do_fis= cmd_search(_FIS_cmds_TAB_)_FIS_cmds_TAB_load = fis_load_RedBoot_CMD_TAB_fisload_RedBoot_CMD_TAB_fiscreate#define CYGARC_P2ALIGNMENT 2#ifndef CYG_HAL_TABLE_BEGIN#define CYG_HAL_TABLE_BEGIN(_label, _name) _asm_(.section .ecos.table. _xstring(_name) .begin,awn .globl _xstring(CYG_LABEL_DEFN(_label) n .type _xstring(CYG_LABEL_DEFN(_label) ,objectn .p2align _xstring(CYGARC_P2ALIGNMENT) n _xstring(CYG_LABEL_DEFN(_label) :n .previousn )#endif展开就是:.section .ecos.table.FIS_cmds.begin,aw.globl _FIS_cmds_TAB_.type _FIS_cmds_TAB_,object /表示_FIS_cmds_TAB_这个标量表示的是一个对象,用来索引数据,而不是函数.p2align 2_FIS_cmds_TAB_:.previous下面是.previous的一行英文解释:The .PREVIOUS directive instructs the assembler to set the current section in memory to the section described immediately before the current one. The .PREVIOUS directive operates on a stack.就像ENTRY(begin)SECTION.=0x10000000;.text:*(.text).data:*(.data).bss:*(.bss).section .ecos.table.FIS_cmds.begin,aw用来说明这里是.ecos.tab

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论