liunx驱动----构造和运行模块

以hello world模块为例

#include <linux/init.h>
#include <linux/module.h>



//在执行  insmod hlello 的时候会被调用
static int hello_init(void)
{

    printk(KERN_ALERT"hello_init\n");
    return 0;
}


//在执行  rmmod hlello 的时候会被调用
static void hello_exit(void)
{
    printk(KERN_ALERT"hello_exit\n");    
}

MODULE_LICENSE("GPL");//添加*许可证
module_init(hello_init);
module_exit(hello_exit);
KERN_ALERT:是用来定义这条消息的优先级的。声明在:kernel.h  include\linux\kernel.h中声明
#define    KERN_EMERG    "<0>"    /* system is unusable    (紧急情况,系统可能会崩溃)        */
#define    KERN_ALERT    "<1>"    /* action must be taken immediately(必须立即响应)    */
#define    KERN_CRIT    "<2>"    /* critical conditions   (临界情况)         */
#define    KERN_ERR    "<3>"    /* error conditions        (错误信息)    */
#define    KERN_WARNING    "<4>"    /* warning conditions    (警告信息)        */
#define    KERN_NOTICE    "<5>"    /* normal but significant condition( 普通的但可能需要注意的信息)    */
#define    KERN_INFO    "<6>"    /* informational         (提示性信息)   */
#define    KERN_DEBUG    "<7>"    /* debug-level messages   (调试信息)         */

Makfile:

KERN_DIR = /work/system/linux-2.6.22.6   //内核路径

all:
        make -C $(KERN_DIR) M=`pwd` modules

clean:
        make -C $(KERN_DIR) M=`pwd` modules clean
        rm -rf modules.order

obj-m   += helloworld.o         //编译成helloworld.o

make输出信息:

make -C /work/system/linux-2.6.22.6 M=`pwd` modules
make[1]: Entering directory `/work/system/linux-2.6.22.6'
  CC [M]  /home/book/work/nfs_root/first_fs/work/helloworld/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/book/work/nfs_root/first_fs/work/helloworld/helloworld.mod.o
  LD [M]  /home/book/work/nfs_root/first_fs/work/helloworld/helloworld.ko
make[1]: Leaving directory `/work/system/linux-2.6.22.6'

从输出信息中可以看出 ,最终的目的是生成了  helloworld.ko 这个文件 

运行结果:

liunx驱动----构造和运行模块

为什么需要使用printk 函数来打印了?

  在模块运行过程中,不能依赖于c库,模块能够调用printk是因为在 insmod函数装入模块后,模块就链接到了内核中。所以就能访问公用的符号(printk)

为什么模块需要初始化?

  模块初始化的目的就是为了以后调用模块中的函数做准备。

设备驱动程序如何引用当前进程?

  在设备驱动程序中只需要包含<linux/sched.h>头文件即可引用当前进程。例如  通过访问  Staruc task_staruct  成员变量答应当前的命令名称。和进程ID

  分别在装载和卸载调用中添加两条打印语句:printk(KERN_INFO"The process is \"%s\"(pid %i)\n",current->comm,current->pid)        

  打印出当前命令名称与进程ID

//在执行  insmod hlello 的时候会被调用
static int hello_init(void)
{

    printk(KERN_ALERT"hello_init\n");
    printk(KERN_INFO"The process is \"%s\"(pid %i)\n",current->comm,current->pid);
    return 0;
}


//在执行  rmmod hlello 的时候会被调用
static void hello_exit(void)
{
    printk(KERN_ALERT"hello_exit\n");    
    printk(KERN_INFO"The process is \"%s\"(pid %i)\n",current->comm,current->pid);
}

运行状态如下:

liunx驱动----构造和运行模块

 

上一篇:(九) 主机增加打印(串口+ssh)


下一篇:printk函数 打印设备编号