Yamon startup分析(未整理四) 作者:makethyme 接上...,继续分析arch/reset/init.S finish_initialisation: DISP_STR(msg_platform) /* perform platform specific initialisaton. this does not include memory test/clear the function returns the following parameters: v0 = error code (0 = no error) 返回值中v0表示error code, v1表示RAM长度 v1 = RAM size in bytes */ jal sys_init_platform 看下面的分析 nop 1: bne v0, zero, error nop move s0, v1 将RAM size放入s0 /* s0 holde RAM size, now perform memory test/clear */ DISP_STR(msq_ram) move a0, s0 jal sys_memory_setup memory setup包括memory test和bss section initialization bne v0, zero, error nop /* COPY code to RAM */ DISP_STR(msg_copy_code) #ifndef _SIMULATE_ la a0, _etext_init /*SRC*/ 其中_etext_init, _ftext_ram, _etext_ram都是定义在link_el.xn中 根据网上文章对linker script的分析,text_init不需要拷贝到RAM中;text_init包含了reset目录下文件的代 码。而其结尾就是_etext_init.接下来定义text_ram,并提到AT(_etext_init)表示设置LMA,这样binary格式 中text_ram段就仅跟着text_init段,但是这个段不能直接运行,要搬到它的VMA(0x80005000)处才能运行, 如果不设置LMA,那默认LMA=VMA,它和上一段就不是紧挨着的,这样最后产生的binary格式文件会很大。 另外,bss段和sbss段在映像文件中不占用空间的,但是并不阻止连接器定位符的移动,_end-_fbss就等于实 际空间大小,要手动在RAM中分配。 la a1, _ftext_ram /* DST*/ la a2, _etext_ram /*STOP*/ bal copy_text nop /* copy the wait code to memory so that it is not running from flash */ la a0, waitcode_start /*SRC*/ 将本来分配在text_init中的代码waitcode_start拷贝到RAM中 li a1, SCRLAUNCH /*DST*/ li a2, SCRLAUNCH + (waitcode_end – waitcode_start) /* stop */ bal copy_text 接上..., 将数据/代码拷贝到RAM中。 copy_data: 将初始化数据拷贝到RAM中 DISP_STR(msg_copy_data) la t0, _etext /*SRC*/ 在linker script中是LMA地址 la t1, _fdata /* DST*/ 在linker script中就是VMA地址 la t2, _fbss /*STOP*/ KSEG0A(t1) KSEG0A(t2) beq t1,t2, setup_sp nop addiu t2, -4 1 : lw t3, 0(t0) add t0, 4 sw t3, 0(t1) bne t1, t2, 1b add t1, 4 #define VERIFY_COPYDATA #ifdef VERIFY_COPYDATA 根据是否定义了VERIFY_COPYDATA,如果定义了,则读出这些数值进行比较,确定是否正确。 #endif 接上面,设置stack setup_sp: /* setup sp (at top of memory) */ DISP_STR(msg_sp) la sp,_ freemen 根据link script,_freemen在bss/sbss段之后了 li t0, SYS_STACK_SIZE 定义为0x5000 addu sp, t0 设定sp li t0, ~0xf and sp, t0 /* align sp to 16 byte boundary */ /* store system info */ DISP_STR(msg_info) la t0, sys_processor sw k1, 0(t0) k1中保存了processor信息 la t0, sys_ramsize sw s0, 0(t0) /* Determine cache info and store it */ 接下来部分,跟cache相关,暂时不讨论 /* calc first free RAM address. We add the dcache line size to avoid cache writeback problem if user executes uncached code */ li t0, SYS_APPL_STACK_SIZE addu t0, sp addu t0, v0 la t1, sys_freemem sw t0, 0(t1) /* C-functions can now be called (memory ready and sp, gp have been set). Interrupts are disabled. we are using the exception handlers of the bootprom */ /* call the first c-function. it should never return. if it does, we consider it an error, and expect vo t0 hold the error code. */ DISP_STR(msg_main) li t0, 4*4 用于参数传递 subu sp, t0 la t0, c_entry jalr t0 nop error : /*Error handling. Display error code(if device for this is available) enter an infinite loop (from init.h) */ ERROR_HANDLING end(_reset_handler) 至此,函数进入到C语言的世界。第一个函数是c_entry.