Android培训班(91)内核解压过程4

在嵌入式系统里,主要存在三种调试手段,一是使用硬件的LED显示灯,这种方式最原始,也最简单,只需要一个高低电平,就可以表示什么状态了,比如电源状态灯,网络连接灯等。二是使用串口通讯调试输出,由于串口通讯设置的参数最简单,连接线也最简单,编码也最简单,更何况在目前计算机环境里,没有串口基本不可能。三是使用调试器,比如JTAG等,一般比较复杂一些,需要硬件也多一些。在内核开发,或者嵌入式系统,最好使用串口调试输出,因为这些对多个CPU运行时,可以准确地输出,使用JTAG就不一定了。

#ifdefined(CONFIG_ARCH_SA1100)


.macro loadsp,rb

mov \rb,#0x80000000 @ physical base address

#ifdefCONFIG_DEBUG_LL_SER3

add \rb,\rb, #0x00050000 @ Ser3

#else

add \rb,\rb, #0x00010000 @ Ser1

#endif

.endm

这段代码主要用来计算串口的物理地址,以便可以选择不同的串口进行调试的操作。loadsp是宏的名称,rb是输入的参数,然后计算好的参数同样放在rb寄存器里返回。



#elifdefined(CONFIG_ARCH_S3C2410)


.macroloadsp, rb

mov \rb,#0x50000000

add \rb,\rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT

.endm

这段代码也是同上面的一样,计算选择不同的串口输入输出调试。



#else

.macro loadsp, rb

addruart\rb

.endm

这段代码里调用了一个宏addruart,使用这个宏来计算串口的地址,这个宏是来自下面的文件:

arch/arm/mach-s3c6400/include/mach/debug-macro.S

addruart是通过协处理器p15来判断选择不同的调试串口输出输入的。



#endif


#endif

#endif

到这里就完成了选择专用的调试输出,还是使用串口输出的工作。编写这段代码的意义就是可以根据不同的架构,不同的CPU类型,统计输出调试信息的地址。




.macro kputc,val

mov r0,\val

bl putc

.endm

这个宏kputc是调用putc来输出字符。



.macro kphex,val,len

mov r0,\val

mov r1,#\len

bl phex

.endm

这个宏kphex输出16进制格式内容。



.macro debug_reloc_start

#ifdefDEBUG

kputc #'\n'

kphex r6,8 /* processor id */

kputc #':'

kphex r7,8 /* architecture id */

#ifdefCONFIG_CPU_CP15

kputc #':'

mrc p15,0, r0, c1, c0

kphex r0,8 /* control reg */

#endif

kputc #'\n'

kphex r5,8 /* decompressed kernel start */

kputc #'-'

kphex r9,8 /* decompressed kernel end */

kputc #'>'

kphex r4,8 /* kernel execution address */

kputc #'\n'

#endif

.endm

这个宏debug_reloc_start是用来输出CPUIDCPU架构,以及解压重定位的信息。




.macro debug_reloc_end

#ifdefDEBUG

kphex r5,8 /* end of kernel */

kputc #'\n'

mov r0,r4

bl memdump /*dump 256 bytes at start of kernel */

#endif

.endm

这个宏debug_reloc_end是与上面的宏debug_reloc_start构成完成输出内核重定位的信息。有了这些调试的函数,就可以提供一个向外输出信息的通道,就可以把黑盒里的信息显示出来大家查看了,跟踪到整个内核到底在做什么事情,解决不正常运行的问题。

你可能感兴趣的:(android)