linux驱动入门——模块参数和导出符号

驱动程序中lsmod命令实际读取的是/proc/modules文件 
即与lsmod命令对应的结果是cat /proc/modules 

内核中已经加载的模块的信息存在于/sys/module目录下 

modprobe命令比insmod命令要强大,它在加载某模块时会同时加载该模块所依赖的其他模块 
使用modprobe -r filename的方式卸载将同时其依赖的模块 
modinfo 模块名命令可以获得模块的信息 
modinfo hello.ko 

filename:       hello.ko 
alias:          a simplest module 
description:    A simple Hello World Module 
author:         Jimmy 
license:        Dual BSD/GPL 
srcversion:     FC20E540C350C6F733C7546 
depends:        
vermagic:       2.6.28-15-generic SMP mod_unload modversions 586 


驱动模块参数,MODULE_PARM_DESC可以注解参数 
如: 
        static int num = 4000; 
        module_param(num, int, S_IRUGO); 
        MODULE_PARM_DESC(myshort, "A integer"); 

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

MODULE_LICENSE("Dual BSD/GPL"); 

static char *book_name = "dissecting Linux Device Driver"; 
static int num = 4000; 
static int param[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 
static int param_len = 8; 

static int book_init(void) 

        int i; 
        printk(KERN_ALERT " book name: %s\n", book_name); 
        printk(KERN_ALERT " book num: %d\n", num); 
        for(i = 0; i < 8; i++) 
        { 
                printk(KERN_ALERT "param[%d] =  %d \n", i, param[i]); 
        } 

        return 0; 


static void book_exit(void) 

        printk(KERN_ALERT " Book module exit\n"); 


module_init(book_init); 
module_exit(book_exit); 
module_param(num, int, S_IRUGO); 
module_param(book_name, charp, S_IRUGO); 
module_param_array(param, int, &param_len, S_IRUGO); 

MODULE_AUTHOR("Jimmy, fightingjimmy@gmail.com"); 
MODULE_DESCRIPTION("A simple Module for testing module params"); 
MODULE_VERSION("v1.0"); 

sudo insmod book.ko 
dmesg |tail -10 
[14047.901352]  book name: dissecting Linux Device Driver 
[14047.901366]  book num: 4000 
[14047.901377] param[0] =  1 
[14047.901386] param[1] =  2 
[14047.901388] param[2] =  3 
[14047.901389] param[3] =  4 
[14047.901390] param[4] =  5 
[14047.901391] param[5] =  6 
[14047.901392] param[6] =  7 
[14047.901393] param[7] =  8 

sudo rmmod book.ko 
sudo insmod book.ko book_name='Hello' num=1000 param=8,7,6,5 
[14298.942521]  book name: Hello 
[14298.942535]  book num: 1000 
[14298.942547] param[0] =  8 
[14298.942558] param[1] =  7 
[14298.942559] param[2] =  6 
[14298.942560] param[3] =  5 
[14298.942561] param[4] =  5 
[14298.942562] param[5] =  6 
[14298.942564] param[6] =  7 
[14298.942565] param[7] =  8 

sudo rmmod book.ko 
sudo insmod book.ko book_name="Hello World" num=1000 param=8,7,6,5 
insmod: error inserting 'book.ko': -1 Unknown symbol in module 

dmesg |tail -10 
[15097.587159] book: Unknown parameter `world' 
猜想:可能是因为传入的字符串参数带有空格的原因(有遇到类似情况的请不吝赐教) 

linux2.6的/proc/kallsyms文件对应着内核符号表,它记录了以及符号所在的内存地址。 
EXPORT_SYMBOL(符号名); 
EXPROT_SYMBOL_GPL(符号名); 

module/ 
        include/ 
                print.h 
        print/ 
                print.c 
                Makefile 
        symbol/ 
                test.c 
                Makefile 

/**************************************** 
* print.h                               * 
*****************************************/ 
#ifndef PRINT_H 
#define PRINT_H 

void add_integer(int a, int b); 
void sub_integer(int a, int b); 

#endif 


/**************************************** 
* print.c                               * 
*****************************************/ 
#include <linux/init.h> 
#include <linux/module.h> 

#include "print.h" 

MODULE_LICENSE("Dual BSD/GPL"); 

void add_integer(int a, int b) 

        printk(KERN_ALERT " sum: %d\n", a + b); 


void sub_integer(int a, int b) 

        printk(KERN_ALERT " sub: %d\n", a - b); 


EXPORT_SYMBOL(add_integer); 
EXPORT_SYMBOL(sub_integer); 


/**************************************** 
* test.c                                * 
*****************************************/ 
#include <linux/init.h> 
#include <linux/module.h>  
  
#include "print.h"  

MODULE_LICENSE("GPL");   
  
static int symbol_init(void)  

        printk(KERN_ALERT " Symbol test init\n");  
        add_integer(10, 6); 
        sub_integer(10, 6);  
        return 0;  
}  
   
static void symbol_exit(void)  
{  
        printk(KERN_ALERT " Symbol test exit\n");  
}  
   
module_init(symbol_init);  
module_exit(symbol_exit);  

print目录下的Makefile: 
obj-m := print.o 
KERNELDIR ?= /lib/modules/$(shell uname -r)/build 
PWD := $(shell pwd) 
PRINT_INC = $(obj)/../include           #包含print.h头文件 
EXTRA_CFLAGS += -I $(PRINT_INC) 

modules: 
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 

modules_install: 
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 

clean: 
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions 

.PHONY: modules modules_install clean 


symbol目录下的Makefile: 
obj-m := test.o 
KERNELDIR ?= /lib/modules/$(shell uname -r)/build 
PWD := $(shell pwd) 
SYMBOL_INC = $(obj)/../include 
EXTRA_CFLAGS += -I $(SYMBOL_INC) 
KBUILD_EXTRA_SYMBOLS=$(obj)/../print/Module.symvers 

modules: 
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 

modules_install: 
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 

clean: 
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions 

.PHONY: modules modules_install clean 

注意:若是Makefile文件中没有KBUILD_EXTRA_SYMBOLS=$(obj)/../print/Module.symvers 
则需要将print目录下的Module.symvers拷贝到symbol目录下,这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看http://bugzilla.kernel.org/show_bug.cgi?id=12446) 


分别编译insmod即可 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值