首页 > 系统服务 > 详细

linux之可安装模块机制

时间:2017-03-13 11:24:25      阅读:158      评论:0      收藏:0      [点我收藏+]

一、背景:

  1.系统可见设备、应用可访问设备,需要具备设备文件节点,设备驱动

  2.所有设备驱动程序静态链接到内核会导致内核过大, 不易运行

二、特点:

  1.可安装模块(module)是编译不链接

  2.运行后,动态加载到内核中

  3.加载操作由内核或者特权用户使用sbin执行

  4.机制支持选择CONFIG_MODULES

二、源码分析:

init/main.c  

asmlinkage void __init start_kernel(void)
{

  ...

  rest_init();

  ...

}

static noinline void __init_refok rest_init(void)
{

  ...

  kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

  ...

}

static int __init kernel_init(void * unused)
{

  ...

  do_basic_setup();

  ...

}

static void __init do_basic_setup(void)
{
  ...
  do_initcalls();
}

static void __init do_initcalls(void)

{
   initcall_t *fn;

   for (fn = __early_initcall_end; fn < __initcall_end; fn++)
      do_one_initcall(*fn);
}

#define INITCALLS       \
 *(.initcallearly.init)      \
 VMLINUX_SYMBOL(__early_initcall_end) = .;   \
   *(.initcall0.init)      \
   *(.initcall0s.init)      \
   *(.initcall1.init)      \
   *(.initcall1s.init)      \
   *(.initcall2.init)      \
   *(.initcall2s.init)      \
   *(.initcall3.init)      \
   *(.initcall3s.init)      \
   *(.initcall4.init)      \
   *(.initcall4s.init)      \
   *(.initcall5.init)      \
   *(.initcall5s.init)      \
 *(.initcallrootfs.init)      \
   *(.initcall6.init)      \
   *(.initcall6s.init)      \
   *(.initcall7.init)      \
   *(.initcall7s.init)

#define INIT_CALLS       \
  VMLINUX_SYMBOL(__initcall_start) = .;   \
  INITCALLS      \
  VMLINUX_SYMBOL(__initcall_end) = .;

#define INIT_DATA_SECTION(initsetup_align)    \
 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {  \
  INIT_DATA      \
  INIT_SETUP(initsetup_align)    \
  INIT_CALLS      \
  CON_INITCALL      \
  SECURITY_INITCALL     \
  INIT_RAM_FS      \
 }

即,从init.data段中取出初始化部分的代码,驱动在初始化时期进行加载

module_init(camera_init);

include\linux\init.h 

#define module_init(x) __initcall(x);

#define __initcall(fn) device_initcall(fn)

#define device_initcall(fn)  __define_initcall("6",fn,6)

#define __define_initcall(level,fn,id) \
 static initcall_t __initcall_##fn##id __used \
 __attribute__((__section__(".initcall" level ".init"))) = fn

此处与系统启动加载时期对应,即将驱动代码放入.initcall" level ".init

linux之可安装模块机制

原文:http://www.cnblogs.com/pokerface/p/6541672.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!