Kernel 地图

前言

在 Linux Kernel 中,根据 Makefile 和 Kconfig,可以快速地了解一个小的内核子系统。所以我将这两个文件称之为 Kernel 地图。

Kernel 地图

基本上,Linux 内核中,每一个目录下面都有一个 Makefile 和一个 Kconfig 文件。这两个文件就像一座城市的地图,地图带领我们去认识一座城市,而这两个文件则可以让我们了解这个目录下面的结构以及大致内容。我们每次浏览 Kernel 寻找属于自己的那段代码时,都应该首先看看目录下的这两个文件。
就像利用地图寻找目的地一样,我们需要利用 Makefile 和 Kconfig 来寻找所要研究的目标代码。
毫不夸张地说,Makefile 和 Kconfig 是我们浏览内核代码时最为依仗的两个文件。对于一个希望能够在 Linux 内核的汪洋代码里看到一丝曙光的人来说,将它们放在怎样重要的地位都不过分。

实例运用

对象:Kernel led trigger 子系统

首先进入 driver/led/ 目录,列出目录内容
在这里插入图片描述
看到有上百个文件,如果心中无地图,基本上会迷失在代码的海洋中。
不过,我们心中有地图,不慌。

Makefile

先看 Makefile

# SPDX-License-Identifier: GPL-2.0# LED Core
obj-$(CONFIG_NEW_LEDS)			+= led-core.o
obj-$(CONFIG_LEDS_CLASS)		+= led-class.o
obj-$(CONFIG_LEDS_CLASS_FLASH)		+= led-class-flash.o
obj-$(CONFIG_LEDS_CLASS_MULTICOLOR)	+= led-class-multicolor.o
obj-$(CONFIG_LEDS_TRIGGERS)		+= led-triggers.o# LED Platform Drivers (keep this sorted, M-| sort)
obj-$(CONFIG_LEDS_88PM860X)		+= leds-88pm860x.o
obj-$(CONFIG_LEDS_AAT1290)		+= leds-aat1290.o
obj-$(CONFIG_LEDS_ACER_A500)		+= leds-acer-a500.o
obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
obj-$(CONFIG_LEDS_AN30259A)		+= leds-an30259a.o
obj-$(CONFIG_LEDS_APU)			+= leds-apu.o
obj-$(CONFIG_LEDS_ARIEL)		+= leds-ariel.o
obj-$(CONFIG_LEDS_AS3645A)		+= leds-as3645a.o
obj-$(CONFIG_LEDS_ASIC3)		+= leds-asic3.o
obj-$(CONFIG_LEDS_AW2013)		+= leds-aw2013.o
obj-$(CONFIG_LEDS_BCM6328)		+= leds-bcm6328.o
obj-$(CONFIG_LEDS_BCM6358)		+= leds-bcm6358.o
obj-$(CONFIG_LEDS_BD2802)		+= leds-bd2802.o
obj-$(CONFIG_LEDS_BLINKM)		+= leds-blinkm.o
obj-$(CONFIG_LEDS_CLEVO_MAIL)		+= leds-clevo-mail.o
obj-$(CONFIG_LEDS_COBALT_QUBE)		+= leds-cobalt-qube.o
obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-cobalt-raq.o
obj-$(CONFIG_LEDS_CPCAP)		+= leds-cpcap.o
obj-$(CONFIG_LEDS_DA903X)		+= leds-da903x.o
obj-$(CONFIG_LEDS_DA9052)		+= leds-da9052.o
obj-$(CONFIG_LEDS_FSG)			+= leds-fsg.o
obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
obj-$(CONFIG_LEDS_HP6XX)		+= leds-hp6xx.o
obj-$(CONFIG_LEDS_INTEL_SS4200)		+= leds-ss4200.o
obj-$(CONFIG_LEDS_IP30)			+= leds-ip30.o
obj-$(CONFIG_LEDS_IPAQ_MICRO)		+= leds-ipaq-micro.o
obj-$(CONFIG_LEDS_IS31FL319X)		+= leds-is31fl319x.o
obj-$(CONFIG_LEDS_IS31FL32XX)		+= leds-is31fl32xx.o
obj-$(CONFIG_LEDS_KTD2692)		+= leds-ktd2692.o
obj-$(CONFIG_LEDS_LM3530)		+= leds-lm3530.o
obj-$(CONFIG_LEDS_LM3532)		+= leds-lm3532.o
obj-$(CONFIG_LEDS_LM3533)		+= leds-lm3533.o
obj-$(CONFIG_LEDS_LM355x)		+= leds-lm355x.o
obj-$(CONFIG_LEDS_LM3601X)		+= leds-lm3601x.o
obj-$(CONFIG_LEDS_LM36274)		+= leds-lm36274.o
obj-$(CONFIG_LEDS_LM3642)		+= leds-lm3642.o
obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o
obj-$(CONFIG_LEDS_LM3697)		+= leds-lm3697.o
obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
obj-$(CONFIG_LEDS_LP3952)		+= leds-lp3952.o
obj-$(CONFIG_LEDS_LP50XX)		+= leds-lp50xx.o
obj-$(CONFIG_LEDS_LP5521)		+= leds-lp5521.o
obj-$(CONFIG_LEDS_LP5523)		+= leds-lp5523.o
obj-$(CONFIG_LEDS_LP5562)		+= leds-lp5562.o
obj-$(CONFIG_LEDS_LP55XX_COMMON)	+= leds-lp55xx-common.o
obj-$(CONFIG_LEDS_LP8501)		+= leds-lp8501.o
obj-$(CONFIG_LEDS_LP8788)		+= leds-lp8788.o
obj-$(CONFIG_LEDS_LP8860)		+= leds-lp8860.o
obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
obj-$(CONFIG_LEDS_MAX77650)		+= leds-max77650.o
obj-$(CONFIG_LEDS_MAX77693)		+= leds-max77693.o
obj-$(CONFIG_LEDS_MAX8997)		+= leds-max8997.o
obj-$(CONFIG_LEDS_MC13783)		+= leds-mc13783.o
obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o
obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
obj-$(CONFIG_LEDS_MLXREG)		+= leds-mlxreg.o
obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
obj-$(CONFIG_LEDS_NETXBIG)		+= leds-netxbig.o
obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
obj-$(CONFIG_LEDS_NS2)			+= leds-ns2.o
obj-$(CONFIG_LEDS_OT200)		+= leds-ot200.o
obj-$(CONFIG_LEDS_PCA9532)		+= leds-pca9532.o
obj-$(CONFIG_LEDS_PCA955X)		+= leds-pca955x.o
obj-$(CONFIG_LEDS_PCA963X)		+= leds-pca963x.o
obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
obj-$(CONFIG_LEDS_POWERNV)		+= leds-powernv.o
obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
obj-$(CONFIG_LEDS_SGM3140)		+= leds-sgm3140.o
obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
obj-$(CONFIG_LEDS_SYSCON)		+= leds-syscon.o
obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
obj-$(CONFIG_LEDS_TI_LMU_COMMON)	+= leds-ti-lmu-common.o
obj-$(CONFIG_LEDS_TLC591XX)		+= leds-tlc591xx.o
obj-$(CONFIG_LEDS_TPS6105X)		+= leds-tps6105x.o
obj-$(CONFIG_LEDS_TURRIS_OMNIA)		+= leds-turris-omnia.o
obj-$(CONFIG_LEDS_WM831X_STATUS)	+= leds-wm831x-status.o
obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o# LED SPI Drivers
obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o
obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
obj-$(CONFIG_LEDS_EL15203000)		+= leds-el15203000.o
obj-$(CONFIG_LEDS_SPI_BYTE)		+= leds-spi-byte.o# LED Userspace Drivers
obj-$(CONFIG_LEDS_USER)			+= uleds.o# LED Triggers
obj-$(CONFIG_LEDS_TRIGGERS)		+= trigger/

这个文件很长,不过不必担心,有用的就前面几行,也就是 LED Core 部分。

  • led-core.c 是整个 led 子系统的核心,我们需要使用该子系统,定要使能 NEW_LEDS 选项
  • led-class.c 是创建 /sys/class/led/ 目录相关信息
  • led-triggers 就是我们想要研究的 led trigger 功能

其余的选项,我们都可以不关心。不过,如果你不放心的话,可以去查看每一项的解释。去哪去看每一项的解释呢?那就是到 Kconfig

Kconfig

# SPDX-License-Identifier: GPL-2.0-only
config LEDS_GPIO_REGISTERboolhelpThis option provides the function gpio_led_register_device.As this function is used by arch code it must not be compiled as amodule.menuconfig NEW_LEDSbool "LED Support"helpSay Y to enable Linux LED support.  This allows control of supportedLEDs from both userspace and optionally, by kernel events (triggers).if NEW_LEDSconfig LEDS_CLASStristate "LED Class Support"helpThis option enables the LED sysfs class in /sys/class/leds.  You'llneed this to do anything useful with LEDs.  If unsure, say N.
。。。

内容太长了,我们只贴开头一段,找两项来看下

  • NEW_LEDS:Say Y to enable Linux LED support.
  • LEDS_CLASS:This option enables the LED sysfs class in /sys/class/leds.

解释地清晰明了,任你选择是否开启该功能。
如果你想知道当前系统开了哪些选项,除了查看内核顶层目录的 .config 文件外,还有一个更直观的办法,那就是 make menuconfig
在这里插入图片描述
打 “*” 或 “M” 的选项表示启用了该功能,空格表示未启用该功能。
这样,我们在了解一个子系统的功能实现时,只需阅读开启的代码就可以了,通常一个开启的选项对应一个 .c 文件。
PS:当然你也可以根据编译后是否生成对应的 .o 文件来判断某个 .c 文件是否被编译到了。但是根据 Makefile 和 Kconfig,我们不仅可以知道哪些文件被编译到了,还可以知道它们的包含关系、依赖关系、简要描述等。这将有利于帮助我们在大脑中构建一个子系统的结构关系图。

Help 选项可以查看当前选项的详细含义
在这里插入图片描述
可以看到,其描述内容和我们在 Kconfig 文件中看到的一致。
除此之外,还可以直观地看出其所依赖的选项,以及它被依赖的选项。这些信息在 Kconfig 中是以文本的形式出现的。比如

if NEW_LEDSconfig LEDS_CLASStristate "LED Class Support"helpThis option enables the LED sysfs class in /sys/class/leds.  You'llneed this to do anything useful with LEDs.  If unsure, say N.endif # NEW_LEDS

LEDS_CLASS 是被 if NEW_LEDS ... endif 限定的,说明 LEDS_CLASS 依赖 NEW_LEDS;

config LEDS_CLASS_FLASHtristate "LED Flash Class Support"depends on LEDS_CLASShelpThis option enables the flash LED sysfs class in /sys/class/leds.It wraps LED Class and adds flash LEDs specific sysfs attributesand kernel internal API to it. You'll need this to provide supportfor the flash related features of a LED device. It can be builtas a module.

LEDS_CLASS_FLASH 有 depends on LEDS_CLASS,说明 LEDS_CLASS 被该功能所依赖。

根据这份地图,我们很快能够明晰哪些文件需要我们关心,哪些可以无视它。很显然,我们需要关心 trigger 这个选项。
发现这个选项对应一个目录,那就继续进入该目录,看该目录下的地图。如同下了高速,开启城市导航。

trigger

根据地图,我们很容易明白,trigger 目录下存放的是各种类型的 trigger 方式,有 heartbeat(心跳),有 mtd(NOR/NAND Flash),
以 mtd 举例,使能 TRIGGER_MTD 选项后,Kernel 启动过程中,就会安装该模块,导出其 activity() 函数,在需要闪烁 mtd 灯的内核代码或驱动模块中,只要调用该 activity() 函数就行了,
在这里插入图片描述
上面这处就是每当从 Flash 读取数据时,led 闪烁一下。

具体想让哪个灯作为 mtd 灯呢?只要在 /sys/class/led/ 对应灯的目录中绑定一下即可,如

# cd /sys/class/leds/orangepi:
orangepi:green:pwr/   orangepi:red:status/
# cd /sys/class/leds/orangepi:red:status/
# ls
brightness      max_brightness  subsystem       uevent
device          power           trigger
# cat trigger 
[none] rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock mtd nand-disk heartbeat default-on mmc0
# echo mtd > trigger
# cat trigger 
none rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock [mtd] nand-disk heartbeat default-on mmc0

这样,每当有读写 Flash 的操作,OrangePi PC 上面的这颗 red 灯就会闪烁。
这里用到的 /sys/class/led/ 目录就是我们开始时介绍的 LEDS_CLASS 选项。

总结

看内核代码,先看 Makefile 和 Kconfig。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/690275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day11-Linux系统iNode及链接知识及企业按哪里精讲

Day11-Linux系统iNode及链接知识及企业按哪里精讲 1. 文件核心 属性知识1.1 什么是索引节点(inode)。1.2 索引节点作用1.3 inode是怎么产生的?1.4 inode的特点?1.5 Linux系统读取文件的原理1.6 企业生产案例:No space …

行人重识别综述

Deep Learning for Person Re-identification: A Survey and Outlook 论文地址https://arxiv.org/pdf/2001.04193 1. 摘要 we categorize it into the closed-world and open-world settings. closed-world:学术环境下 open-world :实际应用场景下 2…

儿时游戏“红色警戒”之“AI警戒”

一、红色警戒里“警戒”命令背后的算法原理是什么 在《红色警戒》系列即时战略游戏中,“警戒”命令背后的算法原理相对简单但又实用,其核心目标是让单位能够自动检测并反击一定范围内的敌方单位。虽然具体的实现细节未公开,但可以推测其基本…

Slack 给平台加入了 AI 驱动的搜索和总结功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

有什么办法解决SQL注入问题

随着互联网的普及和数字化进程的加速,Web攻击已经成为网络安全领域的一大威胁。Web攻击不仅可能导致个人隐私泄露、财产损失,还可能对企业和国家的安全造成严重影响。下面德迅云安全就分享一种常见的web攻击方式-SQL注入,了解下什么是SQL注入…

123.买卖股票的最佳时机II

123.买卖股票的最佳时机II 原题链接:完成情况:参考代码:_122买卖股票的最佳时机II_可以多次买入卖出01_122买卖股票的最佳时机II_可以多次买入卖出02_122买卖股票的最佳时机II_常规dp_122买卖股票的最佳时机II_一维dp_122买卖股票的最佳时机…

leetcode(动态规划)53.最大子数组和(C++详细解释)DAY12

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 提示 2.解答思…

【阅读笔记】红外探测器盲元国标标准及盲元识别

1、盲元定义 盲元的定义:盲元是红外焦平面探测器中响应过高或过低的探测单元,即无法准确成像的像元。盲元主要分为噪声盲元和响应率差异盲元两大类。 线阵红外探测器应用中,经常存在相邻的像元之间响应率有明显差异,其灰度响应输…

Allegro172版本如何用自带功能改变过孔网络属性操作指导

Allegro172版本如何用自带功能改变过孔网络属性操作指导 在用Allegro做PCB设计的时候,时常会需要将过孔的网络进行变更,可以将原来的过孔删除,再重新打一个,这种方法难免会繁琐一些。 当然我们可以借助skill工具来完成更换过孔网络的更改,除此之外,Allegro自带的功能完成…

[计算机网络]---Https协议

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、https协…

消息中间件之RocketMQ源码分析(十)

Namesrv启动流程 第一步:脚本和启动参数配置。 启动命令 nohup ./bin/mqnamesrv -c ./conf/namesrv.conf > dev/null 2>&1 & 通过脚本配置启动基本参数,比如配置文件路径、JVM参数,调用NamesrvStartup.main()方法,解析命令行的…

【PyQt6] 框选截图功能

1 简介 书接上回, 全屏截图实现起来很简单, 来点稍微复杂点的, 框选截图 原理很简单, 弄个控件实现全屏半透视, 在全屏控件上画一个选框或者再弄一个几乎全透的子控件,实现鼠标拖动,缩放,移动, 键盘wasd 微调 用一个控件实现起来会很完美, 但是逻辑全部堆砌在一起,看代码会很…

Mac电脑玩《幻兽帕鲁》卡怎么办?2024年最新解决方法

幻兽帕鲁目前已经在steam卖出了100多万份数,可谓是爆火现象级的游戏。如今在游戏中,我们可以实现工农业自动化,为了实现自动化,将手工作业交给帕鲁就尤为重要。建造工厂,并安排帕鲁在其中工作吧。只要有足够的食物&…

K8s服务发现组件之CoreDNS/NodeLocalDNS /kubeDNS

1 coredns 1.1 概述 1.1.1 什么是CoreDNS CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS,在Kubernetes1.12版本之后成为了默认的DNS服务。 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。 coredns在K8S中的用途,…

spring aop @annotation的用法

直接看原文: spring aop annotation的用法-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- annotation用在定义连接点时,对连接点进行限制。比如我们想对标注了…

prometheus+mysql_exporter监控mysql

prometheus+mysql_exporter监控mysql 一.安装mysql 1.下载:wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 2.安装客户端:yum -y install mysql57-community-release-el7-10.noarch.rpm 3.安装服务端:yum -y install mysql-community-se…

day10:分割链表

问题描述: 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1: 输入:head [1,4…

【HTML】SVG实现炫酷的描边动画

前沿 今天闲来无事,看到Antfu大佬的个性签名,觉得还是非常炫酷的,于是也想要搞一个自己的个性签名用来装饰自己的门面,不过由于手写的签名太丑了,遂放弃。于是尝试理解原理,深入研究此等密法,终…

VLM多模态图像识别小模型UForm

参考:https://github.com/unum-cloud/uform https://huggingface.co/unum-cloud/uform-gen2-qwen-500m https://baijiahao.baidu.com/s?id=1787054120353641459&wfr=spider&for=pc demo:https://huggingface.co/spaces/unum-cloud/uform-gen2-qwen-500m-demo UF…

市场复盘总结 20240219

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整,采用龙空龙模式 一支股票 10%的时候可以操作, 90%的时间适合空仓等待 二进三: 进级率中 22% 最常用的…