C6678 EMIF NOR FLASH自启动方法

本文详细描述了Core0的引导过程,包括一级引导的内存位置和通过BOOT域实现的二级bootloader。还介绍了多核引导的两种方式,其中一种是Core0负责程序迁移,另一种是各核自身完成,作者选择后者并强调了CMD和boot.asm文件的修改需求。
摘要由CSDN通过智能技术生成

程序引导(自启动):

        core0的引导:

        C6678的启动方式是,Core0先从0x70000000开始引导启动,此为第一级引导。

在创建core0工程时,修改cmd文件,增加BOOT域:

MEMORY
{
    ......    
    
    BOOT            : org   = 0x70000000,  len   = 0x00000200
    FLASH           : org   = 0x70000200, len   = 0x3FFE00
    ......
}

        该区域用于存放第二级bootloader,该bootloader通过boot.asm实现,主要完成core0各个段的数据从NOR FLASH到L2SRAM的搬移:

.title  "Flash bootup utility"

 .ref    _c_int00

 .ref    FLASH_TEXT_START

 .ref    RAM_TEXT_START

 .ref    TEXT_SIZE

 .ref    FLASH_CINIT_START

 .ref    RAM_CINIT_START

 .ref    CINIT_SIZE

 .ref    FLASH_CONST_START

 .ref    RAM_CONST_START

 .ref    CONST_SIZE

 .ref    FLASH_SWITCH_START

 .ref    RAM_SWITCH_START

 .ref    SWITCH_SIZE

 .ref    FLASH_VECT_START

 .ref    RAM_VECT_START

 .ref    VECT_SIZE

 .ref    FLASH_VECS_START

 .ref    RAM_VECS_START

 .ref    VECS_SIZE

 .ref    FLASH_META_START

 .ref    RAM_META_START

 .ref    META_SIZE

 .ref    FLASH_FARDATA_START

 .ref    RAM_FARDATA_START

 .ref    FARDATA_SIZE

 .ref    FLASH_NEARDATA_START

 .ref    RAM_NEARDATA_START

 .ref    NEARDATA_SIZE

 .sect "bootload"
 .global _boot
_boot:

 nop  5

 mvkl  copyTable, a3 ; load table pointer

 mvkh  copyTable, a3

copy_section_top:

 ldw   *a3++, b0 ; byte count

 ldw   *a3++, b4 ; load flash start (load) address

 ldw   *a3++, a4 ; ram start address

 nop   2

 [!b0]  b copy_done

 nop   5

copy_loop:

 ldb   *b4++,b5

 sub   b0,1,b0     ; decrement counter

 [b0]  b    copy_loop     ; setup branch if not done

 [!b0]  b    copy_section_top

 zero  a1

 [!b0]  and   3,a3,a1

 stb   b5,*a4++

 [!b0]  and   -4,a3,a5       ; round address up to next multiple of 4

 [ a1]  add   4,a5,a3      ; round address up to next multiple of 4

copy_done:

 mvkl .S2 _c_int00, B0

 mvkh .S2 _c_int00, B0

 b   .S2 B0

 nop   5

copyTable:

; count

; flash start (load) address

; ram start (run) address

;; .text

 .word TEXT_SIZE

 .word FLASH_TEXT_START

 .word RAM_TEXT_START

;; .cinit

 .word CINIT_SIZE

 .word FLASH_CINIT_START

 .word RAM_CINIT_START

;; .const

 .word CONST_SIZE

 .word FLASH_CONST_START

 .word RAM_CONST_START

;; .switch

 .word SWITCH_SIZE

 .word FLASH_SWITCH_START

 .word RAM_SWITCH_START

;; .vect

 ;.word VECT_SIZE

 ;.word FLASH_VECT_START

 ;.word RAM_VECT_START

 ;; .VECS

 .word VECS_SIZE

 .word FLASH_VECS_START

 .word RAM_VECS_START


;; .BIOS_META

 .word META_SIZE

 .word FLASH_META_START

 .word RAM_META_START

;; .BIOS_FARDATA

 .word FARDATA_SIZE

 .word FLASH_FARDATA_START

 .word RAM_FARDATA_START

 ;; .BIOS_NEARDATA

 .word NEARDATA_SIZE

 .word FLASH_NEARDATA_START

 .word RAM_NEARDATA_START

;; end of table

 .word 0

 .word 0

 .word 0

        而在cmd中也会体现:

        这样Core0的启动就完成了。

      其他核的引导:

        1. 其他核的引导,是Core0启动后在依次引导其他Core,而引导方法为将其他核的代码启动地址写入各自的Magic Address里面,然后再发送IPC中断来实现其他核的引导。

这就涉及到两种方式:

  •         分为两个步骤:

        1) Core0将其他核的程序按照各个段的地址和大小拷贝到各自的L2SRAM或者DDR3中;

        2)将_c_int00的地址复制给magicAddr;

core1_magic_addr  = (unsigned int )_c_int00; 
ipc_1_reg  = 0x01;

        2. 其他核自身带有自引导程序(boot.asm),参照核0类似的操作方式实现程序引导,自己把自己的各个代码段加载到缓存或内存中。此时Core0仅需要将每个核的BOOT段基地址写给各个核的Magic Address里面,然后再发送IPC中断来实现其他核的引导。

core1_magic_addr  = (unsigned int )0x7020000; 
ipc_1_reg  = 0x01;

        该方法用于EMIF接口的NOR FLASH,此类NOR FLASH可以不需要指令操作,直接读数据。可以看出这两种方法主要区别是谁来将其他核的程序从FLASH搬移到缓存中。

我采用的是b种方式,即每个核自己搬移自己的程序,每个核的工程都需要添加boot.asm,同时每个核的cmd都需要添加BOOT段。

        需要注意,每个核程序加载的地址在编译时已经固定,如果共用DDR等资源时需要各自分开,在CMD中就要注意区分开才行。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值