linux x64 memmap,linux?memory?memory

#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; } improve this questionedited?Mar 16 '09 at 15:04asked?Mar 15 '09 at 13:01Mikeage3,532●1●17●40?To clarify, you want to (in a module) return an address space to userspace acquired via vmalloc(), not kmalloc(), correct? How much memory do you actually need??–??Tim Post?Mar 15 '09 at 13:09?This is probably done easiest with kmalloc(), what you'd be doing is setting 1.5 MB of kernel space apart and presenting it to userspace. If that's what you want to do, I'll refresh myself on a few kernel innards and try to answer.?–?Tim Post??Mar 15 '09 at 14:06?Note, doing this with vmalloc() can be an extremely obnoxious task. The amount you actually need to map influences the answer, so you're sure its 1.5 MB or less??–??Tim Post?Mar 15 '09 at 14:08?Yes, 1.5 MB. Maybe 2; never more than that.?–?Mikeage?Mar 15 '09 at 19:59?Edited my answer regarding the remap_pfn_range function?–??shodanex?Mar 16 '09 at 15:36show?4?more comments5 Answersorder by?? ?? ?? ?? ?? ?? ?? ?active? ?? ?? ?? ?? ?? ?? ?oldest? ?? ?? ?? ?? ?? ?? ?votes? ? ?? ?? ?? ?? ?_s(vote up)8_s(vote down)acceptedI 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 443Edit : 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 mmapingEdit : 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 callingvirt_to_phys(pt) >> PAGE_SHIFT This probably is not the Right Way (tm) to do it, but you should try itYou 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.improve this answeredited?Mar 16 '09 at 15:35answered?Mar 16 '09 at 9:07shodanex6,699●4●20●53?When you say "I think you should reserve some memory at boot time, ie reserve some physical memory so that is is not touched by the kernel. " do you mean boot with mem=XXXm, where XXX is less than the actual address? That's what I was originally thinking.?–??Mikeage?Mar 16 '09 at 10:43?[cont] I see some code there using ioremap(); I'll try this. So to confirm: boot with mem=XXX, ioremap(XXX 1), and then what's the best way to translate this to a userspace address?1?–??Mikeage?Mar 16 '09 at 10:55?Hrmmm. I tried this, and implemented the mmap as follows (all error checking removed): static int foo_mmap(struct file *filp, struct vm_area_struct *vma) { remap_pfn_range(vma, vma->vm_start, (unsigned long) pt, vma->vm_end - vma->vm_start, PAGE_SHARED); }?–??MikeageMar 16 '09 at 11:24?When I do the mmap, I get what seems to be a valid address, but any attempts to write to it result in: Kernel unaligned instruction access in arch/mips/kernel/unaligned.c::do_ade, line 544[#1]:?–?Mikeage?Mar 16 '09 at 11:26?mmap is something tricky, You should eventually edit your question and post your code, or post a new question.?–?shodanex?Mar 16 '09 at 12:33show?10?more comments_s(vote up)8_s(vote down)Sorry to answer but not quite answer, I noticed that you have already edited the question. Please note that SO does not notify us when you edit the question. I'm giving a generic answer here, when you update the question please leave a comment, then I'll edit my answer.Yes, you're going to need to write a module. What it comes down to is the use of kmalloc() (allocating a region in kernel space) or vmalloc() (allocating a region in userspace).Exposing the prior is easy, exposing the latter can be a pain in the rear with the kind of interface that you are describing as needed. You noted 1.5 MB is a rough estimate of how much you actually need to reserve, is that iron clad? I.e are you comfortable taking that from kernel space? Can you adequately deal with ENOMEM or EIO from userspace (or even disk sleep)? IOW, what's going into this region?Also, is concurrency going to be an issue with this? If so, are you going to be using a futex? If the answer to either is 'yes' (especially the latter), its likely that you'll have to bite the bullet and go with vmalloc() (or risk kernel rot from within). Also, if you are even THINKING about an ioctl() interface to the char device (especially for some ad-hoc locking idea), you really want to go with vmalloc().Also, have you read?this? Plus we aren't even touching on what grsec / selinux is going to think of this (if in use).improve this answeredited?Oct 30 '13 at 11:56answered?Mar 15 '09 at 14:23Tim Post?20.3k●8●61●122?this is an embedded system; I'm not worried about selinux. Regarding the rest of your Q's, I'm adding some more detail now.?–??MikeageMar 15 '09 at 20:00?Broken link for the "this" URL, could you update please??–??jlhonora?Oct 30 '13 at 11:411?@jlhonora Thanks for the ping - Wayback to the rescue :) The link has been fixed to point to an archived copy.?–??Tim Post??Oct 30 '13 at 11:56?@TimPost Wow, thanks! I wasn't expecting such quick answer?–?jlhonora?Oct 30 '13 at 16:21add comment_s(vote up)1_s(vote down)/dev/mem is okay for simple register peeks and pokes, but once you cross into interrupts and DMA territory, you really should write a kernel-mode driver. What you did for your previous memory-management-less OSes simply doesn't graft well to an General Purpose OS like Linux.You've already thought about the DMA buffer allocation issue. Now, think about the "DMA done" interrupt from your device. How are you going to install an Interrupt Service Routine?Besides, /dev/mem is typically locked out for non-root users, so it's not very practical for general use. Sure, you could chmod it, but then you've opened a big security hole in the system.If you are trying to keep the driver code base similar between the OSes, you should consider refactoring it into separate user & kernel mode layers with an IOCTL-like interface in-between. If you write the user-mode portion as a generic library of C code, it should be easy to port between Linux and other OSes. The OS-specific part is the kernel-mode code. (We use this kind of approach for our drivers.)It seems like you have already concluded that it's time to write a kernel-driver, so you're on the right track. The only advice I can add is to read these books cover-to-cover.Linux Device DriversUnderstanding the Linux Kernel(Keep in mind that these books are circa-2005, so the information is a bit dated.)improve this answeranswered?Mar 15 '09 at 19:27msemack2,768●8●14_s(vote up)0_s(vote down)I am by far no expert on these matters, so this will be a question to you rather than an answer. Is there any reason you can't just make a small ram disk partition and use it only for your application? Would that not give you guaranteed access to the same chunk of memory? I'm not sure of there would be any I/O performance issues, or additional overhead associated with doing that. This also assumes that you can tell the kernel to partition a specific address range in memory, not sure if that is possible.I apologize for the newb question, but I found your question interesting, and am curious if ram disk could be used in such a way.improve this answeranswered?Mar 15 '09 at 17:09pseudosaint31●2?Concurrency might be an issue with this, especially when using DM which does not honor write barriers. The question (despite edits) is really ambiguous, how they will actually use that kind of region with that kind of interface is lacking.?–?Tim Post??Mar 15 '09 at 17:15?Also, (referencing my first comment) write cache may be an issue, especially with ordering.?–??Tim Post??Mar 15 '09 at 17:36?Ramdisk won't work; see my latest edit?–?Mikeage?Mar 15 '09 at 20:00add comment_s(vote up)0_s(vote down)Have you looked at the 'memmap' kernel parameter? On i386 and X64_64, you can use the memmap parameter to define how the kernel will hand very specific blocks of memory (see the?Linux kernel parameter?documentation). In your case, you'd want to mark memory as 'reserved' so that Linux doesn't touch it at all. Then you can write your code to use that absolute address and size (woe be unto you if you step outside that space).improve this answeranswered?Oct 28 '09 at 17:36Craig Trader8,417●3●15●36?I actually did use memmap [or just mem=XXm@YY, which my kernel supports to reserve a block in the middle.] The open issue was how to access the memory directly.?–??Mikeage?Oct 31 '09 at 19:16add comment

Your Answer

log in?orName:?Email:?Home Page:?By posting your answer, you agree to the?privacy policy?and?terms of service.meta?chat?about?help?blog?privacy policy?legalcontact us?full site2014 stack exchange, inc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值