Linux(1) 内核驱动基础

内核驱动原理

首先从一张图认识一下内核驱动,有没有很熟悉的5大Linux模块(进程管理、内存管理、文件系统、设备管理、网络管理),而今天需要了解的内核驱动就在其中……
在这里插入图片描述

1、用户态的应用程序调用 C库的 open、read、write、close等接口API函数
2、通过system_call陷入内核态调用虚拟文件系统VFS的system_open、system_read、system_write、system_close等接口
3、通过设备号从驱动链上查找指定的驱动
4、执行指定驱动定义的file_operations中对应的API接口
5、通过API发送具体的指令到硬件设备

内核驱动与裸机驱动

有内核开发裸机开发
功能进程管理、内存管理、文件管理、驱动管理 网络管理
开发模式通过驱动程序+应用程序的模式操作硬件完成任务烧入什么程序,只能跑这一个程序,直接通过烧入程序控制硬件
安全性应用程序不直接操纵硬件更安全应用程序直接访问硬件,不安全
开发难度复杂简单

在这里插入图片描述

运行方式

1)将驱动编译进内核中,当Linux内核启动时会自动运行驱动程序
将xxx.ko文件放到/lib/modules/‘unamer’/extra/目录下,
运行depmod -a命令生成新的modules.alias、modules.dep等文件
修改 etc/modules文件,添加xxx模块名
2)将驱动编译成模块,在内核启动后使用insmod或modprobe命令加载驱动模块
加载模块 insmod xxx.ko
卸载模块 rmmod xxx
查看模块 lsmod |grep xxx
查看信息 modinfo xxx

linux内核与用户数据交互

  • procfs(进程文件系统)

1)占用少量的内存,挂载在 /proc目录下,为用户态和内核态之间的的交互搭建了一个桥梁
2)用户态读写 /proc下的文件,就是读写内核相关的配置参数。
3)当应用程序读取某个 /proc 文件时,内核才会去注册这个文件,然后再调用一组内核函数来处理,将相应的内核参数拷贝到用户态空间,这样用户读这个文件就可以获取到内核的信息。

//创建节点 
proc_create(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops);
proc_create_data(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops, void *data);
//删除节点: 
remove_proc_entry(const char *name, struct proc_dir_entry *parent); 
  • sysfs (基于内核的文件系统)

1)作用是将内核信息以文件的方式提供给用户程序使用
2)sysfs 不仅可以从内核空间读取设备和驱动程序的信息,也可以对设备和驱动进行配置
3)sysfs 有两组接口,一组针对内核,用干将设备映射到文件系统中,另一组针对用户程序,用于读取或操作这些设备
4)创建一个最简单的sysfs文件至少需要创建一个kobject结构(内核对象)和sysfs文件属性(对象属性)

内核层次用户层次
内核对象(kobject)目录
对象属性(attribute)文件
对象关系(relationship)链接(Symbolic Link)
//动态创建一个kobject结构并注册到sysfs 
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent);
//创建sysfs文件
int sysfs_create_group(struct kobject *kobject, const struct attribute_group *group);
  • udev (与用户态相关的驱动设备管理机制)

1)当底层设备发生插拔的时候,底层驱动通过netlink发送事件(uevent)给udev后台程序
2)udev的守护进程侦听来自内核的uevent,并在上层做相应的设备节点创建、命名、权限控制,即添加或删除/dev下的设备文件
3)udev必须要有sysfs的支持
sysfs是建立在内核基础上的文件系统,建立在内核对象kobject的基础上,把链接在系统上的设备和总线组织成一个分级的文件,可以由用户空间获取,也可以向用户空间导出内核数据结构以及它们的属性。

过程描述
1)在内核空间,当系统启动加载驱动或设备发生热插拔的时候,驱动自身需要做相应的硬件探测方面的工作
2)探测到设备后,会去加载相应的设备驱动
3)在sysfs下创建添加内核对象,会调用到kobject_add()来完成该内核对象的添加注册
4)调用kobject_uevent()来通知系统该对象已经添加进来了。
kobject_uevent()函数是uevent的关键函数,它将通过netlink socket把对象相应的信息,属性等发给上层用户空间
通过配置文件/etc/udev/udev.conf查找规则文件目录/etc/udev/rules.d/下的.rules文件

学习思路

模块类型区别
字符设备驱动传输字符
块设备驱动传输块
网络设备驱动根据socket
杂项设备驱动

linux驱动模块大概有30-50个,但是常用的就10来种,搞懂常用的几个,项目基本够用。

$ cat /lib/modules/$(uname -r)/modules.builtin   #查看linux内置驱动模块
模块模块名作用
gpiogpio.ko
UART
I2C
SPI
USB
LCD
WIFI/bluetooth
Ethernet
Power

大多数驱动设备都用了2个以上的驱动模块,比如摄像头就用了MIPI+I2C两种驱动,4/5G 用了USB+虚拟串口驱动.

嵌入式Makefile模板

CROSS_COMPILE 	?= arm-linux-gnueabihf-
TARGET		  	?= bsp

CC 				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY 		:= $(CROSS_COMPILE)objcopy
OBJDUMP 		:= $(CROSS_COMPILE)objdump

INCDIRS 		:= imx6ul \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   			   
SRCDIRS			:= project \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   
				   
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS			:= $(SOBJS) $(COBJS)

VPATH			:= $(SRCDIRS)

.PHONY: clean
	
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

$(SOBJS) : obj/%.o : %.S
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<

$(COBJS) : obj/%.o : %.c
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
	
clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值