[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 &gt;= FOO_REGION1_MMAP_OFFSET &&
+            (u_int)off &lt; (FOO_REGION1_MMAP_OFFSET + FOO_REGION1_SIZE))
+                return (atop(FOO_REGION1_ADDR + ((u_int)off -
+                    FOO_REGION1_MMAP_OFFSET)));
+
+        if ((u_int)off &gt;= FOO_REGION2_MMAP_OFFSET &&
+            (u_int)off &lt; (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 しなければなりません。もし、アロケートしたメモリ
+のサイズ &gt;= 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 &gt;= FOO_REGION1_MMAP_OFFSET &&
+            (u_int)off &lt; (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 &gt;= FOO_REGION2_MMAP_OFFSET &&
+            (u_int)off &lt; (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 &copy;
     1998, 1999, 2000
     The NetBSD Foundation, Inc.  ALL RIGHTS RESERVED.</a>