zoukankan      html  css  js  c++  java
  • Linux内核基础

    操作系统内核模块:

    Linux内核是整体式结构,各个子系统联系紧密,作为一个大程序在内核空间运行。

    image

    Linux内核模块体系结构:

    Linux内核引入内核模块机制。通过动态加载内核模块,使得在运行过程中扩展内核的功能。不需要的时候,卸载该内核模块。

    image

    Linux内核子系统

    image

    写内核程序需要注意:

    image

    Hello模块

    /*hello.c*/

    #include<linux/kernel.h>
    #include<linux/module.h>
    #include<linux/init.h>
    static int __init hello_init(void)
    {
        printk("hello init. ");
        return 0;
    }
    static void __exit hello_exit(void)
    {
        printk("hello exit. ");
    }
    MODULE_INIT(hello_init);
    MODULE_EXIT(hello_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("spron");
    MODULE_DESCRIPTION("hello world modules");

    内核模块的Makefile:
    CONFIG_HELLO_WORLD ?= m     //配置变量,用模块的方式编译
    ifneq ($(KERNELRELEASE),)       //如果这个变量是有定义的话,执行
        hello_world-objs := hello.o  a.o  b.o
        obj-$(CONFIG_HELLO_WORLD) += hello_world.o     //告诉内核要产生的文件为XXX.O
    else
        KERNELDIR = /$(your_kernel_source)/ 内核的源代码的目录     //如:KDIR=/root/LINUX
        PWD := $(shell pwd)  //执行当前目录的命令
        modules:
            $(MAKE) -C $(KERNELDIR) M=$(PWD) modules      //生成内核模块参数为内核源代码目录以及模块所在目录
    endif
    clean:
        rm –rf  *.o  *~ core  .depend .  *.cmd  *.ko  *.mod.c  .tmp_versions
    注意: your_kernel_source,是你的linux kernel源代码的目录

    编译加载/卸载:
    在hello world模块目录上
    #make
    得到hello_world.ko就是产生的内核模块,在评估板上使用 #insmod hello_world.ko 和 #rmmod hello_world 观察控制台输出的结果。

    内核模块证书和内核模块文档说明:
    2.4内核后,引入识别代码是否在GPL许可下发布的机制 。在使用非公开的源代码产品时会得到警告。通过宏MODULE_LICENSE(“GPL”),设置模块遵守GPL证书,取消警告信息。
    MODULE_DESCRIPTION()用来描述模块的用途。
    MODULE_AUTHOR()用来声明模块的作者。
    MODULE_SUPPORTED_DEVICE() 声明模块支持的设备。
    这些宏都在头文件linux/module.h定义。使用这些宏只是用来提供识别信息。

    模块参数:
    module_param(name,type,perm);
        perm是一个权限值,控制谁可以存取模块参数在 sysfs 中的表示。
        perm 被设为 0, 就根本没有 sysfs 项
    这个宏定义应当放在任何函数之外, 典型地是出现在源文件的前面。
    应该总是为变量赋初值。
    宏MODULE_PARM_DESC() 用来注解该模块可以接收的参数。该宏两个参数:变量名和一个对该变量的描述。
    模块可以用这样的命令行加载:./insmod mymodule.ko myvariable=2

    __init、__initdata和__exit、__exitdata
    对于__init、__initdata和__exit、__exitdata的定义位于<linux/init.h>,这些宏定义的作用是告诉编译器将这些函数或者数据放入相应的section中,
    而在模块加载的阶段,.ko文件中的代码和数据的加载区域是根据section来加载的。比如:如果函数的定义中带有__init,那么这个函数的所有代码会被放入.init.text的section中。如果函数的定义中带有__initdata,那么这个函数的所有代码会被放入.init.data的section中。
    之所以要使用这个宏定义,其中一个原因是标记为初始化的函数和数据,表明该函数和数据仅在初始化期间使用。
    在模块装载之后,模块装载就会将初始化函数扔掉。这样可以将该函数占用的内存释放出来。
    详细的说明见详细文档下载链接中的“__init,__initdata,__exit,__exitdata.doc文档” 。

    详细文档及代码下载链接: http://download.csdn.net/detail/klcf0220/5760109

  • 相关阅读:
    把一元可以分解成几个1毛,2毛,5毛?
    记录集导出到Excel方法
    MySQL数据库加密与解密:
    运行时错误'430': 类不支持自动化或不支持期望的接口。New ADODB.Connection问题
    instrrev 和instr 区别vb
    解决用 VB 中用 ADO 访问 数据库时 SQL 查询处理 Null 值的问题( 使用 iff(isNull(字段), 为空时的值,不为空时的值) 来处理)
    Mysql SQL CAST()函数
    MySQL CAST与CONVERT 函数的用法
    一些网页链接
    git上传时出现ERROR: Repository not found.的解决办法
  • 原文地址:https://www.cnblogs.com/klcf0220/p/3188894.html
Copyright © 2011-2022 走看看