Date: Wed, 25 Sep 96 11:28:39 MDT From: johnson@charming.nrtc.northrop.com To: questions@freebsd.org Subject: Question regarding mmap <--> procfs Message-ID: <9609251828.AA09743@charming.nrtc.northrop.com>
next in thread | raw e-mail | index | archive | help
Hello all, My impression is that it is possible in FreeBSD to manipulate the virtual memory system from outside the kernel. As an exercise to see if I understand manipulation of virtual memory outside the kernel, I am trying to do the following: Execute a program, and have that program manipulate its own virtual memory mapping, so that two 4096-byte pages get swapped. (The idea would be to have a page-aligned 8192-byte array, and initialize it (as a 2048-int array) with the values 0, 1, 2, .. 2047. Then, swap the two virtual pages. Finally loop over the array printing out the values, and have it start out 1024, 1025, .. This would demonstate that the two pages had indeed been swapped.) The way I thought I could do this was to use the mmap function in conjunction with the procfs file /proc/curproc/mem. However, at the moment I can't get this to work. First question: Is what I am trying to do supposed to be possible? (If I understand mmap and /proc/curproc/mem, it should be possible in principle.) Second question: Is there some other means of manipulating virtual memory outside the kernel that I should be using instead of mmap and /proc/curproc/mem? Third question: Why does the program below fail?? ;-) Am I doing something obviously wrong in the following program? I am having some fun playing with mmap. It seems to work well, and is really an interesting concept. However, one thing that I cannot get to work is using mmap in conjunction with /proc/curproc/mem. Here's how I thought I could swap two virtual pages: (let's call the two pages to be swapped A and B): 1) malloc a fairly large chunk of memory, so that I have something to play with 2) open /proc/curproc/mem in order to get a file descriptor that can be used with mmap to manipulate virtual memory. 3) mmap page A into some temporary area of virtual memory. 4) mmap page B into the virtual memory location previously occupied by A. 5) mmap the temporary area into the location previously occupied by B. The problem I am having is that after I mmap /proc/curproc/mem, I cannot access it. I get bus errors. As in intermediate step to the above `swap virtual pages' idea, I tried the following experiment, which didn't work. Would much appreciate any ideas. Greg Johnson johnson@nrtc.northrop.com --------------------------- cut here ----------------------------- /* The following program simply attempts to malloc an array, and then mmap /proc/curproc/mem into virtual memory, to create an `alias' to the array. (The same physical memory address would be accessible via two different virtual memory addresses.) */ #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/mman.h> main() { char *map_addr, *vec; int i; int fd; char buf[256]; char *addr; /* get a large array to play with */ vec = (char *) malloc( 80000 ); printf( "vec %x\n", vec ); /* get a file descriptor to the virtual memory of this process */ fd = open( "/proc/curproc/mem", O_RDWR ); printf( "%d\n", fd ); /* demonstrate that we have indeed succeeded in getting at our own virtual memory: Set vec[0] to `A', and then read and print the corresponding byte through the file descripter. */ i = lseek( fd, (off_t) vec, SEEK_SET ); printf( "lseek result %x\n", i ); vec[0] = 'A'; i = read( fd, buf, 1 ); /* this works just fine! Way cool. */ printf( "read result %x, `%c'\n", i, buf[0] ); /* attempt to map the part of virtual memory containing the array `vec' into some other place in virtual memory */ map_addr = mmap( (caddr_t) 0, (size_t) 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, (off_t) vec ); /* this printf comes back happy; I get a return value that looks like a virtual address */ printf( "map_addr %x\n", map_addr ); /* get ready to exercise the alias; here we will write a value to the physical address using one virtual address */ vec[0] = 'B'; /* here we are going to try to read the data value back, using the other virtual address... KABOOM. Bus error. */ printf( "`%c'\n", map_addr[0] ); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9609251828.AA09743>