/* * writereg.c * * * Copyright (C) 2010 - Maxim Levitsky * * is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ #define _LARGEFILE64_SOURCE #include #include #include #include #include #include #include #define PAGE_SIZE 4096 int usage() { printf("Usage (as root): writemem address[.width] value\n"); exit(-1); } int get_mem_fd() { int fd = open ("/dev/mem", O_RDWR); if( fd == -1) { perror("open"); printf("are you root?\n"); exit(-1); } return fd; } int main (int argc, char** argv) { /* Test input arg count */ if (argc != 3 ) usage(); int fd = get_mem_fd(); char *ptr; /* Read the register we need to modify */ off64_t offset = (off64_t)strtoull (argv[1], &ptr, 0); int width = 32; if(*ptr == '.') { ptr++; switch(*ptr) { case 'B': case 'b': width = 8; ptr++; break; case 'W': case 'w': width = 16; ptr++; break; case 'D': case 'd': width = 32; ptr++; break; } } /* read the value */ uint32_t value = strtoull (argv[2], &ptr, 0); off64_t page_offset = offset & ~(PAGE_SIZE -1); int byte_offset = offset - page_offset; unsigned char* mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, page_offset); if (mem == 0) abort(); mem+=byte_offset; printf("writing %lx to 0x%lx (current value = %lx)\n", (long unsigned int)value, (long unsigned int)offset, (long unsigned int)*(uint32_t*)(mem)); switch (width) { case 32: *(uint32_t*)(mem) = value; break; case 16: *(uint16_t*)(mem) = value; break; case 8: *(uint8_t*)(mem) = value; break; } return 0; }