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

📄 kgdb.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  arch/cris/arch-v32/kernel/kgdb.c * *  CRIS v32 version by Orjan Friberg, Axis Communications AB. * *  S390 version *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * *  Originally written by Glenn Engel, Lake Stevens Instrument Division * *  Contributed by HP Systems * *  Modified for SPARC by Stu Grossman, Cygnus Support. * *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de> * *  Copyright (C) 1995 Andreas Busse *//* FIXME: Check the documentation. *//* *  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 <linux/reboot.h>#include <asm/setup.h>#include <asm/ptrace.h>#include <asm/irq.h>#include <asm/arch/hwregs/reg_map.h>#include <asm/arch/hwregs/reg_rdwr.h>#include <asm/arch/hwregs/intr_vect_defs.h>#include <asm/arch/hwregs/ser_defs.h>/* From entry.S. */extern void gdb_handle_exception(void);/* From kgdb_asm.S. */extern void kgdb_handle_exception(void);static int kgdb_started = 0;/********************************* Register image ****************************/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 (if any) */	unsigned int   r9;    /* 0x24 */	unsigned int   r10;   /* 0x28 */	unsigned int   r11;   /* 0x2C */	unsigned int   r12;   /* 0x30 */	unsigned int   r13;   /* 0x34 */	unsigned int   sp;    /* 0x38; R14, Stack pointer */	unsigned int   acr;   /* 0x3C; R15, Address calculation register. */	unsigned char  bz;    /* 0x40; P0, 8-bit zero register */	unsigned char  vr;    /* 0x41; P1, Version register (8-bit) */	unsigned int   pid;   /* 0x42; P2, Process ID */	unsigned char  srs;   /* 0x46; P3, Support register select (8-bit) */        unsigned short wz;    /* 0x47; P4, 16-bit zero register */	unsigned int   exs;   /* 0x49; P5, Exception status */	unsigned int   eda;   /* 0x4D; P6, Exception data address */	unsigned int   mof;   /* 0x51; P7, Multiply overflow register */	unsigned int   dz;    /* 0x55; P8, 32-bit zero register */	unsigned int   ebp;   /* 0x59; P9, Exception base pointer */	unsigned int   erp;   /* 0x5D; P10, Exception return pointer. Contains the PC we are interested in. */	unsigned int   srp;   /* 0x61; P11, Subroutine return pointer */	unsigned int   nrp;   /* 0x65; P12, NMI return pointer */	unsigned int   ccs;   /* 0x69; P13, Condition code stack */	unsigned int   usp;   /* 0x6D; P14, User mode stack pointer */	unsigned int   spc;   /* 0x71; P15, Single step PC */	unsigned int   pc;    /* 0x75; Pseudo register (for the most part set to ERP). */} registers;typedefstruct bp_register_image{	/* Support register bank 0. */	unsigned int   s0_0;	unsigned int   s1_0;	unsigned int   s2_0;	unsigned int   s3_0;	unsigned int   s4_0;	unsigned int   s5_0;	unsigned int   s6_0;	unsigned int   s7_0;	unsigned int   s8_0;	unsigned int   s9_0;	unsigned int   s10_0;	unsigned int   s11_0;	unsigned int   s12_0;	unsigned int   s13_0;	unsigned int   s14_0;	unsigned int   s15_0;	/* Support register bank 1. */	unsigned int   s0_1;	unsigned int   s1_1;	unsigned int   s2_1;	unsigned int   s3_1;	unsigned int   s4_1;	unsigned int   s5_1;	unsigned int   s6_1;	unsigned int   s7_1;	unsigned int   s8_1;	unsigned int   s9_1;	unsigned int   s10_1;	unsigned int   s11_1;	unsigned int   s12_1;	unsigned int   s13_1;	unsigned int   s14_1;	unsigned int   s15_1;	/* Support register bank 2. */	unsigned int   s0_2;	unsigned int   s1_2;	unsigned int   s2_2;	unsigned int   s3_2;	unsigned int   s4_2;	unsigned int   s5_2;	unsigned int   s6_2;	unsigned int   s7_2;	unsigned int   s8_2;	unsigned int   s9_2;	unsigned int   s10_2;	unsigned int   s11_2;	unsigned int   s12_2;	unsigned int   s13_2;	unsigned int   s14_2;	unsigned int   s15_2;	/* Support register bank 3. */	unsigned int   s0_3; /* BP_CTRL */	unsigned int   s1_3; /* BP_I0_START */	unsigned int   s2_3; /* BP_I0_END */	unsigned int   s3_3; /* BP_D0_START */	unsigned int   s4_3; /* BP_D0_END */	unsigned int   s5_3; /* BP_D1_START */	unsigned int   s6_3; /* BP_D1_END */	unsigned int   s7_3; /* BP_D2_START */	unsigned int   s8_3; /* BP_D2_END */	unsigned int   s9_3; /* BP_D3_START */	unsigned int   s10_3; /* BP_D3_END */	unsigned int   s11_3; /* BP_D4_START */	unsigned int   s12_3; /* BP_D4_END */	unsigned int   s13_3; /* BP_D5_START */	unsigned int   s14_3; /* BP_D5_END */	unsigned int   s15_3; /* BP_RESERVED */} support_registers;enum register_name{	R0,  R1,  R2,  R3,	R4,  R5,  R6,  R7,	R8,  R9,  R10, R11,	R12, R13, SP,  ACR,	BZ,  VR,  PID, SRS,	WZ,  EXS, EDA, MOF,	DZ,  EBP, ERP, SRP,	NRP, CCS, USP, SPC,	PC,	S0,  S1,  S2,  S3,	S4,  S5,  S6,  S7,	S8,  S9,  S10, S11,	S12, S13, S14, S15};/* The register sizes of the registers in register_name. An unimplemented register   is designated by size 0 in this array. */static int register_size[] ={	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	1, 1, 4, 1,	2, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	4,	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4, 4,	4, 4, 4};/* Contains the register image of the kernel.   (Global so that they can be reached from assembler code.) */registers reg;support_registers sreg;/************** 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. **********************//* Write a value to a specified register regno in the register image   of the current thread. */static int write_register(int regno, char *val);/* 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);#ifdef CONFIG_ETRAXFS_SIMint getDebugChar(void){  return socketread();}#endif/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */void putDebugChar(int val);#ifdef CONFIG_ETRAXFS_SIMvoid putDebugChar(int val){  socketwrite((char *)&val, 1);}#endif/* 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);

⌨️ 快捷键说明

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