免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 901 | 回复: 0
打印 上一主题 下一主题

内核模块编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-31 14:52 |只看该作者 |倒序浏览

       
       
       
       
       
       
  • 模块就是能用命令进行加载到内核或从内核卸载的程序,它们可以使机器在不重启的情况下可以扩展内核功能,其中一种模块类型就是驱动,可以用lsmod命令来查看什么模块已经被加进内核。
           
  • 当内核需要一个不是驻留在内核里的模块时,它会执行modprobe命令去把模块加载上,而传递给modprobe命令的参数有两种形式,如char-major-180-*
            usbcore,该种形式定义在/etc/modprobe.d/aliases中,对应的模块名为usbcore.ko,然后modprobe将去查看一下/lib/modules/version/modules.dep看是否有模块必须在加载该模块之前加载,该文件是由depmod
            -a命令生成的,是关于模块依赖性的,最后modprobe用insmod命令把依赖的模块加载上,再把该模块加载上。
           
  • 在内核2.3.13之前,内核模块必须有两个功能:初始化功能(init_module()),它是当模块被加载到内核时调用的;卸载功能(cleanup_module()),它是当模块被卸载之前调用的。现在可以用任何名字来实现一个模块的初始化或卸载,但每一个内核模块都必须包含linux/module.h
            如果你要用到一些宏扩展如prink(),还需要包含linux/kernel.h。
           
  • 简单模块例子:
            hello.c
            #include
           
            #include
           
            #include
           
            MODULE_LICENSE("Dual
            BSC/GPL");
            MODULE_AUTHOR("Sam
            Shen ");
            MODULE_DESCRIPTION("Test
            Module Program");
            MODULE_SUPPORTED_DEVICE("Hello,world");
            static
            int  _ _init hello_init(void)
            {
                    printk(KERN_ALERT"Hello,
            world!\n");
                    return
            0;
            }
            static
            void  _ _exit hello_exit(void)
            {
                    printk(KERN_ALERT"Goodbye,
            cruel world!\n");
            }
            module_init(hello_init);
            module_exit(hello_exit);
            Makefile
            obj-m
            += hello.o
            KERNELDIR:=/lib/modules/$(shell
            uname -r)/build
            PWD=$(shell
            pwd)
            all:
                    make
            -C $(KERNELDIR) M=$(PWD) modules
            clean:
                    make
            -C $(KERNELDIR) M=$(PWD) clean
            (想了解更多关于编译模块,请查看linux/Documentation/kbuild/modules.txt,更多关于内核模块的Makefile,请查看linux/Documentation/kbuild/makefiles.txt)
            _
            _ init声明是当init函数执行完成后内核能够回收空间,_
            _initdata和它有相同的功能,但是是对于变量而不是函数的,
            _
            _exit声明是为了内核能够省略掉cleanup函数,它们可装载模块不受影响。MODULE_*定义在linux/include/linux/module.h,它们不被内核本身使用,只是为了让一些工具查看模块的信息。
            按Ctrl+Alt+F5,进入tty5,用modinfo
            hello.ko查看模块的信息,用sudo
            insmod hello.ko加载模块,用lsmod
            | grep hello查看模块是否已加载上,用sudo
            rmmod
            hello卸载该模块。所有已经加载的模块都列在文件/proc/modules中,故也可以通过查看hello是否出现在该文件中来判断模块是否已经加载上,一般刚加载的模块加在第一行,如:hello
            2432 0 - Live 0xf8974000
            (P),其中hello为模块名,2432是模块大小,0是使用数目,-Live是模块状态,0xf8974000是模块位置,(P)为非标准内核模块。
           
  • 可以给模块传递命令行参数,但不是用argc/argv的机制,而是用module_param()或module_param_array()宏,它们定义在include/linux/moduleparam.h文件中,使用范例:
            hello.c
            #include
           
            #include
           
            #include
           
            #include
           
            #include
           
           
            MODULE_LICENSE("Dual
            BSC/GPL");
            MODULE_AUTHOR("Sam
            Shen ");
            MODULE_DESCRIPTION("Test
            Module Program");
            MODULE_SUPPORTED_DEVICE("Hello,world");
           
            static
            short int myshort = 1;
            static
            int myint = 2;
            static
            long int mylong = 8888;
            static
            char *mystring = "shenxiaocheng";
            static
            int myintArray[2] = {-1, 1};
            static
            int arr_argc = 0;
           
            module_param(myshort,
            short, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
            MODULE_PARM_DESC(myshort,
            "A short integer");
            module_param(myint,
            int, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
            MODULE_PARM_DESC(myint,
            "An integer");
            module_param(mylong,
            long, S_IRUSR);
            MODULE_PARM_DESC(mylong,
            "A long integer");
            module_param(mystring,
            charp, 0000);
            MODULE_PARM_DESC(mystring,
            "A character string");
            module_param_array(myintArray,
            int, &arr_argc,0000);
            MODULE_PARM_DESC(myintArray,
            "An array of integer");
            static
            int __init hello_init(void)
            {
                    int
            i;
                    printk(KERN_ALERT"Hello,
            world!\n");
                    printk(KERN_ALERT"myshort
            is a short interger: %hd\n",myshort);
                    printk(KERN_ALERT"myint
            is an integer %d\n", myint);
                    printk(KERN_ALERT"mylong
            is a long integer: %ld\n",mylong);
                    printk(KERN_ALERT"mystring
            is a string: %s\n", mystring);
                    for(i=0;
            i
                          
            printk(KERN_ALERT"myintArray[%d]
            = %d\n", i, myintArray);
                    printk(KERN_ALERT"got
            %d argumeters for myintArray.\n", arr_argc);
                    return
            0;
            }
           
            static
            void __exit hello_exit(void)
            {
                    printk(KERN_ALERT"Goodbye,
            cruel world!\n");
            }
            module_init(hello_init);
            module_exit(hello_exit);
            加载时,可以用sudo
            insmod hello.ko myshort=5命令为模块传递参数。
            如果我们把hello_init和hello_exit函数分开放在start.c和stop.c文件中,则Makefile需要改为
            obj-m
            += startstop.o
            startstop-objs
            := start.o stop.o
                   
                   
                   

    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/78437/showart_1355559.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP