Question regarding physical memory access

I am trying to read the manufacturer’s signature off of a EISA card
located in slot # 2 at 0x2C00. According to the EISA standard, the
signature should be found at xC80 to xC83 where x is the slot number. I
followed the example in the shmopen() help file, and was able to read
the BIOS (or at least I got something back). When I modify it to read
from the card in the slot, I get nothing back (ie 0).

I have included the code. Any thoughts would be appreciated.

#include <stdio.h> /* standard I/O functions */
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <fcntl.h> /* file access functions /
#include <sys/mman.h> /
memory managment functions */

off_t portaddr; /* raw I/O port address /
off_t pageaddr; /
port address - page component /
off_t offsetaddr; /
port address - offset component */

int filedesc; /* file descriptor for memory block /
long buffersize; /
size of memory location in bytes */
char bufferaddr; / address of memory buffer in process space /
char buffer; /
contents of memory buffer */

off_t bufferptr; /* pointer in buffer to material of interest /
long readlen; /
number of bytes to read */

main(int argc, char argv[])
{
long x; /
Loop counter */

portaddr = 0x2c00; /* set port address and parse /
offsetaddr = portaddr % PAGESIZE; /
extract offset address /
pageaddr = portaddr - offsetaddr; /
extract page address /
buffersize = offsetaddr + 0xff; /
set memory buffer size */

fprintf(stderr, "page address = %6.6X, ", pageaddr);
fprintf(stderr, "offset address = %6.6X, ", offsetaddr);
fprintf(stderr, “buffer size = %6.6X\n”, buffersize);

/* open physical memory block for read /
filedesc = shm_open(“Physical”, O_RDONLY, 0777);
if (filedesc == -1)
{
fprintf(stderr, “Open failed:%s\n”, strerror(errno));
exit(1);
}
/
map memory block into current process /
bufferaddr = mmap(0, buffersize, PROT_READ|PROT_WRITE, MAP_SHARED,
filedesc, pageaddr);
if (bufferaddr == (void
) -1)
{
fprintf(stderr, “mmap failed : %s\n”, strerror(errno));
exit(1);
}

printf(“Buffer address in current process space is %6.6X\n”,
bufferaddr);

for (x = 0; x < buffersize; ++x) /* Read single chars from buffer */
{
buffer = bufferaddr++; / read single char from buffer */
fprintf(stderr, “char = %6.6X\n”, buffer);
}

exit(0);
}

If you are using QNX6 you should look into mmap_device_io().

chris


Douglas Reed <dreed@guise.com> wrote:

[-- text/plain, encoding 7bit, 72 lines --]

I am trying to read the manufacturer’s signature off of a EISA card
located in slot # 2 at 0x2C00. According to the EISA standard, the
signature should be found at xC80 to xC83 where x is the slot number. I
followed the example in the shmopen() help file, and was able to read
the BIOS (or at least I got something back). When I modify it to read
from the card in the slot, I get nothing back (ie 0).

I have included the code. Any thoughts would be appreciated.

#include <stdio.h> /* standard I/O functions */
#include <stdlib.h
#include <errno.h
#include <string.h
#include <unistd.h

#include <fcntl.h> /* file access functions /
#include <sys/mman.h> /
memory managment functions */

off_t portaddr; /* raw I/O port address /
off_t pageaddr; /
port address - page component /
off_t offsetaddr; /
port address - offset component */

int filedesc; /* file descriptor for memory block /
long buffersize; /
size of memory location in bytes */
char bufferaddr; / address of memory buffer in process space /
char buffer; /
contents of memory buffer */

off_t bufferptr; /* pointer in buffer to material of interest /
long readlen; /
number of bytes to read */

main(int argc, char argv[])
{
long x; /
Loop counter */

portaddr = 0x2c00; /* set port address and parse /
offsetaddr = portaddr % PAGESIZE; /
extract offset address /
pageaddr = portaddr - offsetaddr; /
extract page address /
buffersize = offsetaddr + 0xff; /
set memory buffer size */

fprintf(stderr, "page address = %6.6X, ", pageaddr);
fprintf(stderr, "offset address = %6.6X, ", offsetaddr);
fprintf(stderr, “buffer size = %6.6X\n”, buffersize);

/* open physical memory block for read /
filedesc = shm_open(“Physical”, O_RDONLY, 0777);
if (filedesc == -1)
{
fprintf(stderr, “Open failed:%s\n”, strerror(errno));
exit(1);
}
/
map memory block into current process /
bufferaddr = mmap(0, buffersize, PROT_READ|PROT_WRITE, MAP_SHARED,
filedesc, pageaddr);
if (bufferaddr == (void
) -1)
{
fprintf(stderr, “mmap failed : %s\n”, strerror(errno));
exit(1);
}

printf(“Buffer address in current process space is %6.6X\n”,
bufferaddr);

for (x = 0; x < buffersize; ++x) /* Read single chars from buffer */
{
buffer = bufferaddr++; / read single char from buffer */
fprintf(stderr, “char = %6.6X\n”, buffer);
}

exit(0);
}

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

“Douglas Reed” <dreed@guise.com> wrote in message news:3BC64E97.F71C7FF9@guise.com
I am trying to read the manufacturer’s signature off of a EISA card located in slot # 2 at 0x2C00. According to the EISA standard, the signature should be found at xC80 to xC83 where x is the slot number. I followed the example in the shmopen() help file, and was able to read the BIOS (or at least I got something back). When I modify it to read from the card in the slot, I get nothing back (ie 0).

I don’t know about EISA, but I assume it’s the same as basicaly the same as ISA with 32 bits access. 0x2c00 looks like an odd address to me. Are you sure these address are not IO address instead?
I have included the code. Any thoughts would be appreciated.

#include <stdio.h> /* standard I/O functions */
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <fcntl.h> /* file access functions /
#include <sys/mman.h> /
memory managment functions */

off_t portaddr; /* raw I/O port address /
off_t pageaddr; /
port address - page component /
off_t offsetaddr; /
port address - offset component */

int filedesc; /* file descriptor for memory block /
long buffersize; /
size of memory location in bytes */
char bufferaddr; / address of memory buffer in process space /
char buffer; /
contents of memory buffer */

off_t bufferptr; /* pointer in buffer to material of interest /
long readlen; /
number of bytes to read */

main(int argc, char argv[])
{
long x; /
Loop counter */

portaddr = 0x2c00; /* set port address and parse /
offsetaddr = portaddr % PAGESIZE; /
extract offset address /
pageaddr = portaddr - offsetaddr; /
extract page address /
buffersize = offsetaddr + 0xff; /
set memory buffer size */

fprintf(stderr, "page address = %6.6X, ", pageaddr);
fprintf(stderr, "offset address = %6.6X, ", offsetaddr);
fprintf(stderr, “buffer size = %6.6X\n”, buffersize);

/* open physical memory block for read /
filedesc = shm_open(“Physical”, O_RDONLY, 0777);
if (filedesc == -1)
{
fprintf(stderr, “Open failed:%s\n”, strerror(errno));
exit(1);
}
/
map memory block into current process /
bufferaddr = mmap(0, buffersize, PROT_READ|PROT_WRITE, MAP_SHARED,
filedesc, pageaddr);
if (bufferaddr == (void
) -1)
{
fprintf(stderr, “mmap failed : %s\n”, strerror(errno));
exit(1);
}

printf(“Buffer address in current process space is %6.6X\n”, bufferaddr);

for (x = 0; x < buffersize; ++x) /* Read single chars from buffer */
{
buffer = bufferaddr++; / read single char from buffer */
fprintf(stderr, “char = %6.6X\n”, buffer);
}

exit(0);
}

Having reread the DDK code for the card, and the installation manual,
the card seems, in fact, to be an ISA card on a EISA chassis. There are
very few true EISA cards in existence (according to the books on the
subject). So the address is in the ISA range at 2C0, not 2C00. 2C00 is a
legitimate EISA address for the second card slot (again according to the
standard docs). I have modified the code below to allow a read of any
range of addresses, and it works. But even the 2C0 range is empty.

I have called the manufacturer to see if zeroed card registers is a
normal power-on behaviour, and if there is a diagnostic trigger on the
card.

Mario Charest wrote:

“Douglas Reed” <> dreed@guise.com> > wrote in message
news:3BC64E97.F71C7FF9@guise.com…I am trying to read the
manufacturer’s signature off of a EISA card located in slot

2 at 0x2C00. According to the EISA standard, the signature

should be found at xC80 to xC83 where x is the slot number.
I followed the example in the shmopen() help file, and was
able to read the BIOS (or at least I got something back).
When I modify it to read from the card in the slot, I get
nothing back (ie 0). I don’t know about EISA, but I assume
it’s the same as basicaly the same as ISA with 32 bits
access. 0x2c00 looks like an odd address to me. Are you
sure these address are not IO address instead?I have
included the code. Any thoughts would be appreciated.

#include <stdio.h> /* standard I/O functions */
#include <stdlib.h
#include <errno.h
#include <string.h
#include <unistd.h

#include <fcntl.h> /* file access functions /
#include <sys/mman.h> /
memory managment functions */

off_t portaddr; /* raw I/O port address /
off_t pageaddr; /
port address - page component /
off_t offsetaddr; /
port address - offset component */

int filedesc; /* file descriptor for memory block /
long buffersize; /
size of memory location in bytes */
char bufferaddr; / address of memory buffer in process
space /
char buffer; /
contents of memory buffer */

off_t bufferptr; /* pointer in buffer to material of
interest /
long readlen; /
number of bytes to read */

main(int argc, char argv[])
{
long x; /
Loop counter */

portaddr = 0x2c00; /* set port address and parse /
offsetaddr = portaddr % PAGESIZE; /
extract offset address
/
pageaddr = portaddr - offsetaddr; /
extract page address
/
buffersize = offsetaddr + 0xff; /
set memory buffer size
*/

fprintf(stderr, "page address = %6.6X, ", pageaddr);
fprintf(stderr, "offset address = %6.6X, ", offsetaddr);
fprintf(stderr, “buffer size = %6.6X\n”, buffersize);

/* open physical memory block for read /
filedesc = shm_open(“Physical”, O_RDONLY, 0777);
if (filedesc == -1)
{
fprintf(stderr, “Open failed:%s\n”, strerror(errno));
exit(1);
}
/
map memory block into current process /
bufferaddr = mmap(0, buffersize, PROT_READ|PROT_WRITE,
MAP_SHARED,
filedesc, pageaddr);
if (bufferaddr == (void
) -1)
{
fprintf(stderr, “mmap failed : %s\n”, strerror(errno));
exit(1);
}

printf(“Buffer address in current process space is
%6.6X\n”, bufferaddr);

for (x = 0; x < buffersize; ++x) /* Read single chars from
buffer */
{
buffer = bufferaddr++; / read single char from buffer
*/
fprintf(stderr, “char = %6.6X\n”, buffer);
}

exit(0);
}

“Douglas Reed” <dreed@guise.com> wrote in message news:3BC75143.6693C3AF@guise.com
Having reread the DDK code for the card, and the installation manual, the card seems, in fact, to be an ISA card on a EISA chassis. There are very few true EISA cards in existence (according to the books on the subject). So the address is in the ISA range at 2C0, not 2C00. 2C00 is a legitimate EISA address for the second card slot (again according to the standard docs). I have modified the code below to allow a read of any range of addresses, and it works. But even the 2C0 range is empty.

0x2C0 is definitely in IO space and not in address space. You need to use in*() and out8() instruction to access the IO space.
I have called the manufacturer to see if zeroed card registers is a normal power-on behaviour, and if there is a diagnostic trigger on the card.

Mario Charest wrote:


“Douglas Reed” <dreed@guise.com> wrote in message news:3BC64E97.F71C7FF9@guise.com…I am trying to read the manufacturer’s signature off of a EISA card located in slot # 2 at 0x2C00. According to the EISA standard, the signature should be found at xC80 to xC83 where x is the slot number. I followed the example in the shmopen() help file, and was able to read the BIOS (or at least I got something back). When I modify it to read from the card in the slot, I get nothing back (ie 0). I don’t know about EISA, but I assume it’s the same as basicaly the same as ISA with 32 bits access. 0x2c00 looks like an odd address to me. Are you sure these address are not IO address instead?I have included the code. Any thoughts would be appreciated.
#include <stdio.h> /* standard I/O functions */
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <fcntl.h> /* file access functions /
#include <sys/mman.h> /
memory managment functions */

off_t portaddr; /* raw I/O port address /
off_t pageaddr; /
port address - page component /
off_t offsetaddr; /
port address - offset component */

int filedesc; /* file descriptor for memory block /
long buffersize; /
size of memory location in bytes */
char bufferaddr; / address of memory buffer in process space /
char buffer; /
contents of memory buffer */

off_t bufferptr; /* pointer in buffer to material of interest /
long readlen; /
number of bytes to read */

main(int argc, char argv[])
{
long x; /
Loop counter */

portaddr = 0x2c00; /* set port address and parse /
offsetaddr = portaddr % PAGESIZE; /
extract offset address /
pageaddr = portaddr - offsetaddr; /
extract page address /
buffersize = offsetaddr + 0xff; /
set memory buffer size */

fprintf(stderr, "page address = %6.6X, ", pageaddr);
fprintf(stderr, "offset address = %6.6X, ", offsetaddr);
fprintf(stderr, “buffer size = %6.6X\n”, buffersize);

/* open physical memory block for read /
filedesc = shm_open(“Physical”, O_RDONLY, 0777);
if (filedesc == -1)
{
fprintf(stderr, “Open failed:%s\n”, strerror(errno));
exit(1);
}
/
map memory block into current process /
bufferaddr = mmap(0, buffersize, PROT_READ|PROT_WRITE, MAP_SHARED,
filedesc, pageaddr);
if (bufferaddr == (void
) -1)
{
fprintf(stderr, “mmap failed : %s\n”, strerror(errno));
exit(1);
}

printf(“Buffer address in current process space is %6.6X\n”, bufferaddr);

for (x = 0; x < buffersize; ++x) /* Read single chars from buffer */
{
buffer = bufferaddr++; / read single char from buffer */
fprintf(stderr, “char = %6.6X\n”, buffer);
}

exit(0);
}