diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 74928c876..175e06740 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1167,7 +1167,7 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target,
 	return ERROR_OK;
 }
 
-void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
+int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
 {
 	command_context_t *cmd_ctx = connection->cmd_ctx;
 
@@ -1189,10 +1189,52 @@ void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
 			free(cmd);
 		}
 		gdb_put_packet(connection, "OK", 2);
-		return;
+		return ERROR_OK;
 	}
 
+	if (strstr(packet, "qCRC:"))
+	{
+		if (packet_size > 5)
+		{
+			int retval;
+			u8 gdb_reply[9];
+			char *separator;
+			u32 checksum;
+			u32 addr = 0;
+			u32 len = 0;
+			
+			/* skip command character */
+			packet += 5;
+			
+			addr = strtoul(packet, &separator, 16);
+			
+			if (*separator != ',')
+			{
+				ERROR("incomplete read memory packet received, dropping connection");
+				return ERROR_SERVER_REMOTE_CLOSED;
+			}
+			
+			len = strtoul(separator+1, NULL, 16);
+			
+			retval = target_checksum_memory(target, addr, len, &checksum);
+			
+			if (retval == ERROR_OK)
+			{
+				snprintf(gdb_reply, 9, "C%2.2x", checksum);
+				gdb_put_packet(connection, gdb_reply, 9);
+			}
+			else
+			{
+				if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
+					return retval; 
+			}
+			
+			return ERROR_OK;
+		}
+	}
+	
 	gdb_put_packet(connection, "", 0);
+	return ERROR_OK;
 }
 
 int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
@@ -1382,7 +1424,7 @@ int gdb_input(connection_t *connection)
 					gdb_put_packet(connection, NULL, 0);
 					break;
 				case 'q':
-					gdb_query_packet(connection, packet, packet_size);
+					retval = gdb_query_packet(connection, target, packet, packet_size);
 					break;
 				case 'g':
 					retval = gdb_get_registers_packet(connection, target, packet, packet_size);
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index b5c9752b2..05cc30f4c 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -70,7 +70,8 @@ target_type_t arm720t_target =
 	.read_memory = arm720t_read_memory,
 	.write_memory = arm720t_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 35cbe6e50..e596d0571 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -2147,6 +2147,82 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
 	return ERROR_OK;
 }
 
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+	working_area_t *crc_algorithm;
+	armv4_5_algorithm_t armv4_5_info;
+	reg_param_t reg_params[2];
+	int retval;
+	
+	u32 arm7_9_crc_code[] = {
+		0xE1A02000,				/* mov		r2, r0 */
+		0xE3E00000,				/* mov		r0, #0xffffffff */
+		0xE1A03001,				/* mov		r3, r1 */
+		0xE3A04000,				/* mov		r4, #0 */
+		0xEA00000B,				/* b		ncomp */
+								/* nbyte: */
+		0xE7D21004,				/* ldrb	r1, [r2, r4] */
+		0xE59F7030,				/* ldr		r7, CRC32XOR */
+		0xE0200C01,				/* eor		r0, r0, r1, asl 24 */
+		0xE3A05000,				/* mov		r5, #0 */
+								/* loop: */
+		0xE3500000,				/* cmp		r0, #0 */
+		0xE1A06080,				/* mov		r6, r0, asl #1 */
+		0xE2855001,				/* add		r5, r5, #1 */
+		0xE1A00006,				/* mov		r0, r6 */
+		0xB0260007,				/* eorlt	r0, r6, r7 */
+		0xE3550008,				/* cmp		r5, #8 */
+		0x1AFFFFF8,				/* bne		loop */
+		0xE2844001,				/* add		r4, r4, #1 */
+								/* ncomp: */
+		0xE1540003,				/* cmp		r4, r3 */
+		0x1AFFFFF1,				/* bne		nbyte */
+								/* end: */
+		0xEAFFFFFE,				/* b		end */
+		0x04C11DB7				/* CRC32XOR:	.word 0x04C11DB7 */
+	};
+	
+	int i;
+	
+	if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
+	{
+		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+	}
+	
+	/* convert flash writing code into a buffer in target endianness */
+	for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
+		target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
+	
+	armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+	armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+	armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+	
+	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+	
+	buf_set_u32(reg_params[0].value, 0, 32, address);
+	buf_set_u32(reg_params[1].value, 0, 32, count);
+		
+	if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+		crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
+	{
+		ERROR("error executing arm7_9 crc algorithm");
+		destroy_reg_param(&reg_params[0]);
+		destroy_reg_param(&reg_params[1]);
+		target_free_working_area(target, crc_algorithm);
+		return retval;
+	}
+	
+	*checksum = buf_get_u32(reg_params[0].value, 0, 32);
+	
+	destroy_reg_param(&reg_params[0]);
+	destroy_reg_param(&reg_params[1]);
+	
+	target_free_working_area(target, crc_algorithm);
+	
+	return ERROR_OK;
+}
+
 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
 {
 	command_t *arm7_9_cmd;
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index 53a0ce9f6..9d11dc2a6 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -121,6 +121,7 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod
 int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
 
 int arm7_9_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_prams, reg_param_t *reg_param, u32 entry_point, void *arch_info);
 
diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c
index ae51e3ae4..9a9a24505 100644
--- a/src/target/arm7tdmi.c
+++ b/src/target/arm7tdmi.c
@@ -75,7 +75,8 @@ target_type_t arm7tdmi_target =
 	.read_memory = arm7_9_read_memory,
 	.write_memory = arm7_9_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 	
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index 0dff25062..882fec2fe 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -79,7 +79,8 @@ target_type_t arm920t_target =
 	.read_memory = arm920t_read_memory,
 	.write_memory = arm920t_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 7d8f371be..ef225145c 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -79,7 +79,8 @@ target_type_t arm926ejs_target =
 	.read_memory = arm7_9_read_memory,
 	.write_memory = arm926ejs_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm966e.c b/src/target/arm966e.c
index 53627a5f5..2885e3dfb 100644
--- a/src/target/arm966e.c
+++ b/src/target/arm966e.c
@@ -70,7 +70,8 @@ target_type_t arm966e_target =
 	.read_memory = arm7_9_read_memory,
 	.write_memory = arm7_9_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 	
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c
index b9b1f953f..5bb7e3998 100644
--- a/src/target/arm9tdmi.c
+++ b/src/target/arm9tdmi.c
@@ -73,7 +73,8 @@ target_type_t arm9tdmi_target =
 	.read_memory = arm7_9_read_memory,
 	.write_memory = arm7_9_write_memory,
 	.bulk_write_memory = arm7_9_bulk_write_memory,
-
+	.checksum_memory = arm7_9_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 	
 	.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 7010b5c0f..22ffb5e7d 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -578,3 +578,83 @@ int armv7m_register_commands(struct command_context_s *cmd_ctx)
 {
 	return ERROR_OK;
 }
+
+int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+	working_area_t *crc_algorithm;
+	armv7m_algorithm_t armv7m_info;
+	reg_param_t reg_params[2];
+	int retval;
+	
+	u16 cortex_m3_crc_code[] = {	    
+		0x4602,					/* mov	r2, r0 */
+		0xF04F, 0x30FF,			/* mov	r0, #0xffffffff */
+		0x460B,					/* mov	r3, r1 */
+		0xF04F, 0x0400,			/* mov	r4, #0 */
+		0xE013,					/* b	ncomp */
+								/* nbyte: */
+		0x5D11,					/* ldrb	r1, [r2, r4] */
+		0xF8DF, 0x7028,			/* ldr		r7, CRC32XOR */
+		0xEA80, 0x6001,			/* eor		r0, r0, r1, asl #24 */
+		
+		0xF04F, 0x0500,			/* mov		r5, #0 */
+								/* loop: */
+		0x2800,					/* cmp		r0, #0 */
+		0xEA4F, 0x0640,			/* mov		r6, r0, asl #1 */
+		0xF105, 0x0501,			/* add		r5, r5, #1 */
+		0x4630,					/* mov		r0, r6 */
+		0xBFB8,					/* it		lt */
+		0xEA86, 0x0007,			/* eor		r0, r6, r7 */
+		0x2D08, 				/* cmp		r5, #8 */
+		0xD1F4,					/* bne		loop */
+		
+		0xF104, 0x0401,			/* add	r4, r4, #1 */
+								/* ncomp: */
+		0x429C,					/* cmp	r4, r3 */
+		0xD1E9,					/* bne	nbyte */
+								/* end: */
+		0xE7FE,					/* b	end */
+		0x1DB7, 0x04C1			/* CRC32XOR:	.word 0x04C11DB7 */
+	};
+
+	int i;
+	
+	if (target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm) != ERROR_OK)
+	{
+		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+	}
+	
+	/* convert flash writing code into a buffer in target endianness */
+	for (i = 0; i < (sizeof(cortex_m3_crc_code)/sizeof(u16)); i++)
+		target_write_u16(target, crc_algorithm->address + i*sizeof(u16), cortex_m3_crc_code[i]);
+	
+	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+	armv7m_info.core_mode = ARMV7M_MODE_ANY;
+	armv7m_info.core_state = ARMV7M_STATE_THUMB;
+	
+	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+	
+	buf_set_u32(reg_params[0].value, 0, 32, address);
+	buf_set_u32(reg_params[1].value, 0, 32, count);
+		
+	if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+		crc_algorithm->address, crc_algorithm->address + (sizeof(cortex_m3_crc_code)-6), 20000, &armv7m_info)) != ERROR_OK)
+	{
+		ERROR("error executing cortex_m3 crc algorithm");
+		destroy_reg_param(&reg_params[0]);
+		destroy_reg_param(&reg_params[1]);
+		target_free_working_area(target, crc_algorithm);
+		return retval;
+	}
+	
+	*checksum = buf_get_u32(reg_params[0].value, 0, 32);
+	
+	destroy_reg_param(&reg_params[0]);
+	destroy_reg_param(&reg_params[1]);
+	
+	target_free_working_area(target, crc_algorithm);
+	
+	return ERROR_OK;
+}
+
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 8d06cc654..64689f0b7 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -168,6 +168,8 @@ extern int armv7m_use_context(target_t *target, enum armv7m_runcontext new_ctx);
 extern enum armv7m_runcontext armv7m_get_context(target_t *target);
 extern int armv7m_restore_context(target_t *target);
 
+extern int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
+
 /* Thumb mode instructions
  */
  
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index c47fbbf84..f1513c7a3 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -74,7 +74,8 @@ target_type_t cortexm3_target =
 	.read_memory = cortex_m3_read_memory,
 	.write_memory = cortex_m3_write_memory,
 	.bulk_write_memory = cortex_m3_bulk_write_memory,
-
+	.checksum_memory = armv7m_checksum_memory,
+	
 	.run_algorithm = armv7m_run_algorithm,
 	
 	.add_breakpoint = cortex_m3_add_breakpoint,
diff --git a/src/target/image.c b/src/target/image.c
index dbb1c2ab3..d20f9df27 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -949,3 +949,34 @@ int image_close(image_t *image)
 	
 	return ERROR_OK;
 }
+
+static u32 crc32_table[256] = {0, 0};
+
+int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum)
+{
+	u32 crc = 0xffffffff;
+	
+	if (!crc32_table[1])
+	{
+		/* Initialize the CRC table and the decoding table.  */
+		int i, j;
+		unsigned int c;
+		for (i = 0; i < 256; i++)
+		{
+			/* as per gdb */
+			for (c = i << 24, j = 8; j > 0; --j)
+				c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+			crc32_table[i] = c;
+		}
+	}
+	
+	while (nbytes--)
+	{
+		/* as per gdb */
+		crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
+	}
+	
+	*checksum = crc;
+	return ERROR_OK;
+}
+
diff --git a/src/target/image.h b/src/target/image.h
index e8f585bbc..47f0215f6 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -105,6 +105,8 @@ extern int image_read_section(image_t *image, int section, u32 offset, u32 size,
 extern int image_close(image_t *image);
 extern int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data);
 
+extern int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum);
+
 #define ERROR_IMAGE_FORMAT_ERROR	(-1400)
 #define ERROR_IMAGE_TYPE_UNKNOWN	(-1401)
 #define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE		(-1402)
diff --git a/src/target/target.c b/src/target/target.c
index f471167b3..f9d957d69 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -69,6 +69,7 @@ int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
 int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -752,6 +753,36 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
 	return ERROR_OK;
 }
 
+int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
+{
+	u8 *buffer;
+	int retval;
+	int i;
+	u32 checksum = 0;
+	
+	if ((retval = target->type->checksum_memory(target, address,
+		size, &checksum)) == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+	{
+		buffer = malloc(size);
+		target_read_buffer(target, address, size, buffer);
+
+		/* convert to target endianess */
+		for (i = 0; i < (size/sizeof(u32)); i++)
+		{
+			u32 target_data;
+			target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);
+			target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);
+		}
+
+		retval = image_calculate_checksum( buffer, size, &checksum );
+		free(buffer);
+	}
+	
+	*crc = checksum;
+	
+	return retval;
+}
+
 int target_read_u32(struct target_s *target, u32 address, u32 *value)
 {
 	u8 value_buf[4];
@@ -881,6 +912,7 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
 	
 	register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19']");
 	register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
+	register_command(cmd_ctx,  NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
 	register_command(cmd_ctx,  NULL, "load_binary", handle_load_image_command, COMMAND_EXEC, "[DEPRECATED] load_binary <file> <address>");
 	register_command(cmd_ctx,  NULL, "dump_binary", handle_dump_image_command, COMMAND_EXEC, "[DEPRECATED] dump_binary <file> <address> <size>");
 	
@@ -1802,6 +1834,101 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
 
 }
 
+int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+	u8 *buffer;
+	u32 buf_cnt;
+	u32 image_size;
+	int i;
+	int retval;
+	u32 checksum = 0;
+	u32 mem_checksum = 0;
+
+	image_t image;	
+	
+	duration_t duration;
+	char *duration_text;
+	
+	target_t *target = get_current_target(cmd_ctx);
+	
+	if (argc < 1)
+	{
+		command_print(cmd_ctx, "usage: verify_image <file> [offset] [type]");
+		return ERROR_OK;
+	}
+	
+	if (!target)
+	{
+		ERROR("no target selected");
+		return ERROR_OK;
+	}
+	
+	duration_start_measure(&duration);
+	
+	if (argc >= 2)
+	{
+		image.base_address_set = 1;
+		image.base_address = strtoul(args[1], NULL, 0);
+	}
+	else
+	{
+		image.base_address_set = 0;
+		image.base_address = 0x0;
+	}
+	
+	image.start_address_set = 0;
+
+	if (image_open(&image, args[0], (argc == 3) ? args[2] : NULL) != ERROR_OK)
+	{
+		command_print(cmd_ctx, "verify_image error: %s", image.error_str);
+		return ERROR_OK;
+	}
+	
+	image_size = 0x0;
+	for (i = 0; i < image.num_sections; i++)
+	{
+		buffer = malloc(image.sections[i].size);
+		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
+		{
+			ERROR("image_read_section failed with error code: %i", retval);
+			command_print(cmd_ctx, "image reading failed, verify aborted");
+			free(buffer);
+			image_close(&image);
+			return ERROR_OK;
+		}
+		
+		/* calculate checksum of image */
+		image_calculate_checksum( buffer, buf_cnt, &checksum );
+		free(buffer);
+		
+		retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
+		
+		if( retval != ERROR_OK )
+		{
+			command_print(cmd_ctx, "image verify failed, verify aborted");
+			image_close(&image);
+			return ERROR_OK;
+		}
+		
+		if( checksum != mem_checksum )
+		{
+			command_print(cmd_ctx, "image verify failed, verify aborted");
+			image_close(&image);
+			return ERROR_OK;
+		}
+			
+		image_size += buf_cnt;
+	}
+
+	duration_stop_measure(&duration, &duration_text);
+	command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);
+	free(duration_text);
+	
+	image_close(&image);
+	
+	return ERROR_OK;
+}
+
 int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
 	int retval;
diff --git a/src/target/target.h b/src/target/target.h
index ae5fbc431..1900351eb 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -129,6 +129,8 @@ typedef struct target_type_s
 	/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
 	int (*bulk_write_memory)(struct target_s *target, u32 address, u32 count, u8 *buffer);
 	
+	int (*checksum_memory)(struct target_s *target, u32 address, u32 count, u32* checksum);
+	
 	/* target break-/watchpoint control 
 	* rw: 0 = write, 1 = read, 2 = access
 	*/
@@ -217,6 +219,7 @@ extern target_t* get_target_by_num(int num);
 
 extern int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer);
 extern int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer);
+extern int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc);
 
 extern int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area);
 extern int target_free_working_area(struct target_s *target, working_area_t *area);
diff --git a/src/target/trace.h b/src/target/trace.h
index 0279d51fa..f7d9e5b1a 100644
--- a/src/target/trace.h
+++ b/src/target/trace.h
@@ -21,6 +21,8 @@
 #define TRACE_H
 
 #include "target.h"
+#include "command.h"
+#include "types.h"
 
 typedef struct trace_point_s
 {
@@ -49,6 +51,7 @@ typedef enum trace_status
 } trace_status_t;
 
 extern int trace_point(struct target_s *target, int number);
+extern int trace_register_commands(struct command_context_s *cmd_ctx);
 
 #define ERROR_TRACE_IMAGE_UNAVAILABLE		-(1500)
 #define ERROR_TRACE_INSTRUCTION_UNAVAILABLE	-(1501)
diff --git a/src/target/xscale.c b/src/target/xscale.c
index b207dbb26..baef5fe90 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -74,6 +74,7 @@ int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo
 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
+int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
 
 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
@@ -109,7 +110,8 @@ target_type_t xscale_target =
 	.read_memory = xscale_read_memory,
 	.write_memory = xscale_write_memory,
 	.bulk_write_memory = xscale_bulk_write_memory,
-
+	.checksum_memory = xscale_checksum_memory,
+	
 	.run_algorithm = armv4_5_run_algorithm,
 	
 	.add_breakpoint = xscale_add_breakpoint,
@@ -2035,6 +2037,11 @@ int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
 	return ERROR_OK;
 }
 
+int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+	return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+}
+
 u32 xscale_get_ttb(target_t *target)
 {
 	armv4_5_common_t *armv4_5 = target->arch_info;