トップ «前の日記(2012-12-23) 最新 次の日記(2012-12-25)» 編集

ヨタの日々

2001|08|09|10|11|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|

2012-12-24 :-)

_ 午前

0930 起床

1030 おひる。カルボナーラ

1100 読書

_ 午後

1200 NHK FM

1530 散歩

IMG_0524

_

1800 NetBSDほげ

2200 飯。豚肉のしょうが焼き

_ 今日は一日“歌う声優”三昧

12 時から 24 時までひたすら聞いていた。

_ NetBSD 擬似デバイスを写経した

参考

ここ

コード

http://www.jp.netbsd.org/docs/kernel/pseudo/pseudo_dev_skel.h

http://www.jp.netbsd.org/docs/kernel/pseudo/pseudo_dev_skel.c

/usr/src/sys/arch/i386/include に pseudo_dev_skel.h を設置

/usr/src/sys/arch/i386/i386 に pseudo_dev_skel.c を設置

pseudo_dev_skel.c の先頭に struct skeleton_softc を追加するらしいんだが、いまんとこ↓だけで済んでる。

struct skelton_softc { struct device sc_dev; };

カーネルに新しいデバイスを知らせる

/usr/src/sys/arch/i386/conf/majors.i386

device-major	skeleton	char	140	skeleton

config(1) に新しいデバイスを知らせる

/usr/src/sys/arch/i386/conf/files.i386

file dev/skeleton.c	   skeleton	needs-flag

とあるんだが、dev には設置してないので結局以下のようにする。

defpseudo skeleton
file sys/arch/i386/i386/skeleton.c	   skeleton	needs-flag

カーネルコンフィグファイルに新しいデバイスを追加する

/usr/src/sys/arch/i386/conf/MYKERNEL

pseudo-device  skeleton

カーネルを再構築してインストール。

cd /usr/src
./build.sh kernel=MYKERNEL
cd ../obj/sys/arch/i386/compile/MYKERNEL
mv /netbsd /netbsd.old
cp netbsd /netbsd
shutdown -r now

手順は上記のとおりなんだが、ドキュメントのままだと ./build.sh したときにエラーになった。

 :
#   compile  MYKERNEL/skeleton.o
/usr/src/obj/tooldir.NetBSD-6.0-i386/bin/i486--netbsdelf-gcc -mno-sse -mno-sse2 -mno-sse3 -ffreestanding -fno-zero-initialized-in-bss -O2 -fstack-protector -Wstack-protector --param ssp-buffer-size=1 -fno-strict-aliasing -std=gnu99 -Werror -Wall -Wno-main -Wno-format-zero-length -Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wno-unreachable-code -Wno-pointer-sign -Wno-attributes -Wextra -Wno-unused-parameter -Wold-style-definition -Wno-sign-compare --sysroot=/usr/src/obj/destdir.i386 -Di386 -I. -I/usr/src/sys/../common/include -I/usr/src/sys/arch -I/usr/src/sys -nostdinc -DMAXUSERS=64 -D_KERNEL -D_KERNEL_OPT -std=gnu99 -I/usr/src/sys/lib/libkern/../../../common/lib/libc/quad -I/usr/src/sys/lib/libkern/../../../common/lib/libc/string -I/usr/src/sys/lib/libkern/../../../common/lib/libc/arch/i386/string -I/usr/src/sys/dist/ipf -I/usr/src/sys/external/isc/atheros_hal/dist -I/usr/src/sys/external/isc/atheros_hal/ic -I/usr/src/sys/external/bsd/drm/dist/bsd-core -I/usr/src/sys/external/bsd/drm/dist/shared-core -I/usr/src/sys/../common/include -I/usr/src/sys/external/bsd/acpica/dist/include -c /usr/src/sys/arch/i386/i386/skeleton.c
/usr/src/sys/arch/i386/i386/skeleton.c:51:53: error: expected declaration specifiers or '...' before 'caddr_t'
cc1: warnings being treated as errors
/usr/src/sys/arch/i386/i386/skeleton.c:60:9: error: initialization from incompatible pointer type
/usr/src/sys/arch/i386/i386/skeleton.c:66:1: error: missing initializer
/usr/src/sys/arch/i386/i386/skeleton.c:66:1: error: (near initialization for 'skeleton_cdevsw.d_flag')
/usr/src/sys/arch/i386/i386/skeleton.c:104:45: error: expected declaration specifiers or '...' before 'caddr_t'
/usr/src/sys/arch/i386/i386/skeleton.c: In function 'skeletonioctl':
/usr/src/sys/arch/i386/i386/skeleton.c:108:61: error: 'data' undeclared (first use in this function)
/usr/src/sys/arch/i386/i386/skeleton.c:108:61: note: each undeclared identifier is reported only once for each function it appears in
 :

ううん?

u_long command か caddr_t data が定義されてないのか?

マニュアル読む。

man driver

    const struct cdevsw foo_cdevsw {
            int (*d_open)(dev_t, int, int, struct lwp *);
            int (*d_close)(dev_t, int, int, struct lwp *);
            int (*d_read)(dev_t, struct uio *, int);
            int (*d_write)(dev_t, struct uio *, int);
            int (*d_ioctl)(dev_t, u_long, void *, int, struct lwp *);   ←←←←これ
            void (*d_stop)(struct tty *, int);
            struct tty *(*d_tty)(dev_t);
            int (*d_poll)(dev_t, int, struct lwp *);
            paddr_t (*d_mmap)(dev_t, off_t, int);
            int (*d_kqfilter)(dev_t, struct knote *);
            int d_flag;
    };

d_ioctl の 3 番目に注目。void* になってる。

skeletonioctl() の定義を見ると

struct skeleton_params *params = (struct skeleton_params *)data;

などとキャストしてるし、void * でいいか。

再度 ./build.sh

またエラーになった。

 :
/usr/src/sys/arch/i386/i386/skeleton.c:68:1: error: missing initializer
/usr/src/sys/arch/i386/i386/skeleton.c:68:1: error: (near initialization for 'skeleton_cdevsw.d_flag')
 :

d_flag って?

man driver を眺めても d_flag は名前しか出てこない。

sys/conf.h を眺める。

これか。

/*
 * Types for d_flag
 */
#define D_OTHER         0x0000
#define D_TAPE          0x0001
#define D_DISK          0x0002
#define D_TTY           0x0003
#define D_TYPEMASK      0x00ff
#define D_MPSAFE        0x0100
#define D_NEGOFFSAFE    0x0200

デバイスのタイプって?

よく分からないから D_OTHER でいいや。

もともとある const struct cdevsw skeleton_cdevsw の定義には最後のメンバー変数 d_flag が足りないのでエラーになっていたようだ。

/usr/src/sys/arch/i386/isa/cmos.c を参考などにして書きなおすとこうなった。

rin@mogu[/usr/src/sys/arch/i386/i386]% diff -u pseudo_dev_skel.c skeleton.c
--- pseudo_dev_skel.c 2009-05-22 00:30:08.000000000 +0900
+++ skeleton.c  2012-12-24 20:19:37.000000000 +0900
@@ -35,27 +35,35 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/conf.h>
-#include <sys/pseudo_dev_skel.h>
+#include <arch/i386/include/skeleton.h>
+
+
+struct skelton_softc {
+        struct device sc_dev;
+};
+
+

 /* Autoconfiguration glue */
 void   skeletonattach(int num);
 int     skeletonopen(dev_t device, int flags, int fmt, struct lwp *process);
 int     skeletonclose(dev_t device, int flags, int fmt, struct lwp *process);
-int     skeletonioctl(dev_t device, u_long command, caddr_t data,
+int     skeletonioctl(dev_t device, u_long command, void* data,
                      int flags, struct lwp *process);

 /* just define the character device handlers because that is all we need */
 const struct cdevsw skeleton_cdevsw = {
-        skeletonopen,
-       skeletonclose,
-       noread,
-       nowrite,
-        skeletonioctl,
-       nostop,
-       notty,
-       nopoll,
-       nommap,
-       nokqfilter,
+        .d_open = skeletonopen,
+       .d_close = skeletonclose,
+       .d_read = noread,
+       .d_write = nowrite,
+        .d_ioctl = skeletonioctl,
+       .d_stop = nostop,
+       .d_tty = notty,
+       .d_poll = nopoll,
+       .d_mmap = nommap,
+       .d_kqfilter = nokqfilter,
+       .d_flag = D_OTHER,
 };

 /*
@@ -94,7 +102,7 @@
  * Handle the ioctl for the device
  */
 int
-skeletonioctl(dev_t device, u_long command, caddr_t data, int flags,
+skeletonioctl(dev_t device, u_long command, void* data, int flags,
              struct lwp *process)
 {
        int error;

ユーザーレベルプログラムが新しいデバイスにアクセスすることを許す

mknod /dev/skel c 140 0
/bin/ls -l /dev/skel
crw-r--r--  1 root  wheel  140, 0 Dec 24 18:51 /dev/skel

ヘッダーファイル skeleton.h をインストールするために sys/arch/i386/include/Makefile に追加。

rin@mogu[/usr/src/sys/arch/i386/include]% diff -u Makefile.orig Makefile
--- Makefile.orig       2012-12-24 20:57:11.000000000 +0900
+++ Makefile    2012-12-24 20:57:31.000000000 +0900
@@ -24,6 +24,7 @@
        svr4_machdep.h sysarch.h \
        trap.h tss.h types.h \
        vm86.h vmparam.h \
-       wchar_limits.h
+       wchar_limits.h \
+        skeleton.h

make includes するとインストールされる。

rin@mogu[/usr/src/sys/arch/i386/include]% sudo make includes
#   install  /usr/include/i386/skeleton.h
/usr/src/obj/tooldir.NetBSD-6.0-i386/bin/i486--netbsdelf-install  -N /usr/src/etc -c  -r -c -o root -g wheel  -m 444 skeleton.h /usr/include/i386/skeleton.h

sample.c は include だけ変更。

rin@mogu[~/work/OS/NetBSD/device driver]% diff -u sample.c.orig sample.c
--- sample.c.orig       2007-06-09 20:33:50.000000000 +0900
+++ sample.c    2012-12-24 21:23:00.000000000 +0900
@@ -33,7 +33,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
-#include <sys/pseudo_dev_skel.h>
+#include <i386/skeleton.h>
+

 int main()
 {

コンパイル。

cc -o sample sample.c

実行

./sample

/var/log/message はこうなる。

Dec 24 20:59:25 mogu /netbsd: Got number of 42 and string of Hello World