作者

彭东林
pengdonglin137@163.com
 

平台

TQ2440 + Linux-4.10.17
Qemu(vexpress-ca9) + Linux-4.10.17
 

概述

下面简单介绍一下用TQ2440和Qemu来搭建KGDB调试环境,对于TQ2440采用KGDB+串口的调试,对于Qemu来说,它已经提供了调试接口,只需在启动qemu时添加相关参数即可。
 

正文

一、GDB基础知识

1、控制命令
 
n: 单步运行
c: 继续运行
q: 退出gdb
 
2、设置、查看和删除断点

(gdb) br start_kernel
Breakpoint at 0x809009b0: file ../init/main.c, line . (gdb) br __irq_svc
Breakpoint at 0x806e8e60: file ../arch/arm/kernel/entry-armv.S, line . (gdb) br gic_handle_irq
Breakpoint at 0x801014f4: file ../drivers/irqchip/irq-gic.c, line . (gdb) info br
Num Type Disp Enb Address What
breakpoint keep y 0x809009b0 in start_kernel at ../init/main.c:
breakpoint keep y 0x806e8e60 ../arch/arm/kernel/entry-armv.S:
breakpoint keep y 0x801014f4 in gic_handle_irq at ../drivers/irqchip/irq-gic.c: (gdb) delete br
(gdb) info br
Num Type Disp Enb Address What
breakpoint keep y 0x809009b0 in start_kernel at ../init/main.c:
breakpoint keep y 0x806e8e60 ../arch/arm/kernel/entry-armv.S: (gdb) delete br // 删除所有断点
Delete all breakpoints? (y or n) y
(gdb) info br
No breakpoints or watchpoints.
(gdb)
 
3、查看调用栈

(gdb) bt
# ftrace_traceoff (ip=, parent_ip=, data=0x80a01f48 <init_thread_union+>) at ../kernel/trace/trace_functions.c:
# 0x80109a18 in arch_cpu_idle () at ../arch/arm/kernel/process.c:
# 0x806dbd54 in p9_write_work (work=0x80a043b0 <tracer_enabled>) at ../net/9p/trans_fd.c:
# 0x8016575c in __list_del (next=<optimized out>, prev=<optimized out>) at ../include/linux/list.h:
# __list_del_entry (entry=<optimized out>) at ../include/linux/list.h:
# list_del_init (entry=<optimized out>) at ../include/linux/list.h:
# __finish_swait (q=<optimized out>, wait=0x0) at ../kernel/sched/swait.c:
# 0x80165abc in current_thread_info () at ../arch/arm/include/asm/thread_info.h:
# need_resched () at ../include/linux/sched.h:
# do_idle () at ../kernel/sched/idle.c:
# 0x806d56f8 in svc_seq_show (seq=0x80a01f94 <init_thread_union+>, statp=<optimized out>) at ../net/sunrpc/stats.c:
# 0x80900d64 in start_kernel () at ../init/main.c:
# 0x6000807c in ?? ()
Backtrace stopped: frame did not save the PC
 
4、查看寄存器的值
  • info registers (除了浮点寄存器)

(gdb) info registers
r0 0x80a043b0 -
r1 0x0
r2 0x80a01f48 -
r3 0x8011b8c0 -
r4 0x0
r5 0x80a03cd0 -
r6 0x80a03c6c -
r7 0x8097f5d8 -
r8 0x80a03cd8 -
r9 0x80a1cace -
r10 0x0
r11 0x80a01f44 -
r12 0x80a01f38 -
sp 0x80a01f38 0x80a01f38 <init_thread_union+>
lr 0x80109a18 -
pc 0x801d0ae4 0x801d0ae4 <ftrace_traceoff>
cpsr 0x60000093
  • info registers 寄存器名称   (查看指定的寄存器的值)

(gdb) info registers cpsr
cpsr 0x60000093
(gdb) info registers pc
pc 0x801d0ae4 0x801d0ae4 <ftrace_traceoff>
(gdb) info registers r0
r0 0x80a043b0 -
(gdb) info registers r0 r1
r0 0x80a043b0 -
r1 0x0
  • print/x $寄存器名   (查看指定的寄存器)
(gdb) print/x $r0
$ = 0x80a043b0
(gdb) print/x $pc
$ = 0x801d0ae4
(gdb) print/x $cpsr
$ = 0x60000093
下面的字符用于设置数据显示的格式:
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量
 
5、查看内存的值
x/<n/f/u> <addr>
n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容
f 表示显示的格式:
            x 按十六进制格式显示变量
            d 按十进制格式显示变量
            u 按十六进制格式显示无符号整型
            o 按八进制格式显示变量
            t 按二进制格式显示变量
            a 按十六进制格式显示变量
            c 按字符格式显示变量
            f 按浮点数格式显示变量
u 表示将多少个字节作为一个值取出来,如果不指定的话,GDB默认是4个bytes,如果不指定的话,默认是4个bytes。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来,可以设置如下几种:

b 表示单字节

h 表示双字节

w 表示四字 节

g 表示八字节


(gdb) info registers
r0 0x80a043b0 -
r1 0x0
r2 0x80a01f48 -
r3 0x8011b8c0 -
r4 0x0
r5 0x80a03cd0 -
r6 0x80a03c6c -
r7 0x8097f5d8 -
r8 0x80a03cd8 -
r9 0x80a1cace -
r10 0x0
r11 0x80a01f44 -
r12 0x80a01f38 -
sp 0x80a01f38 0x80a01f38 <init_thread_union+>
lr 0x80109a18 -
pc 0x801d0ae4 0x801d0ae4 <ftrace_traceoff>
cpsr 0x60000093
(gdb) x/16xw 0x801d0ae4
0x801d0ae4 <ftrace_traceoff>: 0xe92dd8f0 0xe24cb004 0xe24dd008 0xe30403b0
0x801d0af4 <ftrace_traceoff+>: 0xe34800a0 0xe1a0400e 0xe590305c 0xe3130002
0x801d0b04 <update_traceon_count>: 0x0a000011 0xe10f3000 0xe3130080 0x0a00000e
0x801d0b14 <update_traceon_count+>: 0xe1a0200d 0xe3c23d7f 0xe3c3303f 0xe304572c
(gdb) x/16xw 0x80a01f38
0x80a01f38 <init_thread_union+>: 0x80a01f54 0x80a01f48 0x806dbd54 0x801099f4
0x80a01f48 <init_thread_union+>: 0x80a01f84 0x80a01f58 0x8016575c 0x806dbd2c
0x80a01f58 <init_thread_union+>: 0x80702db8 0x000000bb 0x80a74000 0xffffffff
0x80a01f68 <init_thread_union+>: 0x80a03c40 0x80952a28 0x00000001 0x80a74000

上面查看了pc和sp指向的内存地址的内容。

二、TQ2440 + KGDB + 串口

  • 配置内核
Kernel hacking
----> Compile-time checks and compiler options
----> [*] Compile the kernel with debug info
----> [*] Kernel debugging
----> [*] KGDB: kernel debugger
----> <*> KGDB: use kgdb over the serial console

然后编译内核,然后我们就可以在uboot中配置bootargs,用新的kernel启动, 由于目前板子上只有一个调试串口,所以在使用gdb打开串口时,需要把其他

使用该串口的应用关闭,如ckermit以及minicom。
  • 具体调试有两种方式
方式一:开机启动阶段kernel自动等待连接
 
设置uboot的bootargs如下:

setenv bootargs 'noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2  console=ttySAC0,115200n8 kgdboc=ttySAC0,115200 kgdbwait'

设置完bootargs后,可以保存。上面新加的工kgdb调试的参数是'kgdboc=ttySAC0,115200 kgdbwait',表示将来kernel会在ttySAC0这个串口等待连接,并且波特率设置的是115200,kgdbwait表示开机时kernel会自动等待连接。

然后执行boot命令,这样uboot会自动去解析并执行设置在bootcmd环境变量中的命令, log如下:

U-Boot 2015.04-g5095150-dirty (May   - ::)

CPUID:
FCLK: MHz
HCLK: MHz
PCLK: MHz
I2C: ready
DRAM: MiB
WARNING: Caches not enabled
Flash: Bytes
NAND: MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot:
TQ2440 #
TQ2440 # setenv bootargs 'noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2 console=ttySAC0,115200n8 kgdboc=ttySAC0,115200 kgdbwait'
TQ2440 # boot
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in bit mode
MAC: :0c::2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.8
Filename 'uImage'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
#################################################################
#######################################
434.6 KiB/s
done
Bytes transferred = ( hex)
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in bit mode
MAC: :0c::2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.8
Filename 'dtb'.
Load address: 0x32000000
Loading: T #
Bytes/s
done
Bytes transferred = (20f5 hex)
## Booting kernel from Legacy Image at ...
Image Name: Linux-4.10.+
Created: -- :: UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: Bytes = 3.3 MiB
Load Address:
Entry Point:
Verifying Checksum ... OK
## Flattened Device Tree blob at
Booting using the fdt blob at 0x32000000
Loading Kernel Image ... OK
Loading Device Tree to 33aa7000, end 33aac0f4 ... OK Starting kernel ... Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.10.+ (pengdonglin@pengdonglin-dell) (gcc version 4.8. (prerelease) (Sourcery CodeBench Lite 2014.05-) ) # Sun Aug :: CST
[ 0.000000] CPU: ARM920T [] revision (ARMv4T), cr=c000717f
[ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[ 0.000000] OF: fdt:Machine model: TQ2440
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] DT missing boot CPU MPIDR[:], fall back to default cpu_logical_map
[ 0.000000] Built zonelists in Zone order, mobility grouping on. Total pages:
[ 0.000000] Kernel command line: noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2 console=ttySAC0,115200n8 kgdboc=ttySAC0, kgdbwait
[ 0.000000] PID hash table entries: (order: -, bytes)
[ 0.000000] Dentry cache hash table entries: (order: , bytes)
[ 0.000000] Inode-cache hash table entries: (order: , bytes)
[ 0.000000] Memory: 57572K/65536K available (4923K kernel code, 245K rwdata, 1412K rodata, 208K init, 278K bss, 7964K reserved, 0K cma-reserved)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 ( kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff800000 ( MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( MB)
[ 0.000000] .text : 0xc0008000 - 0xc04d7138 ( kB)
[ 0.000000] .init : 0xc066e000 - 0xc06a2000 ( kB)
[ 0.000000] .data : 0xc06a2000 - 0xc06df520 ( kB)
[ 0.000000] .bss : 0xc06df520 - 0xc0725060 ( kB)
[ 0.000000] SLUB: HWalign=, Order=-, MinObjects=, CPUs=, Nodes=
[ 0.000000] NR_IRQS:
[ 0.000000] irq: clearing pending status
[ 0.000000] irq: clearing pending status
... ...
[ 1.306659] .serial: ttySAC0 at MMIO 0x50000000 (irq = , base_baud = ) is a S3C2440
[ 2.156124] console [ttySAC0] enabled
[ 2.162327] KGDB: Registered I/O driver kgdboc
[ 2.163879] KGDB: Waiting for connection from remote gdb...

可以看到此时kernel已经进入等待gdb连接模式, 由于我是用的是ckermit,所以此时需要先退出ckermit,否则下面的gdb将无法打开串口。

在PC上执行如下的命令:

$arm-linux-gdb vmlinux
GNU gdb (Sourcery CodeBench Lite 2014.05-) 7.7.50.20140217-cvs
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://sourcery.mentor.com/GNUToolchain/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vmlinux...done.
(gdb) set serial baud // 设置串口的波特率
(gdb) target remote /dev/ttyUSB0 // 连接板子
Remote debugging using /dev/ttyUSB0
arch_kgdb_breakpoint () at kernel/debug/debug_core.c:
wmb(); /* Sync point before breakpoint */
(gdb) l
* the debugger.
*/
noinline void kgdb_breakpoint(void)
{
atomic_inc(&kgdb_setting_breakpoint);
wmb(); /* Sync point before breakpoint */
arch_kgdb_breakpoint();
wmb(); /* Sync point after breakpoint */
atomic_dec(&kgdb_setting_breakpoint);
}
(gdb) b __irq_svc // 在__irq_svc处设置断点
Breakpoint at 0xc000e8ac: file arch/arm/kernel/entry-armv.S, line .
(gdb) c //继续运行, 此时系统会在__irq_svc断点处停止
Continuing. Breakpoint , __irq_svc () at arch/arm/kernel/entry-armv.S:
irq_handler
(gdb) l //列出代码上下文 .align
__irq_svc:
svc_entry
bt_demo:
irq_handler #ifdef CONFIG_PREEMPT
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
ldr r0, [tsk, #TI_FLAGS] @ get flags
(gdb) info all-registers //打印当前的寄存器信息
r0 0x51
r1 0xbf000000
r2 0xc3433ee8
r3 0xc006967c
r4 0xc00687f8
r5 0x60000013
r6 0xffffffff
r7 0xc3433ecc
r8 0xc06df520
r9 0xc3432000
r10 0xc0695830
r11 0xb0
r12 0x60000013
sp 0xc3433e98 0xc3433e98
lr 0xc006967c
pc 0xc000e8ac 0xc000e8ac <__irq_svc+>
f0 (raw 0x000000000000000000000000)
f1 (raw 0x000000000000000000000000)
f2 (raw 0x000000000000000000000000)
f3 (raw 0x0807463a08f2689800000000)
f4 (raw 0x000000000000000000000000)
f5 (raw 0x000000000000000000000000)
f6 (raw 0x000000000000000000000000)
f7 (raw 0x000000000000000000000000)
fps 0x0
cpsr 0x60000093
(gdb) x/16xw 0xc3433e98 /*将sp栈中的内容打印出来*/
0xc3433e98: 0x0000002f 0x00000001 0x60000013 0xc0707338
0xc3433ea8: 0x00000000 0xc3679900 0xc0687e40 0x00000000
0xc3433eb8: 0xc06df520 0xc0637d40 0xc0695830 0x000000b0
0xc3433ec8: 0x60000013 0xc3433ee8 0xc006967c 0xc00687f8
(gdb)
0xc3433ed8: 0x60000013 0xffffffff 0x00000053 0x00000000
0xc3433ee8: 0xc06c24c0 0xc02aa38c 0x00000000 0x00000000
0xc3433ef8: 0x00000006 0xc06a1428 0x00000006 0xc0687e58
0xc3433f08: 0x00000000 0xc00098ac 0xc0638b00 0x000000b0
(gdb)

退出的话,执行quit。

 
方式二:启动起来后,手动触发,使系统进入等待kgdb连接模式
设置uboot的bootargs如下:

setenv bootargs 'noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2  console=ttySAC0,115200n8 kgdboc=ttySAC0,115200 kgdbcon'

然后可以saveenv,最后执行boot命令启动。

此时系统会正常开机:

U-Boot 2015.04-g5095150-dirty (May   - ::)

CPUID:
FCLK: MHz
HCLK: MHz
PCLK: MHz
I2C: ready
DRAM: MiB
WARNING: Caches not enabled
Flash: Bytes
NAND: MiB
In: serial
Out: serial
Err: serial
Net: dm9000
Hit any key to stop autoboot:
TQ2440 #
TQ2440 #
TQ2440 #
TQ2440 # setenv bootargs 'noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2 console=ttySAC0,115200n8 kgdboc=ttySAC0,115200 kgdbcon'
TQ2440 # boot
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in bit mode
MAC: :0c::2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.8
Filename 'uImage'.
Load address: 0x30008000
Loading: T #################################################################
#################################################################
#################################################################
#######################################
436.5 KiB/s
done
Bytes transferred = ( hex)
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in bit mode
MAC: :0c::2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.2; our IP address is 192.168.1.8
Filename 'dtb'.
Load address: 0x32000000
Loading: T #
Bytes/s
done
Bytes transferred = (20f5 hex)
## Booting kernel from Legacy Image at ...
Image Name: Linux-4.10.+
Created: -- :: UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: Bytes = 3.3 MiB
Load Address:
Entry Point:
Verifying Checksum ... OK
## Flattened Device Tree blob at
Booting using the fdt blob at 0x32000000
Loading Kernel Image ... OK
Loading Device Tree to 33aa7000, end 33aac0f4 ... OK Starting kernel ... Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.10.+ (pengdonglin@pengdonglin-dell) (gcc version 4.8. (prerelease) (Sourcery CodeBench Lite 2014.05-) ) # Sun Aug :: CST
[ 0.000000] CPU: ARM920T [] revision (ARMv4T), cr=c000717f
[ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[ 0.000000] OF: fdt:Machine model: TQ2440
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] DT missing boot CPU MPIDR[:], fall back to default cpu_logical_map
[ 0.000000] Built zonelists in Zone order, mobility grouping on. Total pages:
[ 0.000000] Kernel command line: noinitrd root=/dev/mtdblock5 rw rootfstype=jffs2 console=ttySAC0,115200n8 kgdboc=ttySAC0, kgdbcon
[ 0.000000] PID hash table entries: (order: -, bytes)
[ 0.000000] Dentry cache hash table entries: (order: , bytes)
[ 0.000000] Inode-cache hash table entries: (order: , bytes)
[ 0.000000] Memory: 57572K/65536K available (4923K kernel code, 245K rwdata, 1412K rodata, 208K init, 278K bss, 7964K reserved, 0K cma-reserved)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 ( kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff800000 ( MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( MB)
[ 0.000000] .text : 0xc0008000 - 0xc04d7138 ( kB)
[ 0.000000] .init : 0xc066e000 - 0xc06a2000 ( kB)
[ 0.000000] .data : 0xc06a2000 - 0xc06df520 ( kB)
[ 0.000000] .bss : 0xc06df520 - 0xc0725060 ( kB)
[ 0.000000] SLUB: HWalign=, Order=-, MinObjects=, CPUs=, Nodes=
[ 0.000000] NR_IRQS:
[ 0.000000] irq: clearing pending status
... ...
[ 2.822615] uda134x-codec uda134x-codec: uda134x_codec_probe enter.
[ 2.823450] uda134x-codec uda134x-codec: uda134x_parse_dt parse successfully.
[ 2.836250] s3c24xx_i2s_component_probe enter
[ 2.836801] uda134x_soc_probe enter: UDA134X SoC Audio Codec
[ 2.910656] s3c24xx_snd_rxctrl enter
[ 2.910994] s3c24xx_i2s_set_fmt enter
[ 2.922893] s3c24xx_uda134x s3c24xx_uda134x: uda134x-hifi <-> s3c2440-i2s mapping ok
[ 2.941382] NET: Registered protocol family
[ 2.942137] Key type dns_resolver registered
[ 2.968854] s3c-rtc .rtc: setting system clock to -- :: UTC ()
[ 2.973149] ALSA device list:
[ 2.974745] #: S3C24XX_UDA134X
[ 3.182558] jffs2: Empty flash at 0x025024bc ends at 0x02502800
[ 3.346774] jffs2: Empty flash at 0x02a552bc ends at 0x02a55800
[ 3.411970] jffs2: Empty flash at 0x0317390c ends at 0x03174000
[ 3.592276] jffs2: Empty flash at 0x056b40f0 ends at 0x056b4800
[ 17.600541] VFS: Mounted root (jffs2 filesystem) on device :.
[ 17.602919] Freeing unused kernel memory: 208K
[ 17.605387] This architecture does not have kernel memory protection.
[ 22.112164] dm9000 .ethernet eth0: link down Please press Enter to activate this console. [ 24.340189] dm9000 .ethernet eth0: link up, 100Mbps, full-duplex, lpa 0x4DE1 Set Env for Tslib
[root@tq2440 ]#

然后在板子上执行如下命令:


[root@tq2440 ]# echo g > /proc/sysrq-trigger
[ 85.019192] sysrq: SysRq : DEBUG
[ 85.019436] KGDB: Entering KGDB

可以看到此时系统进入了KGDB模式,等待远程GDB连接.

接下来关闭ckermit,并在PC上执行跟上面一样的命令:

$arm-linux-gdb vmlinux
GNU gdb (Sourcery CodeBench Lite 2014.05-) 7.7.50.20140217-cvs
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://sourcery.mentor.com/GNUToolchain/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vmlinux...done.
(gdb) set serial baud
(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
arch_kgdb_breakpoint () at kernel/debug/debug_core.c:
wmb(); /* Sync point before breakpoint */
(gdb) b __irq_svc
Breakpoint at 0xc000e8ac: file arch/arm/kernel/entry-armv.S, line .
(gdb) c
Continuing. Breakpoint , __irq_svc () at arch/arm/kernel/entry-armv.S:
irq_handler
(gdb) l .align
__irq_svc:
svc_entry
bt_demo:
irq_handler #ifdef CONFIG_PREEMPT
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
ldr r0, [tsk, #TI_FLAGS] @ get flags
(gdb) info all-registers
r0 0x51
r1 0xbf000000
r2 0xc2dd3eb8
r3 0xc0068894
r4 0xc00687f8
r5 0x60000013
r6 0xffffffff
r7 0xc2dd3e9c
r8 0x2
r9 0xc2dd2000
r10 0x0
r11 0x1166284
r12 0x60000013
sp 0xc2dd3e68 0xc2dd3e68
lr 0xc0068894
pc 0xc000e8ac 0xc000e8ac <__irq_svc+>
f0 (raw 0x000000000000000000000000)
f1 (raw 0x000000000000000000000000)
f2 (raw 0x000000000000000000000000)
f3 (raw 0x0807463a099d92c000000000)
f4 (raw 0x000000000000000000000000)
f5 (raw 0x000000000000000000000000)
f6 (raw 0x000000000000000000000000)
f7 (raw 0x000000000000000000000000)
fps 0x0
cpsr 0x60000093
(gdb) x/16xw 0xc2dd3e68
0xc2dd3e68: 0x00000013 0x00000001 0x60000013 0xc0707338
0xc2dd3e78: 0xc06b6518 0x00000067 0x00000000 0x00000007
0xc2dd3e88: 0x00000002 0x01167788 0x00000000 0x01166284
0xc2dd3e98: 0x60000013 0xc2dd3eb8 0xc0068894 0xc00687f8
(gdb)
0xc2dd3ea8: 0x60000013 0xffffffff 0x00000051 0xbf000000
0xc2dd3eb8: 0xc06af650 0xc029515c 0x00000051 0x00000002
0xc2dd3ec8: 0x00000000 0xa0000013 0x00000001 0x00000002
0xc2dd3ed8: 0x01167788 0xc0295664 0xc34cca80 0xc0103a64

退出的话,在gdb里执行quit命令,再次打开ckermit还可以连上板子,并且还可以再次通过echo使kernel再次进入等待远程gdb连接模式。

三、Qemu + GDB

这部分参考的是笨叔叔的《奔跑吧 Linux内核》。
首先需要配置内核,确保编译出来的内核包含调试信息:
Kernel hacking
----> Compile-time checks and compiler options
----> [*] Compile the kernel with debug info

在启动Qemu的时候设置两个参数:

-S: 表示Qemu虚拟机会冻结CPU,知道远程的GDB输入相应的控制命令
-s: 表示在1234端口接受GDB的调试连接
 
下面是启动Qemu的命令:

sudo qemu-system-arm \
-M vexpress-a9 \
-m 1024M \
-smp \
-kernel ./linux-4.10/out_aarch32/arch/arm/boot/zImage \
-append "root=/dev/mmcblk0p1 rw rootfstype=ext4 console=ttyAMA0 init=/linuxrc ignore_loglevel firmware_class.path=/etc/firmware" \
-sd ./rootfs/fs_vexpress_1G.img \
-dtb ./linux-4.10/out_aarch32/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
-net nic,vlan= -net tap,vlan=,ifname=tap3 \
-nographic \
-S -s

然后Qemu会等待远程gdb连接,此时我们在另一个窗口中执行下面的命令:


$arm-none-linux-gnueabi-gdb ./out_aarch32/vmlinux
GNU gdb (Sourcery CodeBench Lite 2014.05-) 7.7.50.20140217-cvs
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://sourcery.mentor.com/GNUToolchain/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./out_aarch32/vmlinux...done.
(gdb) target remote localhost:
Remote debugging using localhost:
0x60000000 in ?? ()
(gdb) b start_kernel
Breakpoint at 0x809009b0: file ../init/main.c, line .
(gdb) c
Continuing. Breakpoint , start_kernel () at ../init/main.c:
{
(gdb) l
vmalloc_init();
ioremap_huge_init();
} asmlinkage __visible void __init start_kernel(void)
{
char *command_line;
char *after_dashes; set_task_stack_end_magic(&init_task);

完。

 
 
 
 

基于TQ2440和Qemu的GDB+串口调试(1)的更多相关文章

  1. ARM平台如何玩转GDB远程调试?

    前  言 关于GDB工具 GDB工具是GNU项目调试器,基于命令行使用.和其他的调试器一样,可使用GDB工具单步运行程序.单步执行.跳入/跳出函数.设置断点.查看变量等等,它是UNIX/LINUX操作 ...

  2. 自己编写的基于VC++6.0的串口调试软件,并贡献源程序!

    自己编写的基于VC++6.0的串口调试软件源程序! 程序下载链接: 点击打开链接

  3. 基于Modbus的C#串口调试开发

    说明:本文主要研究的是使用C# WinForm开发的串口调试软件(其中包含Modbus协议相关操作).Modbus相关协议可以查阅百度文库等,可参考: <http://wenku.baidu.c ...

  4. 搭建基于qemu + eclipse的kernel调试环境(by quqi99)

    作者:张华  发表于:2016-02-06版权声明:能够随意转载.转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 使用q ...

  5. 基于.Net C# 通信开发-串口调试助手

    基于.Net C# 通信开发-串口调试助手 1.概述 串口调试助手,广泛应用于工控领域的数据监控.数据采集.数据分析等工作,可以帮助串口应用设计.开发.测试人员检查所开发的串口应用软硬件的数据收发状况 ...

  6. Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动

    姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...

  7. android模拟器使用PC串口调试

    android模拟器使用PC串口调试1.模拟器可以使用PC的串口  启动模拟器并加载PC串口 命令如下:  运行 emulator @模拟器名称 -qemu -serial COM12.查看串口是否被 ...

  8. keil中的串口调试:

    keil中串口的虚拟调试信息在通过View-serial windows-#usart1/2/3/4/debug(printf)可以看到.当然也可以通过虚拟串口VSPD+串口调试助手在外部实现,方法如 ...

  9. GDB+GDBServer调试Linux应用程序

    参考:http://blog.csdn.net/shanghaiqianlun/article/details/7820401 一.gdb+gdbserver总体介绍 远程调试环境由宿主机GDB和目标 ...

随机推荐

  1. 一个无锁消息队列引发的血案(三)——地:q3.h 与 RingBuffer

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  2. C# 各版本新特性

    C# 2.0 泛型(Generics) 泛型是CLR 2.0中引入的最重要的新特性,使得可以在类.方法中对使用的类型进行参数化. 例如,这里定义了一个泛型类: class MyCollection&l ...

  3. Dede更新提示DedeTag Engine Create File False的解决办法

    第一种情况:列表.频道.文章等命名规则未填写或填写错误 此种情况较为少见,因为初级用户一般不会去修改这些东西,情况可以大致分为: 命名规则未填写(即为空)解决方法:只需填好相应的规则即可,重新选择栏目 ...

  4. java 接口与工厂

    接口时实现多重继承的途径,而生产遵循某个接口的对象的典型方式就是工厂方法设计模式,这与直接调用构造器不同,我们在工厂对象上调用的是某种方法,而该工厂对象将生成接口的某个实现的对象,理论上通过这种方式, ...

  5. Java @Override 注解

    @Override注解,不是关键字,但可以当关键字使用,可以选择添加这个注解,在你不留心重载而并非复写了该方法时,编译器就会产生一条错误:The method doh(Milhouse) of typ ...

  6. Archlinux系统配置学习笔记(一)

    本文档是有关Archlinux系统配置的学习笔记,参考和学习的是Archlinux官方网站上的相应文档:General Recommendations. 这里的配置主要是针对按照官方网站上的文档刚刚完 ...

  7. Java中 equals 和 == 的比较

    先来看这样一个题目,假设有以下代码 下列选项中返回false的语句是? String s = "hello"; String t = "hello"; char ...

  8. 远程登陆linux连接mysql root账号报错:2003-can't connect to MYSQL serve(转)

    远程连接mysql root账号报错:2003-can't connect to MYSQL serve 1.远程连接Linux系统,登录数据库:mysql -uroot -p(密码) 2.修改roo ...

  9. 001.Rsync简介及使用

    一 基础知识 1.1 简介 Rsync是Linux系统中的数据镜像备份工具,通过rsync可以将本地系统数据通过网络备份到任何远程主机上.rysnc不仅仅能对不同位置的文件和目录进行同步,还可以差异计 ...

  10. CSS3利用背景渐变和background-size配合完成渐变与条纹效果[持续更新中...]

    1.不等垂直条纹. <!-- 不等垂直条纹 --> <div class="div1"></div>div1 div{ width: 200px ...