推荐群:C/C++大学技术协会:145655849
Linux中的模块(Modules)
Linux的module其实可以看作是内核的插件。
在Linux系统中,可以通过文件
cat /proc/modules
xxxxxxxxxx1 1cat /proc/modules
查看相关的驱动模块。
也可以通过命令
lsmod
xxxxxxxxxx1 1lsmod
查看,lsmod只是将/proc/modules中的内容做了格式化排版。
设备驱动是模块的一种,它用于为系统上层提供针对硬件的操作。除硬件设备的驱动外,内核模块也是内核扩展功能的一种方式,即有些模块并没有对应的硬件,而是纯软件的运行在0环的代码,如内核级的防火墙(网络模块)。
使用命令
insmod
xxxxxxxxxx1 1insmod
或者
modprobe
xxxxxxxxxx1 1modprobe
可以在内核中插入模块。两者的区别在于,modprobe的功能更强,并且会自动解决依赖问题。
编译及启用Linux内核
随系统发行的Linux内核的头文件(在/usr/src下),不一定与当前系统的内核二进制文件一致,甚至有可能不全。
所以在做内核开发前,最好些自己重编译、安装一份内核。
参考 https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel
获取源码
通过以下命令下载源码
apt-get source linux-image-(uname−r)xxxxxxxxxx11apt−getsourcelinux−image−(uname -r) xxxxxxxxxx1 1apt-get source linux-image-(uname−r)xxxxxxxxxx11apt−getsourcelinux−image−(uname -r)
设置编译依赖
通过以下命令,将build的依赖环境,配置(下载)为与将要编译的内核一致:
sudo apt-get build-dep linux-image-(uname−r)xxxxxxxxxx11sudoapt−getbuild−deplinux−image−(uname -r) xxxxxxxxxx1 1sudo apt-get build-dep linux-image-(uname−r)xxxxxxxxxx11sudoapt−getbuild−deplinux−image−(uname -r)
编译内核
进入源码根目录下,执行
fakeroot debian/rules clean
quicker build:
fakeroot debian/rules binary-headers binary-generic binary-perarch
if you need linux-tools or lowlatency kernel, run instead:
fakeroot debian/rules binary
xxxxxxxxxx5 1fakeroot debian/rules clean2# quicker build:3fakeroot debian/rules binary-headers binary-generic binary-perarch4# if you need linux-tools or lowlatency kernel, run instead:5fakeroot debian/rules binary
将在上层目录下,得到几个deb文件:
cd …
ls *.deb
linux-headers-4.8.0-17_4.8.0-17.19_all.deb
linux-headers-4.8.0-17-generic_4.8.0-17.19_amd64.deb
linux-image-4.8.0-17-generic_4.8.0-17.19_amd64.deb
xxxxxxxxxx5 1cd …2ls *.deb3 linux-headers-4.8.0-17_4.8.0-17.19_all.deb4 linux-headers-4.8.0-17-generic_4.8.0-17.19_amd64.deb5 linux-image-4.8.0-17-generic_4.8.0-17.19_amd64.deb
安装测试新内核
sudo dpkg -i linux4.8.0-17.19.deb
sudo reboot
xxxxxxxxxx2 1sudo dpkg -i linux4.8.0-17.19.deb2sudo reboot
设置编译时产生调试符号信息
sudo apt-get install pkg-config-dbgsym
fakeroot debian/rules clean
fakeroot debian/rules binary-headers binary-generic binary-perarch skipdbg=false
xxxxxxxxxx3 1sudo apt-get install pkg-config-dbgsym2fakeroot debian/rules clean3fakeroot debian/rules binary-headers binary-generic binary-perarch skipdbg=false
使用Make系统手工编译内核及加入模块
以上的方法是Ubuntu的apt-get系统提供的,可以方便地获取源码、编译及安装。
但是对于理解内核编译过程,自己加入驱动模块的用处不大。
将自己的驱动模块加入源码目录中
将自己的源码文件(hello.c)放入到内核源码的./drivers/char目录下,我的测试文件的内容为:
/*
- $Id: hello.c,v 1.5 2004/10/26 03:32:21 corbet Exp $
*/
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE(“Dual BSD/GPL”);
static int hello_init(void)
{
printk(KERN_ALERT “Hello, world\n”);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT “Goodbye, cruel world\n”);
}
module_init(hello_init);
module_exit(hello_exit);
x 1/* 2 * $Id: hello.c,v 1.5 2004/10/26 03:32:21 corbet Exp $ 3 */ 4#include <linux/init.h>5#include <linux/module.h>6MODULE_LICENSE(“Dual BSD/GPL”);78static int hello_init(void)9{10 printk(KERN_ALERT “Hello, world\n”);11 return 0;12}1314static void hello_exit(void)15{16 printk(KERN_ALERT “Goodbye, cruel world\n”);17}1819module_init(hello_init);20module_exit(hello_exit);
编辑Kconfig文件以及Makefile文件
因为我们要使用可视化的
make menuconfig
xxxxxxxxxx1 1make menuconfig
工具来定义内核的编译选项,这需要用到开源的命令行图行库libcurses,可以先安装:
sudo apt-get install libncurses5-dev libncursesw5-dev
xxxxxxxxxx1 1sudo apt-get install libncurses5-dev libncursesw5-dev
接着,通过编辑Kconfig文件,来设置菜单内容(curses通过读取Kconfig来展示菜单)
打开./driver/char目录下的Kcofnig文件(Kconfig的语法可以参考内核源码目录下的Documentation/kbuild/kconfig-language.txt)。
找到类似以下内容:
config BFIN_OTP
tristate “Blackfin On-Chip OTP Memory Support”
…
help
If you say Y here, you will get support for a character device
…
If unsure, it is safe to say Y.
xxxxxxxxxx7 1config BFIN_OTP2 tristate "Blackfin On-Chip OTP Memory Support"3…4 help5 If you say Y here, you will get support for a character device6 …7 If unsure, it is safe to say Y.
依照它的格式,在其后加入:
config MYMODULE
tristate “A new module just for test!”
default n
help
nothing for usage, left blank
xxxxxxxxxx5 1config MYMODULE2 tristate "A new module just for test!"3 default n4 help5 nothing for usage, left blank
接着,再编辑./driver/char目录下的Makefile文件,在依照该文件中的其它项,在最后加入内容:
obj-(CONFIGMYMODULE)+=hello.oxxxxxxxxxx11obj−(CONFIG_MYMODULE) += hello.o xxxxxxxxxx1 1obj-(CONFIGMYMODULE)+=hello.oxxxxxxxxxx11obj−(CONFIG_MYMODULE) += hello.o
其中CONFIG_之后的MYMODULE对应了在Kconfig中的目录设置,其中的hello.o对应了源码的文件名(hello.c)。
编译
此时,回到源码的根目录,运行命令
make menuconfig
xxxxxxxxxx1 1make menuconfig
在device drviers -> character drivers下,找到我们新添的MYMODULE项,并通过空格,设置为M状态,表示以模块的方式编译。
在源码根目录下运行
make modules
xxxxxxxxxx1 1make modules
若一切顺利,在./drivers/char/目录下,会得到hello.ko,即内核模块文件。
安装
使用insmod安装模块,使用lsmod查看模块,使用rmmod删除模块,使用dmesg查看内核模块的输出信息。
insmod hello.ko
1insmod hello.ko
参考资料,推荐群:C/C++大学技术协会:145655849
The Linux Kernel Module Programming Guide
Linux内核源码中的:Documentation/kbuild/的几个txt文档