Hw Hacking Src


Squidge

Certified Guru
Joined
Nov 16, 2003
Messages
8,493
Location
UK
Website
Visit site
One of the first programs I wrote for gp2x linux was a hardware hacker. It may be useful to others, so here's the code. It allows you to play with all the hardware registers. I used it to find out how to work the lcd registers.

Code:
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>

extern int errno;
unsigned long *screendw;
unsigned long *fb0;
unsigned long *fb1;

int Gfxfd;

#define GPIOA 0xC0001180
#define GPIOB 0xC0001182
#define GPIOC 0xC0001184
#define GPIOD 0xC0001186
#define GPIOE 0xC0001188
#define GPIOF 0xC000118A
#define GPIOG 0xC000118C
#define GPIOH 0xC000118E
#define GPIOI 0xC0001190
#define GPIOJ 0xC0001192
#define GPIOK 0xC0001194
#define GPIOL 0xC0001196
#define GPIOM 0xC0001198
#define GPION 0xC000119A
#define GPIOO 0xC000119C

void *trymmap (void *start, size_t length, int prot, int flags, int fd, off_t offset)
{
	char *p;
	int aa;

	printf ("mmap(%X, %X, %X, %X, %X, %X) ... ", (unsigned int)start, length, prot, flags, fd, (unsigned int)offset);
	p = mmap (start, length, prot, flags, fd, offset);
	if (p == (char *)0xFFFFFFFF)
	{
  aa = errno;
  printf ("failed. errno = %d\n", aa);
	}
	else
	{
  printf ("OK! (%X)\n", (unsigned int)p);
	}

	return p;
}

unsigned short ReadGfx(unsigned short addr)
{
	if ((addr % 4) == 0)
	{
  return (screendw[addr >> 2] & 0xFFFF);
	}
	else if ((addr % 2) == 0)
	{
  return (screendw[addr >> 2] >> 16);
	}
	else
	{
  printf ("Unaligned read from memory -> C000%X", addr);
  return 0;
	}
}

void WriteGfx (unsigned short addr, unsigned short data)
{
	if ((addr % 4) == 0)
	{
  screendw[addr >> 2] &= 0xFFFF0000;
  screendw[addr >> 2] |= data;
	}
	else if ((addr % 2) == 0)
	{	
  screendw[addr >> 2] &= 0xFFFF;
  screendw[addr >> 2] |= (data << 16);
	}
	else
	{
  printf ("Unaligned write to memory -> C000%X with data %X", addr, data);
	}
}

unsigned char InitGfx (void)
{
	Gfxfd = open("/dev/mem", O_RDWR);
	if (Gfxfd == -1)
	{
  printf ("Open failed\n");
  return 0;
	}

	printf ("/dev/mem opened successfully - fd = %d\n", Gfxfd);

	screendw = trymmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, Gfxfd, 0xc0000000);
	if (screendw == (unsigned long *)0xFFFFFFFF) return 0;

	return 1;
}

void CloseGfx (void)
{
	close (Gfxfd);
}

int main(void)
{
	int p,q,r = 0;
	int haddr = 0xC0000000;
	unsigned int *mallocaddr = (unsigned int *)malloc ((320*240)*4);
	int fb0fd, fb1fd;
	struct fb_fix_screeninfo fb0_fixed, fb1_fixed;
	struct fb_var_screeninfo fb0_var, fb1_var;

	if (!InitGfx()) return 0;

	printf ("mallocaddr is at %X\n\n", (unsigned int)mallocaddr);

	fb0fd = open ("/dev/fb/0", O_RDWR);
	if (!fb0fd)
	{
  printf ("/dev/fb/0 open fail\n");
  return 0;
	}	

	fb1fd = open ("/dev/fb/1", O_RDWR);
	if (!fb0fd)
	{
  printf ("/dev/fb/1 open fail\n");
  return 0;
	}	

	if (ioctl(fb0fd, FBIOGET_FSCREENINFO, &fb0_fixed) == -1)
	{
  printf ("fb0fd fixed ioctl failed\n");
  return 0;
	}	

	if (ioctl(fb0fd, FBIOGET_VSCREENINFO, &fb0_var) == -1)
	{
  printf ("fb0fd var ioctl failed\n");
  return 0;
	}

	if (ioctl(fb1fd, FBIOGET_FSCREENINFO, &fb1_fixed) == -1)
	{
  printf ("fb1fd fixed ioctl failed\n");
  return 0;
	}	

	if (ioctl(fb1fd, FBIOGET_VSCREENINFO, &fb1_var) == -1)
	{
  printf ("fb1fd var ioctl failed\n");
  return 0;
	}

	printf ("FB0 Fixed\n---------\n\n ID: %s\n MemStart: 0x%X\n MemLength: 0x%X\n LineLength: %d\n MMIO: %X\n MMIOLen: %X\n Accel: %X\n\n",
  	fb0_fixed.id, fb0_fixed.smem_start, fb0_fixed.smem_len, fb0_fixed.line_length, fb0_fixed.mmio_start, 
  	fb0_fixed.mmio_len, fb0_fixed.accel);

	printf ("FB0 Variable\n------------\n\n X Res: %d\n Y Res: %d\n BPP: %d\n AccelFlags: %X\n vmode: %X\n\n",
  	fb0_var.xres, fb0_var.yres, fb0_var.bits_per_pixel, fb0_var.accel_flags, fb0_var.vmode);

	printf ("FB1 Fixed\n---------\n\n ID: %s\n MemStart: 0x%X\n MemLength: 0x%X\n LineLength: %d\n MMIO: %X\n MMIOLen: %X\n Accel: %X\n\n",
  	fb1_fixed.id, fb1_fixed.smem_start, fb1_fixed.smem_len, fb1_fixed.line_length, fb1_fixed.mmio_start, 
  	fb1_fixed.mmio_len, fb1_fixed.accel);

	printf ("FB1 Variable\n------------\n\n X Res: %d\n Y Res: %d\n BPP: %d\n AccelFlags: %X\n vmode: %X\n\n",
  	fb1_var.xres, fb1_var.yres, fb1_var.bits_per_pixel, fb1_var.accel_flags, fb1_var.vmode);

	fb0 = trymmap(0, fb0_fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, Gfxfd, fb0_fixed.smem_start);
	fb1 = trymmap(0, fb1_fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, Gfxfd, fb1_fixed.smem_start);

	for (;;)
	{
  unsigned long qq;
  printf ("Enter address: (-1=same as before, -2=gfx mem select, -3=fb0, -4=blank fb0, -5=0x55 fb0, -6=set fb0)\n: 0x%X+",haddr); scanf ("%X", &p);

  switch (p)
  {
  	case -2:
    haddr = 0xC0000000; break;
  	case -3:
    haddr = fb0; break;
  	case -4:
    memset (fb0, 0x00, fb0_fixed.smem_len); break;
  	case -5:
    memset (fb0, 0x55, fb0_fixed.smem_len); break;
  	case -6:
    printf ("Enter value: "); scanf ("%X", &qq);
    for (q = 0; q < fb0_fixed.smem_len/4; q ++)
    	fb0[q] = qq;
    break; 
  	default:
    if (p == -1) p = r;
    r = p;
    if (haddr == 0xC0000000)
    {
    	printf ("\nAddress: 0x%X - Current value is 0x%X\n", haddr + p, ReadGfx(p));
    	printf ("Enter new value: 0x"); scanf ("%X", &q);
    	printf ("Address: %X - old value - %X - requested value - %X - new actual value - ", haddr + p, ReadGfx(p), q);
    	WriteGfx (p, q);
    	printf ("%X\n\n", ReadGfx(p));
    }
    else
    {
    	printf ("\nAddress: 0x%X - Current value is 0x%X\n", haddr + p, fb0[p]);
    	printf ("Enter new value: 0x"); scanf ("%X", &q);
    	printf ("Address: %X - old value - %X - requested value - %X - new actual value - ", haddr + p, fb0[p], q);
    	fb0[p] = q;
    	printf ("%X\n\n", fb0[p]);
    }
    break;
  }
	
	}
	CloseGfx();
	printf("test complete\n");
	return 0;
}
 
Back
Top