中创建模块对应的对象,可以在通过/sys/module/module_name
* 查看。
*/
err = mod_sysfs_init(mod);
if (err)
goto free_unload;
/* Set up license info based on the info section */
/*
* 从.modinfo段获取license对应的值,检查是否兼容
*/
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
/*
* ndiswrapper is under GPL by itself, but loads proprietary modules.
* Don't use add_taint_module(), as it would prevent ndiswrapper from
* using GPL-only symbols it needs.
*/
if (strcmp(mod->name, "ndiswrapper") == 0)
add_taint(TAINT_PROPRIETARY_MODULE);
/* driverloader was caught wrongly pretending to be under GPL */
if (strcmp(mod->name, "driverloader") == 0)
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
/* Set up MODINFO_ATTR fields */
/*
* 根据.modinfo段设置模块信息。
*/
setup_modinfo(mod, sechdrs, infoindex);
/* Fix up syms, so that st_value is a pointer to location. */
/*
* 解决当前模块对其他模块的符号引用问题,
* 并找到符号对应的值的地址
*/
err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
mod);
if (err < 0)
goto cleanup;
/* Now we've got everything in the final locations, we can
* find optional sections. */
/*
* 获取__param段的运行时地址,及其存储的
* 对象的个数。
*/
mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
sizeof(*mod->kp), &mod->num_kp);
/*
* 获取__ksymtab段的运行时地址,及其存储的
* 对象的个数。
*/
mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
sizeof(*mod->syms), &mod->num_syms);
/*
* 获取__kcrctab段的运行时地址。
*/
mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
/*
* 获取__ksymtab_gpl段的运行时地址,及其存储的
* 对象的个数。
*/
mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl",
sizeof(*mod->gpl_syms),
&mod->num_gpl_syms);
/*
* 获取__kcrctab_gpl段的运行时地址。
*/
mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl");
/*
* 获取__ksymtab_gpl_future段的运行时地址,及其存储的
* 对象的个数。
*/
mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings,
"__ksymtab_gpl_future",
sizeof(*mod->gpl_future_syms),
&mod->num_gpl_future_syms);
/*
* 获取__kcrctab_gpl_future段的运行时地址。
*/
mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings,
"__kcrctab_gpl_future");
#ifdef CONFIG_UNUSED_SYMBOLS
/*
* 获取__ksymtab_unused段的运行时地址,及其存储的
* 对象的个数。
*/
mod->unused_syms = section_objs(hdr, sechdrs, secstrings,
"__ksymtab_unused",
sizeof(*mod->unused_syms),
&mod->num_unused_syms);
/*
* 获取__kcrctab_unused段的运行时地址。
*/
mod->unused_crcs = section_addr(hdr, sechdrs, secstrings,
"__kcrctab_unused");
/*
* 获取__ksymtab_unused_gpl段的运行时地址,及其存储的
* 对象的个数。
*/
mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings,
"__ksymtab_unused_gpl",
sizeof(*mod->unused_gpl_syms),
&mod->num_unused_gpl_syms);
/*
* 获取__kcrctab_unused_gpl段的运行时地址。
*/
mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
"__kcrctab_unused_gpl");
#endif
#ifdef CONFIG_CONSTRUCTORS
/*
* 获取.ctors段的运行时地址,及其存储的
* 对象的个数。
*/
mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
sizeof(*mod->ctors), &mod->num_ctors);
#endif
#ifdef CONFIG_TRACEPOINTS
/*
* 获取__tracepoints段的运行时地址,及其存储的
* 对象的个数。
*/
mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
"__tracepoints",
sizeof(*mod->tracepoints),
&mod->num_tracepoints);
#endif
#ifdef CONFIG_EVENT_TRACING
/*
* 获取_ftrace_events段的运行时地址,及其存储的
* 对象的个数。
*/