15.4.2. Allocate DMA Buffer
This section covers the allocation of DMA buffer at the underlying layer. We will introduce an Advanced Interface later, but it is still a good idea to understand what is displayed here.
The main problem with DMA buffering is that when they are larger than one page, they must occupy the continuous pages of the physical memory because the device uses ISA or PCI system bus to transmit data, they all use the physical address. note that this restriction does not apply to sbus (See Chapter 12 "sbus"), which uses virtual addresses on the peripheral bus. some architectures can also use virtual addresses on the PCI bus, but a portable driver cannot rely on this function.
Although the DMA buffer can be allocated, the module can only allocate its buffer at runtime at system startup or runtime. (Chapter 2 introduces these technologies. The "get large buffer" section covers allocation at system startup, while "kmalloc's authenticity" and "get_free_page and other" describes allocation at runtime ). drivers must be concerned about allocating the correct memory when it is used for DMA operations; not all memory areas are suitable. in particular, high-end memory may not work for DMA on some devices in some systems.
-Peripherals cannot use high-end addresses at all.
Most devices on the Modern Bus can handle 32-bit addresses, meaning normal memory allocation is just right for them. some PCI devices, however, cannot implement the complete PCI standard and cannot use 32-bit addresses. and the ISA Device is limited to only 24-bit addresses.
For devices with such restrictions, the memory should be allocated from the DMA zone and called by adding the gfp_dma sign to kmalloc or get_free_pages. when this sign exists, only 24-bit addressing memory is allocated. another option is to use a general DMA layer (which we will discuss right away) to allocate buffering to address the limitations of your device.
15.4.2.1. Allocate by yourself
We have seen how to allocate get_free_pages until several Mbyte (because order can be used until max_order, which is currently 11), but it is easy to fail for advanced requests. When the request buffer is much smaller than 128 kb, because the system memory has become broken for a long time. [50]
When the kernel cannot return the requested amount of memory or you need more than 128 KB (for example, a common PCI frame capturing request ), an alternative to returning-enomem is to allocate memory at startup or reserve the buffer to you at the top of the physical Ram. in the "get a large buffer" section in Chapter 8th, we describe the allocation at the startup time, but it is unavailable to the module. at the top of the reserved Ram, a mem = parameter is passed to the kernel at startup. for example, if you have 256 MB
Mem = 255 m so that the kernel does not use the top Mbyte. Your module may later use the followingCodeTo obtain access to this memory:
Dmabuf = ioremap (0xff00000/* 255 m */, 0x100000/* 1 M */);
Combined with part of the example code in this book, a simple API is provided to detect and manage such reserved Ram and has been successfully used in several systems.However, this technique is ineffective when you have a high memory system (that is, a system with more physical memory than the CPU address space ).???????
Of course, another option is to use gfp_nofail to allocate your buffer. this method, however, does have serious pressure on the memory management sub-system, and it is likely to lock the system; it is best to avoid unless there are no other methods.
If you allocate a large DMA buffer to such a length, however, it is worth looking at alternative methods. if your device can do divergence/aggregation I/O, you can allocate your buffer with smaller fragments and let the device do something else. divergence/convergence I/O can also be used when direct I/O to user space, it may be the best solution when a real large buffer is needed.