Find the answer to your Linux question:
Results 1 to 6 of 6
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1

    Question on using mmap to access physical memory


    I am pretty new to linux and i have a few questions about an approach for an NVRAM driver.

    We have 4 segments of memory that are attached to our processor via TI's EMIF (external memory interface).

    I think I know at high level what needs to be done, but am having trouble with the details.

    One of the areas is for an area of NonVolatile RAM. Once this is mapped you can read and write to the memory without any special needs. The chip handles the saving of data.

    So, what I think i would like to is write a driver to map that area of memory which starts at 0x06000000 and is 32M in length and then have my application use mmap() to access the memory. The actual amount of memory on this device is much smaller than the 32M, but that is the size of the EMIF partition.

    I found an example driver that implements something similar using a char driver, but it allocates new memory in the kernel and I don't quite get how to do this with existing memory.

    1) Do i need to be using the MTD subsystem to do this?
    2) How do you map the physical memory to an area that can be accessed by mmap?
    3) Does this approach sound reasonable?

    Thanks In Advance.

  2. #2
    For an embedded system the approach is more than reasonable. It is the reason I try, also to get it work on a 2.4.18 for SH4 processor.

    The "Linux device drivers" book states you use remap_page_range in the mmap driver method. Well, I tried and everything I get is an empty, zero filled page. I tried, also the nopage method with the same results. I don't know your case but in mine the area I try to map is non contiguous with the main (program) memory. I guess linux VM is not aware of this area so it cannot remap it. What puzzles me is I don't get any error when trying to remap. I think I should rebuild my kernel with the CONFIG_DISCONTIGMEM option.

    There is extremely few information regarding the linux drivers for embedded systems. Everything I found is the two editions of "Linux device drivers". In spite of being a very commendable effort to educate these books are a very difficult read and cover the workstation/server case. This is very, very far from the embedded case.

    I guess the example you refer to is the one in the LDD book. The mmap example in the book is built based on a buffer allocated in the main memory with kmalloc. This is not my case but on the other hand I understand the author position. It would be totally unacceptable to map in the user space a real IO page on a PC workstation as a driver example.

    Please share here your findings.


  3. #3
    I am also preety new to such things but I would like to give some inputs.
    let me know whether I am wrong or missing something !!
    I would like to have comment on my inputs for sure, because not everything may be feasible.

    If I understand it correctly, you want to map 32k of non volatile RAM, so user space application can write into it and read from it.
    when system goes down, the chip takes care of saving data (because of may be battery backed up nature).
    I think if you are writing kernel module char device drive then it is in the kernel space, and memory only could be mapped by kmap. correct?
    now application can get an interface be /dev/char_driver. where it can access the memory either by reading or writing into the character file.
    I am not sure whether application do mmap on the character file !!
    please let me know if any discrepancies.

  4. $spacer_open
  5. #4
    Yes, basically the goal is to give access to a chunk of real (physical) memory to the user space. This is unacceptable for a linux workstation/server but perfectly acceptable/common in the case of an embedded system.

    Linux has such a mechanism (mmap). The problem is the VM system needs to know about the memory range you want to re-map. Usually the IO/peripheral memory is not declared to the VM system - so the VM just cannot remap it. The alternative of this method is to manually copy between the physical memory and the user buffer in the read/write functions of a driver. This is not so efficient for large memory chunks.

    I'm looking, also for an explanation/example of such implementation (mmap of an IO page).


  6. #5
    So, you couldn't just use request_mem_region() and ioremap_nocache()?

  7. #6
    >>So, you couldn't just use request_mem_region() and ioremap_nocache()?

    I could, but the result is the same - I get a zero filled page which is not what I expect.
    If I go straight with the physical address I can read/write (at kernel lewel) what I want. But ***_remap() doesn't give me the same result.

    request_mem_region() doesn't do any memory work. It only adds your resource to a chained list to facilitate the access-conflict management. ioremap() acts like remap_memory_region() - I mean when in __doubt__ it gives you a zero page. It's what LDD states also.

    I feel like I miss something before. Maybe, somehow I should declare my IO memory range to my kernel during the kernel build process.

Posting Permissions

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