Skip to content

Instantly share code, notes, and snippets.

@mike0
Created June 11, 2012 13:48
Show Gist options
  • Save mike0/2910170 to your computer and use it in GitHub Desktop.
Save mike0/2910170 to your computer and use it in GitHub Desktop.
memtool
/*
* Copyright 2006 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h> /* strcmp() */
#include <stdlib.h> /* strtoul() */
#include <unistd.h> /* close() */
int g_size = 4;
unsigned long int g_paddr;
int g_is_write;
uint32_t g_value = 0;
uint32_t g_count = 1;
int parse_cmdline(int argc, char ** argv)
{
int cur_arg = 0;
char * str;
if (argc < 2)
return -1;
cur_arg++;
if (strcmp(argv[cur_arg], "-8") == 0) {
cur_arg++;
g_size = 1;
}
else if (strcmp(argv[cur_arg], "-16") == 0) {
cur_arg++;
g_size = 2;
}
else if (strcmp(argv[cur_arg], "-32") == 0) {
cur_arg++;
g_size = 4;
}
if (cur_arg >= argc)
return -1;
g_paddr = strtoul(argv[cur_arg], NULL, 16);
if (!g_paddr)
return -1;
if ( ( str = strchr(argv[cur_arg], '=') ) ) {
g_is_write = 1;
if (strlen(str) > 1) {
str++;
g_value = strtoul(str, NULL, 16);
return 0;
}
}
if (++cur_arg >= argc)
return -1;
if ((argv[cur_arg])[0] == '=' ) {
g_is_write = 1;
if (strlen(argv[cur_arg]) > 1) {
(argv[cur_arg])++;
} else {
if (++cur_arg >= argc)
return -1;
}
g_value = strtoul(argv[cur_arg], NULL, 16);
}
else {
if (g_is_write)
g_value = strtoul(argv[cur_arg], NULL, 16);
else
g_count = strtoul(argv[cur_arg], NULL, 16);
}
return 0;
}
void read_mem(void * addr, uint32_t count, uint32_t size)
{
int i;
uint8_t * addr8 = addr;
uint16_t * addr16 = addr;
uint32_t * addr32 = addr;
switch (size)
{
case 1:
for (i = 0; i < count; i++) {
if ( (i % 16) == 0 )
printf("\n0x%08X: ", (uint)g_paddr);
printf(" %02X", addr8[i]);
g_paddr++;
}
break;
case 2:
for (i = 0; i < count; i++) {
if ( (i % 8) == 0 )
printf("\n0x%08X: ", (uint)g_paddr);
printf(" %04X", addr16[i]);
g_paddr += 2;
}
break;
case 4:
for (i = 0; i < count; i++) {
if ( (i % 4) == 0 )
printf("\n0x%08X: ", (uint)g_paddr);
printf(" %08X", addr32[i]);
g_paddr += 4;
}
break;
}
printf("\n\n");
}
void write_mem(void * addr, uint32_t value, uint32_t size)
{
uint8_t * addr8 = addr;
uint16_t * addr16 = addr;
uint32_t * addr32 = addr;
switch (size)
{
case 1:
*addr8 = value;
break;
case 2:
*addr16 = value;
break;
case 4:
*addr32 = value;
break;
}
}
int main(int argc, char **argv)
{
int fd;
void * mem;
void * aligned_vaddr;
unsigned long aligned_paddr;
uint32_t aligned_size;
if (parse_cmdline(argc, argv)) {
printf("Usage:\n\n" \
"Read memory: memtool [-8 | -16 | -32] <phys addr> <count>\n" \
"Write memory: memtool [-8 | -16 | -32] <phys addr>=<value>\n\n" \
"Default access size is 32-bit.\n\nAddress, count and value are all in hex.\n");
return 1;
}
/* Align address to access size */
g_paddr &= ~(g_size - 1);
aligned_paddr = g_paddr & ~(4096 - 1);
aligned_size = g_paddr - aligned_paddr + (g_count * g_size);
aligned_size = (aligned_size + 4096 - 1) & ~(4096 - 1);
if (g_is_write)
printf("Writing %d-bit value 0x%X to address 0x%08X\n",
g_size*8, g_value, (uint)g_paddr);
else
printf("Reading 0x%X count starting at address 0x%08X\n",
g_count, (uint)g_paddr);
if ((fd = open("/dev/mem", O_RDWR, 0)) < 0) {
printf("Open /dev/mem error, maybe check permission.\n");
return 1;
}
aligned_vaddr = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, aligned_paddr);
if (aligned_vaddr == NULL) {
printf("Error mapping address\n");
close(fd);
return 1;
}
mem = (void *)((uint32_t)aligned_vaddr + (g_paddr - aligned_paddr));
if (g_is_write) {
write_mem(mem, g_value, g_size);
}
else {
read_mem(mem, g_count, g_size);
}
munmap(aligned_vaddr, aligned_size);
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment