Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 176823
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T13:56:45+00:00 2026-05-11T13:56:45+00:00

I’m trying to access physical memory directly for an embedded Linux project, but I’m

  • 0

I’m trying to access physical memory directly for an embedded Linux project, but I’m not sure how I can best designate memory for my use.

If I boot my device regularly, and access /dev/mem, I can easily read and write to just about anywhere I want. However, in this, I’m accessing memory that can easily be allocated to any process; which I don’t want to do

My code for /dev/mem is (all error checking, etc. removed):

mem_fd = open('/dev/mem', O_RDWR)); mem_p = malloc(SIZE + (PAGE_SIZE - 1)); if ((unsigned long) mem_p % PAGE_SIZE) {     mem_p += PAGE_SIZE - ((unsigned long) mem_p % PAGE_SIZE); } mem_p = (unsigned char *) mmap(mem_p, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, mem_fd, BASE_ADDRESS); 

And this works. However, I’d like to be using memory that no one else will touch. I’ve tried limiting the amount of memory that the kernel sees by booting with mem=XXXm, and then setting BASE_ADDRESS to something above that (but below the physical memory), but it doesn’t seem to be accessing the same memory consistently.

Based on what I’ve seen online, I suspect I may need a kernel module (which is OK) which uses either ioremap() or remap_pfn_range() (or both???), but I have absolutely no idea how; can anyone help?

EDIT: What I want is a way to always access the same physical memory (say, 1.5MB worth), and set that memory aside so that the kernel will not allocate it to any other process.

I’m trying to reproduce a system we had in other OSes (with no memory management) whereby I could allocate a space in memory via the linker, and access it using something like

*(unsigned char *)0x12345678 

EDIT2: I guess I should provide some more detail. This memory space will be used for a RAM buffer for a high performance logging solution for an embedded application. In the systems we have, there’s nothing that clears or scrambles physical memory during a soft reboot. Thus, if I write a bit to a physical address X, and reboot the system, the same bit will still be set after the reboot. This has been tested on the exact same hardware running VxWorks (this logic also works nicely in Nucleus RTOS and OS20 on different platforms, FWIW). My idea was to try the same thing in Linux by addressing physical memory directly; therefore, it’s essential that I get the same addresses each boot.

I should probably clarify that this is for kernel 2.6.12 and newer.

EDIT3: Here’s my code, first for the kernel module, then for the userspace application.

To use it, I boot with mem=95m, then insmod foo-module.ko, then mknod mknod /dev/foo c 32 0, then run foo-user , where it dies. Running under gdb shows that it dies at the assignment, although within gdb, I cannot dereference the address I get from mmap (although printf can)

foo-module.c

#include <linux/module.h> #include <linux/config.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/mm.h> #include <asm/io.h>  #define VERSION_STR '1.0.0' #define FOO_BUFFER_SIZE (1u*1024u*1024u) #define FOO_BUFFER_OFFSET (95u*1024u*1024u) #define FOO_MAJOR 32 #define FOO_NAME 'foo'  static const char *foo_version = '@(#) foo Support version ' VERSION_STR ' ' __DATE__ ' ' __TIME__;  static void    *pt = NULL;  static int      foo_release(struct inode *inode, struct file *file); static int      foo_open(struct inode *inode, struct file *file); static int      foo_mmap(struct file *filp, struct vm_area_struct *vma);  struct file_operations foo_fops = {     .owner = THIS_MODULE,     .llseek = NULL,     .read = NULL,     .write = NULL,     .readdir = NULL,     .poll = NULL,     .ioctl = NULL,     .mmap = foo_mmap,     .open = foo_open,     .flush = NULL,     .release = foo_release,     .fsync = NULL,     .fasync = NULL,     .lock = NULL,     .readv = NULL,     .writev = NULL, };  static int __init foo_init(void) {     int             i;     printk(KERN_NOTICE 'Loading foo support module\n');     printk(KERN_INFO 'Version %s\n', foo_version);     printk(KERN_INFO 'Preparing device /dev/foo\n');     i = register_chrdev(FOO_MAJOR, FOO_NAME, &foo_fops);     if (i != 0) {         return -EIO;         printk(KERN_ERR 'Device couldn't be registered!');     }     printk(KERN_NOTICE 'Device ready.\n');     printk(KERN_NOTICE 'Make sure to run mknod /dev/foo c %d 0\n', FOO_MAJOR);     printk(KERN_INFO 'Allocating memory\n');     pt = ioremap(FOO_BUFFER_OFFSET, FOO_BUFFER_SIZE);     if (pt == NULL) {         printk(KERN_ERR 'Unable to remap memory\n');         return 1;     }     printk(KERN_INFO 'ioremap returned %p\n', pt);     return 0; } static void __exit foo_exit(void) {     printk(KERN_NOTICE 'Unloading foo support module\n');     unregister_chrdev(FOO_MAJOR, FOO_NAME);     if (pt != NULL) {         printk(KERN_INFO 'Unmapping memory at %p\n', pt);         iounmap(pt);     } else {         printk(KERN_WARNING 'No memory to unmap!\n');     }     return; } static int foo_open(struct inode *inode, struct file *file) {     printk('foo_open\n');     return 0; } static int foo_release(struct inode *inode, struct file *file) {     printk('foo_release\n');     return 0; } static int foo_mmap(struct file *filp, struct vm_area_struct *vma) {     int             ret;     if (pt == NULL) {         printk(KERN_ERR 'Memory not mapped!\n');         return -EAGAIN;     }     if ((vma->vm_end - vma->vm_start) != FOO_BUFFER_SIZE) {         printk(KERN_ERR 'Error: sizes don't match (buffer size = %d, requested size = %lu)\n', FOO_BUFFER_SIZE, vma->vm_end - vma->vm_start);         return -EAGAIN;     }     ret = remap_pfn_range(vma, vma->vm_start, (unsigned long) pt, vma->vm_end - vma->vm_start, PAGE_SHARED);     if (ret != 0) {         printk(KERN_ERR 'Error in calling remap_pfn_range: returned %d\n', ret);         return -EAGAIN;     }     return 0; } module_init(foo_init); module_exit(foo_exit); MODULE_AUTHOR('Mike Miller'); MODULE_LICENSE('NONE'); MODULE_VERSION(VERSION_STR); MODULE_DESCRIPTION('Provides support for foo to access direct memory'); 

foo-user.c

#include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <sys/mman.h>  int main(void) {     int             fd;     char           *mptr;     fd = open('/dev/foo', O_RDWR | O_SYNC);     if (fd == -1) {         printf('open error...\n');         return 1;     }     mptr = mmap(0, 1 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 4096);     printf('On start, mptr points to 0x%lX.\n',(unsigned long) mptr);     printf('mptr points to 0x%lX. *mptr = 0x%X\n', (unsigned long) mptr, *mptr);     mptr[0] = 'a';     mptr[1] = 'b';     printf('mptr points to 0x%lX. *mptr = 0x%X\n', (unsigned long) mptr, *mptr);     close(fd);     return 0; } 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T13:56:46+00:00Added an answer on May 11, 2026 at 1:56 pm

    I think you can find a lot of documentation about the kmalloc + mmap part. However, I am not sure that you can kmalloc so much memory in a contiguous way, and have it always at the same place. Sure, if everything is always the same, then you might get a constant address. However, each time you change the kernel code, you will get a different address, so I would not go with the kmalloc solution.

    I think you should reserve some memory at boot time, ie reserve some physical memory so that is is not touched by the kernel. Then you can ioremap this memory which will give you a kernel virtual address, and then you can mmap it and write a nice device driver.

    This take us back to linux device drivers in PDF format. Have a look at chapter 15, it is describing this technique on page 443

    Edit : ioremap and mmap. I think this might be easier to debug doing things in two step : first get the ioremap right, and test it using a character device operation, ie read/write. Once you know you can safely have access to the whole ioremapped memory using read / write, then you try to mmap the whole ioremapped range.

    And if you get in trouble may be post another question about mmaping

    Edit : remap_pfn_range ioremap returns a virtual_adress, which you must convert to a pfn for remap_pfn_ranges. Now, I don’t understand exactly what a pfn (Page Frame Number) is, but I think you can get one calling

    virt_to_phys(pt) >> PAGE_SHIFT 

    This probably is not the Right Way ™ to do it, but you should try it

    You should also check that FOO_MEM_OFFSET is the physical address of your RAM block. Ie before anything happens with the mmu, your memory is available at 0 in the memory map of your processor.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 88k
  • Answers 88k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Put the following in ~/.vim/plugin/nextunused.vim " nextunused.vim " find the… May 11, 2026 at 5:43 pm
  • Editorial Team
    Editorial Team added an answer In the System.Windows.Forms namespace, you'll find the classes: Menu, ContextMenu,… May 11, 2026 at 5:43 pm
  • Editorial Team
    Editorial Team added an answer Assuming you're not using too many class/function in either one… May 11, 2026 at 5:43 pm

Related Questions

I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I am currently running into a problem where an element is coming back from
Seemingly simple, but I cannot find anything relevant on the web. What is the
Configuring TinyMCE to allow for tags, based on a customer requirement. My config is
Is it possible to replace javascript w/ HTML if JavaScript is not enabled on

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.