このページはWritingPortableDriversセクションの一部です。
メモリに関する問題
原文: MemoryIssues
InternalKernelDataTypesにおけるdrivers/char/serial.cの例で見たように、
カーネルにメモリページを要求することができます。メモリページのサイズは必ずしも
(i386のように)4KBとは限りません。メモリページを参照するなら、PAGE_SHIFT
とPAGE_SIZEを使用する必要があります。
PAGE_SHIFTはPAGE_SIZEの値を得るために左シフトするビット数を表します。
これらの値はアーキテクチャによって異なります。
次に示すテーブルは、いくつかのアーキテクチャにおけるPAGE_SHIFTの値と、
その値から求まるPAGE_SIZEの値の一覧です。
| Architecture | PAGE_SHIFT | PAGE_SIZE |
| i386 | 12 | 4K |
| MIPS | 12 | 4K |
| Alpha | 13 | 8K |
| m68k | 12 | 4K |
| m68k | 13 | 8K |
| ARM | 12 | 4K |
| ARM | 14 | 16K |
| ARM | 15 | 32K |
| IA-64 | 12 | 4K |
| IA-64 | 13 | 8K |
| IA-64 | 14 | 16K |
| IA-64 | 16 | 64K |
同じ基本アーキテクチャであっても、ページサイズは異なることがあります。 ページサイズは、(IA-64のように)コンフィグレーションオプションに依存する こともあれば、(ARMのように)プロセッサの種類の違いによることもあります。
以下に示すdrivers/usb/class/audio.cのコードの断片は、メモリに直接
アクセスするときにPAGE_SHIFTとPAGE_SIZEをどのように使用する
かを示しています。
#!cplusplus
static int dmabuf_mmap(...)
{
size >>= PAGE_SHIFT;
for(nr = 0; nr < size; nr++)
if (!db->sgbuf[nr])
return -EINVAL;
db->mapped = 1;
for (nr = 0; nr < size; nr++) {
unsigned long pfn;
pfn = virt_to_phys(db->sgbuf[nr]) >> PAGE_SHIFT;
if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, prot))
return -EAGAIN;
start += PAGE_SIZE;
}
return 0;
}