[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Documentation/kernel/programming.list
Documentation/kernel/programming.list の 1.11-1.12 の差分のための
パッチです。
-- やまの
--- /tmp/programming.list Sat Jun 10 13:58:39 2000
+++ programming.list Sat Jun 10 14:02:34 2000
@@ -100,6 +100,88 @@
<CURRENTSRC>/usr/src/lib/libc/sys/Makefile.inc
</tt> の適当な場所に追加してください。
+<ENTRY>mmap_in_pseudo-device 仮想デバイスに mmap を実装する方法
+あなたの作ったデバイスは、おそらくキャラクターデバイスでしょう。もし、
+そうであれば、デバイスページャーを使っているはずです。(VM システムは、
+これらすべてを隠蔽しているので、心配しないでください)。
+<p>
+最初に、mmap インターフェースのために、適当なオフセットをいくつか選
+んでください。例えば「mmap オフセット 0-M は オブジェクトAをあたえる、
+N-O はオブジェクト B をあたえる」等のように。
+<p>
+これが終ると、mmap ルーチンは以下のように実装できます。
+<p>
+<pre>
+int
+foommap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+
+ if (off & PAGE_MASK)
+ panic("foommap");
+
+ if ((u_int)off >= FOO_REGION1_MMAP_OFFSET &&
+ (u_int)off < (FOO_REGION1_MMAP_OFFSET + FOO_REGION1_SIZE))
+ return (atop(FOO_REGION1_ADDR + ((u_int)off -
+ FOO_REGION1_MMAP_OFFSET)));
+
+ if ((u_int)off >= FOO_REGION2_MMAP_OFFSET &&
+ (u_int)off < (FOO_REGION2_MMAP_OFFSET + FOO_REGION2_SIZE))
+ return (atop(FOO_REGION1_ADDR + ((u_int)off -
+ FOO_REGION2_MMAP_OFFSET)));
+
+ /* Page not found. */
+ return (-1);
+}
+</pre>
+<p>
+さて、実際には単純なカーネルメモリーオブジェクトを mmap するので、
+コードはもうすこし複雑になります(結局は仮想デバイスですから)。
+<p>
+これを動作させるためには、アロケートしたメモリーオブジェクトをページ調整
+された境界に確実に mmap しなければなりません。もし、アロケートしたメモリ
+のサイズ >= PAGE_SIZE なら、これは保証されます。そうでなければ、
+uvm_km_alloc() を使い、アロケーションサイズをページサイズに切りあげてください。
+<p>
+若干の修正を加えると以下のようになります。
+<p>
+<pre>
+int
+foommap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ paddr_t pa;
+
+ if (off & PAGE_MASK)
+ panic("foommap: offset not page aligned");
+
+ if ((u_int)off >= FOO_REGION1_MMAP_OFFSET &&
+ (u_int)off < (FOO_REGION1_MMAP_OFFSET + FOO_REGION1_SIZE)) {
+ if ((vaddr_t)foo_object1 & PAGE_MASK)
+ panic("foommap: foo_object1 not page aligned");
+ if (pmap_extract(pmap_kernel(), foo_object1 +
+ (u_int)off - FOO_REGION1_MMAP_OFFSET, &pa) == FALSE)
+ panic("foommap: foo_object1 page not mapped");
+ return (atop(pa));
+ }
+
+ if ((u_int)off >= FOO_REGION2_MMAP_OFFSET &&
+ (u_int)off < (FOO_REGION2_MMAP_OFFSET + FOO_REGION2_SIZE)) {
+ if ((vaddr_t)foo_object2 & PAGE_MASK)
+ panic("foommap: foo_object2 not page aligned");
+ if (pmap_extract(pmap_kernel(), foo_object2 +
+ (u_int)off - FOO_REGION2_MMAP_OFFSET, &pa) == FALSE)
+ panic("foommap: foo_object2 page not mapped");
+ return (atop(pa));
+ }
+
+ /* Page not found. */
+ return (-1);
+}
+</pre>
+
<ENTRY>accessing_a_kernel_structure_from_userland ユーザーランドからカーネルの構造体へアクセスする
良い例が <tt>
<CURRENTSRC>/usr/src/usr.bin/vmstat/dkstats.c
@@ -116,7 +198,7 @@
<hr>
<address>
<a href="../../Misc/feedback.html">(Contact us)</a>
- $NetBSD: programming.list,v 1.11 2000/01/16 01:27:43 abs Exp $<br>
+ $NetBSD: programming.list,v 1.12 2000/03/23 18:25:01 dent Exp $<br>
<a href="../../../Misc/disclaimer.html">Copyright ©
1998, 1999, 2000
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.</a>