程序引导(自启动):
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中就要注意区分开才行。