http://www.eefocus.com/yq000cn/blog/11-10/233600_ab9bd.html
Author:KiKi
Date: 2011.10.28
近日在Digilent Nexys3板卡做一些入门级的嵌入式Linux开发,第一个吃螃蟹的人,那少不了碰壁,有效的debug工具确实是一把利器。
忙忙碌碌,没有太多时间和心思去写一篇完整的Blog,于是将开发中写的一份Howto文档直接拿来。
希望对于那些望 “嵌入式Linux,FPGA,SOPC等概念”而却步的人有所帮助。一定要Hold得住!
时间:2011.10.07
版本:v0.0
说明:该文档是关于如何使用mb-gdb命令进行内核调试的入门介绍
-------------------------------------------------------------------------------
--常用命令描述
-------------------------------------------------------------------------------
load [program] Load the program into the target.
b main Set a breakpoint in function main.
c Continue after a breakpoint.
l View a listing of the program.
n Step one line (stepping over function calls).
s Step one line (stepping into function calls).
stepi Step one assembly line.
info reg View register values.
p xyz Print the value of xyz data.
hbreak main Set Hardware breakpoint in function main.
watch gvar1 Set Watchpoint on Global Variable gvar1.
rwatch gvar1 Set Read Watchpoint on Global Variable gvar1.
-------------------------------------------------------------------------------
--如何使用mb-gdb调试内核
-------------------------------------------------------------------------------
1. 通过XMD命令下载内核镜像
打开EDK Shell终端
$xmd #打开xmd调试终端
XMD% connect mb mdm #初始化JTAG链
XMD% dow simpleImage.xilinx #下载内核
2. 内核下载完成后打开gdb终端
打开另一个EDK Shell终端
$cd #进入内核源代码该目录
V:\kernel_source\linux-2.6.37-xlnx>mb-gdb vmlinux
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i386-mingw32 --target=microblaze-xilinx-elf"...
(gdb) target remote localhost:1234 #进入内核调试
Remote debugging using localhost:1234
_text () at arch/microblaze/kernel/head.S:61
61 mfs r1, rmsr
Current language: auto; currently asm
(gdb) b mm_init #设置mm_init()函数断点
Breakpoint 1 at 0x8500fa48: file kernel/fork.c, line 481.
(gdb) b shced_init #设置sched_init()函数断点
Function "shced_init" not defined.
(gdb) b sched_init
Breakpoint 2 at 0x851ab9a8: file kernel/sched.c, line 833.
(gdb) b time_init #设置time_init()函数断点
Breakpoint 4 at 0x851aa304: file arch/microblaze/kernel/timer.c, line 270.
(gdb) b 10 #设置当前文件第10行为断点
Breakpoint 5 at 0x85000000: file arch/microblaze/kernel/head.S, line 10.
(gdb) c #继续运行
Continuing.
Breakpoint 2, sched_init () at kernel/sched.c:833
833 return (u64)sysctl_sched_rt_period * NSEC_PER_USEC;
Current language: auto; currently c
(gdb) p (char*) &__log_buf
$1 = 0x85283c50 "<5>Linux version 2.6.37 (YaoQ@TechServer) (gcc version 4.1.2 20070214
(Xilinx 13.1 Build EDK_O.40 7 Jan 2011)) #3 Sat Oct 8 16:31:09 CST 2011\n<6>setup_cpuinfo:
initialising\n<4>setup_cpuinfo: No PVR su"...
(gdb) l #打印源代码
828 */
829 int sysctl_sched_rt_runtime = 950000;
830
831 static inline u64 global_rt_period(void)
832 {
833 return (u64)sysctl_sched_rt_period * NSEC_PER_USEC;
834 }
835
836 static inline u64 global_rt_runtime(void)
837 {
(gdb) c #继续运行
Continuing.
Breakpoint 4, time_init () at arch/microblaze/kernel/timer.c:270
270 for (i = 0; timer_list[i] != NULL; i++) {
(gdb) n #单步调试
249 {
(gdb) n 10
278 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
(gdb) l
273 break;
274 }
275 BUG_ON(!timer);
276
277 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
278 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
279 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
280 timer_num = be32_to_cpup(of_get_property(timer,
281 "xlnx,one-timer-only", NULL));
282 if (timer_num) {
(gdb) p timer #打印timer变量值
$5 = (struct device_node *) 0x85ffbe80
(gdb) x timer #打印timer变量值为地址的值
0x85ffbe80: 0x85ffbff4
(gdb) x 0x85ffbe80 #打印0x85ffbe80为地址的值
0x85ffbe80: 0x85ffbff4
(gdb) info reg #打印寄存器信息
r0 0x0 0
r1 0x85199f8c 0x85199f8c
r2 0x85196d40 -2061931200
r3 0x87004000 -2030026752
r4 0x0 0
r5 0x87004000 -2030026752
r6 0x8513b6a0 -2062305632
r7 0x0 0
r8 0x85805000 -2055188480
r9 0x635688c0 1666615488
r10 0xd0 208
r11 0x98000000 -1744830464
r12 0x8000003e -2147483586
r13 0x851a53c0 -2061872192
r14 0x0 0
r15 0x851aa38c -2061851764
. . .
r31 0x8519d308 -2061905144
rpc 0x851aa3a0 0x851aa3a0
rmsr 0x61a0 24992
rear 0x84fffffc -2063597572
resr 0x812 2066
rfsr 0x0 0
rbtr 0x851aa394 -2061851756
rpvr0 0x0 0
. . .
rpid 0x0 0
rzpr 0x10000000 268435456
rtlbx 0x8000003e -2147483586
rtlbsx 0x0 0
rslr 0x0 0
rshr 0x0 0
(gdb) help #帮助命令
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
(gdb) help status #相关命令的帮助文档
Status inquiries.
List of commands:
info -- Generic command for showing things about the program being debugged
macro -- Prefix for commands dealing with C preprocessor macros
show -- Generic command for showing things about the debugger
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
以上记录了在用gdb对内核调试过程中,一些基本命令的使用,更多详细的命令可参考gdb help.
-------------------------------------------------------------------------------
--参考资料
-------------------------------------------------------------------------------
1.http://elinux.org/DebuggingTheLinuxKernelUsingGdb
2.http://www.xilinx.com/support/documentation/sw_manuals/xilinx11/platform_studio/ps_r_dbg_gdb_command_reference.htm
3.http://www.xilinx.com/itp/xilinx10/help/platform_studio/ps_p_dbg_debugging_programs_gdb.htm