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