For those who (like me) didn't realize it existed, I found a handy way to probe random memory addresses from userspace: /dev/mem.
This lets you directly read kernel and/or device memory! very useful.
A program to access it is here (not written by me):
http://ftp://ftp.buici.com/pub/arm/devmem/devmem2.cI should mention that i modified the original program to pad the output to the size of the request, or else it leaves off/truncates leading 0's. patch is here:
--- devmem2.c.orig 2009-04-17 22:20:05.226440750 -0700
+++ devmem2.c 2009-04-17 22:09:21.483230909 -0700
@@ -90,18 +90,20 @@
switch(access_type) {
case 'b':
read_result = *((unsigned char *) virt_addr);
+ printf("Value at address 0x%X (%p): 0x%02X\n", target, virt_addr, read_result, read_result);
break;
case 'h':
read_result = *((unsigned short *) virt_addr);
+ printf("Value at address 0x%X (%p): 0x%04X\n", target, virt_addr, read_result, read_result);
break;
case 'w':
read_result = *((unsigned long *) virt_addr);
+ printf("Value at address 0x%X (%p): 0x%08X\n", target, virt_addr, read_result, read_result);
break;
default:
fprintf(stderr, "Illegal data type '%c'.\n", access_type);
exit(2);
}
- printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result);
fflush(stdout);
if(argc > 3) {
To build, i used the GCC included in the linux host package.
gcc/bin/arm-none-linux-gnueabi-gcc devmem2.c -o devmem2
scp devmem2 user@sheevaplug:
For example, say you want to figure out how the GPIO pins are programmed.
For the HW offsets, we consult the marvell docs MV-S104860-U0 (p773) and MV-S104859-U0 (page 53).
I am interested in the GPIO pins, 12-17, as these are shared with the SDIO. I am willing to break the SD card access if i can use those pins for GPIO.
Consulting page 774, i see that the memory offset for the register function controls is 0x10000. Based on the mmc module init message (mvsdmmc: irq =28 start f1090000) , i know that the base is 0xf1000000.
So let's query 0xf1010000 through 0xf1010008, to see how the pins are currently programmed:
root@charger:~# ./devmem2 0xf1010000 w
/dev/mem opened.
Memory mapped at address 0x4001f000.
Value at address 0xF1010000 (0x4001f000): 0x01111111
root@charger:~# ./devmem2 0xf1010004 w
/dev/mem opened.
Memory mapped at address 0x4001f000.
Value at address 0xF1010004 (0x4001f004): 0x11113322
root@charger:~# ./devmem2 0xf1010008 w
/dev/mem opened.
Memory mapped at address 0x4001f000.
Value at address 0xF1010008 (0x4001f008): 0x00001111
The right-most bits represent the lower #'d pins. So GPP pins are set as follows:
Value at address 0xF1010000: 0x01111111
0-6 are all set to 1
7 is set to 0
Value at address 0xF1010004: 0x11113322
8,9 are set to 2
10,11 are set to 3
12-15 are set to 1
Value at address 0xF1010008: 0x00001111
16-19 are set to 1
20-23 are set to 0
I'm interested in 12-17. All are set to '1'. Checking page 53 of the Hardware spec, i see that this indicates they are currently set as SDIO pins. This jives with what i expect. As a sanity check, 8,9 are 2, and 10,11 are 3. These group together to form 4 pins for serial port UA0. Bingo!
I have not tried using /dev/mem to make changes to the settings, but i plan to soon. Stay tuned.
-tmk