http://www.idcnews.net/html/edu/code/20070101/286505.html

  • 基 于at91rm9200的arm平台kgdb+linux内核调试
  • 来 源: ChinaUnix博客  作者: ChinaUnix博客   发布时间:2007-01-01 22:42:00
  • 2007-09-10
       在做这个实验之前,本人参考了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平台调试的时候是相同的版本了。

    kgdb_serial.c  /* 2.6.13 */:::   
    http://control.cublog.cn/fileicon/zip.gif’);}" alt="" border="0">
    文档:
    kgdb_serial.zip
    大小:
    1KB
    下载:
    下载

    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文档。如下
    http://control.cublog.cn/fileicon/zip.gif’);}" alt="" border="0">
    文档:
    kgdb_serial_2.6.15.5.c.zip
    大小:
    1KB
    下载:
    下载
        我们把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的这个参数。(本人暂时是这样做的)。我的 启动参数如下:
        bootargs=root=/dev/ram rw kgdbwait initrd=0x20a00000,4M init=/linux
    rc console=ttyS0,115200,mem=16m ip=192.168.2.10
       
        下载内核后,启动内核:
    ## Booting image at 20007fc0 ...
       Image Name:   Linux 2.6.15.5
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    928060 Bytes = 906.3 kB
       Load Address: 20007fc0
       Entry Point:  20008000
       Verifying Checksum ... OK
       XIP Kernel Image ... OK

    Starting kernel ...

    Uncompressing Linux.............................................................
    ..... done, booting the kernel.

    这个时候我在host端上开启我的gdb:
    [EMAIL PROTECTED] linux-2.6.15.5]# ./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来调试内核了。信息如下:
    [EMAIL PROTECTED] bin]# ./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 (
    [EMAIL PROTECTED]@dengdalong[/email]
    ) (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 (
    [EMAIL PROTECTED]@dengdalong[/email]
    ) (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构成。

Reply via email to