このページは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をどのように使用する かを示しています。
1 static int dmabuf_mmap(...)
2 {
3 size >>= PAGE_SHIFT;
4 for(nr = 0; nr < size; nr++)
5 if (!db->sgbuf[nr])
6 return -EINVAL;
7 db->mapped = 1;
8 for (nr = 0; nr < size; nr++) {
9 unsigned long pfn;
10
11 pfn = virt_to_phys(db->sgbuf[nr]) >> PAGE_SHIFT;
12 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, prot))
13 return -EAGAIN;
14 start += PAGE_SIZE;
15 }
16 return 0;
17 }