Thread: reading/writing from/to dev/mem

  1. #1
    Registered User
    Join Date
    Jul 2018
    Posts
    1

    reading/writing from/to dev/mem

    Hello everyone,
    I am trying to contribute to an open source project. Now, for that I am trying to read/write from/to dev/mem. The problem is my code is compiling right (as I feel so) and it's reading and writing but the problem is the file that I am reading into the memory and the one being written out doesn't match. And I can't figure out why.

    Codes :

    for writing image data into memory

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    static char *cmd_name = NULL;
    
    static uint32_t map_base = 0x18000000;
    static uint32_t map_size = 0x08000000;
    
    static uint32_t map_addr = 0x00000000;
    
    static char *dev_mem = "/dev/mem";
    
    static bool opt_raw = false;    /* To check if the image is raw, which should be default in this tool */
    
    static
    void write_line(uint8_t * bp, uint64_t * dp, unsigned row)
    {
      uint64_t val = 0;             /*  */
      uint64_t mask = 0;
      unsigned inc;
    
      inc = 4;                      /* Step-size for RGB */
    
      mask = ~0xFFFF;               /*Using mask of ~0xFFFF because 0xFFFF is used to mask the overlay */
    
      /* Iterating over full HD */
      for (unsigned col = 0; col < 2048; col++) {
        /* copying data from the source */
    
        val = bp[0];
        val = (val << 8) | bp[1];   /* Loads one byte after another into val */
        val = (val << 8) | bp[2];
        val = (val << 8) | bp[3];
        val = (val << 8) | bp[4];
        val = (val << 8) | bp[5];
        val = (val << 16);          /* After 6 bytes, shift the input by 16 skipping over the overlay */
    
        *dp = (*dp & ~mask) | (val & mask); /* Data is masked out and then modified into memory */
        /* First we read data from frame buffer and then mask it with complementary mask */
        dp++;                       /* Incrementing data pointer */
        bp += inc;                  /* Incrementing buffer pointer by steo-size i.e 3 */
      }
    }
    
    int main(int argc, char **argv)
    {
      extern int optind;
    
      cmd_name = argv[0];
    
      /* Opening dev/mem with read/write permission */
      int fd = open(dev_mem, O_RDWR | O_SYNC);
      if (fd == -1) {
        fprintf(stderr, "error opening >%s<.\n%s\n", dev_mem, strerror(errno));
        exit(1);
      }
    
      if (map_addr == 0)
        map_addr = map_base;
    
      /* Mapping base for memory allocation */
      void *base = mmap((void *) map_addr, map_size,
                        PROT_READ | PROT_WRITE, MAP_SHARED,
                        fd, map_base);
      if (base == (void *) -1) {
        fprintf(stderr,
                "error mapping 0x%08lX+0x%08lX @0x%08lX.\n%s\n",
                (long) map_base, (long) map_size, (long) map_addr, strerror(errno));
        exit(2);
      }
    
      /* Printing message after sucessfully mapping base */
      fprintf(stderr,
              "mapped 0x%08lX+0x%08lX to 0x%08lX.\n",
              (long unsigned) map_base, (long unsigned) map_size,
              (long unsigned) base);
    
      /* Checking if filename was supplied, if so, open as stdin */
      if (argc > optind) {
        close(0);
        open(argv[optind], O_RDONLY, 0);
      }
      // Iteration over every row count of 1536 for raw image format
    
      for (unsigned row = 0; row < 1536; row++) {
    
        uint8_t buf[2048 * 6];      /* Creating local buffer which can hold one row */
        uint8_t *bp = buf;          /* bp stands for buffer pointer */
        size_t buf_size;
    
        buf_size = 2048 * 4;
    
        /* loading the data from the file */
    
        size_t total = 0;
        while (total < buf_size) {
          size_t len = read(0, bp, buf_size - total);
    
          if (len == 0)
            exit(1);
          if (len < 0)
            exit(2);
    
          total += len;
          bp += len;
        }
    
        bp = buf;
    
        // Only calling write_line() when we have to write active raw buffer
    
        uint32_t dp_base = map_addr;
        uint64_t *dp = (uint64_t *) (dp_base + row * 16384);  /* dp stands for data pointer */
        /* frame buffer has 16384 bytes per row b/c 16384/2048=8 */
        /* We will put 4 pixel in a pack and address that as 64 bit int */
        write_line(bp, dp, row);    /* Using write_line() to write into the memory */
      }
    
      printf("%u\n", map_base);
    
      exit((err_flag) ? 1 : 0);
    
    }

    for dumping image data

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <math.h>
    
    static char *cmd_name = NULL;
    
    static uint32_t map_base = 0x18000000;
    static uint32_t map_size = 0x08000000;
    
    static uint32_t map_addr = 0x00000000;
    
    static char *dev_mem = "/dev/mem";
    
    static bool out_buf = false;
    
    int main(int argc, char *argv[])
    {
      extern int optind;
      cmd_name = argv[0];
    
      /* Opening dev/mem with read/write permission */
      int fd = open(dev_mem, O_RDWR | O_SYNC);
      if (fd == -1) {
        fprintf(stderr, "error opening >%s<.\n%s\n", dev_mem, strerror(errno));
        exit(1);
      }
    
      /* Mapping frane buffer */
      void *buf = mmap((void *) map_addr, map_size,
                       PROT_READ | PROT_WRITE, MAP_SHARED,
                       fd, map_base);
      if (buf == (void *) -1) {
        fprintf(stderr,
                "error mapping 0x%08lX+0x%08lX @0x%08lX.\n%s\n",
                (long) map_base, (long) map_size, (long) map_addr, strerror(errno));
        exit(2);
      } else
        map_addr = (long unsigned) buf;
    
      uint64_t *dp = (uint64_t *) (map_addr); /* Data pointer */
      size_t ds = 0x1200100;
    
      /* Starting to write image */
      if (out_buf) {
        fprintf(stderr, "dumping buffer data ...\n");
        fprintf(stderr, "%p %ld\n", dp, ds);
    
        while (ds > 0) {
          ssize_t cnt = write(1, dp, ds);
    
          fprintf(stderr, "%p %d -> %d\n", dp, ds, cnt);
          dp = (uint64_t *) (((char *) dp) + cnt);
          ds -= cnt;
        }
    
      }
    
      printf("%u\n", map_base);
    
      exit(0);
    
    }

    after that I use gdb ./read for reading in terminal and then
    (gdb) r > img.raw12

    for dumping image data I do gdb ./write in terminal and then
    (gdb) r < new.raw12

    The data isn't matching at all.
    Last edited by Salem; 07-01-2018 at 12:31 PM. Reason: fixed horrible formatting

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Because it is not a valid idea for some operating systems.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Writing/Reading to and from log
    By !AR!BlackHawk in forum C++ Programming
    Replies: 5
    Last Post: 12-30-2007, 12:46 PM
  2. reading and writing xml using c
    By cnu_sree in forum C Programming
    Replies: 3
    Last Post: 04-20-2007, 05:25 AM
  3. Reading and Writing
    By niroopan in forum C++ Programming
    Replies: 2
    Last Post: 10-16-2002, 02:17 PM
  4. Reading and Writing
    By niroopan in forum C++ Programming
    Replies: 5
    Last Post: 10-06-2002, 08:58 PM
  5. Reading and Writing in C++
    By niroopan in forum C++ Programming
    Replies: 3
    Last Post: 10-03-2002, 03:47 PM

Tags for this Thread