zoukankan      html  css  js  c++  java
  • linux之可安装模块机制

    一、背景:

      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);

    includelinuxinit.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

  • 相关阅读:
    namespace std 定义的位置
    [Struts]学习日记3 在页面中显示条目列表
    [Hibernate]关于ID的一个容易混淆的地方
    [Struts]"Cannot find bean in any scope"之一解
    [Struts]HibernatePlugIn for Struts(转贴)
    日志搬家了!
    [Struts]学习日记2 增加一些验证
    实验室的项目 讨论
    Struts常见异常信息和解决方法
    参加婚礼
  • 原文地址:https://www.cnblogs.com/pokerface/p/6541672.html
Copyright © 2011-2022 走看看