自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(89)
  • 资源 (1)
  • 收藏
  • 关注

原创 CPUFreq驱动的简单总结

以上就是一个简单的CPUFreq驱动示例,展示了如何使用Linux内核提供的API来实现对CPU频率的控制。在具体的 频率和电压设置环节,用的都是Linux的标准API regulator_set_voltage()和clk_set_rate()之类的函数。在这个例子中,我们将实现 target_index 回调函数来设置新的频率,并实现 get 函数来获取当前频率。以下是一个简化的CPUFreq驱动示例,演示了如何为一个假想的CPU实现基本的频率调节功能。:提供了统一的接口和机制来管理CPU频率。

2025-04-02 15:19:01 796

原创 sysfs_create_group的简单使用

在 Linux 驱动开发中,是用于为设备创建单个属性文件的函数。如果你需要为一个设备创建多个属性文件(即多个sysfs属性),可以通过多次调用来实现。不过,为了提高代码的可读性和维护性,Linux 内核提供了一种更高效的方式——使用机制来批量定义和注册多个属性文件。

2025-04-01 16:17:08 217

原创 PCIe参考时钟和嵌入式时钟

主板提供 100 MHz 参考时钟给显卡。显卡的 PLL 锁定到这个参考时钟,准备进入链路训练阶段。主板和显卡通过链路训练协商链路速率(如 Gen3, 8 GT/s)。链路训练依赖于参考时钟来进行同步和校准。链路建立后,数据流中的嵌入式时钟被用来同步数据传输。参考时钟继续作为备用时钟,支持低功耗模式和其他操作。当链路进入低功耗状态时,嵌入式时钟可能停止。参考时钟仍然保持工作,确保设备可以在需要时快速恢复。

2025-03-31 11:01:33 918

原创 squashfs文件系统怎么让某个目录可读写?

SquashFS是一种只读的压缩文件系统,主要用于嵌入式系统、Live CD/DVD 和其他需要高效存储和快速访问只读数据的应用场景。它通过压缩文件和目录结构来减少存储空间的需求,并且支持快速随机访问。OverlayFS是一种联合文件系统(Union Filesystem),它可以将多个目录层叠在一起形成一个新的虚拟文件系统。这种技术使得在不修改底层文件系统的情况下进行读写操作成为可能。OverlayFS 在容器技术、Live 系统和嵌入式设备中得到了广泛应用。

2025-03-24 17:24:25 998

原创 cache一致性问题

此时a=1还放在cache line中,在这个cache line还没被替换时,主存中a还是=0;当核心1里面修改了cache某个数据时,通过总线广播给其他核心,每个核心也会监听广播的事件,如果自己的cache也有相同的数据,则会更新到自己的L1 cache;Mesi虽然保证了cache一致性,但是没有解决执行乱序的问题,因为执行乱序是一定存在的,在不能的乱序的地方需要使用屏障指令(保证指令跟数据按照程序逻辑执行)避免它,比如互斥锁里面就用到了屏障指令。//核心1执行,flag先于a=1执行。

2025-03-05 17:24:17 359

原创 pcie设备驱动怎么获取中断号

wifi驱动调用pci_enable_msi来使能和获取msi中断判断是否支持msi,读取配置空间--获取支持的msi向量数,遍历执行msi_capability_init来使能msimsi_setup_entry读取msi_cap等配置信息,msi_mask_irq写配置空间使能msi_irq;pci_msi_setup_msi_irqs用以配置msi;dev->irq = entry->irq来将entry的中断号写进pci_dev中msi的中断域注册的时候一般是线性的,不是层级或者树形的;

2024-12-31 17:25:32 402

原创 platform_get_resource怎么获取reg和irq的

下面是一段那paltform_device获取irq和reg的代码,platform_get_resource_byname加IORESOURCE_MEM参数获取特定名字的内存空间上面通过直接读中断属性,读出的物理中断号值加上16得出最终的irq;platform_get_irq会调用platform_get_resource来获取irq;那证明在platform_get_resource之前已经有过转换操作了,也即of_irq_get。

2024-12-05 11:31:00 682

原创 简析MISC驱动注册流程

misc子系统在初始化的时候,用class_create创建misc类,register_chrdev注册杂项主设备号和对应fops,主设备号决定的驱动程序,也就misc_fops。

2024-12-05 11:12:28 192

原创 ov13850的数据接收流程

通过下面设备树和驱动代码可以看到ov13850出图需要的硬件支撑sensor,mipi,isp,数据流从下至上。

2024-12-05 11:03:30 300

原创 网络设备驱动的接口

net_device的生成和成员的赋值可由alloc_netdev来生成一个net_device结构体,对其成员赋值并返回该结构体的指针。第一个参数为设备私有成员的大小,第二个参数为设备名,第三个参数为net_device的setup()函数指针,第四、五个参数为要分配的发送和接收子队列的数量。setup()函数接收的参数也为struct net_device指针,用于预置net_device成员的值setup函数一般就是初始化net_device的一些成员。

2024-11-22 16:36:13 348 1

原创 为什么建议使用copy_from_user

(1)无论是内核态还是用户态访问合法的用户空间地址,当虚拟地址并未建立物理地址的映射关系的时候,page fault的流程几乎一样,都会帮助我们申请物理内存并创建映射关系。所以这种情况下memcpy()和copy_{to,from}_user()是类似的(2)当内核态访问非法用户空间地址的时候,通过.fixup和__ex_table两个段的帮助尝试修复异常。这种修复异常并不是建立地址映射关系,而是修改do_page_fault()返回地址。

2024-11-21 11:41:31 932

原创 iw添加wlan0导致crash问题分析

nl80211_send_iface的wdev这个参数为空指针;看看nl80211_new_interface调用nl80211_send_iface之前,是怎么给wdev赋值的,如下述代码是从rdev_add_virtual_intf获取wdev这个wireless_dev结构体;也就是要找到这个函数为什么返回空指针。rdev_add_virtual_intf调用的是cfg80211_registered_device的ops成员的add_virtual_intf函数指针。会产生如下panic内容。

2024-11-20 09:54:27 457

原创 块设备的两种访问方法的区别

当我们运行类似于“dd if=/dev/sdb1of=sdb1.img”的命令把整个/dev/sdb1裸分区复制到sdb1.img的时候,内核走的是def_blk_fops这个file_operations另外一种方法是通过文件系统来访问块设备,file_operations的实现则位于文件系统内,文件系统会把针对文件的读写转换为针对块设备原始扇区的读写。

2024-11-15 18:10:28 537

原创 内存管理概述

简要描述linux的内存管理概述,主要参考《Linux内核深度解析》

2024-11-11 15:58:52 885

原创 简述网络设备驱动的结构

网络设备是完成用户数据包在网络媒介上发送和接收的设备,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送,并将接收到的数据包传递给上层协议。Linux网络设备驱动程序的体系结构如下图所示,从上到下可以划分为4层,依次为网络协议接口层、网络设备接口层、提供实际功能的设备驱动功能层以及网络设备与媒介层,这4层的作用如下所示。

2024-11-07 16:57:41 673

原创 device_create,device_register,device_add的应用场景的区别

主要应用场景是在/dev下创建设备节点;主要是dev_t设备号,引起了device_add的设备节点创建操作。

2024-11-04 17:27:50 452

原创 块设备驱动的基本概念

块设备只能以块为单位接收输入和返回输出,而字符设备则以字节为单位。大多数设备是字符设备,因为它们不需要缓冲而且不以固定块大小进行操作;字符设备只能被顺序读写,而块设备可以随机访问。块设备对于I/O请求有对应的缓冲区,因此它们可以选择以什么顺序进行响应,字符设备无须缓冲且被直接读写。对于存储设备而言,调整读写的顺序作用巨大,因为在读写连续的扇区的存储速度比分离的扇区更快。所有的EXT4、UBIFS、原始块设备又都工作于VFS之下,而EXT4、UBIFS、原始块设备之下又包含块I/O调度层以进行排序和合并。

2024-10-30 18:11:53 712

原创 page cache是怎么回写到存储设备的?

blk_queue_bio先调用add_acct_request,里面通过I/O电梯调度算法将request插到request_queue中,电梯调度算法有3种: cfq, deadline, noop,然后他调用__blk_run_queue,里面会调用之前块设备中注册的request处理回调函数q->request_fn来在块设备驱动中处理这个request。在blk_init_queue这个函数中会初始化request_fn和make_request_fn这两个回调函数。

2024-10-15 17:45:13 322

原创 PCIe使用INTA报错的示例及解决

某soc的pcie设备节点更改如下;以使用inta这个传统中断但是获取中断的时候会报错,打印如下分析of_irq_parse_pci的调用栈,那个函数会返回这个-14的错误值,错误值的定义在实际我们就能找到是里面对中断相关属性的读取后,进行的判断报错了由于是从中断控制器节点获取的 interrupt-cells确实是3个单元 ,address-cells是2个单元;所以大于加入的中断属性中gic后的三个单元。

2024-10-14 17:50:17 506

原创 cfg80211是怎么配置无线设备的AP的?

cfg80211 是 Linux 内核中一个用于无线网络的配置和管理的子系统,它为多个无线网络驱动提供了一个统一的接口,以便于无线设备的配置和操作。cfg80211 的设计目标是提供一个简化的管理和配置无线设备的框架,同时支持多种无线设备的标准和功能,其在内核中的/net/wireless/core.c文件会对wifi使用的cfg80211进行初始化。等通过Netlink 套接字和构建消息来与内核空间进行交互。当启动 AP 模式时,hostapd会将请求发送到内核,内核接收并调用cfg80211的。

2024-09-30 11:35:28 1504

原创 PCIe时钟与中断

REFCLK-/REFCLK+: 是一组低压差分信号,PCIe主板提供的REFCLK信号必须满足PCIe规范中的要求。PERST#: 信号用于复位PCIe设备,同时也指示了系统主电源的稳定时间。WAKE#: 信号用于给PCIe主机提供复位信号,由PCIe设备驱动,当PCIe主机接收到该信号后,需要向PCIe设备提供主电源和参考时钟,以激活PCIe链路。WAKE#信号也可以和OBFF机制配合使用,当PCIe主机需要调整设备的缓冲行为(如刷新或填充缓冲区)时,可以通过WAKE#信号通知PCIe设备。

2024-09-13 16:53:56 1704

原创 驱动与应用的编译

无论是去驱动编译,还是应用编译,本质上都是用gcc这个工具,后面跟不同的参数来完成。

2024-09-10 17:17:08 359

原创 pcie的基本概念

PCI Express (peripheral component interconnect express) 简称PCIe,是一种高速、串行、全双工、计算机扩展总线标准,采用高速差分总线,并采用点到点的连接方式用于两个设备之间的通信。多个PCI Express设备通过使用Switch互连,因此可以在一个系统中将大量设备连接在一起。相对于PCI引入了一些新特性,如流量控制机制、服务质量管理(QoS)、热插拔支持、数据完整性和新型错误处理机制等。

2024-09-10 16:59:24 3348 1

原创 反汇编快速定位内核OOPS

简单的说,出现内核奔溃,我们可以通过串口日志提供的信息;使用gdb反汇编出问题函数所在的文件,然后使用《disassemble /m 函数名》查看具体函数的源码和汇编码;这样能直观的看到源代码对应的汇编码干了什么;再根据串口日志的寄存器信息,查看当时寄存器的值,就能对上当时的参数,和变量的值。

2024-08-26 18:02:47 539

原创 简述DMA与cache一致性

DMA是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制;DMA方式的数据传输由DMA控制器(DMAC)控制,在传输期间,CPU可以并发地执行其他任务。当DMA结束后,DMAC通过中断通知CPU数据传输已经结束,然后由CPU执行相应的中断服务程序进行后处理。

2024-08-22 09:53:32 930

原创 MDIO时序分析

也被称作MII管理接口(MII Management Interface),包括MDC和MDIO两条信号线。MDIO是一个PHY的管理接口,用来读/写PHY的寄存器,以控制PHY的行为或获取PHY的状态,MDC为MDIO提供时钟MDIO是双向的,只支持一个MAC连接最多32个PHY的连接方式,且MAC作为master,PHY作为slave。在写PHY寄存器的时候,由MAC驱动MDIO向PHY写入数据;在读PHY寄存器时,前半段由MAC驱动发送寄存器地址,后半段由PHY驱动回复寄存器的值。

2024-08-16 15:13:57 1081

原创 详解sotfirq和tasklet

软中断是在硬件中断推出后执行。软中断不能被自己打断(即单个cpu上软中断不能嵌套执行),只能被硬件中断打断(上半部)。可以并发运行在多个CPU上(同一类型也可以)。所以软中断必须设计为可重入的函数(允许多个CPU同时操作),因此也需要使用自旋锁来保其数据结构。

2024-07-29 16:50:48 891

原创 怎么简单熟悉下一个新平台的设备树

gpio节点可能有多个,他们的中断号都是位于同一个中断控制器,比如gic中断控制器;还有个细节就是simple-bus的字节点也会在系统初始化时生成platform_device,以匹配驱动aon {ranges;

2024-07-29 15:02:48 497

原创 连续调用usleep_range导致的lockup

crng_finalize_init后出现死锁。

2024-07-25 18:00:06 355

原创 设备树节点和struct device的关系及示例

设备树节点-> device_node-> device-> i2c_client;一次呈包含关系。

2024-07-18 16:50:07 1088

原创 简述linux通知链机制

Linux内核中各个子系统相互依赖,当其中某个子系统状态发生改变时,有时需要使用一定的机制告知使用其服务的其他子系统,以便其他子系统采取相应的措施。为满足这样的需求,内核实现了事件通知链机制(notification chain)。通知链只能用在各个子系统之间(当然一个子系统内部也可以使用),而不能在内核和用户空间进行事件的通知。事件通知链表是一个事件处理函数的列表,每个通知链都与某个或某些事件有关,当特定的事件发生时,就调用相应的事件通知链中的回调函数,进行相应的处理。

2024-07-12 16:58:11 548

原创 硬件中断号怎么跟irq映射的?

内核启动由这两个函数,完成中断的的初始化,包括硬件中断号和virq的映射。

2024-07-04 16:40:35 507

原创 linux内核编译流程、驱动加载顺序

根据这个展开 vmlinux-deps := arch/$(SRCARCH)/kernel/vmlinux.lds (head-y init-y core-y libs-y2 drivers-y net-y virt-y libs-y1)上面的xxxx-y就是,每个目录生成的各.o文件集合,会被打包成一个个built-in.a。

2024-07-03 17:37:48 707

原创 device_node和platform_device的生成流程

有介绍DT_MACHINE_START的一些初始化操作,匹配上就会在后续的初始化中调用DT_MACHINE_START的成员来初始化系统的设备树,时钟,中断等。

2024-07-01 16:05:23 769

原创 scatterlist的相关概念与实例分析

scatterlist用来描述一块内存,sg_table一般用于将物理不同大小的物理内存链接起来,一次性送给DMA控制器搬运page_link:(1).对于chain sg 来说,记录下一个 SG 数组的首地址,并且用bit[0] 和 bit[1] 来表示是chain sg 还是 end sg;(2).对于 end sg 来说,只有bit[1] 为1,其他无意义;(3).对于普通 sg 来说,记录的是关联的内存页块的地址;

2024-06-28 15:44:40 1691

原创 cache一致性的概念和场景

Cache是由cache Line组成 它是 CPU 从内存读取的基本单位;数据在Cache和内存之间传输时,不是一个字节一个字节进行传输的,而是以缓存行(Cache Line)为单位进行传输的。不同CPU的Cache line大小可能不同,典型的CPU Cache line大小是64个字节而cache Line 是由各种标志(Tag)+ 数据块(Data Block)组成;但是怎么写呢?:如果命中,直接将数据写到cache和主存;如果没命中,直接写到主存:写到Cache line,标记为脏;

2024-06-25 14:52:02 731

原创 内核模块的各种概念及示例

在Linux中,所有标识为__init的函数如果直接编译进入内核,成为内核镜像的一部分,在连接的时候都会放在.init.text这个区段内--#define _ _init _ _attribute_ _ ((_ _section_ _ (".init.text")))所有的__init函数在区段.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数,并在初始化完成后,释放init区段(包括.init.text、.initcall.init等)的内存。

2024-06-20 11:28:06 895

原创 内核启动时的中断和时钟的初始化流程

内核通过start_kernel从汇编进入c世界,在用serup_arch设置体系架构的时候,会返回当前机器的machine_desc;然后init_IRQ和time_init来初始化中断。时钟子系统mdesc = setup_machine_fdt(atags_vaddr) //返回成功匹配的machine_desc//赋值给全局变量machine_desc,以供后续初始化等操作使用,比如给下面的中断和时钟子系统使用......init_IRQ......time_initelse。

2024-06-19 11:22:41 963

原创 gpio-0设置成输出失败的原因

影响代码如下:of_property_read_u32返回0是找到节点里的属性了,返回负数是没找到;而且没对gpio_request做返回判断,如果有冲突的情况,这个地方还设置了gpio0为输入---那就异常了,该输出的gpio,被异常设置成了输入。但是后面其他驱动,使用of_property_read_u32获取设备树节点的属性时,没去判断返回值;而直接使用参数返回的0,导致gpio-0又被设置成了输入。修改如下:所以对接口的返回值做判断很重要,能避免一些奇葩的bug。正常的如下,gpio显示为输出。

2024-06-14 17:54:59 382

原创 poweroff, reboot流程

当传递特定的magic值如 LINUX_REBOOT_CMD_POWER_OFF时,内核会执行关机并尝试触发硬件层面的电源关闭。poweroff /halt /reboot操作通常由用户空间的systemd或其他初始化系统通过sys_reboot()系统调用触发。poweroff流程,pm_power_off函数被各平台赋值到具体函数,比如通过操作PMIC来实现关机。reboot流程,arm_pm_restart函数可能被具体平台赋值到具体函数,比如操作WDT实现重启。

2024-06-06 15:22:16 458

esp8266入门教程

这款芯片使用了3.3V的直流电源,体积小,功耗低,支持透传,丢包现象不严重,而且价格超低,有ESP8266-01系列,相应的还有ESP8266-02,03等等,它们使用的核心芯片都是相同的,不同之处就是引出的引脚不同,而且有的系列对核心芯片还加了金属屏蔽壳,有的可外接陶瓷天线等。

2019-01-20

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除