📄 arm-lite.patch
字号:
+ struct pt_regs *thread_regs;++ /* Just making sure... */+ if (task == NULL)+ return;++ /* Initialize to zero */+ for (regno = 0; regno < GDB_MAX_REGS; regno++)+ gdb_regs[regno] = 0;++ /* Otherwise, we have only some registers from switch_to() */+ thread_regs = kgdb_get_user_regs(task);+ gdb_regs[_R0] = thread_regs->ARM_r0; /* Not really valid? */+ gdb_regs[_R1] = thread_regs->ARM_r1; /* " " */+ gdb_regs[_R2] = thread_regs->ARM_r2; /* " " */+ gdb_regs[_R3] = thread_regs->ARM_r3; /* " " */+ gdb_regs[_R4] = thread_regs->ARM_r4;+ gdb_regs[_R5] = thread_regs->ARM_r5;+ gdb_regs[_R6] = thread_regs->ARM_r6;+ gdb_regs[_R7] = thread_regs->ARM_r7;+ gdb_regs[_R8] = thread_regs->ARM_r8;+ gdb_regs[_R9] = thread_regs->ARM_r9;+ gdb_regs[_R10] = thread_regs->ARM_r10;+ gdb_regs[_FP] = thread_regs->ARM_fp;+ gdb_regs[_IP] = thread_regs->ARM_ip;+ gdb_regs[_SP] = thread_regs->ARM_sp;+ gdb_regs[_LR] = thread_regs->ARM_lr;+ gdb_regs[_PC] = thread_regs->ARM_pc;+ gdb_regs[_CPSR] = thread_regs->ARM_cpsr;+}++static int compiled_break;++int kgdb_arch_handle_exception(int exception_vector, int signo,+ int err_code, char *remcom_in_buffer,+ char *remcom_out_buffer,+ struct pt_regs *linux_regs)+{+ long addr;+ char *ptr;++ switch (remcom_in_buffer[0]) {+ case 'c':+ kgdb_contthread = NULL;++ /*+ * Try to read optional parameter, pc unchanged if no parm.+ * If this was a compiled breakpoint, we need to move+ * to the next instruction or we will just breakpoint+ * over and over again.+ */+ ptr = &remcom_in_buffer[1];+ if (kgdb_hex2long(&ptr, &addr)) {+ linux_regs->ARM_pc = addr;+ } else if (compiled_break == 1) {+ linux_regs->ARM_pc += 4;+ }++ compiled_break = 0;++ return 0;+ }++ return -1;+}++static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)+{+ kgdb_handle_exception(1, SIGTRAP, 0, regs);++ return 0;+}++static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)+{+ compiled_break = 1;+ kgdb_handle_exception(1, SIGTRAP, 0, regs);++ return 0;+}++static struct undef_hook kgdb_brkpt_hook = {+ .instr_mask = 0xffffffff,+ .instr_val = KGDB_BREAKINST,+ .fn = kgdb_brk_fn+};++static struct undef_hook kgdb_compiled_brkpt_hook = {+ .instr_mask = 0xffffffff,+ .instr_val = KGDB_COMPILED_BREAK,+ .fn = kgdb_compiled_brk_fn+};++/*+ * Register our undef instruction hooks with ARM undef core.+ * We regsiter a hook specifically looking for the KGB break inst+ * and we handle the normal undef case within the do_undefinstr+ * handler.+ */+int kgdb_arch_init(void)+{+ register_undef_hook(&kgdb_brkpt_hook);+ register_undef_hook(&kgdb_compiled_brkpt_hook);++ return 0;+}++struct kgdb_arch arch_kgdb_ops = {+#ifndef __ARMEB__+ .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}+#else+ .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}+#endif+};Index: linux-2.6.16/arch/arm/kernel/traps.c===================================================================--- linux-2.6.16.orig/arch/arm/kernel/traps.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/kernel/traps.c 2006-04-25 11:40:09.000000000 +0530@@ -282,6 +282,7 @@ unsigned int instr; struct undef_hook *hook; siginfo_t info;+ mm_segment_t fs; void __user *pc; /*@@ -291,12 +292,15 @@ */ regs->ARM_pc -= correction; + fs = get_fs();+ set_fs(KERNEL_DS); pc = (void __user *)instruction_pointer(regs); if (thumb_mode(regs)) { get_user(instr, (u16 __user *)pc); } else { get_user(instr, (u32 __user *)pc); }+ set_fs(fs); spin_lock_irq(&undef_lock); list_for_each_entry(hook, &undef_hook, node) {@@ -688,6 +692,13 @@ void __init trap_init(void) {+#if defined(CONFIG_KGDB)+ return;+}++void __init early_trap_init(void)+{+#endif extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[];Index: linux-2.6.16/arch/arm/kernel/Makefile===================================================================--- linux-2.6.16.orig/arch/arm/kernel/Makefile 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/kernel/Makefile 2006-04-25 11:40:40.000000000 +0530@@ -21,6 +21,7 @@ obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o+obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxtIndex: linux-2.6.16/arch/arm/kernel/setup.c===================================================================--- linux-2.6.16.orig/arch/arm/kernel/setup.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/kernel/setup.c 2006-04-25 11:40:09.000000000 +0530@@ -791,6 +791,11 @@ conswitchp = &dummy_con; #endif #endif++#if defined(CONFIG_KGDB)+ extern void __init early_trap_init(void);+ early_trap_init();+#endif } Index: linux-2.6.16/arch/arm/mach-omap1/serial.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-omap1/serial.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-omap1/serial.c 2006-04-25 11:40:09.000000000 +0530@@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/serial.h> #include <linux/tty.h>+#include <linux/kgdb.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> #include <linux/clk.h>@@ -199,6 +200,9 @@ break; } omap_serial_reset(&serial_platform_data[i]);+#ifdef CONFIG_KGDB_8250+ kgdb8250_add_platform_port(i, &serial_platform_data[i]);+#endif } } Index: linux-2.6.16/arch/arm/mach-ixp4xx/ixdp425-setup.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-ixp4xx/ixdp425-setup.c 2006-04-25 11:40:09.000000000 +0530@@ -24,6 +24,7 @@ #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h>+#include <asm/kgdb.h> static struct flash_platform_data ixdp425_flash_data = { .map_name = "cfi_probe",@@ -76,7 +77,8 @@ .mapbase = IXP4XX_UART1_BASE_PHYS, .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, .irq = IRQ_IXP4XX_UART1,- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |+ UPF_SHARE_IRQ, .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL,@@ -85,7 +87,8 @@ .mapbase = IXP4XX_UART2_BASE_PHYS, .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, .irq = IRQ_IXP4XX_UART2,- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |+ UPF_SHARE_IRQ, .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL,@@ -116,6 +119,11 @@ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));++#ifdef CONFIG_KGDB_8250+ kgdb8250_add_port(0, &ixdp425_serial_ports[0]);+ kgdb8250_add_port(1, &ixdp425_serial_ports[1]);+#endif } #ifdef CONFIG_ARCH_IXDP425Index: linux-2.6.16/arch/arm/mach-ixp4xx/coyote-setup.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-ixp4xx/coyote-setup.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-ixp4xx/coyote-setup.c 2006-04-25 11:42:08.000000000 +0530@@ -96,6 +96,10 @@ } platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));++#ifdef CONFIG_KGDB_8250+ kgdb8250_add_port(0, &coyote_serial_port);+#endif } #ifdef CONFIG_ARCH_ADI_COYOTEIndex: linux-2.6.16/arch/arm/mach-ixp2000/core.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-ixp2000/core.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-ixp2000/core.c 2006-04-25 11:40:09.000000000 +0530@@ -34,6 +34,7 @@ #include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h>+#include <asm/kgdb.h> #include <asm/mach/map.h> #include <asm/mach/time.h>@@ -184,6 +185,9 @@ void __init ixp2000_uart_init(void) { platform_device_register(&ixp2000_serial_device);+#ifdef CONFIG_KGDB_8250+ kgdb8250_add_port(0, &ixp2000_serial_port);+#endif } Index: linux-2.6.16/arch/arm/mach-ixp2000/ixdp2x01.c===================================================================--- linux-2.6.16.orig/arch/arm/mach-ixp2000/ixdp2x01.c 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/arch/arm/mach-ixp2000/ixdp2x01.c 2006-04-25 11:40:09.000000000 +0530@@ -38,6 +38,7 @@ #include <asm/system.h> #include <asm/hardware.h> #include <asm/mach-types.h>+#include <asm/kgdb.h> #include <asm/mach/pci.h> #include <asm/mach/map.h>@@ -175,6 +176,11 @@ early_serial_setup(&ixdp2x01_serial_ports[0]); early_serial_setup(&ixdp2x01_serial_ports[1]);++#ifdef CONFIG_KGDB_8250+ kgdb8250_add_port(0, &ixdp2x01_serial_ports[0]);+ kgdb8250_add_port(1, &ixdp2x01_serial_ports[1]);+#endif } Index: linux-2.6.16/lib/Kconfig.debug===================================================================--- linux-2.6.16.orig/lib/Kconfig.debug 2006-04-25 11:34:01.000000000 +0530+++ linux-2.6.16/lib/Kconfig.debug 2006-04-25 11:40:09.000000000 +0530@@ -232,7 +232,7 @@ config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION- depends on DEBUG_KERNEL && (X86 || MIPS || (SUPERH && !SUPERH64) || IA64 || X86_64 || PPC)+ depends on DEBUG_KERNEL && (ARM || X86 || MIPS || (SUPERH && !SUPERH64) || IA64 || X86_64 || PPC) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enableIndex: linux-2.6.16/include/asm-arm/kgdb.h===================================================================--- linux-2.6.16.orig/include/asm-arm/kgdb.h 2006-04-25 10:59:23.506518750 +0530+++ linux-2.6.16/include/asm-arm/kgdb.h 2006-04-25 11:40:09.000000000 +0530@@ -0,0 +1,87 @@+/*+ * include/asm-arm/kgdb.h+ *+ * ARM KGDB support+ *+ * Author: Deepak Saxena <dsaxena@mvista.com>+ *+ * Copyright (C) 2002 MontaVista Software Inc.+ *+ */++#ifndef __ASM_KGDB_H__+#define __ASM_KGDB_H__++#include <linux/config.h>+#include <asm/ptrace.h>+++/*+ * GDB assumes that we're a user process being debugged, so+ * it will send us an SWI command to write into memory as the+ * debug trap. When an SWI occurs, the next instruction addr is+ * placed into R14_svc before jumping to the vector trap.+ * This doesn't work for kernel debugging as we are already in SVC+ * we would loose the kernel's LR, which is a bad thing. This+ * is bad thing.+ *+ * By doing this as an undefined instruction trap, we force a mode+ * switch from SVC to UND mode, allowing us to save full kernel state.+ *+ * We also define a KGDB_COMPILED_BREAK which can be used to compile+ * in breakpoints. This is important for things like sysrq-G and for+ * the initial breakpoint from trap_init().+ *+ * Note to ARM HW designers: Add real trap support like SH && PPC to+ * make our lives much much simpler. :)+ */+#define BREAK_INSTR_SIZE 4+#define GDB_BREAKINST 0xef9f0001+#define KGDB_BREAKINST 0xe7ffdefe+#define KGDB_COMPILED_BREAK 0xe7ffdeff+#define CACHE_FLUSH_IS_SAFE 1++#ifndef __ASSEMBLY__++#define BREAKPOINT() asm(".word 0xe7ffdeff")+++extern void kgdb_handle_bus_error(void);+extern int kgdb_fault_expected;++/*+ * From Amit S. Kale:+ *+ * In the register packet, words 0-15 are R0 to R10, FP, IP, SP, LR, PC. But+ * Register 16 isn't cpsr. GDB passes CPSR in word 25. There are 9 words in+ * between which are unused. Passing only 26 words to gdb is sufficient.+ * GDB can figure out that floating point registers are not passed.+ * GDB_MAX_REGS should be 26.+ */+#define GDB_MAX_REGS (26)++#define KGDB_MAX_NO_CPUS 1+#define BUFMAX 400+#define NUMREGBYTES (GDB_MAX_REGS << 2)+#define NUMCRITREGBYTES (32 << 2)++#define _R0 0+#define _R1 1+#define _R2 2+#define _R3 3+#define _R4 4+#define _R5 5+#define _R6 6+#define _R7 7+#define _R8 8+#define _R9 9+#define _R10 10+#define _FP 11+#define _IP 12+#define _SP 13+#define _LR 14+#define _PC 15+#define _CPSR (GDB_MAX_REGS - 1)++#endif /* !__ASSEMBLY__ */+#endif /* __ASM_KGDB_H__ */Index: linux-2.6.16/include/asm-arm/system.h===================================================================--- linux-2.6.16.orig/include/asm-arm/system.h 2006-03-20 11:23:29.000000000 +0530+++ linux-2.6.16/include/asm-arm/system.h 2006-04-25 11:40:09.000000000 +0530@@ -418,6 +418,47 @@ extern void disable_hlt(void); extern void enable_hlt(void); +#define __HAVE_ARCH_CMPXCHG 1++#include <asm/types.h>++static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,+ unsigned long new)+{+ u32 retval;+ unsigned long flags;++ local_irq_save(flags);+ retval = *m;+ if (retval == old)+ *m = new;+ local_irq_restore(flags); /* implies memory barrier */++ return retval;+}++/* This function doesn't exist, so you'll get a linker error+ if something tries to do an invalid cmpxchg(). */+extern void __cmpxchg_called_with_bad_pointer(void);++static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,+ unsigned long new, int size)+{+ switch (size) {+ case 4:+ return __cmpxchg_u32(ptr, old, new);+ }+ __cmpxchg_called_with_bad_pointer();+ return old;+}++#define cmpxchg(ptr,o,n) \+ ({ \+ __typeof__(*(ptr)) _o_ = (o); \+ __typeof__(*(ptr)) _n_ = (n); \+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \+ (unsigned long)_n_, sizeof(*(ptr))); \+ }) #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -