/* Now copy in args */
/*
* 将���入模块时指定的参数从用于空间拷贝到args中。
*/
args = strndup_user(uargs, ~0UL >> 1);
if (IS_ERR(args)) {
err = PTR_ERR(args);
goto free_hdr;
}
/*
* 为与符号表相关的字符串表段在内存中分配用于映射的空间。
* sechdrs[strindex].sh_size是与符号表相关的字符串表段的大小。
* 这里分配的是一个位图,用于符号表中的符号名称的
* 映射。
*/
strmap = kzalloc(BITS_TO_LONGS(sechdrs[strindex].sh_size)
* sizeof(long), GFP_KERNEL);
if (!strmap) {
err = -ENOMEM;
goto free_mod;
}
/*
* 查找当前要加载的模块是否已经存在,如果存在,则
* 跳转到free_mod标签处。
*/
if (find_module(mod->name)) {
err = -EEXIST;
goto free_mod;
}
mod->state = MODULE_STATE_COMING;
/* Allow arches to frob section contents and sizes. */
/*
* err总是为0
*/
err = module_frob_arch_sections(hdr, sechdrs, secstrings, mod);
if (err < 0)
goto free_mod;
/*
* 如果存在.data.percpu段,则为该段在内存中分配空间。
* 分配成功后,移除SHF_ALLOC标志,并且初始化module实例
* 的percpu成员。
*/
if (pcpuindex) {
/* We have a special allocation for this section. */
percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
sechdrs[pcpuindex].sh_addralign,
mod->name);
if (!percpu) {
err = -ENOMEM;
goto free_mod;
}
sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
mod->percpu = percpu;
}
/* Determine total sizes, and put offsets in sh_entsize. For now
this is done generically; there doesn't appear to be any
special cases for the architectures. */
/*
* 对core section和init section中的大小及代码段的信息进行
* 统计
*/
layout_sections(mod, hdr, sechdrs, secstrings);
/*
* 处理符号表中的符号,返回值是core section尾部的
* 符号表的偏移。
*/
symoffs = layout_symtab(mod, sechdrs, symindex, strindex, hdr,
secstrings, &stroffs, strmap);
/* Do the allocs. */
/*
* 为core section分配内存,初始化后存储在module实例
* 的module_core成员中。
*/
ptr = module_alloc_update_bounds(mod->core_size);
/*
* The pointer to this block is stored in the module structure
* which is inside the block. Just mark it as not being a
* leak.
*/
kmemleak_not_leak(ptr);
if (!ptr) {
err = -ENOMEM;
goto free_percpu;
}
memset(ptr, 0, mod->core_size);
mod->module_core = ptr;
/*
* 为init section分配内存,初始化后存储在module实例
* 的module_init成员中。
*/
ptr = module_alloc_update_bounds(mod->init_size);
/*
* The pointer to this block is stored in the module structure
* which is inside the block. This block doesn't need to be
* scanned as it contains data and code that will be freed
* after the module is initialized.
*/
kmemleak_ignore(ptr);
if (!ptr && mod->init_size) {
err = -ENOMEM;
goto free_core;
}
memset(ptr, 0, mod->init_size);
mod->module_init = ptr;