让内核启动时的调试信息能过串口输出
目标机: 打开/boot/grub/grub.conf
加入
title Red Flag Desktop (2.6.32.8) root (hd0,0) kernel /boot/vmlinuz-2.6.32.8 ro root=LABEL=/ vga=788 splash=silent resume=/dev/sda2 console=ttyS0,115200 console=tty0
(console=ttyS0,115200指控制台重定位到串口一,并设置速率为115200)
initrd /boot/initrd-2.6.32.8.img
开发机:
设置串口:
[root@localhost boot]# stty ispeed 115200 ospeed 115200 -F /dev/ttyS0
接收数据:
[root@localhost boot]# cat /dev/ttyS0
用KGDB远程调试 内核:
原理:
内核配置:
General setup
--> Prompt for development and/or incomplete code/drivers
Kernel hacking
-->KGDB:kernel debugging with remote gdb
-->KGDB:use kgdb over the serial console
因为kgdb加入内核代码为未成熟的代码,所以要选择“显示未成熟代码选项”,kgdb再会显示。内核从2.6.25后,KGDB已被加入内核代码树中,但直到现在,还处于未成熟代码。也仅仅支持串口调试,暂没有网络调试接口。内核2.5.25以前要使用KGDB,则要打补丁。
选择通过串口调试。
代码位于内核树的:
/kernel/kgdb.c #KGDB stub
/drivers/serial/kgdboc.c #KGDB串口驱动
串口配置:同上
目标机:
grub.conf 配置:
title Red Flag Desktop (2.6.32.8)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32.8 ro root=/dev/sda1 3 vga=788 splash=silent resu
me2=swap:/dev/sda2 kgdbwait kgdboc=0,115200
initrd /boot/initrd-2.6.32.8.img
kgdbwait:kgdb 让内核等待
kgdboc:设置串口和速率
开发机:
进入linux内核目录树根。执行下面命令:
[root@localhost linux-2.6.32.8]# gdb vmlinux #装入未压缩的内核映像
GNU gdb Everest Linux (6.4-2)
Copyright 2005 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 "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) set remotebaud 115200 #设置串口速率
(gdb) target remote /dev/ttyS0 #连接串口1
Remote debugging using /dev/ttyS0
kgdb_breakpoint () at kernel/kgdb.c:1721
1721 wmb(); /* Sync point after breakpoint */
warning: shared library handler failed to enable breakpoint
(gdb) c
Continuing. #继续执行
如果想再中断,则要在目标机上输入:
[root@localhost linux-2.6.32.8]# echo g > /proc/sysrq-trigger
SysRq : DEBUG
或者:
2. 中断测试系统
为了在测试系统运行的时候让 gdb 获得控制权,需要使用 Sys-Rq。关于 Sys-Rq 的详细设置方法,见 Documentation/sysrq.txt。 你可以在系统运行时键盘上输入 Sys Rq+g,然后 gdb 就会出现:
用GDB调试模块:
Linux 可加载模块是 ELF 格式的可执行映象;这样,它们被分成几个节.。一个典型的模块可能包含一打或更多节, 但是有 3 个典型的与一次调试会话相关:
.text
这个节包含有模块的可执行代码。 调试器必须知道在哪里以便能够给出回溯或者设置断点。( 这些操作都不相关, 当运行一个调试器在 /proc/kcore 上,但是它们在使用 kgdb 时可能有用,下面描述).
.bss
.data
这 2 个节持有模块的变量。在编译时不初始化的任何变量在 .bss 中, 而那些要初始化的在 .data 里。使 gdb 能够处理可加载模块需要通知调试器一个给定模块的节加载在哪里.。这个信息在 sysfs 中,在 /sys/module 下。 例如, 在加载 scull 模块后,目录 /sys/module/scull/sections 包含名子为 .text 的文件;每个文件的内容是那个节的基地址。
下面脚本可以取出这些值:
# gdbline module image # # Outputs an add-symbol-file line suitable for pasting into gdb to examine # a loaded module. # cd /sys/module/$1/sections echo -n add-symbol-file $2 `/bin/cat .text` for section in .[a-z]* *; do if [ $section != ".text" ]; then echo " //" echo -n " -s" $section `/bin/cat $section` fi done echo |
在目标机上执行上面脚本 ./gdbline hello /home/test/hello.ko add-symbol-file /home/test/hello.ko 0xd0e1e000 / -s .bss 0xd0e1e7c8 / -s .data 0xd0e1e600 / -s .gnu.linkonce.this_module 0xd0e1e680 / -s .rodata 0xd0e1e5d0 / -s .rodata.str1.1 0xd0e1e448 / -s .rodata.str1.4 0xd0e1e508 / -s .strtab 0xd0e21450 / -s .symtab 0xd0e21000 / -s __param 0xd0e1e594 |
然后开发机上,用上面输出把符号加入gdb中: (gdb) add-symbol-file /home/test/hello.ko 0xd0e1e000 /
-s .bss 0xd0e1e7c8 /
-s .data 0xd0e1e600 /
-s .gnu.linkonce.this_module 0xd0e1e680 /
-s .rodata 0xd0e1e5d0 /
-s .rodata.str1.1 0xd0e1e448 /
-s .rodata.str1.4 0xd0e1e508 /
-s .strtab 0xd0e21450 /
-s .symtab 0xd0e21000 /
-s __param 0xd0e1e594
add symbol table from file "/home/test/hello.ko" at
.text_addr = 0xd0e1e000
.bss_addr = 0xd0e1e7c8
.data_addr = 0xd0e1e600
.gnu.linkonce.this_module_addr = 0xd0e1e680
.rodata_addr = 0xd0e1e5d0
.rodata.str1.1_addr = 0xd0e1e448
.rodata.str1.4_addr = 0xd0e1e508
.strtab_addr = 0xd0e21450
.symtab_addr = 0xd0e21000
__param_addr = 0xd0e1e594
(y or n) y
Reading symbols from /home/test/hello.ko...warning: section .strtab not found in /home/test/hello.ko
warning: section .symtab not found in /home/test/hello.ko
done.
(gdb)
|