最简单的helloworld模块编译加载(linux3.5内核源码树建立)

之前在VM8上安装了ubuntu12.10,通过uname -r命令可以知道该linux内核版本是3.5.0-17-generic,网上下了一个LDD3的PDF,自己也想建立和运行一个简单的模块(helloworld)。

首先建立相应版本的内核树。找到内核源码的位置

其中淡蓝色的压缩包是自己下载的。

通过执行 :apt-cache search linux-source 可以看到可以下载的源码包型号,选择适当的版本就可以下载了(80M左右的源码)。

执行:spt-get install linux-source-3.5.0开始下载。下载完成后会得到一个linux-source-3.5.0的目录。进入目录下,可以开始编译内核了。

执行make oldconfig 或者make menuconfig保存后。

执行:make 或直接 make bzImage。

成功后,在该目录下会生成一个绿色的vmlinux文件。然后开始执行编译模块和安装模块。

执行:make modules 

执行:make modules_install

完成后找到build:如下图

 其中build,是我们随后编译模块文件时要使用到的,记住它的路径。到这里,内核编译完成了,sudo reboot重启下吧。

其次,自己写个简单的驱动吧。

在写个简单的Makefile文件:

分析:obj-m:=hello.o表示要构建的模块名为hello.ko。make会在内核中自动找到hello.c进行编译

KERNRLDIR指定了内核源代码的位置,其中保存有内核的顶层makfile文件。

也可以写成 $(MAKE) -C $(KERNRLDIR) M=$(PWD) modules  

M=$(PWD)指定了模块源代码的位置,modules目标指向obj-m变量中设定的模块。

执行:make

产生:

 执行:insmod  ./hello.ko (将模块加载到内核中,即把该程序加载模块代码段和数据段到内核中)

终端上没有显示:(因为该消息进入了其中一个系统日志文件中,/var/log/xxx  实际的文件名字随linux发布而变化)

执行:lsmod | grep hello 可以查找到。

执行:cat /var/log/syslog 可以查看到输出的语句。

嘿嘿,hello简单的模块至此完成。使用完记得rmmod hello 把hello模块删除掉。(这也是驱动模块和应用程序的一大不同之处,应用程序退出时可以不管资源释放或者其他的清除工作,但是内核模块的退出函数必须通过撤销函数将其清除,否则,子系统重新引导之前某些东西就会残留在系统中。如果你的模块没有定于一个清理函数,内核是不会允许它被卸载的。)

原文地址:https://www.cnblogs.com/zhou2011/p/2849823.html