Linuxでメモリ確保をするのをケース別で・・・
(1) アプリで確保
通常のアプリでメモリを確保する。
これはmallocだよね。
特に説明する必要はないのでgoogleで"man malloc"でもすれば良い。
(2) カーネルで確保
(2-1) 4K以下なら
slab領域から取得すれば良い。
kmallocすれば良い。
これも特に説明する必要はないのでgoogle先生に"man kmalloc"とすれば良い。
(2-2) 4K以上なら
vmallocでも良いか・・・
vmallocは使わないので調べてない。
間違えてたらゴメン。
(2-3) Linuxから見えない領域にする。
実メモリが1GBならKernel起動時に例えば"mem=768M"とすると、1GB空間の実メモリのうち、後半の256MBはLinuxが使わない空間になる。
ここをLinuxからmmapで確保する。
mmapはKernel 3.X系では2MBまで確保できるようになったらしいが、Linuxには基本4KBのページングがあることを忘れてはいけない。
下図のようにLinux領域とピンク領域を物理的に分けてしまう方法だね。
連続領域が必要なDMAを実装したり、Linuxに明示的に邪魔されたくない場合はこの方法を使用する。

(2-4) CMA(Contiguous Memory Allocator)
CMA領域を使用して、連続したメモリ領域を取得する。
連続領域が必要なDMAを実装する場合で、かつ、Linux用のメモリとしても使用したい場合はこの方法を使用する。
確保方法は下記の通りである。
{
int dmasize = 0;
char *dmabuf = NULL;
dma_addr_t dmaphys = 0;
dmasize = 0x1000000;
dmabuf = dma_alloc_coherent(NULL, dmasize, &dmaphys, GFP_KERNEL|GFP_DMA),
printk(KERN_INFO "Depois do dma_alloc\n"),
if (!dmabuf){
printk("can''t alloc dmabuf\n"),
}else{
printk("dmabuf: %08X\n", dmaphys),
}
}
コンフィグでCMAを有効にすることと、メモリ領域を予め指定しておくことが必要。
Kernelの起動時に"CMA=16M"としても良い。
開放は"dma_free_coherent"する。
(3)まとめ
ユーザランドでMMUで取得して、それをDMAにscatter/gather空間としてDMAできると良いのだが、これに対応するにはハードのMMU、Linuxの仮想メモリ空間、DMA回路への合わせこみとかなり大変な作業になる。
そこら辺を意識したOSならいいんだが、Linuxだと大変そうだなぁ。
自作DMAでも、scatter/gather化することはそう滅多に無いので、連続領域が取れればOKだ。