Linux

LINUX

http://www.kernel.org/(Linux内核源代码官方网站)

驱动

裸机驱动 系统驱动

设备驱动在Linux操作系统中的层次

Linux_第1张图片

Linux系统驱动类型

字符设备
块设备
网络设备

Linux内核模块的三要素

入口
出口
许可证

#include 
#include 

//内核模块入口函数
static int __init mycdev_init(void)
{
    //static声明当前函数只能在当前文件中使用
    //int 声明返回值类型为int
   // mycdev_init是函数名,可以更换
   //内核模块中的参数如果无,一定要写一个void
   //#define __init     __section(".init.text")
    //__init的作用是指定入口函数存放在.init.text段中
    return 0;  //一定要返回一个int类型的值,不然编译报错
}
//内核模块出口函数
static void __exit mycdev_exit(void)
{
    //__exit声明当前的出口函数在.exit.text段

}
//用于向内核声明当前内核模块的入口函数地址
module_init(mycdev_init);
//用于向内核声明当前内核模块的出口函数地址
module_exit(mycdev_exit);
//声明当前内核模块遵循GPL协议
MODULE_LICENSE("GPL");

makefile

arch?=arm  #存储编译架构的变量
modname?=demo #存储模块文件名的变量
#指定内核顶层目录的路径
ifeq ($(arch),arm)
KERNELDIR:=/home/ubuntu/linux-5.10.61/   #编译为ARM架构的内核路径
else
KERNELDIR:=/lib/modules/$(shell uname -r)/build   #编译生成x86架构文件的内核路径
endif
#指定当前源码所在的路径
PWD:=$(shell pwd)  #将shell命令pwd的执行结果赋值给变量PWD
all:
#make modules表示进行模块化编译
#make -C $(KERNELDIR)先切换路径到KERNELDIR下,按照这个路径下Makefile的规则进行make
#M=$(PWD)指定模块化编译的路径
    make -C $(KERNELDIR) M=$(PWD) modules
clean:
#编译清除
    make -C $(KERNELDIR) M=$(PWD) clean
#将指定的.o文件独立链接为模块文件
obj-m:=$(modname).o

Linux_第2张图片

insmod
rmmod
lsmod
modinfo
Linux_第3张图片
在这里插入图片描述
Linux_第4张图片

printk

#define KERN_EMERG    KERN_SOH "0"    /* system is unusable */
#define KERN_ALERT    KERN_SOH "1"    /* action must be taken immediately */
#define KERN_CRIT    KERN_SOH "2"    /* critical conditions */
#define KERN_ERR    KERN_SOH "3"    /* error conditions */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
#define KERN_NOTICE    KERN_SOH "5"    /* normal but significant condition */
#define KERN_INFO    KERN_SOH "6"    /* informational */
#define KERN_DEBUG    KERN_SOH "7"    /* debug-level messages */
#include 
#include 

// 内核模块入口函数
static int __init mycdev_init(void)
{
    printk(KERN_ERR "模块安装,执行入口函数\n");
    return 0;
}
// 内核模块出口函数
static void __exit mycdev_exit(void)
{
   printk(KERN_ERR "模块卸载,执行出口函数\n");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

dmesg

Linux_第5张图片

传参

module_param(name, type, perm)

#include 
#include 

int a=10;
module_param(a,int,0664);//声明当前变量可以进行命令行传参
MODULE_PARM_DESC(a,"value is a int");
// 内核模块入口函数
static int __init mycdev_init(void)
{
    printk(KERN_ERR "模块安装,执行入口函数\n");
    printk("a=%d\n",a);
    return 0;
}
// 内核模块出口函数
static void __exit mycdev_exit(void)
{
   printk(KERN_ERR "模块卸载,执行出口函数\n");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

Linux_第6张图片
Linux_第7张图片
Linux_第8张图片

#include 
#include 

int a=10;
char b='c';
char *p="hello world";
module_param(a,int,0664);//声明当前变量可以进行命令行传参
MODULE_PARM_DESC(a,"value is a int");
module_param(b,byte,0664);
MODULE_PARM_DESC(b,"value is a char");
module_param(p,charp,0664);
MODULE_PARM_DESC(p,"value is a charp");
// 内核模块入口函数
static int __init mycdev_init(void)
{
    printk(KERN_ERR "模块安装,执行入口函数\n");
    printk("a=%d\n",a);
    printk("b=%c\n",b);
    printk("p=%s\n",p);
    return 0;
}
// 内核模块出口函数
static void __exit mycdev_exit(void)
{
   printk(KERN_ERR "模块卸载,执行出口函数\n");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

你可能感兴趣的:(linux)