Chinaunix首页 | 论坛 | 博客
  • 博客访问: 363659
  • 博文数量: 160
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-18 01:16
文章分类

全部博文(160)

文章存档

2016年(4)

2015年(13)

2014年(29)

2013年(114)

我的朋友

分类: LINUX

2015-02-10 14:58:12

下面是代码的设置流程:
//在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

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