OSを介さずに、専用のメモリブロックを必要とするデバイスがあります。メモリブロックが予約されていることをBIOSまたはOSに伝える方法はありますか?
このデバイスをopenSUSEマシンで使用しています。
OSを介さずに、専用のメモリブロックを必要とするデバイスがあります。メモリブロックが予約されていることをBIOSまたはOSに伝える方法はありますか?
このデバイスをopenSUSEマシンで使用しています。
回答:
あなたが求めているのはDMAと呼ばれるものです。このメモリを予約するには、ドライバを作成する必要があります。
はい、OSに介入したくないと言い、ドライバーがOSの一部になりますが、ドライバーの予約がない場合、カーネルはすべてのメモリがそれに属すると信じています。(カーネルにメモリブロックを無視するように指示しない限り、アーロンの答えによると、つまり)
Rubini、Corbet、およびKroah-Hartmannによる「Linux Device Drivers、3 / e」の第15章(PDF)は、 DMAおよび関連するトピックをカバーしています。
このHTMLバージョンが必要な場合は、オンラインでこの章の第2版を見つけました。カーネル2.4が新しくなったときに出てきて、第2版が10年以上前になっていることに注意してください。当時のカーネルのメモリ管理サブシステムには多くの作業が行われていたため、これ以上適用されない可能性があります。
OSで完全に無視する場合は、memmap
「」を使用してメモリホールを作成する必要があります。このリファレンスを参照してください。たとえば、2GBの障壁で512Mが必要な場合memmap=512M$2G
は、カーネルコマンドラインに " "を配置できます。
dmesg
盗む連続した穴を見つけるためにあなたをチェックする必要があります従ってあらゆるデバイスで踏みつけないため; それは、マザーボードとカードに固有です。
これは物事を行うための推奨される方法ではありません -それを適切に行う方法についてはウォーレンヤングの回答を参照してください(カーネルドライバー+ DMA)。あなたが尋ねた正確な質問に答えています。エンドユーザー向けにこれを作成する予定がある場合、エンドユーザーにこれを行うと、彼らはあなたを嫌います...私を信頼してください。
編集:grub2 w / grubby(CentOS 7など)を使用している場合は、必ず$をエスケープする必要があります。単一の\
前にある必要があり$
ます。例:
$ sudo -v
$ sudo grubby --update-kernel=ALL --args=memmap='128M\\$0x57EF0000'
$ sudo grubby --info $(sudo grubby --default-kernel) | grep memmap
args="ro crashkernel=auto ... memmap=128M\$0x57EF0000"
uint8_t *ptr = 0x8000000
私の例では「」と思いますか?または、それはセグメンテーション違反の可能性があります...ええと、私は本当に知りません。繰り返しになりますが、私は貧弱に設計されたPCIカードのエンドユーザーであり、4Gマークより下に手動でバッファーを割り当て、そのスペースがどこにあるかをドライバーに伝える必要があるため、答えを知っていました。ユーザーランドからは不可能な場合があります。
MMAP_FIXED | MMAP_ANON
。ここにカスタムDMAデバイスがなければ、OPが実際に望んでいたことを実行できるかどうかはわかりませんが、memmap=8M$512M
GRUBで言ったとき、CentOSボックスは512 MBで8 MBブロックを喜んでくれました。私は恐れていたので、ルートアクセスさえ必要としません。しかし、これが正しいことをしたとしても、おそらく割り込みなどを処理するためにドライバーが必要になると思います。
mmap()
「d」ページはユーザーランドコードがそれらを見る前にゼロにされます。セキュリティのために行われているため、あるプロセスから次のプロセスにデータが漏れることはありません。ドライバーを使用するもう1つの理由は、ドライバーのロード時にDMAバッファーの内容を保持する必要がある場合があるためです。ああ、ところで、任意の場所に配置されたmmap()
呼び出しは、memmap
カーネルブートオプションがなくても成功します。少なくとも、要求した場所にあるメモリを誰も使用していない限りです。ブートオプションは間違いなく成功の可能性を高めますが、必ずしも必要ではありません。
ARMベースのLinuxのカーネルからメモリブロックを予約するにreserved-memory
は、デバイスツリー(dts)ファイルのノードを使用することもできます。カーネルのドキュメント(こちらをご覧ください)に例があります:
memory {
reg = <0x40000000 0x40000000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x4000000>;
alignment = <0x2000>;
linux,cma-default;
};
display_reserved: framebuffer@78000000 {
reg = <0x78000000 0x800000>;
};
multimedia_reserved: multimedia@77000000 {
compatible = "acme,multimedia-memory";
reg = <0x77000000 0x4000000>;
};
};
最初にこのコマンドを入力して、現在の設定を確認します。
sysctl vm.min_free_kbytes
設定値を変更するには、を編集します/etc/sysctl.conf
。次の行を探します。
vm.min_free_kbytes=12888
存在しない場合は、(目的の値とともに)作成します。次の値が許容されます。
8192
12288
16384
20480
8Mは非常に保守的です。16Mで快適に座ることができます。値を変更したら、これを実行すると、再起動は不要です。
sudo sysctl -p