Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1599426
  • 博文数量: 204
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 4427
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-06 08:03
个人简介

气质,源于心灵的自信!

文章存档

2018年(1)

2017年(1)

2016年(1)

2015年(18)

2014年(20)

2013年(30)

2012年(119)

2011年(14)

分类: LINUX

2012-10-30 16:32:00

下面是代码的设置流程:
//在init.c中
int main(int argc, char **argv)
{
     ......................
    INFO("reading config file\n");
    init_parse_config_file("/init.rc");

    /* pull the kernel commandline and ramdisk properties file in */
    import_kernel_cmdline(0, import_kernel_nv);//取出从boot传递过来的命令行参数
    /* don't expose the raw commandline to nonpriv processes */
    chmod("/proc/cmdline", 0440);
     ...................
    queue_builtin_action(set_init_properties_action, "set_init_properties");//保存参数到属性中
     ................
    return 0;
}

//跟踪该函数
void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu))
{
    char cmdline[1024];
    char *ptr;
    int fd;

     //从虚拟文件系统中取参数
    fd = open("/proc/cmdline", O_RDONLY);
    if (fd >= 0) {
        int n = read(fd, cmdline, 1023);
        if (n < 0) n = 0;

        /* get rid of trailing newline, it happens */
        if (n > 0 && cmdline[n-1] == '\n') n--;

        cmdline[n] = 0;
        close(fd);
    } else {
        cmdline[0] = 0;
    }

    ptr = cmdline;
    while (ptr && *ptr) {
        char *x = strchr(ptr, ' ');//找到下一个参数位置
        if (x != 0) *x++ = 0;
        import_kernel_nv(ptr, in_qemu);//解析
        ptr = x;//下一个要解析参数的位置
    }
}

//调用函数指针
static void import_kernel_nv(char *name, int in_qemu)
{
    char *value = strchr(name, '=');

    if (value == 0) return;
    *value++ = 0;//把“=”替换成终结符
    if (*name == 0) return;

    if (!in_qemu)//在实际应用中走该分支
    {
        /* on a real device, white-list the kernel options */
        if (!strcmp(name,"qemu")) {
            strlcpy(qemu, value, sizeof(qemu));
        } else if (!strcmp(name,"androidboot.console")) {
            strlcpy(console, value, sizeof(console));
        } else if (!strcmp(name,"androidboot.mode")) {
            strlcpy(bootmode, value, sizeof(bootmode));
        } else if (!strcmp(name,"androidboot.serialno")) {//比较名字
            strlcpy(serialno, value, sizeof(serialno));//取出usb串号的值
        }
     .......
    } else {
        /* in the emulator, export any kernel option with the
         * ro.kernel. prefix */
        char  buff[32];
        int   len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
        if (len < (int)sizeof(buff)) {
            property_set( buff, value );
        }
    }
}

//保存传递的值到属性中
static int set_init_properties_action(int nargs, char **args)
{
    ...................
    property_set("ro.serialno", serialno[0] ? serialno : "");
     ............
    return 0;
}

//在system/core/rootdir/etc/init.qcom.usb.sh中设置如下:
serialno=`getprop persist.usb.serialno`//如果persist.usb.serialno为空,则用传递过来的
case "$serialno" in
    "")
    serialnum=`getprop ro.serialno`//取出环境变量的值
    case "$serialnum" in
        "");; #Do nothing, use default serial number
        *)
        echo "$serialnum" > /sys/class/android_usb/android0/iSerial//写入到kernel中
    esac
    ;;
    * )
    echo "$serialno" > /sys/class/android_usb/android0/iSerial
esac

//在system/core/rootdir/etc/init.qcom.usb.rc设置vid,pid时位置代码如下:
on property:sys.usb.config=rndis,diag,adb
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 05C6//设置vid
    write /sys/class/android_usb/android0/idProduct 902D//设置pid
    write /sys/class/android_usb/android0/f_diag/clients diag
    write /sys/class/android_usb/android0/functions rndis,diag,adb//打开对应的功能
    write /sys/class/android_usb/android0/enable 1
    start adbd
    setprop sys.usb.state $sys.usb.config

阅读(16687) | 评论(2) | 转发(2) |
给主人留下些什么吧!~~

haijian01142013-06-09 11:46:00

老大 应用层是如果调用init.qcom.usb.rc来向kernel写入function的呢?比如我们进行usb功能的切换的时候,应用是如何调用init.qcom.usb.rc来写function的呢?