【轉】Android如何生成設備節點

在Android中,由於沒有mdev和udev,所以它沒有辦法動態的生成設備節點,那麼它是如何做的呢?
我們可以在system/core/init/下的init.c和devices.c中找到答案:
init.c中

  1. int  main( int  argc,  char  **argv) 
  2.     ...  
  3.         /* Get the basic filesystem setup we need put  
  4.          * together in the initramdisk on / and then we'll  
  5.          * let the rc file figure out the rest.  
  6.          */  
  7.     mkdir("/dev" , 0755); 
  8.     mkdir("/proc" , 0755); 
  9.     mkdir("/sys" , 0755); 
  10.   
  11.     mount("tmpfs" "/dev" "tmpfs" , 0,  "mode=0755" ); 
  12.     mkdir("/dev/pts" , 0755); 
  13.     mkdir("/dev/socket" , 0755); 
  14.     mount("devpts" "/dev/pts" "devpts" , 0, NULL); 
  15.     mount("proc" "/proc" "proc" , 0, NULL); 
  16.     mount("sysfs" "/sys" "sysfs" , 0, NULL); 
  17.   
  18.    for (;;) { 
  19.        ... 
  20.         if  (ufds[0].revents == POLLIN) 
  21.             handle_device_fd(device_fd); 
  22.   
  23.         if  (ufds[1].revents == POLLIN) 
  24.             handle_property_set_fd(property_set_fd); 
  25.         if  (ufds[3].revents == POLLIN) 
  26.             handle_keychord(keychord_fd); 
  27.     } 
  28.   
  29.     return  0; 
  30. }  


我們再來看看handle_device_fd(),該函數定義在devices.c中

  1. void  handle_device_fd( int  fd) 
  2.         ... 
  3.         handle_device_event(&uevent); 
  4.         handle_firmware_event(&uevent); 
  5.     } 
  6. }  


而handle_device_event定義如下:

  1. static   void  handle_device_event( struct  uevent *uevent) 
  2.     ... 
  3.     if (!strcmp(uevent->action,  "add" )) { 
  4.         make_device(devpath, block, uevent->major, uevent->minor); 
  5.         return
  6.     } 
  7.     ... 
  8. }  


make_device定義如下:

  1. static   void  make_device( const   char  *path,  int  block,  int  major,  int  minor) 
  2.     ... 
  3.     mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); 
  4.     dev = (major << 8) | minor; 
  5.     ... 
  6.     setegid(gid); 
  7.     mknod(path, mode, dev); 
  8.     chown(path, uid, -1); 
  9.     setegid(AID_ROOT); 
  10. }  


我們看看get_device_perm如下實現:

  1. static  mode_t get_device_perm( const   char  *path, unsigned *uid, unsigned *gid) 
  2.     mode_t perm; 
  3.   
  4.     if  (get_device_perm_inner(qemu_perms, path, uid, gid, &perm) == 0) { 
  5.         return  perm; 
  6.     } else   if  (get_device_perm_inner(devperms, path, uid, gid, &perm) == 0) { 
  7.         return  perm; 
  8.     } else  { 
  9.         struct  listnode *node; 
  10.         struct  perm_node *perm_node; 
  11.         struct  perms_ *dp; 
  12.   
  13.         /* Check partners list. */  
  14.         list_for_each(node, &devperms_partners) { 
  15.             perm_node = node_to_item(node, struct  perm_node, plist); 
  16.             dp = &perm_node->dp; 
  17.   
  18.             if  (dp->prefix) { 
  19.                 if  (strncmp(path, dp->name, strlen(dp->name))) 
  20.                     continue
  21.             } else  { 
  22.                 if  (strcmp(path, dp->name)) 
  23.                     continue
  24.             } 
  25.             /* Found perm in partner list. */  
  26.             *uid = dp->uid; 
  27.             *gid = dp->gid; 
  28.             return  dp->perm; 
  29.         } 
  30.         /* Default if nothing found. */  
  31.         *uid = 0; 
  32.         *gid = 0; 
  33.         return  0600; 
  34.     } 
  35. }  


我們最後可以看到在devperms中定義了要生成的設備節點:

  1. static   struct  perms_ devperms[] = { 
  2.     { "/dev/null" ,          0666,   AID_ROOT,       AID_ROOT,       0 }, 
  3.     { "/dev/zero" ,          0666,   AID_ROOT,       AID_ROOT,       0 }, 
  4.     { "/dev/full" ,          0666,   AID_ROOT,       AID_ROOT,       0 }, 
  5.     { "/dev/ptmx" ,          0666,   AID_ROOT,       AID_ROOT,       0 }, 
  6.     { "/dev/tty" ,           0666,   AID_ROOT,       AID_ROOT,       0 }, 
  7.     { "/dev/random" ,        0666,   AID_ROOT,       AID_ROOT,       0 }, 
  8.     { "/dev/urandom" ,       0666,   AID_ROOT,       AID_ROOT,       0 }, 
  9.     { "/dev/ashmem" ,        0666,   AID_ROOT,       AID_ROOT,       0 }, 
  10.     { "/dev/binder" ,        0666,   AID_ROOT,       AID_ROOT,       0 }, 
  11.   
  12.         /* logger should be world writable (for logging) but not readable */  
  13.     { "/dev/log/" ,          0662,   AID_ROOT,       AID_LOG,        1 }, 
  14.   
  15.     /* the msm hw3d client device node is world writable/readable. */  
  16.     { "/dev/msm_hw3dc" ,     0666,   AID_ROOT,       AID_ROOT,       0 }, 
  17.   
  18.     /* gpu driver for adreno200 is globally accessible */  
  19.     { "/dev/kgsl" ,          0666,   AID_ROOT,       AID_ROOT,       0 }, 
  20.   
  21.         /* these should not be world writable */  
  22.     { "/dev/diag" ,          0660,   AID_RADIO,      AID_RADIO,        0 }, 
  23.     { "/dev/diag_arm9" ,     0660,   AID_RADIO,      AID_RADIO,        0 }, 
  24.     { "/dev/android_adb" ,   0660,   AID_ADB,        AID_ADB,        0 }, 
  25.     { "/dev/android_adb_enable" ,   0660,   AID_ADB,        AID_ADB,        0 }, 
  26.     { "/dev/ttyMSM0" ,       0600,   AID_BLUETOOTH,  AID_BLUETOOTH,  0 }, 
  27.     { "/dev/ttyHS0" ,        0600,   AID_BLUETOOTH,  AID_BLUETOOTH,  0 }, 
  28.     { "/dev/uinput" ,        0660,   AID_SYSTEM,     AID_BLUETOOTH,  0 }, 
  29.     { "/dev/alarm" ,         0664,   AID_SYSTEM,     AID_RADIO,      0 }, 
  30.     { "/dev/tty0" ,          0660,   AID_ROOT,       AID_SYSTEM,     0 }, 
  31.     { "/dev/graphics/" ,     0660,   AID_ROOT,       AID_GRAPHICS,   1 }, 
  32.     { "/dev/msm_hw3dm" ,     0660,   AID_SYSTEM,     AID_GRAPHICS,   0 }, 
  33.     { "/dev/input/" ,        0660,   AID_ROOT,       AID_INPUT,      1 }, 
  34.     { "/dev/eac" ,           0660,   AID_ROOT,       AID_AUDIO,      0 }, 
  35.     { "/dev/cam" ,           0660,   AID_ROOT,       AID_CAMERA,     0 }, 
  36.     { "/dev/pmem" ,          0660,   AID_SYSTEM,     AID_GRAPHICS,   0 }, 
  37.     { "/dev/pmem_adsp" ,     0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  38.     { "/dev/pmem_camera" ,   0660,   AID_SYSTEM,     AID_CAMERA,     1 }, 
  39.     { "/dev/oncrpc/" ,       0660,   AID_ROOT,       AID_SYSTEM,     1 }, 
  40.     { "/dev/adsp/" ,         0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  41.     { "/dev/snd/" ,          0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  42.     { "/dev/mt9t013" ,       0660,   AID_SYSTEM,     AID_SYSTEM,     0 }, 
  43.     { "/dev/msm_camera/" ,   0660,   AID_SYSTEM,     AID_SYSTEM,     1 }, 
  44.     { "/dev/akm8976_daemon" ,0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  45.     { "/dev/akm8976_aot" ,   0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  46.     { "/dev/akm8973_daemon" ,0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  47.     { "/dev/akm8973_aot" ,   0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  48.     { "/dev/bma150" ,        0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  49.     { "/dev/cm3602" ,        0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  50.     { "/dev/akm8976_pffd" ,  0640,   AID_COMPASS,    AID_SYSTEM,     0 }, 
  51.     { "/dev/lightsensor" ,   0640,   AID_SYSTEM,     AID_SYSTEM,     0 }, 
  52.     { "/dev/msm_pcm_out" ,   0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  53.     { "/dev/msm_pcm_in" ,    0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  54.     { "/dev/msm_pcm_ctl" ,   0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  55.     { "/dev/msm_snd" ,       0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  56.     { "/dev/msm_mp3" ,       0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  57.     { "/dev/audience_a1026" , 0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  58.     { "/dev/tpa2018d1" ,     0660,   AID_SYSTEM,     AID_AUDIO,      1 }, 
  59.     { "/dev/msm_audpre" ,    0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  60.     { "/dev/msm_audio_ctl" , 0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  61.     { "/dev/htc-acoustic" ,  0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  62.     { "/dev/vdec" ,          0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  63.     { "/dev/q6venc" ,        0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  64.     { "/dev/snd/dsp" ,       0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  65.     { "/dev/snd/dsp1" ,      0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  66.     { "/dev/snd/mixer" ,     0660,   AID_SYSTEM,     AID_AUDIO,      0 }, 
  67.     { "/dev/smd0" ,          0640,   AID_RADIO,      AID_RADIO,      0 }, 
  68.     { "/dev/qemu_trace" ,    0666,   AID_SYSTEM,     AID_SYSTEM,     0 }, 
  69.     { "/dev/qmi" ,           0640,   AID_RADIO,      AID_RADIO,      0 }, 
  70.     { "/dev/qmi0" ,          0640,   AID_RADIO,      AID_RADIO,      0 }, 
  71.     { "/dev/qmi1" ,          0640,   AID_RADIO,      AID_RADIO,      0 }, 
  72.     { "/dev/qmi2" ,          0640,   AID_RADIO,      AID_RADIO,      0 }, 
  73.         /* CDMA radio interface MUX */  
  74.     { "/dev/ts0710mux" ,     0640,   AID_RADIO,      AID_RADIO,      1 }, 
  75.     { "/dev/ppp" ,           0660,   AID_RADIO,      AID_VPN,        0 }, 
  76.     { "/dev/tun" ,           0640,   AID_VPN,        AID_VPN,        0 }, 
  77.     { NULL, 0, 0, 0, 0 }, 
  78. };  



本文出自 “Mobile and Linux Development ” 博客,請務必保留此出處http://buaadallas.blog.51cto.com/399160/394351

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章