一个开发板 上一节的最后我们讲到设备树的三大作用,其最后一个作用也是最重要的作用:设备信息集合。这一节结合设备信息集合的详细讲解来认识一下设备和驱动是如何绑定的。...我们看到一个开发板有很多的设备,这些设备是如何一层一层展开的呢?设备和驱动又是如何绑定的呢?我们带着这些疑问进入本节的主题。...第一节中讲了总线、设备和驱动模型的原理,即任何驱动都是通过对应的总线和设备发生联系的,故虽然 soc 内部没有具体的总线,但是内核通过 platform 这条虚拟总线,把控制器一个一个找到,一样遵循了内核高内聚...下面我们按照 platform 设备、i2c 设备、spi 设备的顺序探究设备是如何一层一层展开的。...下面看下 platform 设备是如何展开的。 还记得上一节讲到在内核初始化的时候有一个叫做 init_machine() 的回调函数吗?
前言 这一部分主要是用来介绍 Linux 设备驱动程序的一些基本概念,包括:Linux 设备驱动程序的作用、内核功能的划分、设备和模块的分类以及版本编号。...驱动程序应当做到使硬件可用, 将所有关于如何使用硬件的事情留给应用程序。...,并处理它们与外部世界的联系(输入和输出)。...Linux,相反,允许应用程序读写一个块设备象一个字符设备一样 – 它允许一次传送任意数目的字节。结果就是,块和字符设备的区别仅仅在内核在内部管理数据的方式上,并且因此在内核/驱动的软件接口上不同。...一个网络接口负责发送和接收数据报文,在内核网络子系统的驱动下,不必知道单个事务是如何映射到实际的被发送的报文上的。
Linux设备驱动概述 操作系统内核是通过各种驱动程序来驾驭硬件设备,它为用户屏蔽了各种各样的设备。 设备驱动程序是操作系统内核和机器硬件之间的接口,系统调用是操作系统内核和应用程序之间的接口。...linux如何管理文件 Linux把设备纳入文件系统的范畴来管理。 每个设备在Linux系统上看起来都像一个文件,它们存放在/dev目录中,称为"设备节点"。...Linux下设备的属性 设备的类型:字符设备、块设备、网络设备; 主设备号:标识设备对应的驱动程序。...一些重要的数据结构 大部分驱动程序涉及三个重要的内核数据结构: 文件操作file_operations结构体 - 结构体file_operations在头文件 linux/fs.h中定义,用来存储驱动内核模块提供的对设备进行各种操作的函数的指针...进程通过文件描述符fd与已打开文件的file结构相联系。 struct file 在中定义。 指向结构体struct file的指针通常命名为filp,或者file。
目录 示例程序目标 编写驱动程序 编写应用程序 卸载驱动模块 在前几篇文章中,我们一块讨论了:在 Linux 系统中,编写字符设备驱动程序的基本框架,主要是从代码流程和 API 函数这两方面触发。...创建驱动目录和驱动程序 $ cd linux-4.15/drivers/ $ mkdir mygpio_driver $ cd mygpio_driver $ touch mygpio.c mygpio.c...从代码中可以看出:驱动程序使用 alloc_chrdev_region 函数,来动态注册设备号,并且利用了 Linux 应用层中的 udev 服务,自动在 /dev 目录下创建了设备节点。...另外还有一点:在上面示例代码中,对设备的操作函数只实现了 open 和 ioctl 这两个函数,这是根据实际的使用场景来决定的。 这个示例中,只演示了如何控制 GPIO 的状态。...设备节点 由于在驱动程序的初始化函数中,使用 cdev_add 和 device_create 这两个函数,自动创建设备节点。
在Linux设备驱动之字符设备(一)中学习了设备号的构成,设备号的申请与释放。在Linux设备驱动之字符设备(二)中学习了如何创建一个字符设备,初始化,已经注册到系统中和最后释放该字符设备。...本节将结合前两节学到的知道,编写一个简单的字符设备驱动。最后总结一下字符设备驱动的模型。...字符设备驱动程序源码 #include #include #include #include <linux/...237,所以下一步就是根据主设备号创建设备节点。...可以看到是进入了open函数和read函数。 字符设备驱动模型
Linux中设备驱动的分类 从上图可以看到Linux系统将各异的设备分为三大类:字符设备,块设备和网络设备。内核针对每一类设备都提供了对应驱动模型架构,包括基本的内核设施和文件系统接口。...主设备号用来标识对于的设备驱动程序,而次设备号则由驱动程序使用,用来标识它所管理的若干同类设备。 设备号的表示 在linux系统中,设备号用dev_t表示。这是个32位的无符号整数。...随着Linux系统的演变,上述的主次设备号的分发可能在将来会发生变化,所以设备驱动程序开发者应该避免直接使用主次设备号所占的位宽来获得对于的主设备号或次设备号。...MKDEV则是将主设备号ma和次设备号mi合成一个dev_t类型的设备号。...假设在内核版本之后对主次设备号所占的位数发生了变化,MINORBITS修改为18位,只要驱动是使用MAJOR和MINOR宏来操作设备号,就不需要修改驱动代码也可以在新内核中使用。
块设备是与字符设备并列的概念, 这两类设备在 Linux 中驱动的结构有较大差异,总体而言, 块设备驱动比字符设备驱动要复杂得多,在 I/O 操作上表现出极大的不同,缓冲、 I/O 调度、请求队列等都是与块设备驱动相关的概念...在Linux中,驱动对块设备的输入或输出(I/O)操作,都会向块设备发出一个请求,在驱动中用request结构体描述。...但对于一些磁盘设备而言请求的速度很慢,这时候内核就提供一种队列的机制把这些I/O请求添加到队列中(即:请求队列),在驱动中用request_queue结构体描述。...编写块设备驱动时,使用的一些单位介绍: 1. 扇区(Sectors):任何块设备硬件对数据处理的基本单位。通常,1个扇区的大小为512字节。(对设备而言) 2....2.1 内核自带可参考的块设备驱动源码 drivers\block\z2ram.c drivers\block\xd.c \drivers\mmc\host\sdhci-s3c.c 2.2 块设备注册与注销函数
通过上一节Linux设备驱动字符设备(一)了解了Linux设备驱动的分类,设备号的构成,设备号的申请以及设备号的释放。 在Linux内核中使用struct cdev结构来代码字符设备。...struct kobject kobj 内核的内嵌对象,是Linux设备驱动模型的重要成员。...字符设备的注册 在前面知道了如何分配字符设备,以及初始化。接下来的任务就是将字符设备注册到系统中去。内核提供了cdev_add函数,用来将一个字符设备加入到系统中。...第一个参数p代表加入到系统的字符设备的指针,第二个参数dev代表该设备的设备号,第三个参数count代表次设备的个数。 函数主要的部分kobj_map实现了如何将一个字符设备加入到系统的。...该部分在后面Linux字符设备框架一节会详细分析,目前只要明白主要流程即可。 字符设备的注销 当驱动程序需要从系统卸载的时候,就需要使用cdev_del释放字符设备占用的内存。
前言 在linux设备驱动模型中,总线可以看作是linux设备模型的核心,系统中的其他设备以及驱动都是以总线为核心围绕。不过驱动程序员在系统中创建一条总线的机会并不多。...为此linux设备驱动模型都将围绕"总线--设备--驱动"来展开,因为符合linux设备驱动模型的设备与驱动都是必须挂载在一个总线上的,无论是实际存在的或者虚拟的。....dev_attrs: 此bus设备上默认的属性。 .bus_groups, dev_groups, drv_groups: 分别是总线, 设备,驱动的属性。....match: 当一个设备或者驱动添加到此总线上的时候,bus就会调用match对设备和驱动一一匹配的。...p: 一个用来管理总线上设备与驱动的数据结构。
前言 linux将所有的驱动抽象为struct device_driver结构。这样设计可以方便驱动程序更好编写,在编写驱动的时候只需要将此结构嵌入到具体的驱动中即可。...,同样通过注册,最后调用到驱动的show和store函数。...和设备一样,内核也为设备驱动定义了一些驱动的宏属性,方便定义驱动属性。...remove driver %s\n", drv->bus->name, drv->name); driver_detach(drv); //解除设备与驱动联系...->bus); //总线引用计数减1 } 重点看下设备与对应的驱动是如何解除联系的。
sysfs_ops: 该kobject的属性的操作函数,也就是show和store函数,直接可以通过shell命令操作。...#include #include #include #include #include #include #include static struct kobject kobj;...这时候上层就如果使用到此文件,首先肯定是open的操作,会通过系统调用进入到内核的sys_open函数中,经过一系列的操作最后进入到kernfs_fop_open函数中,关于如何执行到此函数,暂且不分析...it */ if (name) { pr_debug("kobject: '%s': free name\n", name); kfree(name); } } 所以基于上述的执行路径,在驱动的
Kobject是linux设备驱动模型的基础,也是设备模型中抽象的一部分。如果想了解设备驱动模型就需要明白Kobject的构成或原理。...linux内核为了兼容各种形形色色的设备,就需要对各种设备的共性进行抽象,抽象出一个基类,其余的设备只需要继承此基类就可以了。...kset对象用来容纳一系列同类型的kobject ktype: 用来定义该内核对象的sys文件系统的相关操作函数和属性。...#include #include #include #include #include #include #include
Linux 内核源码:include\linux\usb.h Linux 内核源码:drivers\hid\usbhid\usbmouse.c 1....BUS/DEV/DRV 模型 "USB 接口"是逻辑上的 USB 设备,编写的 usb_driver 驱动程序,支持的是"USB 接口": USB 控制器或 Hub 识别出 USB 设备后,会创建、...左边的 usb_driver 和右边的 usb_interface 如果匹配,则调用 usb_driver.probe 2....接口函数 在 USB 设备驱动程序中,能使用的 USB 函数都在这个头文件里:include\linux\usb.h。...关键就在于需要填充 URB: dev:跟谁传输数据 pipe:跟哪个 pipe 传输数据 buffer:里面存有要发送的数据,或者用来接收要读取的数据 数据长度 回调函数 2.3.1 分配和释放 URB
前言 当一个设备动态的加入到系统时候(比如常见的将U盘插入到PC机器上), 设备驱动程序就需要动态的检测到有设备插入了系统,就需要将此事件通知到用户层,然后用户层对这一事件做响应的处理,比如加载USB驱动...而将此事件通知到用户层就需要某种机制,典型的就是mdev hotplug和udev。关于udev和mdev hotplug可以在上篇文章有解释。...Linux系统对uevent机制的具体实现是建立在设备模型的基础上的,通过kobject_uevent函数实现。 在前面的kset小节中提到了注册一个kset的接口,可以在这里习复下。...而kobject和kset的主要区别就是,将一个kset注册到系统的时候,就需要将此事件通过kobject_uevent发送到用户空间,而kobject如果是单独的,没有依赖kset,则无法通过uevent...} #endif exit: kfree(devpath); kfree(env); return retval; } uevent_helper机制 目前内核支持两种方式,netlink和uevent_helper
coresight cpu event_source hid i2c iio mdio_bus mmc platform scsi sdio serio spi usb virtio workqueue 数据结构 linux...//初始化操作 err = kobject_add_internal(&k->kobj); //将kset->kobject对象添加到sys下,此过程和添加...//设置ktype kset->kobj.kset = NULL; return kset; } kset_create_and_add(kset_register和kset_create...而__start___param和__stop___param定义在链接脚本中。..., perm) 接着上面的分析,看kernel_add_sysfs_param此函数,在此函数中通过locate_module_kobject函数建立起与kset(module_kset)之间的联系
图1-1 声音的录音和播放过程 数据结构 在ALSA架构下,pcm也被称为设备,所谓的逻辑设备。在linux系统中使用snd_pcm结构表示一个pcm设备。....streams: 指向pcm的capture和playback stream,通常0代表playback,1代表capture。...linux系统中使用snd_pcm_str定义stream, 使用snd_pcm_substream定义substream。...应用到驱动的过程 当应用程序在通过open系统调用打开/dev/pcmC0D0c的过程 1....if ((err = substream->ops->open(substream)) < 0) 至此,整个pcm设备创建,调用,以及应用到驱动整个流程分析完毕。:)
Linux系统一次读取磁盘的大小是一个块,而不是一个扇区,块设备驱动由此得名。 二、块设备处理过程 1、linux 内核中,块设备将数据存储与固定的大小的块中,每个块都有自己的固定地址。...Linux内核中块设备和其他模块的关系如下。 ? 1、块设备的处理过程涉及Linux内核中的很多模块,下面简单描述之间的处理过过程。 ... ?...(Linux系统中,对块设备的IO请求,都会向块设备驱动发出一个请求,在驱动中用request结构体描述) 内核结构如下:. struct request { struct list_head queuelist...(也可以不用注册设备,驱动一样可以工作,该函数和字符设备的register_chrdev()函数相对应,对于大多数的块设备,第一个工作就是相内核注册自己,但是在Linux2.6以后,register_blkdev
前言 Linux将所有的设备统一抽象为struct device结构, 同时将所有的驱动统一抽象为struct device_driver结构。...最终会调用device_register和driver_register将驱动和设备注册到系统,表现出来就是在sys目录的device和driver目录下。...本小节先分析device结构,以及相关API,以及如何注册到系统中,以及提供给上层的sys接口。 数据结构 Linux将所有的设备统一抽象为struct device结构。...probe,这下知道驱动的probe函数是如何调用的。...,最终会调用到设备的show和store函数中,具体的流程分析可见Linux设备驱动模型-Ktype static ssize_t dev_attr_show(struct kobject *kobj
设备通过设备号来标识。设备号分两部分,主设备号和次设备号。 通常,主设备号标示设备对应的驱动程序,linux允许多个驱动共用一个主设备号; 而次设备号用于确定设备文件所指的设备。...在驱动中访问设备号应该用中定义的宏。...见和驱动书的p54 2.6内核结构的初始化: struct file_operations my_fops = { .owner = THIS_MODULE, .llseek =...当inode表示一个字符设备时,i_cdev指向内核中的struct cdev. 其他结构和设备驱动关系不大。...(mi)) //根据指定的主设备和次设备号生成设备号 #include //静态:申请指定的设备号, from指设备号, count指使用该驱动有多少个设备(次设备号
领取专属 10元无门槛券
手把手带您无忧上云