a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 159|回复: 3

[综合辅导] Linux认证自动创建设备节点

[复制链接]
发表于 2012-8-4 12:07:07 | 显示全部楼层 |阅读模式
在驱动用加入对udev的支持主要做的就是:在驱动初始化的代码里调用class_create(…)为该设备创建一个class,再为每个设备调用 device_create(…)( 在2.6较早的内核中用class_device_create)创建对应的设备。
; X& Z" }$ Y) \    5 h: N" b" A3 M) t  c
    内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
/ r6 v! A( g% K6 J   
7 e1 A7 x' Z& V/ E- `9 t5 X9 |    struct class定义在头文件include/linux/device.h中class_create(…)在/drivers/base/class.c中实现device_create(…)函数在/drivers/base/core.c中实现 class_destroy(…),device_destroy(…)也在/drivers/base/core.c中实现调用过程类似如下:& A7 K( c7 v% }$ e0 {% Q; c
   
8 L" I8 g1 i  d9 S' O    static struct class *spidev_class;4 W* C7 ~# A/ ]$ J; L
    & x% {' d4 {1 P- ]6 i; u
    /*-------------------------------------------------------------------------*/
/ f9 q! N; w' |    " |7 c' X1 C7 y' |4 L
    static int spidev_probe(struct spi_device *spi)
3 ]2 M" y  ]: ~; {( J! c7 f    % i) }+ n% I# t! ?5 X
    {5 g7 j0 f4 M, M' z
   
  w4 z6 T6 {9 K  ]- R' w    …5 w" U5 y5 O. @" Q$ l- V' J
    / [' x# V. ?3 J1 W$ ]
    dev = device_create(spidev_class, &spi->dev, spidev->devt,
+ I9 Z, q- _" F4 v    ! z2 a8 `7 m# k: N* [
    spidev, "spidev%d.%d",
- ]% D' r3 ?7 x- w- ?   
3 V4 r4 ], I* c( x+ L    spi->master->bus_num, spi->chip_select);+ J6 u; T/ _( s$ ?  n
      l; v# Q! E5 F
    …8 l7 Z8 e% E8 @2 M4 V% \
    . C& [% `8 ~  L& s+ g
    }
( v5 @1 F5 m( d( ]# \  R    ! y% b' o+ e. @+ H: }+ ^) g+ J
    static int spidev_remove(struct spi_device *spi)
  M! B1 F4 C6 O6 E' |4 v4 w' ?   
4 n/ J. p: p+ `, q    {/ X& {! v( T/ K* P2 ]5 t
    . X5 }3 U' R, \6 c' z+ w0 Q
    ……
' k8 D  R7 R# h0 v3 i' b+ s   
( [! z# O+ o  ^& k; L    device_destroy(spidev_class, spidev->devt);: |! j- k! t: v8 F
   
' W) m- Z( ~, I8 V. u* f+ }# b    ……
# m; N: v- {7 J( o& t# h1 @    9 F" h- E2 C3 D. ~: b# F5 o& p
    return 0;
3 }4 j8 s8 B% H& f1 u; T9 K" Y   
4 W- f3 N# }# D    }
2 R# w- |& S1 K; d# X   
' X# |3 B$ F5 I1 |% w    static struct spi_driver spidev_spi = {
7 `0 _% @2 ~: a   
: z2 V2 g, n: h, Q    .driver = {. ]) W5 i/ Y- H' @  l1 ?9 W
    4 u' g7 {" v- i  {
    .name =        "spidev",- {6 F: `( j. _; a' m
    # y3 j5 L0 O$ d1 W( |; D
    .owner =    THIS_MODULE,, e* K) M: J9 |& S& [) b
   
! `& x, u5 D( q6 X2 w* m7 M    },5 f3 L( u9 Z6 D3 n0 \/ i
    1 D2 s, G) i9 F* S! B
    .probe =    spidev_probe,
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:07:08 | 显示全部楼层

Linux认证自动创建设备节点

.remove =    __devexit_p(spidev_remove),, ^! H  s0 ?1 ~: U/ i
   
5 z; H7 p! ]- \5 P6 V    };
% Y* Z8 a7 |: C  X5 d   
' f0 p6 J$ f! a    /*-------------------------------------------------------------------------*/
7 i+ K9 R6 a9 g& s   
* s0 P8 g8 y' V& l1 ]    static int __init spidev_init(void)
, ]7 e& @! E6 n- \# ~4 k; K1 d4 U* L    8 I) |2 G4 y- n& T! [, L3 i  L
    {
7 v) E7 K9 D. K5 h, y    1 B: _( X) G& p# I/ v' Q* }
    …/ s3 v# S9 M2 @  h* ^
   
% W/ Z5 ?. A( R- l) v    spidev_class = class_create(THIS_MODULE, "spidev");" y" E5 c9 ]+ b* |- B) i+ e
    : U7 B8 T9 z6 L* m/ Z  G
    if (IS_ERR(spidev_class)) {4 x* m& W" V- P, c+ Y
   
  c3 O! s  D# ^0 ~1 V2 r5 ^1 a    unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);  K' i: o/ |% \/ m5 K8 ^0 b
    & A2 z4 F. ~0 e  C: ^
    return PTR_ERR(spidev_class);; ]5 x; N; D2 i3 ~( e1 k
    ! d  r3 r  R' b
    }
- [# J3 \6 v% w    + B3 C" |: t* j+ l
    …6 K( g( {% V' v) u4 k
    7 G. F: c# `! R9 Z. q, q0 V
    }$ P" `1 ^. ^5 d. I. G: Y
    5 z. U! y/ J7 m- `" M8 J
    module_init(spidev_init);
: }7 m$ o) q1 ?    & ]% R2 I3 j( [% n8 g; c
    static void __exit spidev_exit(void)- l( }0 _9 j+ W* n
   
3 n1 [8 W5 o5 P$ u. a- B2 L  {    {
0 {/ [, e' r$ F% q    & t- M0 `$ Y5 ]* r# Y! [6 n. f. g
    ……- |& L0 C: z9 ^) M  u
    6 C+ a. E* ~/ k$ r
    class_destroy(spidev_class);/ t* g5 ?2 z8 V& o" }8 N* X1 S
    3 A5 w7 ]/ @8 W; D! f3 y% C/ G  r" c
    ……  W4 ]. N4 r* g- F
    % F# \, |- B) V
    }
8 S5 Q/ G3 Q, n8 g9 m; d  T   
! D! r" `, \' v9 d+ O    module_exit(spidev_exit);
! {+ B! {$ O& i& H   
% j: X* O% }, A0 B    MODULE_DESCRIPTION("User mode SPI device interface");5 d4 S1 r& J) y# w! v) p
    7 X% L0 M! w+ l4 R8 S
    MODULE_LICENSE("GPL");9 }$ w/ [4 n2 X8 B
    ' q. v0 x4 g% X' C$ E5 F) i
    下面以一个简单字符设备驱动来展示如何使用这几个函数
2 @1 `+ Y  I: Y- f7 \" y  R8 g   
) V  ]% a$ q3 c2 {    #include - P2 s- }$ x$ g. D2 j: B
   
/ M; u3 b  i! Q$ c    #include   v* k% ]6 s, U1 y+ R, Q; d
   
, x: q' G: a" y1 @# U: ?0 U    #include / i/ ^% F9 }6 L* I' |- y* H5 T
    # K6 y# }6 I- A& O9 w$ H
    #include
8 |; d$ [3 `$ L- v1 ?7 Y2 `    3 N- G: d; {# R2 y7 l) x
    #include
: \, L1 O% W3 q   
  r0 R- R7 K% l4 F, j& q5 X1 k  z    #include
2 `" `0 V' G& H; C. {+ U4 f   
1 e" c  z# S, g& j5 f) w    int HELLO_MAJOR = 0;
% {+ c! W% R$ V1 N% X   
% Q" V3 {: n" x' u! W# ^+ k& Q4 T4 Y    int HELLO_MINOR = 0;1 n# f4 ~, L/ Z6 X# D, f
    + n" w9 B8 d" s! H: l
    int NUMBER_OF_DEVICES = 2;
' }, y, u- n$ u* w  |) h   
8 ?8 M8 ~+ s$ K8 N( Z' P, D    struct class *my_class;
9 _$ |: ?% o$ O   
+ y1 ]) z8 G, M! V    struct cdev cdev;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:07:09 | 显示全部楼层

Linux认证自动创建设备节点

dev_t devno;
6 a7 e- x! ], _9 m$ `   
, h, V+ ?. @5 s7 u9 u    struct file_operations hello_fops = {
  ]6 w! ^0 `* w' f* W& Z) g5 f    . t8 L/ a, N8 f
    .owner = THIS_MODULE
$ b% _5 M7 e" M1 g, B   
( l: s2 _  e# V) U+ o    };
: y: J! f# ?, |8 Z) f' {* j9 k4 w3 y   
# _" c0 x( b/ K/ N+ k; K    static int __init hello_init (void)/ h4 V1 r& y. C' h% ]) o3 [
   
) y; }" H9 ^4 ~4 c* j- T    {* q) S" S! w' b. l8 C, X& h
    & c7 Z0 u: X! ^3 o! m
    int result;% a' _- r0 R) Y  N
    6 {( d/ q3 k2 c2 w' k$ v
    devno = MKDEV(HELLO_MAJOR, HELLO_MINOR);! P2 m, e: L: Q
    2 ]' A  W/ E5 C( z
    if (HELLO_MAJOR)+ w+ p2 u8 o/ T7 W
    1 R; p. m7 k+ a/ g5 k
    result = register_chrdev_region(devno, 2, "memdev");
& \: V6 @1 z/ r: r6 V3 {   
# E, M/ U3 G1 ~& F  P    else+ ^5 B4 j( S2 M$ \9 p# w, V
   
; x& W, t. s+ k' Y) f$ {    {8 M# g9 n7 ~9 M5 M& d& r# s% h
   
2 G8 N7 W3 J6 G) T    result = alloc_chrdev_region(&devno, 0, 2, "memdev");
7 Z/ q! U1 ]% S2 t1 ^5 x0 H    5 `( Y7 x" Z% r2 @0 c; L2 X
    HELLO_MAJOR = MAJOR(devno);
3 p, a6 w0 v; l7 x) S   
" b: E" U5 t# V    }
0 l5 ?- k0 m" I; i# A% @! N+ R   
7 a8 `4 O. F2 L2 J; M8 G    printk("MAJOR IS %d\n",HELLO_MAJOR);4 s/ ]+ |. }& ?4 `4 Y
   
  f5 Y& `; I, K6 I5 K    my_class = class_create(THIS_MODULE,"hello_char_class");  //类名为hello_char_class
7 d7 n; I( B: ~5 y   
( ^+ d  U4 n2 m1 _& r/ K    if(IS_ERR(my_class))( x0 s' G* Z& _0 R1 ~! H
   
: H' F' S: N) f8 O0 k# n' @! ?! N6 e    {
, Q' Z3 u# a; S# T   
/ v9 S& y8 v3 O4 E3 d7 V    printk("Err: failed in creating class.\n");: l, T. E+ I6 Q  C/ ~) X
   
" `7 D7 \8 y& `# U2 d) g) i    return -1;
4 k% r4 }- j* t" Y   
2 h5 ]3 X$ O" ^5 Z) V    }  G( ]8 ]& e. `  y" J' n
    ' l' a7 F3 r# Q( S1 I: H  q$ X
    device_create(my_class,NULL,devno,NULL,"memdev");      //设备名为memdev
  P) w. a* }; A3 ]& o8 P    ' ~) s. E1 n3 X+ S3 a' X
    if (result
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:07:10 | 显示全部楼层

Linux认证自动创建设备节点

}! u" A7 t5 e& L! @. R! @8 ^
    8 U; i, K0 P* m  s
    static void __exit hello_exit (void)  E' q/ p' L5 x: Y9 g2 ^: r, O- `4 G
   
& k- f( A( u/ i/ r    {
& Q: ?6 m( P  ^2 ~4 r& k   
# l' e4 t7 N1 W. f$ V8 t8 G! V+ A    cdev_del (&cdev);( ^) X: n5 p( j% X$ v: f3 U0 `
   
% I+ J3 @% m: v* i, \* J  v- ~* B    device_destroy(my_class, devno);         //delete device node under /dev//必须先删除设备,再删除class类9 V" V4 {' u8 y) t+ f
   
  y6 ^& m0 S6 H0 ?6 ^+ i7 d    class_destroy(my_class);                 //delete class created by us
  H; D+ M; z3 e. N5 H   
+ i+ z3 l1 Z1 T    unregister_chrdev_region (devno,NUMBER_OF_DEVICES);4 p! T5 J8 J# J$ F1 a+ C
   
# H& x" ]1 r* b3 H6 E( J/ [% P    printk (KERN_INFO "char driver cleaned up\n");
$ H- t, `9 E0 d$ q9 x# t   
$ x# O' t- }4 \    }
. C" @! i* g/ I8 g4 C6 W- T6 P   
( ^) |* o8 u5 W( u! s& {    module_init (hello_init);) b4 A( ~; Z$ T( t  ?6 c* Y
   
5 J" W; X6 @7 m- G" K. ^- P3 z    module_exit (hello_exit);
# o9 M6 p, W5 G/ M/ I% h    9 y+ P. [' E) e
    MODULE_LICENSE ("GPL");' i3 m3 J% _9 k! P- z
   
' \  d2 k7 m  O( v    这样,模块加载后,就能在/dev目录下找到memdev这个设备节点了。6 a% B- F8 k+ T, |; u9 {0 t+ T+ t
   
* }: ?3 R+ |7 l! \$ w7 v    例2:内核中的drivers/i2c/i2c-dev.c
6 R" B5 ]  U( q   
: ]$ Y4 Y; j% p% _5 u/ j5 Y    在i2cdev_attach_adapter中调用device_create(i2c_dev_class, &adap->dev,% z8 W! y& @6 H
   
: A* I5 {1 R( Q  x/ U    MKDEV(I2C_MAJOR, adap->nr), NULL,/ v8 Y% A* k% L3 ]
   
' S9 A* k  J7 T0 d1 O; \* E    "i2c-%d", adap->nr);8 n# p' T' L% Y0 A
    2 v6 }" U/ {( X, }! U9 c( b$ d; q3 K
    这样在dev目录就产生i2c-0  或i2c-1节点; F0 ?( m) S/ g7 F7 |- I
    " c- q4 j& Q. R  O$ z
    接下来就是udev应用,udev是应用层的东西,udev需要内核sysfs和tmpfa的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间
$ E- t( ^5 A& a, e, ^- _6 a) u   
( a! X$ E5 |8 ]2 C- r* W    udev的源码可以在去相关网站下载,然后就是对其在运行环境下的移植,指定交叉编译环境,修改Makefile下的CROSS_COMPILE,如为 mipsel-linux-,DESTDIR=xxx,或直接make CROSS_COMPILE=mipsel-linux-,DESTDIR=xxx 并install把主要生成的udevd、udevstart拷贝rootfs下的/sbin/目录内,udev的配置文件udev.conf和 rules.d下的rules文件拷贝到rootfs下的/etc/目录内,并在rootfs/etc/init.d/rcS中添加以下几行:+ N8 O7 U$ j5 Y, m8 o8 g* r
   
- v3 R* j" C: l4 A7 }    echo "Starting udevd…") A. @, a( v5 B% ?6 h3 g& B2 _1 q& M
   
+ B0 L3 e) f* u) ]: r2 b2 {    /sbin/udevd --daemon* Y% {1 C6 y8 e
   
" J4 G7 R/ M( e( Y% x+ z    /sbin/udevstart' ^  ~4 ]  X* Z/ \+ f2 _4 W7 Y
    ! x9 X: o( b7 L' {
    (原rcS内容如下:$ g2 h7 M6 [* [! P: o! }! @' p: F
    & _. W3 l, H8 S2 M7 v2 |7 w8 g
    # mount filesystems4 w! J0 O; w0 j
    # g0 ~2 @. I1 E2 E: x
    /bin/mount -t proc /proc /proc, c3 ~% @( H; R0 `) }& N
    ( S% X& j0 j1 z' w. ^' Y% }3 Q
    /bin/mount -t sysfs sysfs /sys
; h2 t6 y5 L  U* p( B7 g    4 O$ s$ E& u$ w5 y  d8 a
    /bin/mount -t tmpfs tmpfs /dev
' |- y/ ~0 C7 Z2 M: {    + P. y, K8 a0 m
    # create necessary devices
8 D; x* V$ w4 q- x0 J  D. v# J    6 f. a% n' N% B5 G- x- A
    /bin/mknod /dev/null c 1 3
! b6 E2 [8 d! u' r- n2 }: T   
4 u! G, @6 D8 {5 U" m    /bin/mkdir /dev/pts
0 [+ U3 ]) R0 p7 d6 Q7 t, c   
+ z3 s3 \1 q/ j6 J    /bin/mount -t devpts devpts /dev/pts1 v( X7 y: h+ d
   
7 c0 {# [4 }4 J$ g5 r    /bin/mknod /dev/audio c 14 4
  ~3 n; m& ~5 Y, X6 @   
! @) Q9 p' G* |, R3 e- s; B8 B    /bin/mknod /dev/ts c 10 163 o3 T- k! y( p+ H! P
   
" u: L' g; Z+ Q3 y    )- _+ D* u6 r; U" L
   
' `, K- x; }. Y% ]+ V& O3 x    这样当系统启动后,udevd和udevstart就会解析配置文件,并自动在/dev下创建设备节点文件
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-17 23:29 , Processed in 0.258376 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表