From owner-freebsd-questions Wed Sep 25 11:28:56 1996 Return-Path: owner-questions Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id LAA01802 for questions-outgoing; Wed, 25 Sep 1996 11:28:56 -0700 (PDT) Received: from nrtc.nrtc.northrop.com (nrtc.northrop.com [128.99.0.1]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id LAA01735 for ; Wed, 25 Sep 1996 11:28:50 -0700 (PDT) From: johnson@charming.nrtc.northrop.com Received: from charming.nrtc.northrop.com by nrtc.nrtc.northrop.com id aa15377; 25 Sep 96 11:20 PDT Received: from charming.nrtc.northrop.com by charming.nrtc.northrop.com (4.1/SMI-4.1.1) id AA09743; Wed, 25 Sep 96 11:28:40 PDT Message-Id: <9609251828.AA09743@charming.nrtc.northrop.com> To: questions@freebsd.org Subject: Question regarding mmap <--> procfs Date: Wed, 25 Sep 96 11:28:39 MDT Sender: owner-questions@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 #include #include #include 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] ); }