Messages in this thread | | | Date | Mon, 11 Jan 1999 18:09:21 -0800 (PST) | From | Terence Murphy <> | Subject | MMAP /dev/mem INITRD? |
| |
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/
| |