CMPS 3600 Lab-10 - Memory Maps

Goal: understand the use of low-level memory mapping

resources

Lab-10 covers mmap(2), a system call that maps a chunk of memory. Review the manpages in /examples/a directory for help on this lab. Low-level access to virtual memory (memory mapping) is the last IPC service we will cover in this course. You can view the mapping for a process in /proc/self/maps. See proc(5) for info on this file. Mmap(2) grabs a chunk of memory from the page table of the process's virtual memory space. If the memory is associated with a file (a file mapping), reads and writes to the memory chunk are redirected to the file. If the chunk of memory is not associated with a file (an anonymous mapping) reads and writes are redirected to the virtual memory swap file.
In this lab you will create a mapped and an unmapped.
Copy these files into your 3600/a/ directory:

    $ cd 
    $ cd 3600/a
    $ cp /home/fac/gordon/public_html/3600b/examples/a/maptest.c .
    $ cp /home/fac/gordon/public_html/3600b/examples/a/rvlab10.c .
    $ cp /home/fac/gordon/public_html/3600b/examples/a/Makefile .
    $ cp /home/fac/gordon/public_html/3600b/examples/a/article .
Before coding read the comments in maptest.c. Compile and execute. Start coding only when you are comfortable with the concepts in the program.
    $ cp maptest.c rvlab10.c
You task is to modify rvlab10.c to create a second mapping that is anonymous (not associated with a file). You will do a memcpy of the existing mapping to this second anonymous mapping. You will then open an output file and write the second mapping to the output file. Currently, rvlab10.c creates a memory mapping that is attached to a file named article.

The functionality of this lab is essentially to read an input file and copy it to an output file with memory mappings on both files. This is something you may never do in a real program, but it will give you practice on creating and using a memory mapping. Details follow.

STEP 1. Use open(2) to open an output file for writing. Pass the filename in from the cmdline. Recall this *sample* open system call:

    int outf = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
STEP 2. Use mmap(2) to create an anonymous mapping the same size as infile. From mmap manpage:
   MAP_ANONYMOUS
   The mapping is not backed by any file; its contents are initialized to
   zero. The fd and offset arguments are ignored; however, some implementations
   require fd to be -1 if  MAP_ANONYMOUS is specified, and portable applications
   should ensure this.
A *sample* mmap command to create the mapping is shown here:
        dest = mmap(NULL, filesize, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,-1,0);
        if (dest == MAP_FAILED)
            perror("mmap:");
STEP 3. Use memcpy(3) to to copy the original mapping (memory to memory copy) to the new mapping. From the manpage on memcpy note that you need to include <string.h>.
        void *memcpy(void *dest, const void *src, size_t n);

        copies n bytes from memory area src to memory area dest; the memory 
        areas should not overlap. Returns a pointer to dest.
STEP 4. Use write to copy the anonymous mapping to the output file (if you opened the file in append mode you will append the file). This is a *sample* write command. See write(2) manpage for more details.
        write(outf, source, filesize);  # source is char *ptr to the memmap
STEP 5. Remove the code that displays the article to the screen.
Clarification of this lab... Add a command-line argument to get an output file name. (see sample runs) If no command-line arguments are entered, display a Usage statement, and end the program. If <offset> or <length> are not entered on the command-line, display a Usage statement, but continue the program. Default the offset and length to reasonable values. Command-line arguments offset and length are optional for the user. Flow of this lab: 1. Update any changes to your command-line arguments. 2. Open an output file. 3. Use mmap to map some anonymous memory. 4. Copy the input file's memory mapping to the anonymous memory. 5. Write from memory-map to memory-map with memcpy() function. 6. Write from Anonymous memory-map to file with write().
Sample runs:
with no arguments...
$ ./lab10 Usage: ./lab10 <infile> <outfile> <offset> <length>
with file names...
$ ./lab10 article log Usage: ./lab10 <infile> <outfile> <offset> <length> filesize: 2088 bytes pa_offset 0 pid: 14014 pagesize: 4096 2088 bytes written to file.
including offset and length...
$ ./lab10 article log 1470 75 filesize: 2088 bytes pa_offset 0 pid: 19268 pagesize: 4096 75 bytes written to file. $ cat log Linux distributions are dominant in the server and supercomputing sectors.
secret test run...
$ ./lab10 article log2 1119 46 $ cat log2 (secret output will be here)
using strace...
$ strace -e trace=mmap ./lab10 article log 2>out Usage: ./lab10 <infile> <outfile> <offset> <length> filesize: 2088 bytes pa_offset 0 pid: 16448 pagesize: 4096 2088 bytes written to file. $ cat out mmap(NULL, 165587, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6606f5a000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6606f58000 mmap(NULL, 132288, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6606f37000 mmap(0x7f6606f3d000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f6606f3d000 mmap(0x7f6606f4c000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f6606f4c000 mmap(0x7f6606f52000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7f6606f52000 mmap(0x7f6606f54000, 13504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f54000 mmap(NULL, 1832960, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6606d77000 mmap(0x7f6606d99000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f6606d99000 mmap(0x7f6606ee0000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x169000) = 0x7f6606ee0000 mmap(0x7f6606f2d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f6606f2d000 mmap(0x7f6606f33000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f33000 mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6606d74000 mmap(NULL, 2088, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6606f82000 mmap(NULL, 2088, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f81000 +++ exited with 0 +++ $ md5sum article log 32b7b6ec5ae25a69c05c5dd75f8f51e2 article 32b7b6ec5ae25a69c05c5dd75f8f51e2 log

To be collected...


     3600/a/rvlab10.c 
     3600/a/Makefile