MMAP /dev/mem INITRD?

Terence Murphy (tsmurphy@ichips.intel.com)
Mon, 11 Jan 1999 18:09:21 -0800 (PST)


Am I correct in assuming that if I mmap() /dev/mem, I will be returned
a virtual addresses which points to the physical address which was the
offset in mmap()?

I try to mmap() a page into a physical address (0x100000). In one run, I
get a virtual address back 0x8060000 (which sounds fine), which translates
into physical address 0x3fe3000 (i.e. not the one I asked for). When I
dereference the pointer to write to it, the value never gets into 0x100000.

The system is set up in the following manner:

o Machine has 64 MB physical ram (and no swap device)
o There is an 32 MB init ram disk (initrd) placed at phyical address
0x2000000 (so 0x2000000 - 0x3ffffff physical space is reserved for the
ram disk...I hope) This is the root device and only FS
o Presumably 0x0000000 - 0x1ffffff is used for system physical memory

What's curious about this, of course (aside from getting the wrong
physical address), is that the address I do get back (physical address:
0x3fe3000) is in the region of the initrd ram disk.

Since the file /dev/mem is on this RAM disk, it almost makes sense, but to
double check, the file is a device file and not a regular file:

[svlinux1.intel.com]-> bias_00000001 22> ls -l /mnt/ram/dev/mem
0 crw-r----- 1 root kmem 1, 1 May 5 1998 /mnt/ram/dev/mem

Any clues on this one? I am using a fairly unusual kernel (2.1.126 + lots
of hacks, and with almost no hardware support compiled in). None of our
kernel changes affect mmap stuff (just initialization and scheduler).

The method of translating the virtual address to physical address is an
internal product. I would like to find a second way to do this to verify
that this is correct. Any suggestions?

My code for the program is below:

#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define PAGE_SIZE 4096

#define BEEF_BASE 0x100000
#define BEEF_SIZE 4096

main()
{
void *beef_mem;
unsigned int mem_fd;

if ((mem_fd = open("/dev/mem", O_RDWR)) < 0)
{
printf("can't open /dev/mem\n");
exit(-1);
}

if ((beef_mem = malloc(BEEF_SIZE + (PAGE_SIZE - 1))) == NULL)
{
printf("allocation error\n");
exit(-1);
}

if ((unsigned long) beef_mem % PAGE_SIZE)
{
beef_mem += PAGE_SIZE - ((unsigned long)beef_mem % PAGE_SIZE);
}

beef_mem = (unsigned char *)mmap(
(caddr_t)beef_mem,
BEEF_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED,
mem_fd,
BEEF_BASE);

if ((long)beef_mem < 0)
{
printf("mmap error\n");
printf("%s\n", strerror(errno));
exit(-1);
}

while (1)
{

*((unsigned int *)beef_mem) = 0xdeadbeef;
}
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/