博文

目前显示的是标签为“module”的博文

模块参数

了解了内核模块、中断、定时器等内容后,我们缓一下来补充之前的一些内容和相关内容,接下来主要是了解内核态与用户态之间数据传递的机制,这次先了解内核模块参数,该部分在中断时有使用到,但未整理说明,现在补充学习下。 那么什么是内核态和用户态呢? 简单来理解,内核模块和内核就是运行在内核态,而用户程序和命令行操作等则运行在用户态,即程序运行的空间状态不一样,那么两者如何通信?本次说到的内核模块参数会感受到。 作为内核模块参数,我们只有将驱动代码编译成ko文件,再使用insmod和modprobe命令加载时才会使用到(也可在加载模块后在/sys里修改),而一旦将其编译进内核,那么我们会使用到内核启动参数,这个后期再说明。 在include/linux/moduleparam.h文件里有关于内核模块参数的定义,而我们常用到的宏有如下: #define module_param(name, type, perm) \ module_param_named(name, name, type, perm) #define module_param_array(name, type, nump, perm) \ module_param_array_named(name, name, type, nump, perm) #define MODULE_PARM_DESC(_parm, desc) \ __MODULE_INFO(parm, _parm, #_parm ":" desc) 其中module_param 和module_param_array是定义相关参数时使用,而 MODULE_PARM_DESC仅仅是对参数进行描述,说明该参数的作用,上述宏的相关参数说明如下: 1.name与_parm是参数名; 2.type:参数的类型,可使用的类型如下: byte, short, ushort, int, uint, long, ulong charp: a character pointer bool: a bool, values 0/1, y/n, Y/N. invbool: the above, only sense-reversed (N = true). 3.perm:在include/uapi/...

书写首个内核模块

在《为Ubuntu换颗“心”》一文中,我们已经了解到了如何去编译安装新的Kernel,编译过程也生成了相应的内核树,为什么要生成内核树呢?其实就跟我们写应用程序时一样,写程序会调用到其他的库文件或其他文件生成的目标文件,最后再由链接器把这些目标文件处理生成可执行文件,就是这道理,这为我们后期调试内核模块时打下了应有的基础,有了这编译调试内核模块的基础,接下来就可以开始尝试写我们的首个模块了。  于是接下来我们按照学习编程语言时写一个我们自己的Hello world——Hello xinu,向自己问声好,表扬下自己迈出这一步,踏入了内核驱动模块的圈。 下面是我们的hello_xinu.c文件内容: #include <linux/init.h> #include <linux/module.h> static int hello_xinu_init(void) { printk("Hello xinu!\n"); return 0; } static void hello_xinu_exit(void) { printk("Bye xinu!\n"); } module_init(hello_xinu_init); module_exit(hello_xinu_exit); 源码写好后,在此只需确认整个模块的入口,即module_init对应的hello_xinu_init,而出口是hello_xinu_exit,这个在后面的操作中可以确认。 接下来需要编译时用到的Makefile文件,内容如下: obj-m += hello_xinu.o CUR_PATH:=$(shell pwd) LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6 all: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules clean: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean 此处只需要确认下LINUX_KERNEL_PATH这个变量的值,请根据实际来确认。 我这边最终...