IMX8 UBOOT源码分析(四)conf.c分析

接着上一篇文章继续分析:

scripts/kconfig/conf  --defconfig=arch/../configs/imx8qxp_mek_defconfig Kconfig

             0                                                 1                                                     2

分析conf.c源码,看conf怎么解析imx8qxp_mek_defconfig和Kconfig

分析main函数

int main(int ac, char **av)
{
    const char *progname = av[0];                               //progname=scripts/kconfig/conf
    int opt;
    const char *name, *defconfig_file = NULL /* gcc uninit */;
    struct stat tmpstat;

    setlocale(LC_ALL, "");                                           //设置时区函数,此处什么也没做
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    /*static inline void textdomain(const char *domainname) {}
    static inline void bindtextdomain(const char *name, const char *dir) {}*/

    定义了两个空函数

    tty_stdio = isatty(0) && isatty(1);                         //判断是否为终端

    while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {

        从命令行获取参数,短参数-s,长参数从long_opts中获取

        scripts/kconfig/conf  --defconfig=arch/../configs/imx8qxp_mek_defconfig Kconfig

        可以看到命令行没有-s参数,长参数中定义了defconfig,在long_opts中查找

        static struct option long_opts[] = {
                  {"oldaskconfig",    no_argument,       NULL, oldaskconfig},
                  {"oldconfig",       no_argument,       NULL, oldconfig},
                  {"syncconfig",      no_argument,       NULL, syncconfig},
                  {"defconfig",       optional_argument, NULL, defconfig},
                  {"savedefconfig",   required_argument, NULL, savedefconfig},
                  {"allnoconfig",     no_argument,       NULL, allnoconfig},
                  {"allyesconfig",    no_argument,       NULL, allyesconfig},
                  {"allmodconfig",    no_argument,       NULL, allmodconfig},
                  {"alldefconfig",    no_argument,       NULL, alldefconfig},
                  {"randconfig",      no_argument,       NULL, randconfig},
                  {"listnewconfig",   no_argument,       NULL, listnewconfig},
                  {"olddefconfig",    no_argument,       NULL, olddefconfig},
                  {"oldnoconfig",     no_argument,       NULL, olddefconfig},
                  {NULL, 0, NULL, 0}
     };

     得到opt=defconfig, optarg=arch/../configs/imx8qxp_mek_defconfig optind=2
        if (opt == 's') {                                                            //不执行
            conf_set_message_callback(NULL);
            continue;
        }
        input_mode = (enum input_mode)opt;                   
//input_mode =defconfig
        switch (opt) {
        case syncconfig:
            sync_kconfig = 1;
            break;
        case defconfig:                                                       
//执行此处
        case savedefconfig:
            defconfig_file = optarg;                                     
//defconfig_file =arch/../configs/imx8qxp_mek_defconfig
            break;
        case randconfig:
        {
            struct timeval now;
            unsigned int seed;
            char *seed_env;

            /*
             * Use microseconds derived seed,
             * compensate for systems where it may be zero
             */
            gettimeofday(&now, NULL);
            seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));

            seed_env = getenv("KCONFIG_SEED");
            if( seed_env && *seed_env ) {
                char *endp;
                int tmp = (int)strtol(seed_env, &endp, 0);
                if (*endp == '\0') {
                    seed = tmp;
                }
            }
            fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
            srand(seed);
            break;
        }
        case oldaskconfig:
        case oldconfig:
        case allnoconfig:
        case allyesconfig:
        case allmodconfig:
        case alldefconfig:
        case listnewconfig:
        case olddefconfig:
            break;
        case '?':
            conf_usage(progname);
            exit(1);
            break;
        }
    }

if (ac == optind) {                                                                                        //不执行
        fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]);
        conf_usage(progname);
        exit(1);
    }
    name = av[optind];                                                                                 //name=Kconfig
    conf_parse(name);

    此处解析传入的Kconfig的文件,将可选的配置信息,保存到一个链表中

    if (sync_kconfig) {                                                                                 //不执行,当opt=syncconfig时执行
        name = conf_get_configname();
        if (stat(name, &tmpstat)) {
            fprintf(stderr, _("***\n"
                "*** Configuration file \"%s\" not found!\n"
                "***\n"
                "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
                "*** \"make menuconfig\" or \"make xconfig\").\n"
                "***\n"), name);
            exit(1);
        }
    }

    switch (input_mode) {
    case defconfig:                                                                                 //执行此处
        if (!defconfig_file)
            defconfig_file = conf_get_default_confname();
        if (conf_read(defconfig_file)) {                                                     //读取arch/../configs/imx8qxp_mek_defconfig,并且生成新的                                                                                                              配置文件
            fprintf(stderr,_("***\n*** Can't find default configuration \"%s\"!\n***\n"),defconfig_file);
            exit(1);
        }
        break;
    case savedefconfig:
    case syncconfig:
    case oldaskconfig:
    case oldconfig:
    case listnewconfig:
    case olddefconfig:
        conf_read(NULL);
        break;
    case allnoconfig:
    case allyesconfig:
    case allmodconfig:
    case alldefconfig:
    case randconfig:
        name = getenv("KCONFIG_ALLCONFIG");
        if (!name)
            break;
        if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
            if (conf_read_simple(name, S_DEF_USER)) {
                fprintf(stderr,
                    _("*** Can't read seed configuration \"%s\"!\n"),
                    name);
                exit(1);
            }
            break;
        }
        switch (input_mode) {
        case allnoconfig:    name = "allno.config"; break;
        case allyesconfig:    name = "allyes.config"; break;
        case allmodconfig:    name = "allmod.config"; break;
        case alldefconfig:    name = "alldef.config"; break;
        case randconfig:    name = "allrandom.config"; break;
        default: break;
        }
        if (conf_read_simple(name, S_DEF_USER) &&
            conf_read_simple("all.config", S_DEF_USER)) {
            fprintf(stderr,
                _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
                name);
            exit(1);
        }
        break;
    default:
        break;
    }

    if (sync_kconfig) {                                                                                        //不执行
        if (conf_get_changed()) {
            name = getenv("KCONFIG_NOSILENTUPDATE");
            if (name && *name) {
                fprintf(stderr,
                    _("\n*** The configuration requires explicit update.\n\n"));
                return 1;
            }
        }
    }

    switch (input_mode) {
    case allnoconfig:
        conf_set_all_new_symbols(def_no);
        break;
    case allyesconfig:
        conf_set_all_new_symbols(def_yes);
        break;
    case allmodconfig:
        conf_set_all_new_symbols(def_mod);
        break;
    case alldefconfig:
        conf_set_all_new_symbols(def_default);
        break;
    case randconfig:
        /* Really nothing to do in this loop */
        while (conf_set_all_new_symbols(def_random)) ;
        break;
    case defconfig:                                                                                    //执行此处
        conf_set_all_new_symbols(def_default);                                        //更新关系链表
        break;
    case savedefconfig:
        break;
    case oldaskconfig:
        rootEntry = &rootmenu;
        conf(&rootmenu);
        input_mode = oldconfig;
        /* fall through */
    case oldconfig:
    case listnewconfig:
    case syncconfig:
        /* Update until a loop caused no more changes */
        do {
            conf_cnt = 0;
            check_conf(&rootmenu);
        } while (conf_cnt);
        break;
    case olddefconfig:
    default:
        break;
    }

    if (sync_kconfig) {
        /* syncconfig is used during the build so we shall update autoconf.
         * All other commands are only used to generate a config.
         */
        if (conf_get_changed() && conf_write(NULL)) {
            fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
            exit(1);
        }
        if (conf_write_autoconf()) {
            fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
            return 1;
        }
    } else if (input_mode == savedefconfig) {
        if (conf_write_defconfig(defconfig_file)) {
            fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
                defconfig_file);
            return 1;
        }
    } else if (input_mode != listnewconfig) {                                                                   //执行此处
        if (conf_write(NULL)) {                                                                                         //将新的配置写入到.config中
            fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
            exit(1);
        }
    }
    return 0;
}

scripts/kconfig/conf  --defconfig=arch/../configs/imx8qxp_mek_defconfig Kconfig的主要作用就是读取Kconfig的默认配置,根据

arch/../configs/imx8qxp_mek_defconfig更新配置关系链表,最后把新的配置写入到.config文件中

猜你喜欢

转载自blog.csdn.net/yanggx0929/article/details/88593969