本文编辑整理自: http://www.linuxidc.com/Linux/2011-07/38987.htm 三、 Logger初始化过程分析。 kernel/drivers/staging/Android/logger.c 文件,定义了四个日志设备: /*   * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which   * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than   * LONG_MAX minus LOGGER_ENTRY_MAX_LEN.   */   #define  DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \    static unsigned char _buf_ ## VAR[SIZE]; \   static struct logger_log VAR = { \       .buffer = _buf_ ## VAR, \       .misc = { \           .minor = MISC_DYNAMIC_MINOR, \           .name = NAME, \           . fops &logger_fops, \           .parent = NULL, \       }, \       .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \       .readers = LIST_HEAD_INIT(VAR .readers), \       .mutex = __MUTEX_INITIALIZER(VAR .mutex), \       .w_off = 0, \       .head = 0, \       .size = SIZE, \   };      DEFINE_LOGGER_DEVICE( log_main ,  LOGGER_LOG_MAIN , 64*1024)   DEFINE_LOGGER_DEVICE( log_events ,  LOGGER_LOG_EVENTS , 256*1024)   DEFINE_LOGGER_DEVICE(l og_radio LOGGER_LOG_RADIO , 64*1024)   DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024       上面的代码创建了 log_main log_events,log_system log_radio 这4个logger_log结构体,名称分别 LOGGER_LOG_MAIN LOGGER_LOG_EVENTS,LOGGER_LOG_SYSTEM LOGGER_LOG_RADIO ,它们的次设备号为MISC_DYNAMIC_MINOR,即为在注册时动态分配。在 logger.h 文件中,这三个宏的定义如下:         #define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */        #define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */        #define LOGGER_LOG_SYSTEM "log_system" /* system/framework  message*/        #define LOGGER_LOG_MAIN "log_main" /* everything else */ 注册的日志设备文件操作方法为 logger_fopsstatic struct  file_operations logger_fops  = {       .owner = THIS_MODULE,       .read = logger_read,       .aio_write = logger_aio_write,       .poll = logger_poll,       .unlocked_ioctl = logger_ioctl,       .compat_ioctl = logger_ioctl,       .open = logger_open,       .release = logger_release,   };   日志驱动程序模块的初始化函数为logger_init: static int  __init  logger_init(void)    {       int ret;        ret = init_log(&log_main);       if (unlikely(ret))           goto out;        ret = init_log(&log_events);        if (unlikely(ret))           goto out;           ret = init_log(&log_radio);        if (unlikely(ret))           goto out;       ret = init_log(&log_system);       if (unlikely(ret))           goto out;   out:       return ret;   }   device_initcall( logger_init );  
logger_init 函数通过调用 init_log 函数来初始化了上述提到的4个日志设备. 关于 static int  __init  logger_init(void)  __init的意义请参照《 linux代码中的__init和__exit宏》 关于 device_initcall( logger_init );  请参考《 Linux内核中的xx_initcallstatic int  __init init_log(struct logger_log *log)  {        int ret;           ret =  misc_register (&log->misc);       if (unlikely(ret)) {           printk(KERN_ERR "logger: failed to register misc "                  "device for log '%s'!\n", log->misc.name);           return ret;       }          printk(KERN_INFO "logger: created %luK log '%s'\n",              (unsigned long) log->size >> 10, log->misc.name);           return 0;   }      init_log 函数主要调用了 misc_register 函数来注册misc设备, misc_register 函数定义在 kernel/common/drivers/char/misc.c 文件中: /**   *      misc_register   -       register a miscellaneous device   *      @misc: device structure   *   *      Register a miscellaneous device with the kernel. If the minor   *      number is set to %MISC_DYNAMIC_MINOR a minor number is assigned   *      and placed in the minor field of the structure. For other cases   *      the minor number requested is used.   *   *      The structure passed is linked into the kernel and may not be   *      destroyed until it has been unregistered.   *   *      A zero is returned on success and a negative errno code for   *      failure.   */      int misc_register(struct miscdevice * misc)   {           struct miscdevice *c;           dev_t dev;            int err = 0;              INIT_LIST_HEAD(&misc->list);              mutex_lock(&misc_mtx);           list_for_each_entry(c, &misc_list, list) {                    if (c->minor == misc->minor) {                           mutex_unlock(&misc_mtx);                           return -EBUSY;                   }           }               if (misc->minor == MISC_DYNAMIC_MINOR) {                    int i = DYNAMIC_MINORS;                    while (--i >= 0)                           if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)                                   break;                   if (i<0) {                           mutex_unlock(&misc_mtx);                           return -EBUSY;                   }                   misc->minor = i;           }               if (misc->minor < DYNAMIC_MINORS)                   misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);            dev = MKDEV(MISC_MAJOR, misc->minor);              misc->this_device = device_create(misc_class, misc->parent, dev, NULL,                                             "%s", misc->name);           if (IS_ERR(misc->this_device)) {                   err = PTR_ERR(misc->this_device);                   goto out;           }              /*           * Add it to the front, so that later devices can "override"           * earlier defaults           */            list_add(&misc->list, &misc_list);    out:           mutex_unlock(&misc_mtx);           return err;   }   注册完成后,通过device_create创建设备文件节点。 这样将创建 /sys/class/misc/log_radion , /sys/class/misc/log_events , /sys/class/misc/log_system , /sys/class/misc/log_main 四个设备节点文件。 我们一般是通过读写这四个文件的映射文件来进行交互。映射文件分别为 /dev/log/radio , /dev/log/events , /dev/log/system , /dev/log/main 应用init层之后init进程 在system/core/init/devices.c中device_init()->coldboot()->do_coldboot()->handle_device_fd()->handle_device_event() static void handle_device_event(struct uevent *uevent) {      char devpath[96];      char *base, *name;     i nt block;
         /* if it's not a /dev device, nothing to do */      if((uevent->major < 0) || (uevent->minor < 0))          return;
         /* do we have a name? */     name = strrchr(uevent->path, '/');      if(!name)          return;     name++;
         /* too-long names would overrun our buffer */      if(strlen(name) > 64)         return;
         /* are we block or char? where should we live? */      if(!strncmp(uevent->path, "/block", 6)) {         block = 1;         base = "/dev/block/";         mkdir(base, 0755);     }  else {         block = 0;              /* this should probably be configurable somehow */          if(!strncmp(uevent->path, "/class/graphics/", 16)) {             base = "/dev/graphics/";             mkdir(base, 0755);         }  else if (!strncmp(uevent->path, "/class/oncrpc/", 14)) {             base = "/dev/oncrpc/";             mkdir(base, 0755);         }  else if (!strncmp(uevent->path, "/class/adsp/", 12)) {             base = "/dev/adsp/";             mkdir(base, 0755);       }  else if(!strncmp(uevent->path, "/class/input/", 13)) {             base = "/dev/input/";             mkdir(base, 0755);         }  else if(!strncmp(uevent->path, "/class/mtd/", 11)) {             base = "/dev/mtd/";             mkdir(base, 0755);         }  else if(!strncmp(uevent->path,  "/class/misc/", 12) &&                     !strncmp(name, " log_", 4)) {             base = " /dev/log/";              mkdir(base, 0755);             name += 4;         } else             base = "/dev/";     }
     snprintf(devpath, sizeof(devpath), "%s%s", base, name);
     if(!strcmp(uevent->action, "add")) {          make_device(devpath, block, uevent->major, uevent->minor);          return;     }
     if(!strcmp(uevent->action, "remove")) {         unlink(devpath);          return;     } } 这样将日志的四个设备节点文件映射为以下4个文件/dev/log/radio,/dev/log/events,/dev/log/system,/dev/log/main.

更多相关文章

  1. C语言函数的递归(上)
  2. CM13.0代码下载
  3. Android(安卓)笔记
  4. Ubuntu 编译Android若干错误及解决方法(转)
  5. Android(安卓)MediaPlayer基本使用方式
  6. android miscdevice(混杂设备)驱动编写注意
  7. Android(安卓)读取内存文件返回byte数组
  8. PackageManagerService(Android5.1)深入分析(四)安装应用
  9. mac版 android破解软件下载安装

随机推荐

  1. Error:Cause: buildToolsVersion is not
  2. 如何在一个声卡添加pa codec设备
  3. Android源码开发中单个模块的编译自动化
  4. Android(安卓)ConstraintLayout 降低布局
  5. Android(安卓)-- View
  6. Error while executing process /Users/x
  7. Android(安卓)使用ORMLite 操作数据库
  8. Android(安卓)使用的Project build.gradl
  9. [译]ANDROID Porting系列
  10. Android双击事件拦截方法