基于at91rm9200的arm平台 kgdb+linux内核调试

基于at91rm9200的arm平台 kgdb+linux内核调试
2010年06月27日
  在做这个实验之前,本人参考了bob_zhang2004的贴子,实现了在vmware下的x86平台linux的kgdb调试。现在准备建立arm平台,在这边先说说我的意图,希望大家指导,
  在bob_zhang2004的帖子中,也说明了arm平台建立kgdb调试的思路,就是在打了core-lite.patch 和 arm-lite.patch的补丁后,我们需要在arch/arm/mach-XXX/目录下实现适合我们自己板子的kgdb-serial.c文件。
  在 kgdb-serial.c文件中,主要是实现下面的几个函数:kgdb_serial_init() , kgdb_serial_putchar() , kgdb_serial_getchar() 。这在http://www.arm.linux.org.uk/deve ... tch.php?id=1335%2F1 上有说明。
  不知道谁用这种方法实现了arm平台的kgdb调试。还请各位指导指导。本人正在实验中!!!
  2007-09-11
  今天一天,主要熟悉了9200在linux中的一些配置,以及 9200的Debug串口的驱动编程。在参考kgdb补丁在pxa的板子上的kgdb_serial.c文件(了解其函数意图,在9200上实现其同等功能)。代码是写出来了,但是还没有编译,这边先贴出来给大家,哪位大侠了解的也帮忙找找bug。明天开始编译实验。大家祝我好运啊!!
  这边是针对2.6.13版本的kernel以及补丁2.6.13-at91.patch.gz进行编程的。我这边把我的代码帖给大家。这个代码可以编译通过,但是kgdb补丁在2.6.13版本(linux-2.6.13-kgdb-2.3.tar.bz2)似乎少了core.patch这个补丁。在最后编译的时候,会提示出错。所以本人又把kernel改成2.6.15.5版本,这样和我前面做x86平台调试的时候是一样的版本了。
  
  2007-09-12
  今天在把2.6.13版本下编写的kgdb_serial.c文件修改成适合2.6.15.5版本。2.6.15.5版本主要是 9200的补丁在头文件上作了很大的修改。对于很多结构体以及物理地址与虚拟地址之间的转换的方式都做了修改。这些修改有下面几个头文件中就可以体现出来:include\asm-arm\arch-at91rm9200目录下的
  AT91RM9200_USART.h hardware.h board.h AT91RM9200_SYS.h pio.h AT91RM9200.h。
  所以这边修改了kgdb_serial.c文件。如下
  
  我们把kgdb_serial.c文件放置在目录arch/arm/mach-at91rm9200/目录下,并且修改该目录下的Makefile。在 Makefile的最后加上:
  obj-$(CONFIG_KGDB) += kgdb_serial.o /* 在kgdb调试功能打开的时候,编译kgdb_serial.cw文件 */
  配置完后,我们就按照正常的配置方式配置内核,对于kgdb选项我们要选上:
  kernel hacking ---> KGDB: kernel debugging with remote gdb
  --->KGDB: Console messages through gdb
  --->Method for KGDB communication(KGDB: Use only
  kernel modules for I/O)
  内核配置完毕之后,我们就可以make zImage来生成zImage。然后通过uboot的mkimage来生成uImage. 这边还需要注意的是,在uboot传递给kernel的启动参数必须加上kgdbwait参数。在kgdb的官方文档中介绍的kgdbwait 8250kgdb=0,115200。因为我们不是用8250的串口控制器,所以我们只要传递kgdbwait的这个参数。(本人暂时是这样做的)。我的启动参数如下:
  # ./gdbmod-2.4 vmlinux
  GNU gdb 6.4
  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/tls/i686/libthread_db.so.1".
  (gdb) set remotebaud 115200
  (gdb) target remote /dev/ttyS0
  Remote debugging using /dev/ttyS0
  do_early_param (param=0xc001e195 "kgdbwait", val=0x0) at init/main.c:412
  412 {
  (gdb) break console_init
  Breakpoint 1 at 0xc0016d0c: file drivers/char/tty_io.c, line 2928.
  (gdb) c
  Continuing.
  [New thread 32768]
  Program received signal SIGTRAP, Trace/breakpoint trap.
  0x2001dc08 in ?? () at proc_fs.h:194
  194 remove_proc_entry(name,proc_net);
  (gdb) c
  Continuing.
  Program received signal SIGTRAP, Trace/breakpoint trap.
  0x2001dc08 in ?? () at proc_fs.h:194
  194 remove_proc_entry(name,proc_net);
  (gdb) list
  189 return res;
  190 }
  191
  192 static inline void proc_net_remove(const char *name)
  193 {
  194 remove_proc_entry(name,proc_net);
  195 }
  196
  197 #else
  这边我们可以判断host端的gdb已经和target上的kgdb连接上了。但是我发现内核根本无法启动,一直在0x2001dc08 in ?? () at proc_fs.h:194
  194 remove_proc_entry(name,proc_net) 停下来。这边还是个问题。不知道哪位大侠能够帮忙解决一下。我也将继续努力,希望能给大家送上好消息.
  2007-9-14
  在前面kgdb的调试中,host的gdb已经能够和target的kgdb通讯正常了。但是还是会出现一个问题,如上红字所标示的。
  后面在augustusqing网友的提醒下,是因为我host上的gdb初始化是采用x86平台的:This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/i686/libthread_db.so.1".导致的。正确的应该是在host上采用初始化为arm平台的gdb来调试。
  这边我们可以到相应的官方网站上去下载gdb源码。针对linux-2.6.15.5-kgdb-2.4补丁的gdb版本是6.4版本。所以我们下载 gdb-6.4.tar。gz。然后按照arm平台对gdb进行配置、编译、安装(详细步骤可以参考本人bolg上关于gdb的文章:《GDB 远程调试的实现》)。
  然后我们就可以调用arm-linux-gdb来调试内核了。信息如下:
  # ./arm-linux-gdb vmlinux
  bash: child setpgid (20000 to 20000): 没有那个进程
  GNU gdb 6.4
  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 "--host=i686-pc-linux-gnu --target=arm-linux"...
  (gdb) set remotebaud 115200
  (gdb) target remote /dev/ttyS0
  Remote debugging using /dev/ttyS0
  0xc0057fc4 in $d () at kernel/kgdb.c:1872
  1872 atomic_set(&kgdb_setting_breakpoint, 1);
  warning: shared library handler failed to enable breakpoint
  (gdb) break console_init
  Breakpoint 1 at 0xc0016d18: file drivers/char/tty_io.c, line 2932.
  (gdb) c
  Continuing.
  [New thread 32768]
  Breakpoint 1, console_init () at drivers/char/tty_io.c:2932
  2932 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
  (gdb) c
  Continuing.
  Linux version 2.6.15.5 (root@dengdalong) (gcc version 3.4.1) #3 Sat Sep 8 10:02:56 CST 2007
  CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
  Machine: Atmel AT91RM9200-DK
  Memory policy: ECC disabled, Data cache writeback
  Clocks: CPU 179 MHz, master 59 MHz, main 18.432 MHz
  CPU0: D VIVT write-back cache
  CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
  CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
  Built 1 zonelists
  Kernel command line: root=/dev/ram rw kgdbwait initrd=0x20a00000,4M init=/linuxrc console=ttyS0,115200,mem=16M ip=192.168.2.10
  Waiting for connection from remote gdb...
  AT91: 128 gpio irqs in 4 banks
  PID hash table entries: 128 (order: 7, 2048 bytes)
  Console: colour dummy device 80x30
  Linux version 2.6.15.5 (root@dengdalong) (gcc version 3.4.1) #3 Sat Sep 8 10:02:56 CST 2007
  CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
  Machine: Atmel AT91RM9200-DK
  Memory policy: ECC disabled, Data cache writeback
  Clocks: CPU 179 MHz, master 59 MHz, main 18.432 MHz
  CPU0: D VIVT write-back cache
  CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
  CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
  Built 1 zonelists
  Kernel command line: root=/dev/ram rw kgdbwait initrd=0x20a00000,4M init=/linuxrc console=ttyS0,115200,mem=16M ip=192.168.2.10
  Waiting for connection from remote gdb...
  AT91: 128 gpio irqs in 4 banks
  PID hash table entries: 128 (order: 7, 2048 bytes)
  Console: colour dummy device 80x30
  Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
  Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
  Memory: 16MB = 16MB total
  Memory: 9964KB available (1652K code, 368K data, 96K init)
  Mount-cache hash table entries: 512
  CPU: Testing write buffer coherency: ok
  checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
  Freeing initrd memory: 4096K
  NET: Registered protocol family 16
  usbcore: registered new driver usbfs
  usbcore: registered new driver hub
  NetWinder Floating Point Emulator V0.97 (double precision)
  io scheduler noop registered
  io scheduler anticipatory registered
  AT91 Real Time Clock driver.
  AT91 SPI driver loaded
  AT91 Watchdog Timer enabled (5 seconds)
  ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL
  ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL
  RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize
  at91_ether: Your bootloader did not configure a MAC address.
  eth0: AT91 ethernet at 0xfefbc000 int=24 10-HalfDuplex (00:00:00:00:00:00)
  eth0: Davicom 9196 PHY (Copper)
  physmap flash device: 200000 at 10000000
  phys_mapped_flash: Found 1 x16 devices at 0x0 in 16-bit bank
  Support for command set 0001 not present
  gen_probe: No supported Vendor Command Set found
  at91_cf: irqs det #64, io #0
  usbmon: debugfs is not available
  at91rm9200-ohci at91rm9200-ohci: AT91RM9200 OHCI
  at91rm9200-ohci at91rm9200-ohci: new USB bus registered, assigned bus number 1
  at91rm9200-ohci at91rm9200-ohci: irq 23, io mem 0x00300000
  usb usb1: Product: AT91RM9200 OHCI
  usb usb1: Manufacturer: Linux 2.6.15.5 ohci_hcd
  usb usb1: SerialNumber: at91rm9200
  hub 1-0:1.0: USB hub found
  hub 1-0:1.0: 2 ports detected
  udc: at91_udc version 8 March 2005
  mice: PS/2 mouse device common for all mice
  i2c /dev entries driver
  Found AT91 i2c
  AT91RM9200 MCI initialized
  NET: Registered protocol family 2
  IP route cache hash table entries: 256 (order: -2, 1024 bytes)
  TCP established hash table entries: 1024 (order: 0, 4096 bytes)
  TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
  TCP: Hash tables configured (established 1024 bind 1024)
  TCP reno registered
  TCP bic registered
  NET: Registered protocol family 1
  NET: Registered protocol family 17
  usb 1-2: new low speed USB device using at91rm9200-ohci and address 2
  usb 1-2: device descriptor read/64, error -110
  usb 1-2: device descriptor read/64, error -110
  IP-Config: Failed to open eth0
  IP-Config: No network devices available.
  RAMDISK: Compressed image found at block 0
  usb 1-2: new low speed USB device using at91rm9200-ohci and address 3
  usb 1-2: device descriptor read/64, error -110
  usb 1-2: device descriptor read/64, error -110
  usb 1-2: new low speed USB device using at91rm9200-ohci and address 4
  usb 1-2: device not accepting address 4, error -110
  usb 1-2: new low speed USB device using at91rm9200-ohci and address 5
  usb 1-2: device not accepting address 5, error -110
  VFS: Mounted root (ext2 filesystem).
  Freeing init memory: 96K
  系统启动到这边,gdb上就没有打印出来信息了。正常启动的话,应该后面是挂载文件系统。但是我没有用过kgdb,不知道这样是不是正常的。也不知道,到这边如果要调试程序,应该怎么去调试。等待继续努力!!看看kgdb的官方文档,去多了解一下。
  2007-09-23
  最近因为工作的原因,所以linux的学习停滞了一下,这边把这几天所做的kgdb的arm平台调试做一下说明。前面在kernel打上kgdb补丁后,通过debeg串口(同时作为console)连接host上的gdb,在挂载文件系统的时候,串口上就没有输出了。后面我把kgdb的调试串口改成 9200的uart2,debug的uart作为kernel的console。这个时候能够在console上清楚的看到kernel已经挂载上 ramdisk,shell也正常启动了。至于为什么在gdb串口中没有输出,我猜想是因为,系统这个时候没有任何断点,程序在正常运行了,那么在gdb 那边也就不能得到任何信息,所以就不显示任何的东西。所以看来kgdb调试的时候,需要两个串口。一个作为console,一个作为gdb的串口。
  如果我们的驱动模块静态编译进kernel的,那么我应该可以在kernel启动的时候,在register驱动的时候设置断点,从而达到调试的目的。至于动态加载的模块程序调试。本人在随后实验后贴出。
  还有前面说到2.6.13版本在打上kgdb补丁后不能正常编译问题,这个问题我另起一篇文章说明!网上也有相关的patch说明。
  2007-10-03
  最近工作比较多,所以linux的实验就停下来了,前面我将kgdb已经成功的安装在kernel上,kernel的启动调试已经可以正常运作了。后面需要实验的就是kgdb调试动态加载的模块。但是我的实验总是不成功,
  在test machine中insmod ****.ko后,develop machine的gdb会正确的停在module.c的sys_module_init的函数中。但是准备step单步进入模块的init函数,gdb提示segmentation fault,这个错误是因为访问了错误的内存造成的。所以我这边怀疑是gdb的原因。gdb在调试模块的时候对地址的解析会出现错误。但是我编译的gdb 也是kgdb官方网上下载gdb-6.3-kgdb-2.3.tar.bz2。但是是配置成ARM模式。
  后面只能将模块编译进内核,然后再进行调试了。模块编译进内核,只需要将程序拷贝到arch/arm/mach-at91rm9200目录,然后修改该目录下的Makefile。增加下面两句:
  obj-y += scull.o
  scull-objs = access.o main.o pipe.o
  其中scull模块程序由access.c main.c pipe.c构成。

你可能感兴趣的:(技术杂绘)