UBOOT中增加backtrace功能
目前有些bootloader中编译时,没有设置fp寄存器,因此无法打印出backtrace,调试时会较为麻烦,按照如下方法,可以在异常时增加backtrace打印,更加方便debug。
1. arch/arm/cpu/armv7/config.mk中加入编译参数-mapcs-frame
PLATFORM_CPPFLAGS += $(call cc-option, -mapcs-frame,)
2. 异常函数中加入如下内容,主要作用是打印backtrace
struct stackframe { /* FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled and R11 otherwise. */ unsigned long fp; unsigned long sp; unsigned long lr; unsigned long pc; }
#define MAX BACK _TRACE LEVEL 6 /* Unwind a single frame starting with *sp for the symbol at *pc. It updates the *pc and tsp with the new values。 */ int unwind_ frame(struct stackframe *frame) { static int cnt=0; unsigned long fp = frame->fp; if(++cnt = MAX_ BACK_TRACE_LEVEL) return -1: frame->fp = *(unsigned long *)(fp - 12); frame->sp = *(unsigned long *)(fp - 8); frame->lr = *(unsigned long *)(fp - 4); return 0; } void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { printf("Function entered at [<%08lx>] from [<%08lx>]\n",where, from); } void dump stack(struct pt_regs *regs) { struct stackframe frame ; int urc; frame.fp = regs->ARM_fp; frame.sp = regs->ARM_sp; frame.lr= regs->ARM_lr; frame.pc = instruction_pointer (regs): printf("Function entered at [<%08lx>] from [<%88lx>]n", frame.pc, frame .lr); while(1) { unsigned long where = frame.lr : urc = unwind. frame(&frame); if (urc< 0) break; dump_ backtrace entry(where, frame.lr, frame.sp - 4); } }