Linux谁访问这个内存,在Linux中的直接内存访问

我试图直接访问物理内存的一个嵌入式Linux项目,但我不知道如何我最好指定我的使用的内存。

如果我定期启动我的设备,并访问/ dev / mem,我可以轻松地读取和写入到我想要的任何地方。但是,在这里,我正在访问可以轻松地分配给任何进程的内存;我不想做

我的代码/ dev / mem是(所有错误检查等):

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);

这工作。然而,我想使用没有其他人会碰到的记忆。我试图限制内存的内存量,通过使用mem = XXXm启动,然后将BASE_ADDRESS设置为高于此值(但低于物理内存),但似乎没有一致地访问相同的内存。

根据我在网上看到的,我怀疑我可能需要一个内核模块(这是OK)使用ioremap()或remap_pfn_range()(或两个???),但我绝对不知道如何;可以任何人帮助?

编辑:

我想要的是一种方法来总是访问相同的物理内存(例如,1.5MB的价值),并将该内存放在一边,以便内核不会分配给任何其他进程。

我试图重现一个系统,我们在其他操作系统(没有内存管理),我可以通过链接器在内存中分配一个空间,并使用类似的东西

*(unsigned char *)0x12345678

EDIT2:

我想我应该提供一些更多的细节。此内存空间将用于嵌入式应用程序的高性能日志记录解决方案的RAM缓冲区。在我们拥有的系统中,没有什么能够在软重启期间清除或扰乱物理内存。因此,如果我写一个位到物理地址X,并重新启动系统,相同的位仍将在重新启动后设置。这已经在运行VxWorks的完全相同的硬件上测试过(这个逻辑在Nucleus RTOS和OS20在不同的平台上也很好地工作,FWIW)。我的想法是在Linux中通过直接寻址物理内存来尝试同样的事情;因此,每次启动都必须得到相同的地址。

我应该澄清一下,这是为内核2.6.12和更新。

编辑3:

这里是我的代码,首先是内核模块,然后是用户空间应用程序。

要使用它,我使用mem = 95m,然后insmod foo-module.ko,然后mknod mknod / dev / foo c 32 0启动,然后运行foo-user,它在那里死了。在gdb下运行显示它在分配时死,虽然在gdb中,我不能取消引用从mmap获取的地址(虽然printf可以)

foo-module.c

#include

#include

#include

#include

#include

#include

#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

#include

#include

#include

#include

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值