linux驱动基础知识(一)

对于无操作系统的驱动,就是裸机,也就是我们常说的单片机。我们并不需要操作系统,可以直接使用单片机进行通断控制,从编程角度来看,就是直接控制寄存器。

对于有操作系统时的驱动(此处来到我们要说的linux系统驱动),我们开发驱动需要基于linux的各种框架进行编程,按照linux系统给出的框架进行编程,可以提供一个统一的接口给应用程序调用(统一的接口就是指dev下的设备节点)。

linux驱动分为字符设备、网络设备,块设备三类(此处不再赘述,可百度)

linux源码目录是一个树状结构,下图为linux顶层目录的各个文件说明

linux驱动基础知识(一)_第1张图片

一个最简单的驱动加载程序应具备以下几个方面:

1.头文件

2.驱动加载函数

3.驱动卸载函数

4.许可证声明。linux是开源的驱动在加载的时候也需要遵守相关协议,可以接收到的license有GPL、GPL v2等

5.模块参数(可选)选择是否被编译为内核模块

#include 
#include 

static int helloworld_init(void)//模块加载函数需要返回一个int类型
{
    printk("hello world\n");//驱动程序的打印需要使用printk!!!!因为我们并没有加载stdio.h这个头文件,难道不是嘛
    return 0;
}
static void helloworld_exit(void)//驱动卸载程序是没有返回值的
{
    printk("bye world\n");
} 
module_init(helloworld_init);//此处调用模块加载函数,输出hello world
module_exit(helloworld_exit);//此处调用模块卸载函数,输出bye world

MODUBLE_LICENSE("GPL");//此处是声明调用的协议

那么如何编译linux驱动程序呢?

共有两种方法:

第一:将驱动程序放在Linux内核当中,然后编译Linux内核,将驱动编译到Linux内核当中。

第二:将驱动编译成内核模块,独立于Linux内核之外

此处的内核模块是指,linux所具有的功能,使用Linux模块可以减少内核体积,加快速度。内核模块的后缀是.ko

将驱动编译为内核模块往往通过makefile,以下为makefile的代码

#在#号后边表示注释

#此处-m是指编译为模块,“+=” 表示对变量进行追加赋值,表示把目标文件hello.o作为模块进行编译
obj-m += hello.o
#对于变量赋值的情况 “:=”是立刻赋值,就是a:= $(object) 变量a就已经等于 变量object了,此处为内核源码的绝对路径,你需要根据自己的实际路径进行填写
KDIR := /home/topeet/linux-kernel
#"?="FOO ?= bar

#其含义是,如果 FOO 没有被定义过,那么变量 FOO 的值就是“bar”。而此处$(shell pwd)表示使用命令 pwd获取当前地址
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules  
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

在编译之前需要,首先编译通过linux内核,然后设置环境变量

linux驱动基础知识(一)_第2张图片

交叉编译器也需要根据自己的实际路径进行填写

模块加载命令

insmod模块名

modprobe 模块名

模块卸载命令

rmmod 模块名

查看模块命令

lsmod或者用cat /pro/modules

查看内核模块信息

modinfo 模块名

在linux内核源码使用命令make menuconfig,记得使用这条命令之前,先用环境变量初始化linux的架构,有三种方式,空的,不对驱动进行操作,*编译进内核,M编译成linux内核模块

你可能感兴趣的:(Linux驱动,linux,运维,服务器)