[ACCEPTED]-Direct Memory Access in Linux-linux-kernel
I think you can find a lot of documentation 37 about the kmalloc + mmap part. However, I 36 am not sure that you can kmalloc so much 35 memory in a contiguous way, and have it 34 always at the same place. Sure, if everything 33 is always the same, then you might get a 32 constant address. However, each time you 31 change the kernel code, you will get a different 30 address, so I would not go with the kmalloc 29 solution.
I think you should reserve some 28 memory at boot time, ie reserve some physical 27 memory so that is is not touched by the 26 kernel. Then you can ioremap this memory 25 which will give you a kernel virtual address, and 24 then you can mmap it and write a nice device 23 driver.
This take us back to linux device drivers in PDF format. Have 22 a look at chapter 15, it is describing this 21 technique on page 443
Edit : ioremap and 20 mmap. I think this might be easier to debug 19 doing things in two step : first get the 18 ioremap right, and test it using a character 17 device operation, ie read/write. Once you 16 know you can safely have access to the whole 15 ioremapped memory using read / write, then 14 you try to mmap the whole ioremapped range.
And 13 if you get in trouble may be post another 12 question about mmaping
Edit : remap_pfn_range 11 ioremap returns a virtual_adress, which 10 you must convert to a pfn for remap_pfn_ranges. Now, I 9 don't understand exactly what a pfn (Page 8 Frame Number) is, but I think you can get 7 one calling
virt_to_phys(pt) >> PAGE_SHIFT
This probably is not the Right 6 Way (tm) to do it, but you should try it
You 5 should also check that FOO_MEM_OFFSET is 4 the physical address of your RAM block. Ie 3 before anything happens with the mmu, your 2 memory is available at 0 in the memory map 1 of your processor.
Sorry to answer but not quite answer, I 29 noticed that you have already edited the 28 question. Please note that SO does not notify 27 us when you edit the question. I'm giving 26 a generic answer here, when you update the 25 question please leave a comment, then I'll 24 edit my answer.
Yes, you're going to need 23 to write a module. What it comes down to 22 is the use of
kmalloc() (allocating a region in kernel 21 space) or
vmalloc() (allocating a region in userspace).
Exposing 20 the prior is easy, exposing the latter can 19 be a pain in the rear with the kind of interface 18 that you are describing as needed. You noted 17 1.5 MB is a rough estimate of how much you 16 actually need to reserve, is that iron clad? I.e 15 are you comfortable taking that from kernel 14 space? Can you adequately deal with ENOMEM 13 or EIO from userspace (or even disk sleep)? IOW, what's 12 going into this region?
Also, is concurrency 11 going to be an issue with this? If so, are 10 you going to be using a futex? If the answer 9 to either is 'yes' (especially the latter), its 8 likely that you'll have to bite the bullet 7 and go with
vmalloc() (or risk kernel rot from within). Also, if 6 you are even THINKING about an
ioctl() interface 5 to the char device (especially for some 4 ad-hoc locking idea), you really want to 3 go with
Also, have you read this? Plus we aren't 2 even touching on what grsec / selinux is 1 going to think of this (if in use).
/dev/mem is okay for simple register peeks 29 and pokes, but once you cross into interrupts 28 and DMA territory, you really should write 27 a kernel-mode driver. What you did for 26 your previous memory-management-less OSes 25 simply doesn't graft well to an General 24 Purpose OS like Linux.
You've already thought 23 about the DMA buffer allocation issue. Now, think 22 about the "DMA done" interrupt 21 from your device. How are you going to 20 install an Interrupt Service Routine?
Besides, /dev/mem 19 is typically locked out for non-root users, so 18 it's not very practical for general use. Sure, you 17 could chmod it, but then you've opened a 16 big security hole in the system.
If you are 15 trying to keep the driver code base similar 14 between the OSes, you should consider refactoring 13 it into separate user & kernel mode 12 layers with an IOCTL-like interface in-between. If 11 you write the user-mode portion as a generic 10 library of C code, it should be easy to 9 port between Linux and other OSes. The 8 OS-specific part is the kernel-mode code. (We 7 use this kind of approach for our drivers.)
It 6 seems like you have already concluded that 5 it's time to write a kernel-driver, so you're 4 on the right track. The only advice I can 3 add is to read these books cover-to-cover.
(Keep 2 in mind that these books are circa-2005, so 1 the information is a bit dated.)
I am by far no expert on these matters, so 14 this will be a question to you rather than 13 an answer. Is there any reason you can't 12 just make a small ram disk partition and 11 use it only for your application? Would 10 that not give you guaranteed access to the 9 same chunk of memory? I'm not sure of there 8 would be any I/O performance issues, or 7 additional overhead associated with doing 6 that. This also assumes that you can tell 5 the kernel to partition a specific address 4 range in memory, not sure if that is possible.
I 3 apologize for the newb question, but I found 2 your question interesting, and am curious 1 if ram disk could be used in such a way.
Have you looked at the 'memmap' kernel parameter? On 9 i386 and X64_64, you can use the memmap 8 parameter to define how the kernel will 7 hand very specific blocks of memory (see 6 the Linux kernel parameter documentation). In your case, you'd 5 want to mark memory as 'reserved' so that 4 Linux doesn't touch it at all. Then you 3 can write your code to use that absolute 2 address and size (woe be unto you if you 1 step outside that space).
More Related questions