linux 最简单驱动的构建 【掘金日新计划】

196 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

环境搭建

需要一个搭建一个Linux系统,随便centos,rocky 或者ubuntu。
安装内核树。自带的内核树路径一般位于:/lib/modules/【kernel-ver】/build。
如果没有内核树或者需要编译其他版本的驱动,那就需要自己构建一个内核树,可以参考文档

编译,装载

以下代码是一个没有任何功能、非常简单的驱动,动态申请设备号。仅可装载到内核,没有实现任何功能,来让我们感受一下一个最小内存的表现,作为对Linux驱动的入门。 代码如下

#include<linux/module.h>
#include<linux/fs.h>
#include<linux/types.h>
#include<linux/kdev_t.h>
#include<linux/version.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zsy");
MODULE_DESCRIPTION("this is a test driver!");
MODULE_VERSION("1.00");

static dev_t ws_dev ;
static int  __init hello_init(void)
{
    int res = alloc_chrdev_region(&ws_dev,0,1,"MyDri");
    if(res == 0){
        printk(KERN_ALERT "hello world,majorId[%d]!!\n",MAJOR(ws_dev));
    }else{
        printk(KERN_ALERT "hello world,fail\n");
    }
    return res;
}
static void __exit hello_exit(void)
{
    printk(KERN_ALERT "goodbye, cruel world!!\n");
    unregister_chrdev_region(ws_dev,1);
}

module_init(hello_init);
module_exit(hello_exit);

编译脚本 Makefile,如下

obj-m := hello.o
all:
	$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

脚本命令行的缩紧必须使用tab,不可使用空格,不然编译失败。
编译脚本命名: Makefile。
源文件和编译脚本放于同一个文件夹,控制终端输入make,执行编译,执行结果如下。

image.png 使用命令 insmod hello.ko,驱动加载到内核中。

使用modinfo hello.ko可以查看驱动信息。 image.png 和代码中的信息一致。
使用命令rmmod hello 卸载驱动

问题

打印的日志终端看不到? 可以去系统日志里看,如果通过远程测试驱动,驱动的日志信息是打印到实体控制台,而通过网络远程链接的虚拟终端是看不到的。ubuntu可以看一下文件,/etc/rsyslog.d/50-default.conf,查看一下系统日志的配置,看一下syslog的配置文件的基本规则,就可以把咱们驱动的日志打到日志文件里了。 image.png 日志写入两处文件:syslog 和 kernel.log

image.png