⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    char name[16];    int number;} mtd_part_map[MAX_MTD_PARTITIONS];static int mtd_part_count = -1;static void find_mtd_partitions(void){    int fd;    char buf[1024];    char *pmtdbufp;    ssize_t pmtdsize;    int r;    fd = open("/proc/mtd", O_RDONLY);    if (fd < 0)        return;    buf[sizeof(buf) - 1] = '\0';    pmtdsize = read(fd, buf, sizeof(buf) - 1);    pmtdbufp = buf;    while (pmtdsize > 0) {        int mtdnum, mtdsize, mtderasesize;        char mtdname[16];        mtdname[0] = '\0';        mtdnum = -1;        r = sscanf(pmtdbufp, "mtd%d: %x %x %15s",                   &mtdnum, &mtdsize, &mtderasesize, mtdname);        if ((r == 4) && (mtdname[0] == '"')) {            char *x = strchr(mtdname + 1, '"');            if (x) {                *x = 0;            }            INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1);            if (mtd_part_count < MAX_MTD_PARTITIONS) {                strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1);                mtd_part_map[mtd_part_count].number = mtdnum;                mtd_part_count++;            } else {                ERROR("too many mtd partitions\n");            }        }        while (pmtdsize > 0 && *pmtdbufp != '\n') {            pmtdbufp++;            pmtdsize--;        }        if (pmtdsize > 0) {            pmtdbufp++;            pmtdsize--;        }    }    close(fd);}int mtd_name_to_number(const char *name) {    int n;    if (mtd_part_count < 0) {        mtd_part_count = 0;        find_mtd_partitions();    }    for (n = 0; n < mtd_part_count; n++) {        if (!strcmp(name, mtd_part_map[n].name)) {            return mtd_part_map[n].number;        }    }    return -1;}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));        } else if (!strcmp(name,"androidboot.baseband")) {            strlcpy(baseband, value, sizeof(baseband));        } else if (!strcmp(name,"androidboot.carrier")) {            strlcpy(carrier, value, sizeof(carrier));        } else if (!strcmp(name,"androidboot.bootloader")) {            strlcpy(bootloader, value, sizeof(bootloader));        } else if (!strcmp(name,"androidboot.hardware")) {            strlcpy(hardware, value, sizeof(hardware));        } else {            qemu_cmdline(name, value);        }    } 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 void import_kernel_cmdline(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;    }        /* don't expose the raw commandline to nonpriv processes */    chmod("/proc/cmdline", 0440);}static void get_hardware_name(void){    char data[1024];    int fd, n;    char *x, *hw, *rev;    /* Hardware string was provided on kernel command line */    if (hardware[0])        return;    fd = open("/proc/cpuinfo", O_RDONLY);    if (fd < 0) return;    n = read(fd, data, 1023);    close(fd);    if (n < 0) return;    data[n] = 0;    hw = strstr(data, "\nHardware");    rev = strstr(data, "\nRevision");    if (hw) {        x = strstr(hw, ": ");        if (x) {            x += 2;            n = 0;            while (*x && !isspace(*x)) {                hardware[n++] = tolower(*x);                x++;                if (n == 31) break;            }            hardware[n] = 0;        }    }    if (rev) {        x = strstr(rev, ": ");        if (x) {            revision = strtoul(x + 2, 0, 16);        }    }}static void drain_action_queue(void){    struct listnode *node;    struct command *cmd;    struct action *act;    int ret;    while ((act = action_remove_queue_head())) {        INFO("processing action %p (%s)\n", act, act->name);        list_for_each(node, &act->commands) {            cmd = node_to_item(node, struct command, clist);            ret = cmd->func(cmd->nargs, cmd->args);            INFO("command '%s' r=%d\n", cmd->args[0], ret);        }    }}void open_devnull_stdio(void){    int fd;    static const char *name = "/dev/__null__";    if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {        fd = open(name, O_RDWR);        unlink(name);        if (fd >= 0) {            dup2(fd, 0);            dup2(fd, 1);            dup2(fd, 2);            if (fd > 2) {                close(fd);            }            return;        }    }    exit(1);}int main(int argc, char **argv){    int device_fd = -1;    int property_set_fd = -1;    int signal_recv_fd = -1;    int s[2];    int fd;    struct sigaction act;    char tmp[PROP_VALUE_MAX];    struct pollfd ufds[4];    char *tmpdev;    act.sa_handler = sigchld_handler;    act.sa_flags = SA_NOCLDSTOP;    act.sa_mask = 0;    act.sa_restorer = NULL;    sigaction(SIGCHLD, &act, 0);    /* clear the umask */    umask(0);        /* Get the basic filesystem setup we need put         * together in the initramdisk on / and then we'll         * let the rc file figure out the rest.         */    mkdir("/dev", 0755);    mkdir("/proc", 0755);    mkdir("/sys", 0755);    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");    mkdir("/dev/pts", 0755);    mkdir("/dev/socket", 0755);    mount("devpts", "/dev/pts", "devpts", 0, NULL);    mount("proc", "/proc", "proc", 0, NULL);    mount("sysfs", "/sys", "sysfs", 0, NULL);        /* We must have some place other than / to create the         * device nodes for kmsg and null, otherwise we won't         * be able to remount / read-only later on.         * Now that tmpfs is mounted on /dev, we can actually         * talk to the outside world.         */    open_devnull_stdio();    log_init();        INFO("reading config file\n");    parse_config_file("/init.rc");    /* pull the kernel commandline and ramdisk properties file in */    qemu_init();    import_kernel_cmdline(0);    get_hardware_name();    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);    parse_config_file(tmp);    action_for_each_trigger("early-init", action_add_queue_tail);    drain_action_queue();    INFO("device init\n");    device_fd = device_init();    property_init();    if (console[0]) {        snprintf(tmp, sizeof(tmp), "/dev/%s", console);        console_name = strdup(tmp);    }    fd = open(console_name, O_RDWR);    if (fd >= 0)        have_console = 1;    close(fd);    if( load_565rle_image(INIT_IMAGE_FILE) ) {	fd = open("/dev/tty0", O_WRONLY);	if (fd >= 0) {	    const char *msg;            msg = "\n"		"\n"		"\n"		"\n"		"\n"		"\n"		"\n"  // console is 40 cols x 30 lines		"\n"		"\n"		"\n"		"\n"		"\n"		"\n"		"\n"		"             A N D R O I D ";	    write(fd, msg, strlen(msg));	    close(fd);	}    }    if (qemu[0])        import_kernel_cmdline(1);     if (!strcmp(bootmode,"factory"))        property_set("ro.factorytest", "1");    else if (!strcmp(bootmode,"factory2"))        property_set("ro.factorytest", "2");    else        property_set("ro.factorytest", "0");    property_set("ro.serialno", serialno[0] ? serialno : "");    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");    property_set("ro.baseband", baseband[0] ? baseband : "unknown");    property_set("ro.carrier", carrier[0] ? carrier : "unknown");    property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");    property_set("ro.hardware", hardware);    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);    property_set("ro.revision", tmp);        /* execute all the boot actions to get us started */    action_for_each_trigger("init", action_add_queue_tail);    drain_action_queue();        /* read any property files on system or data and         * fire up the property service.  This must happen         * after the ro.foo properties are set above so         * that /data/local.prop cannot interfere with them.         */    property_set_fd = start_property_service();    /* create a signalling mechanism for the sigchld handler */    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {        signal_fd = s[0];        signal_recv_fd = s[1];        fcntl(s[0], F_SETFD, FD_CLOEXEC);        fcntl(s[0], F_SETFL, O_NONBLOCK);        fcntl(s[1], F_SETFD, FD_CLOEXEC);        fcntl(s[1], F_SETFL, O_NONBLOCK);    }    /* make sure we actually have all the pieces we need */    if ((device_fd < 0) ||        (property_set_fd < 0) ||        (signal_recv_fd < 0)) {        ERROR("init startup failure\n");        return 1;    }    /* execute all the boot actions to get us started */    action_for_each_trigger("early-boot", action_add_queue_tail);    action_for_each_trigger("boot", action_add_queue_tail);    drain_action_queue();        /* run all property triggers based on current state of the properties */    queue_all_property_triggers();    drain_action_queue();        /* enable property triggers */       property_triggers_enabled = 1;         ufds[0].fd = device_fd;    ufds[0].events = POLLIN;    ufds[1].fd = property_set_fd;    ufds[1].events = POLLIN;    ufds[2].fd = signal_recv_fd;    ufds[2].events = POLLIN;#if BOOTCHART    if (bootchart_init() < 0)        ERROR("bootcharting init failure\n");    else {        NOTICE("bootcharting started\n");        bootchart_count = BOOTCHART_MAX_COUNT;    }#endif    for(;;) {        int nr, timeout = -1;        ufds[0].revents = 0;        ufds[1].revents = 0;        ufds[2].revents = 0;        drain_action_queue();        restart_processes();        if (process_needs_restart) {            timeout = (process_needs_restart - gettime()) * 1000;            if (timeout < 0)                timeout = 0;        }#if BOOTCHART        if (bootchart_count > 0) {            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)                timeout = BOOTCHART_POLLING_MS;            if (bootchart_step() < 0 || --bootchart_count == 0) {                bootchart_finish();                bootchart_count = 0;            }        }#endif        nr = poll(ufds, 3, timeout);        if (nr <= 0)            continue;        if (ufds[2].revents == POLLIN) {            /* we got a SIGCHLD - reap and restart as needed */            read(signal_recv_fd, tmp, sizeof(tmp));            while (!wait_for_one_process(0))                ;            continue;        }        if (ufds[0].revents == POLLIN)            handle_device_fd(device_fd);        if (ufds[1].revents == POLLIN)            handle_property_set_fd(property_set_fd);    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -