⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kgdb.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*!***************************************************************************!*! FILE NAME  : kgdb.c*!*! DESCRIPTION: Implementation of the gdb stub with respect to ETRAX 100.*!              It is a mix of arch/m68k/kernel/kgdb.c and cris_stub.c.*!*!---------------------------------------------------------------------------*! HISTORY*!*! DATE         NAME            CHANGES*! ----         ----            -------*! Apr 26 1999  Hendrik Ruijter Initial version.*! May  6 1999  Hendrik Ruijter Removed call to strlen in libc and removed*!                              struct assignment as it generates calls to*!                              memcpy in libc.*! Jun 17 1999  Hendrik Ruijter Added gdb 4.18 support. 'X', 'qC' and 'qL'.*! Jul 21 1999  Bjorn Wesen     eLinux port*!*! $Log: kgdb.c,v $*! Revision 1.4  2003/04/09 05:20:44  starvik*! Merge of Linux 2.5.67*!*! Revision 1.3  2003/01/21 19:11:08  starvik*! Modified include path for new dir layout*!*! Revision 1.2  2002/11/19 14:35:24  starvik*! Changes from linux 2.4*! Changed struct initializer syntax to the currently prefered notation*!*! Revision 1.1  2001/12/17 13:59:27  bjornw*! Initial revision*!*! Revision 1.6  2001/10/09 13:10:03  matsfg*! Added $ on registers and removed some underscores*!*! Revision 1.5  2001/04/17 13:58:39  orjanf*! * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.*!*! Revision 1.4  2001/02/23 13:45:19  bjornw*! config.h check*!*! Revision 1.3  2001/01/31 18:08:23  orjanf*! Removed kgdb_handle_breakpoint from being the break 8 handler.*!*! Revision 1.2  2001/01/12 14:22:25  orjanf*! Updated kernel debugging support to work with ETRAX 100LX.*!*! Revision 1.1  2000/07/10 16:25:21  bjornw*! Initial revision*!*! Revision 1.1.1.1  1999/12/03 14:57:31  bjornw*! * Initial version of arch/cris, the latest CRIS architecture with an MMU.*!   Mostly copied from arch/etrax100 with appropriate renames of files.*!   The mm/ subdir is copied from arch/i386.*!   This does not compile yet at all.*!*!*! Revision 1.4  1999/07/22 17:25:25  bjornw*! Dont wait for + in putpacket if we havent hit the initial breakpoint yet. Added a kgdb_init function which sets up the break and irq vectors.*!*! Revision 1.3  1999/07/21 19:51:18  bjornw*! Check if the interrupting char is a ctrl-C, ignore otherwise.*!*! Revision 1.2  1999/07/21 18:09:39  bjornw*! Ported to eLinux architecture, and added some kgdb documentation.*!*!*!---------------------------------------------------------------------------*!*! $Id: kgdb.c,v 1.4 2003/04/09 05:20:44 starvik Exp $*!*! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN*!*!**************************************************************************//* @(#) cris_stub.c 1.3 06/17/99 *//* *  kgdb usage notes: *  ----------------- * * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be  * built with different gcc flags: "-g" is added to get debug infos, and * "-fomit-frame-pointer" is omitted to make debugging easier. Since the * resulting kernel will be quite big (approx. > 7 MB), it will be stripped * before compresion. Such a kernel will behave just as usually, except if * given a "debug=<device>" command line option. (Only serial devices are * allowed for <device>, i.e. no printers or the like; possible values are * machine depedend and are the same as for the usual debug device, the one * for logging kernel messages.) If that option is given and the device can be * initialized, the kernel will connect to the remote gdb in trap_init(). The * serial parameters are fixed to 8N1 and 115200 bps, for easyness of * implementation. * * To start a debugging session, start that gdb with the debugging kernel * image (the one with the symbols, vmlinux.debug) named on the command line. * This file will be used by gdb to get symbol and debugging infos about the * kernel. Next, select remote debug mode by *    target remote <device> * where <device> is the name of the serial device over which the debugged * machine is connected. Maybe you have to adjust the baud rate by *    set remotebaud <rate> * or also other parameters with stty: *    shell stty ... </dev/... * If the kernel to debug has already booted, it waited for gdb and now * connects, and you'll see a breakpoint being reported. If the kernel isn't * running yet, start it now. The order of gdb and the kernel doesn't matter. * Another thing worth knowing about in the getting-started phase is how to * debug the remote protocol itself. This is activated with *    set remotedebug 1 * gdb will then print out each packet sent or received. You'll also get some * messages about the gdb stub on the console of the debugged machine. * * If all that works, you can use lots of the usual debugging techniques on * the kernel, e.g. inspecting and changing variables/memory, setting * breakpoints, single stepping and so on. It's also possible to interrupt the * debugged kernel by pressing C-c in gdb. Have fun! :-) * * The gdb stub is entered (and thus the remote gdb gets control) in the * following situations: * *  - If breakpoint() is called. This is just after kgdb initialization, or if *    a breakpoint() call has been put somewhere into the kernel source. *    (Breakpoints can of course also be set the usual way in gdb.) *    In eLinux, we call breakpoint() in init/main.c after IRQ initialization. * *  - If there is a kernel exception, i.e. bad_super_trap() or die_if_kernel() *    are entered. All the CPU exceptions are mapped to (more or less..., see *    the hard_trap_info array below) appropriate signal, which are reported *    to gdb. die_if_kernel() is usually called after some kind of access *    error and thus is reported as SIGSEGV. * *  - When panic() is called. This is reported as SIGABRT. * *  - If C-c is received over the serial line, which is treated as *    SIGINT. * * Of course, all these signals are just faked for gdb, since there is no * signal concept as such for the kernel. It also isn't possible --obviously-- * to set signal handlers from inside gdb, or restart the kernel with a * signal. * * Current limitations: * *  - While the kernel is stopped, interrupts are disabled for safety reasons *    (i.e., variables not changing magically or the like). But this also *    means that the clock isn't running anymore, and that interrupts from the *    hardware may get lost/not be served in time. This can cause some device *    errors... * *  - When single-stepping, only one instruction of the current thread is *    executed, but interrupts are allowed for that time and will be serviced *    if pending. Be prepared for that. * *  - All debugging happens in kernel virtual address space. There's no way to *    access physical memory not mapped in kernel space, or to access user *    space. A way to work around this is using get_user_long & Co. in gdb *    expressions, but only for the current process. * *  - Interrupting the kernel only works if interrupts are currently allowed, *    and the interrupt of the serial line isn't blocked by some other means *    (IPL too high, disabled, ...) * *  - The gdb stub is currently not reentrant, i.e. errors that happen therein *    (e.g. accessing invalid memory) may not be caught correctly. This could *    be removed in future by introducing a stack of struct registers. * *//* *  To enable debugger support, two things need to happen.  One, a *  call to kgdb_init() is necessary in order to allow any breakpoints *  or error conditions to be properly intercepted and reported to gdb. *  Two, a breakpoint needs to be generated to begin communication.  This *  is most easily accomplished by a call to breakpoint().  * *    The following gdb commands are supported: * * command          function                               Return value * *    g             return the value of the CPU registers  hex data or ENN *    G             set the value of the CPU registers     OK or ENN * *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN * *    c             Resume at current address              SNN   ( signal NN) *    cAA..AA       Continue at address AA..AA             SNN * *    s             Step one instruction                   SNN *    sAA..AA       Step one instruction from AA..AA       SNN * *    k             kill * *    ?             What was the last sigval ?             SNN   (signal NN) * *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets *							   baud rate * * All commands and responses are sent with a packet which includes a * checksum.  A packet consists of * * $<packet info>#<checksum>. * * where * <packet info> :: <characters representing the command or response> * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>> * * When a packet is received, it is first acknowledged with either '+' or '-'. * '+' indicates a successful transfer.  '-' indicates a failed transfer. * * Example: * * Host:                  Reply: * $m0,10#2a               +$00010203040506070809101112131415#42 * */#include <linux/string.h>#include <linux/signal.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/linkage.h>#include <asm/setup.h>#include <asm/ptrace.h>#include <asm/arch/svinto.h>#include <asm/irq.h>static int kgdb_started = 0;/********************************* Register image ****************************//* Use the order of registers as defined in "AXIS ETRAX CRIS Programmer's   Reference", p. 1-1, with the additional register definitions of the   ETRAX 100LX in cris-opc.h.   There are 16 general 32-bit registers, R0-R15, where R14 is the stack   pointer, SP, and R15 is the program counter, PC.   There are 16 special registers, P0-P15, where three of the unimplemented   registers, P0, P4 and P8, are reserved as zero-registers. A read from   any of these registers returns zero and a write has no effect. */typedefstruct register_image{	/* Offset */	unsigned int     r0;   /* 0x00 */	unsigned int     r1;   /* 0x04 */	unsigned int     r2;   /* 0x08 */	unsigned int     r3;   /* 0x0C */	unsigned int     r4;   /* 0x10 */	unsigned int     r5;   /* 0x14 */	unsigned int     r6;   /* 0x18 */	unsigned int     r7;   /* 0x1C */	unsigned int     r8;   /* 0x20 Frame pointer */	unsigned int     r9;   /* 0x24 */	unsigned int    r10;   /* 0x28 */	unsigned int    r11;   /* 0x2C */	unsigned int    r12;   /* 0x30 */	unsigned int    r13;   /* 0x34 */	unsigned int     sp;   /* 0x38 Stack pointer */	unsigned int     pc;   /* 0x3C Program counter */        unsigned char    p0;   /* 0x40 8-bit zero-register */	unsigned char    vr;   /* 0x41 Version register */        unsigned short   p4;   /* 0x42 16-bit zero-register */	unsigned short  ccr;   /* 0x44 Condition code register */		unsigned int    mof;   /* 0x46 Multiply overflow register */	        unsigned int     p8;   /* 0x4A 32-bit zero-register */	unsigned int    ibr;   /* 0x4E Interrupt base register */	unsigned int    irp;   /* 0x52 Interrupt return pointer */	unsigned int    srp;   /* 0x56 Subroutine return pointer */	unsigned int    bar;   /* 0x5A Breakpoint address register */	unsigned int   dccr;   /* 0x5E Double condition code register */	unsigned int    brp;   /* 0x62 Breakpoint return pointer (pc in caller) */	unsigned int    usp;   /* 0x66 User mode stack pointer */} registers;/************** Prototypes for local library functions ***********************//* Copy of strcpy from libc. */static char *gdb_cris_strcpy (char *s1, const char *s2);/* Copy of strlen from libc. */static int gdb_cris_strlen (const char *s);/* Copy of memchr from libc. */static void *gdb_cris_memchr (const void *s, int c, int n);/* Copy of strtol from libc. Does only support base 16. */static int gdb_cris_strtol (const char *s, char **endptr, int base);/********************** Prototypes for local functions. **********************//* Copy the content of a register image into another. The size n is   the size of the register image. Due to struct assignment generation of   memcpy in libc. */static void copy_registers (registers *dptr, registers *sptr, int n);/* Copy the stored registers from the stack. Put the register contents   of thread thread_id in the struct reg. */static void copy_registers_from_stack (int thread_id, registers *reg);/* Copy the registers to the stack. Put the register contents of thread   thread_id from struct reg to the stack. */static void copy_registers_to_stack (int thread_id, registers *reg);/* Write a value to a specified register regno in the register image   of the current thread. */static int write_register (int regno, char *val);/* Write a value to a specified register in the stack of a thread other   than the current thread. */static write_stack_register (int thread_id, int regno, char *valptr);/* Read a value from a specified register in the register image. Returns the   status of the read operation. The register value is returned in valptr. */static int read_register (char regno, unsigned int *valptr);/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */int getDebugChar (void);/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */void putDebugChar (int val);void enableDebugIRQ (void);/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,   represented by int x. */static char highhex (int x);/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,   represented by int x. */static char lowhex (int x);/* Returns the integer equivalent of a hexadecimal character. */static int hex (char ch);/* Convert the memory, pointed to by mem into hexadecimal representation.   Put the result in buf, and return a pointer to the last character   in buf (null). */static char *mem2hex (char *buf, unsigned char *mem, int count);/* Convert the array, in hexadecimal representation, pointed to by buf into   binary representation. Put the result in mem, and return a pointer to   the character after the last byte written. */static unsigned char *hex2mem (unsigned char *mem, char *buf, int count);/* Put the content of the array, in binary representation, pointed to by buf   into memory pointed to by mem, and return a pointer to   the character after the last byte written. */static unsigned char *bin2mem (unsigned char *mem, unsigned char *buf, int count);/* Await the sequence $<data>#<checksum> and store <data> in the array buffer   returned. */static void getpacket (char *buffer);/* Send $<data>#<checksum> from the <data> in the array buffer. */static void putpacket (char *buffer);/* Build and send a response packet in order to inform the host the   stub is stopped. */static void stub_is_stopped (int sigval);/* All expected commands are sent from remote.c. Send a response according   to the description in remote.c. */static void handle_exception (int sigval);/* Performs a complete re-start from scratch. ETRAX specific. */static void kill_restart (void);/******************** Prototypes for global functions. ***********************//* The string str is prepended with the GDB printout token and sent. */void putDebugString (const unsigned char *str, int length); /* used by etrax100ser.c *//* The hook for both static (compiled) and dynamic breakpoints set by GDB.   ETRAX 100 specific. */void handle_breakpoint (void);                          /* used by irq.c *//* The hook for an interrupt generated by GDB. ETRAX 100 specific. */void handle_interrupt (void);                           /* used by irq.c *//* A static breakpoint to be used at startup. */void breakpoint (void);                                 /* called by init/main.c *//* From osys_int.c, executing_task contains the number of the current   executing task in osys. Does not know of object-oriented threads. */extern unsigned char executing_task;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -