Linux内核模块的加载过程(3)

/* 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;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/bf168a7a8c38771e643a5f406db5752c.html