''このページは[[WritingPortableDrivers]]セクションの一部です。''<<BR>>
== メモリに関する問題 ==
原文: [[http://kernelnewbies.org/MemoryIssues|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;
}
}}}