清浦网站建设,网站建设 电子商务网站开发,家具设计软件,设置网站404页面一、概述 Linux操作系统通常是基于Linux内核#xff0c;并结合GNU项目中的工具和应用程序而成。Linux操作系统支持多用户、多任务和多线程#xff0c;具有强大的网络功能和良好的兼容性。本文主要讲述如何编译及加载linux驱动模块。
二、概念及原理 应用程序通过系统调用与内…一、概述 Linux操作系统通常是基于Linux内核并结合GNU项目中的工具和应用程序而成。Linux操作系统支持多用户、多任务和多线程具有强大的网络功能和良好的兼容性。本文主要讲述如何编译及加载linux驱动模块。
二、概念及原理 应用程序通过系统调用与内核进行交互而驱动程序则提供了硬件设备的访问接口内核本身则提供了系统调用、驱动框架等基础设施。 驱动开发Linux 驱动开发是指为 Linux 内核开发各种设备驱动程序用于控制和管理硬件设备。驱动程序运行在内核空间直接与硬件进行交互。Linux 内核提供了丰富的接口和框架开发者可以编写各种类型的设备驱动包括网络设备、存储设备、输入设备等。驱动程序通过内核提供的接口与用户空间的应用程序进行通信。 应用开发Linux 应用开发是指在 Linux 系统上开发各种类型的应用程序包括命令行工具、图形界面应用、服务器端应用等。Linux 提供了丰富的开发环境和工具链开发者可以使用各种编程语言和开发工具进行应用开发。应用程序运行在用户空间通过系统调用与操作系统内核进行交互执行各种任务和功能。 内核开发Linux 内核开发是指对 Linux 内核本身进行开发和维护。Linux 内核是操作系统的核心负责管理系统资源、调度任务、提供系统调用等功能。内核开发包括对内核功能的添加和修改修复内核漏洞优化性能等工作。内核开发人员通常会编写和维护内核的各种子系统和模块包括调度器、文件系统、网络协议栈等。 模块加载与卸载在 Linux 中模块是指可以动态加载到内核中并扩展其功能的代码段。模块的加载意味着将模块的代码和数据加载到内核空间并使其在内核中运行从而扩展内核的功能。模块的卸载则是将其从内核中移除释放其占用的资源。模块的加载与卸载允许内核在运行时动态地添加或移除功能这为系统提供了灵活性和可扩展性。
三、编译前准备 在 Ubuntu 系统中进行 Linux 内核驱动模块的编译需要做一些准备工作 安装必要的软件包 确保你的系统已经安装了必要的软件包包括编译工具链、内核源码和头文件等。你可以使用以下命令来安装这些软件包 sudo apt update
sudo apt install build-essential linux-headers-$(uname -r)确认内核源码路径 确保你知道系统中内核源码的路径通常位于 /lib/modules/$(uname -r)/build。这个路径在编译驱动模块时可能会用到。
四、代码实现及编译
驱动模块代码 新建一个名为helloworld.c的文件添加如下代码。
#include linux/init.h
#include linux/module.h/* 定义模块的初始化函数 */
static int Helloworld_Init(void)
{printk(Im Chewie, Helloworld init ok!\n);return 0;
}/* 定义模块的退出函数 */
static void Helloworld_Exit(void)
{printk(Bye bye!\n);
}/* 注册模块的初始化和退出函数这个是给内核识别的 */
module_init(Helloworld_Init);
module_exit(Helloworld_Exit);/* 声明该模块符合GPL协议 */
MODULE_LICENSE(GPL);Makefile编写 新建一个名为Makefile的文件不需要后缀必须是Makefile首字母大写makefile识别不了一开始不知道踩了个坑这个 Makefile 文件主要是用于告诉 make 命令如何编译驱动程序模块并提供了编译和清理的规则。在文件中添加如下内容。
obj-m : helloworld.oKDIR : /lib/modules/$(shell uname -r)/buildall:make -C $(KDIR) M$(PWD) modulesclean:make -C $(KDIR) M$(PWD) clean其中各部分的具体含义如下 obj-m : helloworld.o: obj-m 是一个特殊的变量用于指定要编译成模块的目标文件。helloworld.o 是模块的目标文件名这里是你要编译生成的驱动模块文件名。 KDIR : /lib/modules/$(shell uname -r)/build: KDIR 是一个变量用于指定内核源码的路径。/lib/modules/$(shell uname -r)/build 是一个动态获取当前系统内核版本并拼接出内核源码路径的命令。 all:: all 是一个 Makefile 中的默认目标表示默认情况下执行的规则。 make -C $(KDIR) M$(PWD) modules: make -C $(KDIR) 是在内核源码路径下执行 make 命令M$(PWD) 表示当前目录是模块源码的路径。modules 是指定了要编译生成模块对象文件的规则。 clean:: clean 是一个用于清理的目标用于清理编译产生的文件。 make -C $(KDIR) M$(PWD) clean: make -C $(KDIR) 是在内核源码路径下执行 make 命令M$(PWD) 表示当前目录是模块源码的路径。clean 是指定了要执行清理操作的规则。 然后在当前helloworld.c目录下打开终端输入以下命令进行编译。
make -C /lib/modules/$(uname -r)/build M$(pwd) modules五、模块加载及卸载 编译完模块后需要把模块加载到内核才可正常使用。这里可以使用insmod指令加载驱动模块。注意需要加上sudo使用root权限。
sudo insmod helloworld.ko那如何知道模块是否加载成功呢这里需要使用lsmod | grep helloworld检查模块加载情况。如果有如下显示则说明加载成功。 卸载模块时则需要使用rmmod进行卸载。同样需要加上sudo使用root权限。
sudo rmmod helloworld到这里可能有人要问了模块初始化和退出函数里不是加了printk打印了一些信息吗为什么终端里没有显示任何内容是因为printk打印的信息是在内核空间中而终端是属于用户空间的所以不会显示内核的信息。如果想要显示这个打印内容可以使用dmesg打印内核日志同样的要加上sudo使用root权限这样就能看到上面模块加载和卸载的信息及打印的相关信息。 如果想要实时查看内核日志可以通过以下命令实时打印内核日志。这里建议单独开一个终端实时查看。
sudo tail -f /var/log/kern.log六、相关链接
【学习记录】从0开始的Linux学习之旅——编译linux内核