作者:邹飞邹飞邹飞 | 来源:互联网 | 2023-06-03 16:01
之前在VM8上安装了ubuntu12.10,通过uname-r命令可以知道该linux内核版本是3.5.0-17-generic,网上下了一个LDD3的PDF,自己也想建立和运行一
之前在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模块删除掉。(这也是驱动模块和应用程序的一大不同之处,应用程序退出时可以不管资源释放或者其他的清除工作,但是内核模块的退出函数必须通过撤销函数将其清除,否则,子系统重新引导之前某些东西就会残留在系统中。如果你的模块没有定于一个清理函数,内核是不会允许它被卸载的。)