Find the answer to your Linux question:
Results 1 to 7 of 7
I recently started working with Linux and wrote my first device driver for a hardware chip controlled by a host CPU running Linux 2.6.x kernel. 1. The user space process ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jan 2010
    Posts
    10

    Avoid memory copying between user space and kernel space


    I recently started working with Linux and wrote my first device driver for a hardware chip controlled by a host CPU running Linux 2.6.x kernel.

    1. The user space process makes an IOCTL call with pointer to a user memory buffer.
    2. The kernel device driver in the big switch-case of IOCTL, first does a copy to kernel space
    3. The driver then processes the memory, eventually writing words to the hardware blocks as appropriate

    The memory copying is a performance hit because of limited cycles available on this embedded CPU. How does one avoid unnecessary memory copy between user space and kernel space? Suppose there is a buffer in the user-space that needs to be read by the kernel space? I believe that the typical code in the kernel mode device driver is:

    ....
    copy_from_user(kernel_dst_buffer, user_src_buffer, length);
    use kernel_dst_buffer;
    ...

    I want to avoid the copy_from_user and was trying to read up my "Linux Device Drivers book by Corbet/Rubini" and search online as well. It appears that one of the following will be used:
    get_user_pages
    mmap
    shm_get

    but I can't figure out. It appears extremely difficult/complicated for a simple task of sharing memory between user/kernel modes. Is that how it is? I couldn't even get any sample code for sharing memory though there appears to be sample code for just about everything. Maybe my search strings are broken.

    Any pointers? Thanks a lot! I am an absolute beginner so apologies in advance if this is standard knowledge.
    Gaurav

  2. #2
    Linux Guru coopstah13's Avatar
    Join Date
    Nov 2007
    Location
    NH, USA
    Posts
    3,149
    I'm not sure if it is any different, but in that book they have a driver called scull, it is a kernel module that is basically shared memory, you could write to that in the user space, then read from it in the kernel space, but you wouldn't have any way to guarantee the integrity of the data

  3. #3
    Just Joined!
    Join Date
    Jan 2010
    Posts
    10

    Thanks

    I looked at it but it appears that they recommend a copy_from_user and copy_to_user for these operations, as in Chapter 3 (pages 67-68 of 3rd Edition). I want to avoid these since my system has no swapping and everything is always available in DRAM and I don't care for any testing or data integrity tests.

  4. #4
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49

    Memory Mapped space...

    I use the memory mapped feature in a driver I'm working with right now. I'm using the 2.6.24 kernel. As you would expect I'm allocating the memory in the kernel module and using the character file operation mmap() to map my user space application to the kernel memory. Works like a charm. In my case I'm actually moving the data from kernel space to user space. Essentially though, we are trying to solve the same problem. Neither of us can waste CPU cycles doing a useless copy. You definitely don't want to be using the "copy" primitives used by IOCTL commands which are really used for control type data going back and forth between the applications in user space and the kernel.

    Those recommendations in the Rubini/Corbet/Kroah-Hartman (may they ever be blessed and exhalted) are a rule of thumb and knowing when to stray is part of the art of custom kernel driver writing.

    It should be very straight forward but the complexity comes in with synchronizing your access to the data space in the application and then signaling the kernel module that there is valid data and then knowing in the application when it can write to that space again since the kernel is finished with it.

    Cheers!!

  5. #5
    Just Joined!
    Join Date
    Jan 2010
    Posts
    10
    thanks bloggins666.

    I got it working (to a large extent). I used mmap in user-space and the driver used remap_pfn_range. Seems to work so far in a small application/driver. Now need to code it properly in the actual driver. This appears to be really useful. Thanks a lot.

    The Rubini/Corbet book talks about it but I didn't understand it well enough. But I found some sample code on the Internet that helped.

  6. #6
    Just Joined!
    Join Date
    Feb 2010
    Posts
    2

    hi

    Hi gaurav,

    Thats interesting ...
    I am also working on linux kernel programming and very new to this.
    So can you just explain a more on this ......as how can we map a common area so that we avoid copying to kernel space ?

    Thanks

  7. #7
    Just Joined!
    Join Date
    Jan 2010
    Posts
    10
    Quote Originally Posted by freiend_333 View Post
    Hi gaurav,

    Thats interesting ...
    I am also working on linux kernel programming and very new to this.
    So can you just explain a more on this ......as how can we map a common area so that we avoid copying to kernel space ?

    Thanks
    Yes, that is correct.

    1. you allocate memory in the kernel device driver
    2. You write a "mmap" function in the device driver
    3. This mmap file_ops function will do a remap_pfn when invoked by the user-space application
    4. In the application code, call the driver mmap.
    5. The driver will now return a pointer to the memory that the driver allocated in kernel space.

    Thus, a memory portion is now visible to both the kernel device driver and the user-space application program. The Rubini book has an example though it is a bit confusing and brief at first sight.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •