今天我们来讲解一下 ios 内核,相信各位对它都不陌生,哪怕是没开过的小白都知道内核非常稳定,那么我就来跟大家讲一下内核为什么会这么稳定。 ios 巨魔和多巴胺有两个空间,分为用户空间和内核空间,内核空间可以读取用户空间的数据,可做到只读取不修改, 内核的权限高于游戏应用,所以游戏检测不到内核的存在,但是游戏可以通过行为检测判断你是否作弊,这就是为什么有些人容易高风险的原因。总之,内核就是普通人能接触到的最稳项目了,还是别把号浪费在职装上。目前和平这个游戏内核市面上鱼龙混杂, 如何选择一款稳定可靠的内核即为重要。主播目前在用的 jk 纯巨模内核耳机非常之稳定,小白号也能直接干到金星段位。给主播点赞加关注,下期带你揭秘内核如何演戏!
粉丝1977获赞1.6万

hi, 大家好呀,欢迎收看本期严厉解析,我是你们的 linux 向导,今天怎么样?一起硬核拆解一个超级好玩儿也超级实用的技术, linux fuse。 说真的,无论你是高摸到底层开发门道的萌新,还是想继续点亮技能数的老手,今天的内容绝对会让你觉得,哇,原来还能这么玩儿!准备好跟我一起黑进科脑的世界了吗?我们直接开始吧! 咱们先从这句大名鼎鼎的 unix 哲学说起。万物皆文件熟悉 linux 的 小伙伴对这句话肯定不陌生,对吧?这绝对不是一句空话哦!在 unix 的 世界里,从普通的文本数据到复杂的格式转换,甚至连操作系统底层的内部数据结构全都被极其优雅地抽象成了文件。 但是你有没有想过一个问题,当这套标准的文件规则撞上咱们开发者天马行空的想象力时,要是咱们想亲自动手定制一个完完全全属于自己的文件系统,会发生什么呢? 这就是咱们今天要解答的终极问题了。快速过一下今天的路线图,首先聊聊万物皆文件,接着看看什么是 fuse, 然后拆解 fuse 的 运行机制,再盘点一下那些强大的应用场景,最后教你怎么写出你的第一个 fuse。 ok, 那 我们马上进入第一部分。第一部分,万物皆文件 既然说到这儿了,咱们就先来看看历史上各位开发者大佬们在面对文件这玩意时,到底踩过什么坑。 你看啊,传统意义上像 open read 还有 write 这些常规的文件操作,平时大家基本就是用来处理处理普通数据的对吧?但 unix 哲学可比这激进多了,它硬是把这些操作直接套用到了系统复杂的内部结构上。 这也就意味着,理论上讲,只要你能把跟某个底层对象的交互脑补成目录结构和文件操作,你就能直接给他写个文件系统出来。听起来是不是超级酷? 但是呢,现实往往很骨感,这里有一道巨大的传统壁垒。在以前,如果你想新建一个文件系统,你必须得去动操作系统的核心内核。各位改内核啊,这可是特权级超高风险的危险动作, 你想想,稍微手抖一下,出个小 bug, 整个系统直接就给你当场崩溃荡机,对咱们日常写代码的开发者来说,简直就是一道跨不过去的红沟嘛! 这就来到了我们的第二部分,什么是 fuse? 就 在大家对着那一堆内核代码瑟瑟发抖望而却步的时候,一位救世主闪亮登场了,隆重介绍今天的主角, fuse, 也就是用户空间文件系统。 这到底是个什么神仙技术呢?简单来说啊,它就像是一座神奇的桥梁,或者说是一个特别贴心的翻译官。它给 linux 系统提供了一个绝佳的软件接口,让咱们这些没有任何特权的用户,完完全全不需要去碰那些危险的核心代码,就能舒舒服服、安全安全地在用户空间里搞出自己的文件系统。 咱们来直观对比一下新旧两种方式,一边是以前那种老旧的核心空间特权级高风险,稍微改改都让人心惊肉跳。而另一边呢,就是咱们超级友好的 fuse, 用户空间不需要特权及其安全,最爽的是你可以直接调用标准的 c 源库,比如 lip fuse。 顺带一提, fuse 在 linux 内核二点六点一四版本的时候,已经正式合并进主线了,从那以后,它绝对是 linux 生态里一件不可获取的强大武器。 第三部分, fuse 的 运行机制。刚才咱们把它夸上天了,那它到底是怎么在底层发力的呢?别怕,咱们现在就用最通俗的方式把它的技术机制拆解一下, 想弄个新的文件系统,核心引擎就在于 fuse, 你 其实只需要写一个连接到 leap fuse 库的处理程序就可以了。 这个程序的工作极其简单明确,就是去定义你的文件系统该怎么响应各种请求,比如读个数据啊,写个数据啊,查个状态等等。一旦你的文件系统被挂载上去了,这个处理程序就会自动注册到内核里,直接化身为你文件系统的逻辑大脑。 咱们把整个处理过程想象成一场接力赛就好理解了。第一步,用户敲一个 l s 烂的命令,去查 fuse 目录。第二步,核心的虚拟文件系统,也就是 v f s, 接到请求后,特别聪明地把它重定向给了 fuse 模块。第三步,重点来了, fuse 会立马唤醒你在用户空间写好的那个处理程序来执行逻辑。 最后第四步,你的程序把结果扔给 fuse, fuse 再转交给用户,一个完美的闭环就这么形成了。你看,作为开发者,咱们其实只要盯紧第三步怎么写代码就行了,是不是很轻松? 所以这里面最最关键的一点就是 f u s e, 它是虚拟的,不是物理的。和那种需要吭哧吭哧读写硬盘扇区的传统文件系统完全不一样, f u s e 本身压根就不存数据, 它们更像是一个试图或者一层翻译原文的。上说,只要你的 f u s c 程序能摸得到的任何资源,通通都可以被包装导出成一个文件系统。接着进入第四部分强大的应用场景。既然说什么资源都能变成文件系统,那这座神奇的桥梁到底能玩出多少花样呢?这就到了咱们今天最激动的展示环节了, 你看看这些让人兴奋的分类。首先是词盘端,比如有个特别极客的项目叫 richofuse, 它居然能让现代的操作系统去挂在贝尔实验室第五版那种古董级 unix 的 文件系统,简直就是活生生的代码考古神器。然后是分层处理,像 ncfs 就 能透明地帮你在底层把文件全加密了。 接着是归党备份,你能直接把一个巨大的压缩包当成文件夹挂在上去浏览。当然了, fus 真正杀手级的应用还得是远程和分布式课后端 来瞅瞅这组神仙软件的列表, s s h f s 允许你直接通过 s s h 把远程服务挂载成本地的文件夹。 google drive ocamo views 更是能让你在 linux 上原生挂载谷歌云盘。不过说实话,最让我觉得惊艳甚至有点不可思议的其实是最后一个, wikipedia f s 等等,把维基百科变成你电脑硬盘里的一个文件夹。没错,你绝对没听错,维基 pdffs 真的 做到了这一点,它能让你就像用本地的文本编辑器改一个普通的 txt 记事本儿文件一样去直接查看和编辑维基百科的条目。 在你按下快捷键保存文件的那一瞬间,它就在后台默默通过网络把维基百科给更新了。这简直绝妙地印证了万物皆文件的了。 听到这里,我相信屏幕前的你,作为一名硬核开发者, dna 绝对已经动了吧。那么问题来了,到底怎么才能自己动手写一个 feels 呢?会不会特别难呢?第五部分,你的第一个 f u s e 放宽心,接下来的这点时间,我会给你指一条特别清晰的明路,带你零门槛开启你的 f u s e 下盟之旅。 在咱们今天的参考资料里啊,介绍了一位叫约瑟福普菲菲教授写的教程,他专门设计了一个叫 b b f s 的 项目,全称是老大哥文件系统。如果你是第一次想学着写 fuse 信我,这绝对是最完美的 hello world 敲门砖。 为什么起名叫老大哥文件系统呢?因为它会把你所有的文件操作都完完全全透明地传给底层的真实目录。但重点来了,它在暗地里会偷偷把你做的每一个操作都记录进日记里。没错,老大哥正在看着你哦! 这种日记机制不仅听起来有点黑色幽默,更是一个极其聪明的学习方法。因为通过它,你能清清楚楚的看到你在终端敲下的每一个系统命令,到底是怎么一步步精准触发你写的 c 代码的。 想构建一个像 b b f s 这样的私同,其实特别平易近人,你压根就不需要去啃什么深奥的核心访问编程,只要你稍微懂一点点基础的 c 源,照着 leapfuse 提供的原型写几个咱们平时再熟悉不过的函数,比如 open 函数、 read 函数,还有 write 函数,就完全搞定了。 而且所有东西都在安全的用户空间里跑,就算你代码写崩了,大不了也就是个普通程序闪退而已,重新跑下就行,核心根本毫发无伤。 咱们今天一路看下来,其实 fuse 就 像是一座早就搭好的极其坚固的桥梁,它现在正静静地等在那儿,等着充满创意的架构师去大展身手。 你可以把网盘变成硬盘,把数据库映射成文件夹,甚至把整个网络上的某种资源直接挂载到你的目录树下面。那么聊到这里,我想把最后这个问题留给 你,就在今天,你想在你的系统里构建出一个什么样神奇的文件系统呢?别犹豫了,快去动手巧妙行代码试试吧!我们下期原理解析,再见!

内核稳定你一定看过,但看完又无法真正的做到,这是因为你没有完全的理解内核两个字的含义。今天一分钟带你拆解什么是内核,建议码数收藏,反复观看,就能实现真正的内核稳定。 你有没有认真看过内核这两个字?我以前觉得内核稳定就是内心强大嘛,直到和伙伴讨论后才发现,百分之九十的人都没有正确理解内核这两个字。先看内 内是什么?是人生的承重墙,是一个人在相对围住的空间内,不允许别人随便进入的那个空间。有门禁的才叫内,而没有门禁的那叫广场内。在墙的人是把自己和外界的底层秩序守护的很好,即使有一个口面向广阔天地, 但依然有着三面墙围住自己的内心。在那看河,河是什么呢?是能量密度最大的那个东西。水果的河是它最坚硬的部分,保护里面的种子,也就是它的生命。果肉也许会腐烂,但果核不会。 就像人无论被生活如何的锤打,不会碎掉的那部分就是我们的核,并且核往往蕴藏着巨大的能量。我们常提到的核弹、核能、核反应堆,都是发生在原子核的最内部,而不是普通的化学反应能达到的能量爆发。那么人的核就是一个人最底层的运行系统。 核强的人知道自己的能量在哪,不会天天爆发,但是有我可以不爆发的勇气。在社会各种烦扰的声音中,在无数的选择中,我们不断经历,逐步形成自己的核。 果肉烂了,明年还能再长,而种子烂了,就什么都没了。希望大家越来越兼顾自己的内核,迭代自己的底层系统,运行出丝滑流畅的高能量人生。我是图图,我们下期再见。





root 是 什么?获取 root 后需要注意什么?一个视频带你了解 root 以及 root 后需要注意什么。一般手机出厂时默认吧,用户限定在普通使用权限内,目的是防止用户误修改系统文件以及维护系统稳定等。而 root 就是 获取安卓系统和 linux 系统的最高管理员权限, 也叫做超级用户,相当于电脑 windows 的 administrator。 获取 root 后,用户可以解锁系统分区,读写到原本隐藏的系统,并且能卸载手机预装流氓软件,使用冰箱等框架,同时还可以从底层修改游戏数据,安装 xbox 的 等框架或刷入第三方内核。 而获取 root 后,大部分人都会选择安装各种模块与检测软件,但是模块并不是越多越好,相反,如果不了解模块的作用, 同时安装好几个相同效果的模块,可能会冲突造成环境损坏或者成砖。而咱们拥有了 root 后,肯定需要一个好的内核,给兄弟们推荐我一直在用的一个叫 x 的 内核,并且这个 x 内核还是真正的硬件断点追踪与内核及陀螺一子喵同时无视任何加密文件, 因为它拥有不动内存的独家算法解密与坐标解密。如果你玩大号或者想和我一样长期稳定,不妨大胆尝试一下我说的这个 x 内核,相信它一定不会让你失望。

hello, 大家好,这是一期视频,来教大家如何编辑一个支持桌面的 space 的 内核,并且教大家解决安装桌面的 space 虚拟机并部署图形化界面之后黑屏的问题。 很多朋友自己定义了支持桌面的 space 的 内核,刷入手机后,我安装虚拟机部署图形化界面, 一打开直接黑屏,只剩鼠标公屏可以移动,找遍教程也找不到问题个月。今天这个视频就把这个问题给大家解决了。出现这种现象大的利是内核没有开启拥引力的空间,导致容器内的用户运输失败,图形化服务就无法支撑启动。 我们先来看到这台机器,连接后,我们使用这条命令检查是否开启这个选项,发现是 not set 的 状态,也就是说没有开启这个配置。现在就让大家从零开始变异一个自己的 alien control 三来开启选项,并且支持桌面的 space。 我们来看到这个项目,这个项目是专门用来给欧嘉诚手机变异艾尼克隆三的 action 项目,我们首先需要给它 get 下来。 get 之前我们需要安装依赖,输入这条命令进行安装依赖, 安装依赖完成后,我们需要克隆仓库,使用这条命令进行克隆,所有命令我都放在了视频简介供大家复制。 克隆完成后,我们进入该文件夹,进入 local 文件夹, 这底下有非常多的编辑脚本,我们要选择对应自己手机内核的脚本才可以编辑成功并开机。由于我的手机是为了有点巴结,我就先删除其他不必要脚本, 现在只剩下这一个脚本了, 我们首先需要改两点,对于这个脚本,第一个就是内核制作者,第二个就是开启用户命名空间选项,我们使用 vm 编辑器对齐继续编辑。我们首先使用 vm 编辑器打开, 我们来到这个界面,首先需要更改内核制作者的名称, 往下翻,找到拉取 k s u, 并且设置版本号这一栏,将这一行的 at 后面改为你自己想要的东西。比如说我这里为视例,按下 i 键,进入编辑模式进行修改, 修改完成后,因为我们还要在后面更改内容。为了防止误操作,我们首先要按下 esc, 现在去修改桌面的 space 内核配置项。 我们来到这一栏,奇用 joy 的 spaces 容器支持。我们在开启虚拟 hci 设备之时,这里添加一个新的配置项,按下 i 键,进入编辑模式,换行添加新的,我们在这里添加一行代码, 设置用户命名空间等于 y, 然后按下 esc, 打一个冒号 wq 保存并退出。然后为了防止我们更改错误,我们需要先验证脚本更改是否正确,输入以下命令, 首先检查用户命名空间, 发现是没有问题的,我们再来检查我们自定义的名称是不是正确的, 好了,更改也是正确的。在编辑之前,我们首先需要给脚本赋予执行权限,输入以下命令来给脚本赋予执行权限,然后用管理员启动脚本 自已内核后缀,我这里就用默认输入回车 是否启动 s u s f s 这里简单说明一下。 s u s f s 是 一个内核级隐藏模块,开启后可以隐藏 bot loader 解锁状态,还有更强的 root 隐藏能力,能绕过大部分环境检测,大家根据自己的需求选择,我这里就演示开启保持默认 是否起用 k p m k p m 我是 不建议开启的,因为开启有可能影响系统稳定性。如果你是实在有使用 k p m 模块里的需求,你可以选择 y, 我 这里为了测试选择默认,也就是不开气。 奔驰版本任意选都可以。呃,需要根据你的面具版本去选择 ksu 奔驰版本,我这里就选择默认是否应用 lv 四补丁,这个补丁是让你的 swap 支持 lv 四格式,我是建议开启的,选择默认 这个也是跟上面一样,让你的 swipe 支持 x s k d 这样一个格式。如果你开启了上面那个补丁,那么下面这个就可以不用开启了。因为我开了上面这个补丁,所以说我就不开下面这个了,这个是可以起用的。 这个 bbr 优化算法我是不建议开启的,因为在国内网络环境下有可能是会复优化的。 是否添加容息支持,我们要选择 e 按下回车,这个 adios 调度器是用来优化 i o 性能的,不建议开启就选择 y, 这个是不建议开启的。 这个 bbg 既带保护可以开启,在一定程度上保护你的设备不受恶意。脚本写入你的关键分区,我们就保持默认。现在就开始构建依赖了, 变异时间根据电脑性能不等,一般十几分钟到半个小时,大家耐心等待即可。 我们可以看到内核已经翻译好了文件所在目录,在这里,我们直接打开文件去找到那个目录,我们找到 a k 三存在的位置, 我们还需要修改一下这个压缩包里面的 s h 小 本,因为在刷入的时候也会显示作者名称,这个作者名称是和内核里的名称是完全分开的,我们只修改了内核里的名称,还没有修改刷入时 s h 小 本的名称。我们用耶压缩软件打开这个文, 我们找到这个 s h 文件,打开 找到这里。首先第一个我们需要改名称,这里都可以的,随便你怎么改,下面还有一个名称,内核构建者, 我这也就同上更改了,这个是在刷入时会显示,呃,制作者好了,保存利用到压缩包, 然后去传到设备上刷入就好。这里需要准备一个软件,是我经过 kernel flash 修改了一个软件,优化了一些功能,立即为方简介了,可以自己去下载。我们需要把这个传到手机, 并且打开这个软件。我们来到手机端,打开这个软件, 找到刷写区域,选择活跃的槽位,我们这里是 a 槽,点击刷入,点击刷入 a k 三压缩包,找到我们 a k 三压缩包的位置, 选择确认刷入。我们这里看到了已经确实改为了我们记的名字,点击刷写, 然后重启。 重启之后我们打开我们的面具,发现已经是工作中了,名称也是改为为正确的了。 然后我们开始检查用户命名空间是否打开,我们还是一样打开终端,输入之前的命令,检查,发现已经设为开启了。接着我们也可以到手手机端桌面的 space 软件,经检查 我们回到手机,检查要求是全部通过的,这个警告是因为我们开启了用户文明空间的支持。 好的,这期视频就到了这里,希望这期视频对你帮助,再见。


欢迎大家来到本期技术讲解,今天我们要来一场极其硬核但也绝对让人大呼过瘾的探险。咱们要直接潜入计算机系统的最深处,用 linux 六点一八内核当我们的向导,去扒一扒支撑现代计算机结构的那些精密基石。 如果你平时总对代码在底层到底是怎么跑的充满好奇,那我敢说,这次直击魔气灵魂的旅程你绝对不想错过! 好了,废话不多说,咱们直接看今天的路线图,一共分五步,首先是大家最熟悉的互空间内存请求,然后下探到虚拟内存管理器,接着进入核心内存分配期, 再聊聊系统后台的回收交换与安全。最后直击最底层的物理内存架构,这就是咱们今天从上到下的完整路径 哇!来看这张 linux 六点一八内存管理架构的全景蓝图。说实话,乍一看这密密麻麻的网状结构确实有点让人头皮发麻,对吧?它完美展示了现在操作系统的庞大规模, 不过别担心,它就像一个巨大的拼图,咱们接下来就一层一层的把这些模块拆解开,把里面的门道看的清清楚楚。 第一部分也是咱们旅程的起点,用户空间内存请求。这里就是咱们写的应用程序每天真正生存呼吸并且向系统粘口要资源的地方。 咱们平时写代码,你是怎么跟操作系统要内存的?绝对绕不开这里列出的这些家伙,不管是用的最狠的 mmap, 又或者是调整权限的 mprotect, 但有一点非常关键,你的应用在用户空间喊破喉咙也没用,所有这些请求都必须纵身一跃,穿过这道至关重要的边界,也就是系统调用。 cisco 只有敲开了这扇大门,你的请求才算真正闯进了内核的领地。 穿过细虫调用,咱们就来到了第二部分,虚拟内存管理器,也就是 vmm。 它就像一位极其高明的制图大师,为所有的应用程序变了个魔术,让每个程序都以为自己拥有无限大并且完全连续的内存。 那么这个魔术是怎么变的呢?你看, vmm 搞了一个极其复杂的五级叶表结构, 就像一个超级漏斗一样,从最顶层的局目录 p g d, 一 层一层向下集,连 p four d, p u d, p m d, 最后一直精准落到具体的页表象 p t e 上, 配合着硬件儿的 m m u 和 t l b, 它就在一眨眼的功夫,把咱们程序里的虚拟地址严丝合缝地翻译成了物理机器上的真实地址。这套动态过滤机制真的是极其精妙。 在这个翻译过程中啊,你肯定经常听到缺页异常这个词儿,很多人一听异常,心里一紧呢,以为是程序出 bug 了。其实根本不是。 对 vmm 来说,缺页异常不仅不是错误,反而是它最厉害的资源管理策略。比如写实复制,也就是平时说的 c o w, 你 只要不修改,大家就共享同一块内存, 或者到了真正需要读写的那一刻,才去给你分配匿名内存,甚至是去感知 nama 节点做就近分配,这其实是内核在极其聪明的按需分配资源。当然了,在这一层架构里,咱们不能忘了夜缓存陪开始, 为了让文件读写操作飞起来,核心在这里用上了叉 j 触觉结构和超浅的预读机制。 不仅如此,通过 mmu notify 这套虚拟内存系统,还能直接跟 kvm、 淤泥稀 r、 dma 网卡甚至咱们的 gpu 同步状态,保证那些失效的内存范围在所有些处理器那里都能瞬间同步。 虚拟地址的事理顺了,咱们继续往下走,进入第三部分,核心内存分配器。欢迎来到柯南的超级大仓库,物理内存就是在这里被打包,然后火速发往系统各个角落的。 你看内核,这个大仓库里有两位配合极其默契的搭档,底层的伙伴系统,也就是 body system, 它就像个批发商,专做大宗交易,按完整的页面把内存一大块一大块的批出去。 而它旁边儿的 slab 分 配器是个极其精细的零售商, slab 从伙伴系统那里进货,拿到准业内存后,就像切蛋糕一样,把它切成极其小巧的数据结构对象。咱们平时用的 capolok 就是 在找这位零售商拿货,批发加零售天衣无缝。 除了批发和零售,仓库里还藏着几支特种部队,比如 v malik, 专门负责把那些物理上东拼西凑的碎块儿,在虚拟地址上给你缝合成连续的 percpu 分 配器。 这是为了多核 cpu 极限性能量身定制的处理超大内存块儿的 huge t l b 和透明巨液机制。还有那个专门给挑剔的设备驱动,强行预留大块儿物理连续念存的 cma, 它们各自把守着系统最刁钻的需求。 不过话要说回来,永借有还再借不难对吧?系统不能光顾着发内存不收内存。 所以,第四部分咱们来看一看系统后台默默付出的清洁工和保镖们。内存的回收、交换与安全, 这里必须得敲黑板了。我们要说的是 linux 六点一八里绝对的明星特性, mgru 多代 lru, 以前老旧的回收算法,在今天这种动辄几百 g 内存的服务器上早就跑得气喘吁吁了。而 mgru 引入了一种非常聪明的待机老化机制,它能极度精准地判断出哪些页面是真正处于落灰状态的闲置页面。 这极大地提升了内核在后台回收和换出内存时的决策效率,是现代核心性能的一次巨大飞跃。可是,如果清洁工拼了老命回收,内存,还是彻底被榨干了怎么办? 这时候,潜伏在 c group 里的终极保镖 o m killer 就 该拔枪了, 他平时一声不吭,一旦内存危在旦夕,他就会根据一套非常冷酷的公式,计算出每个进程的恶劣度, 谁占的最多,谁最不像话,直接一枪爆头,毫不留情的终止进程。听起来有点残忍,但这却是保护整个系统不至于彻底崩盘的最后防线。 除了防崩沛,还得防黑客。除了姐妹提过的 m log 和 mcl 这种页面锁定机制,盒类里还内置了 kasan 和 kfenc 这样的内存清理工具, 它们就像全天后开启的探照灯,一刻不停地扫描、越界访问。呐,释放后重用啊!这些致命的内存漏洞,在这个危机四伏的环境里,它们是保障每一笔内存交易安全的定海神针。 好了,拨开重出迷雾,咱们一路向下,终于要接触到硬件的钢铁之躯了。第五部分,物理内存架构真正的基实 在这最底层啊!你得知道,现代服务器的物理内存早就不是一块单片的大铁板了,它是被分割成多个 numa 节点的。你看,每个节点不仅有自己的地盘,里面的内存还被切分成了不同功能的区域或 zones, 比如专门给老设备做直接内存访问的 dma 区、普通的 normal 区,还有为了支持内存条热插拔搞出来的 move 补区。 内核在这里必须精打细算,疯狂调度,确保你的 cpo 能够尽可能多地去访问离他自己最近的那个本地内存,只有这样,性能才能真的拉满。 而在这个最基础的层面上, linux 六点一八交出了一份非常有意思的答卷,那就是从传统的 struct page 开始,向现代的 struct folio 全面引进。 过去十几年,咱们都是用一个极其紧凑的六十四字节 struct page 来死死盯住每一个四 kb 的 基础物理页。但时代变了,现在动辄就是几兆甚至更大的巨页,用老方法去管那些连续的大内存块越来越吃力。 于是,内核引入了 struct folio 这个新物种,它天生就是为了跟踪和管理跨越多页的实体而存在的,这不仅减少了代码里的歧义,更是把多页内存管理的效率提升到了一个新的高度。现在啊,咱们回过头来想一想, 当你只是在键盘上敲下一个极其普通的 my look 或者鼠标轻轻点开一个应用的时候,在区区几个毫秒的时间里,你的请求穿过了系统调用的大门, 在多级页表里完成了虚拟映射,触发了缺页异常,唤醒了底层的伙伴系统和撕拉布根背气,甚至可能还惊动了后台的 mglr 去远端的努末节点上回收页面,这是一场多么波澜壮阔又极度精密的机械芭蕾啊! 所以当你下次再写代码或者部署软件的时候,不妨问问自己,我真的最大限度地利用好这个庞大的架构了吗?我的软件和它的交互达到完美了吗?希望今天的技术讲解能给你带来一些新的启发和思考,感谢大家的收看,咱们下期再见!

意式产品的核心,其实它的内核非常简单,就是空间的秩序感以及中性的配色,用材质和一些颜色来呈现它相应的高级感。那你像刚才说的几点秩序感的几何图形啊,这种钢琴键的墙板,那我们所说的形式就是功能,其实就很简单, 其实是一趟门,一个平开门可以进到我们的工位以及孩子的这个空间。那整面的柜体通过不同的配色,其实就表达了咱们浴室空间的这种感觉。那在这样一个客餐厅一体的这样一个功能区,我们也是先确定功能,再定义形式,像这样的一个 八十六公分长,两米左右的这样一个餐岛一体,当然这个只是我们作为早餐台,以及 像那边做完一些简餐的加工,应对像孩子上学早晨这样的一个场景,那我们也做了一个吧凳,然后下面也有一些相应的收纳区,包括背侧 同样也有收纳区。那像我后面呢,也是整组的餐边柜体啊,它的功能是形式多样的,我们也可以摆放一些你的碗碗碟碟能呈现展示出来的东西,然后我们正餐的使用就通过这样的一个原版餐桌就解决了。那我们的设计切入的重点在重点功能上,确实也会 在意这两个空间,但是其实还有很多的生活起居场景。那你像这两个空间在走廊的尽头是我们的主卧啊,两侧呢就是一个多功能的空间,像这一侧一个两联动的隔音性,利弊性非常好的这样的一个推拉门, 这是我们衣帽间的一个空间,它不光承载着衣物的收纳啊,包括我们所说的起居以及打理的一些日常。像我们这面柜体 就是一个大开合角度的这样的一个门板,然后我们有一个卫衣板,那像他旁边这样的一个次进一区,看面上会是一个斜切的一个状态,当然他也是 形式追随结构了,因为这一侧的墙体他是达不到相应的厚度的,所以做了一个斜切。那我们再过来同样有很多不同的功能定义,像这面是一个 案台,我们的女主人可以在这个空间化妆,甚至可以陪孩子进行学习啊,而且两不耽误,也不用非得摆个凳子看着孩子学习。然后整面这面的柜体就是我们的衣物收纳以及一个镭射镜啊,可以作为一个。 呃,穿衣镜的补充。整个空间的功能其实就已经非常完善了,那他对象也就是左手边的这个空间是一个多功能房,同时也作为一个客房, 他这样的一个重型的隔山移门,也辅助了整个这边的一个视觉效果,通过一个地台也强调了一个相对私人的一个领域。这个屋呢也同样有很多的功能,可以看到这就是一组折叠床,我们通过下拉, 其实他是有一个阻尼和缓冲的,然后托住他。哎呀,这个垫子很喜庆啊,当然作为一个防护啊,那我们还有一个地方 做了一个小汽车,我们可以在这里放一个小型的投影仪,这块的汽车的桌板呢,可以作为补充的一个床头柜体,放一些水啊,或者我们的手机充电器都可以在这实现。然后这边也是我们衣物收纳的一个地方, 像这种横向的,因为他的进深并没有满足我们常规衣柜的六十啊,所以做了一个这样横向的, ok, 我 们出来,那么主卧的空间呢?我就留到下一期有时间,然后再给大家分享。

大家好,我是老李,上节课聊了零拷贝,讲了数据在内核缓冲区和用户空间之间的搬运,那数据到底从哪来的? 今天聊 linux page cache 页缓存,它是操作系统读写硬盘的核心机制。应用程序想读文件,如果每次都直接访问词盘,速度非常慢,所以操作系统在内存和词盘之间加了一层 page cache, 把硬盘数据缓存到内存里,读的时候先看缓存,命中了就不用碰硬盘。 访问 page cache 有 三种方式, buffer io、 默认模式,数据经过内核缓冲区 map, 内存映设。上期零拷贝聊过, 用户空间直接映设内核缓冲区, direct i o 绕过 page cache, 用户空间直接和内存交互,数据库场景会用。读文件的时候,操作系统先检查 page cache, 如果数据在缓存里叫命中,直接从内存返回,速度极快。 如果数据不在缓存里叫未命中,就要从内存读取,再写入 page cache, 下次就能命中了。 这就是 page cache 的 核心逻辑,用内存换速度。具体来说,未命中的时候, page cache 里没有所需数据。操作系统发起词盘读,请求 dma 把数据从词盘搬到 page cache, 然后从内存返回给应用。 注意,读取是以页为单位的,通常是四 kb 或八 kb, 即使你只读几个字节,操作系统也会读完整的一页到缓存。 写文件的过程是先把数据写入 page cache, 不是 直接写词盘,被修改的页会被标记为脏页,也就是 dirty page, 表示这些数据需要写入词盘。 操作系统不会立刻写,而是等合适的时机批量刷盘,比如系统空闲时或者达到一定预值时, 这种方式减少了磁盘 i o 的 次数,提高整体性能。脏页什么时候会真正写入磁盘?三种情况,第一, page cache 大 小达到预值,操作系统触发写操作,把部分或全部脏页刷盘。第二,系统内存压力大,主动将脏页写入磁盘,释放内存空间。 第三,应用程序调用 f sync 或 sync 命令,强制将所有脏页写入磁盘,确保数据持久化。 page cache 的 优点很明显,第一,提高性能,按照页去读写磁盘,减少了对磁盘的频繁 i o 操作。 第二,减少磁盘损耗, i o 次数少了,还能延长磁盘使用寿命。 缺点也有两个,第一,缓存数据要占用内存资源,内存有限时可能影响其他应用。 第二,数据写入 page cache 后,如果系统崩溃,还没刷到硬盘的脏页会丢失,这就是数据丢失风险。 page cache 是 操作系统和硬盘之间的核心缓存层, 理解它才能真正理解文件 i o 的 性能瓶颈。关注老李,持续更新!

大家好,欢迎来到本期的深度解析,今天呢,咱们直接换个视角,戴上资深核心维护者的帽子,一起钻到 linux 六点一八的最底层,去拆解一下进程创建的那条极其精密的工厂流水线。 大家想想,一个进程到底是怎么在操作系统的核心深处孕育出来的?别眨眼,咱们直接硬核开局。 咱们今天的路线图非常清晰,其实一共就五步,首先过一遍系统调用和核心入口,然后对比一下大家都熟悉的 fork 和 fork, 接着深入 kernel clone 的 分配顺序,然后再死磕 copy process 的 核心策略。 最后肯定少不了咱们内河老兵最关注的出错清理和站回溯机制。说白了,咱们要把一层层的抽象外衣全扒掉,直击最核心的内存分配和错误处理 好,咱们立刻进入第一站,系统调用于核心入口。可以说,所有伟大建成的诞生,都是从敲开这扇大门开始的。 在用户太空间写代码的时候,大家手头的工具箱其实挺满的对吧?老牌的 fork 和 v fork, 能提供细力度控制的 clone, 还有支持结构体传餐的现代 api clone three。 哦对了,还有大家写多线题儿天天都会用到的 pthree de crate。 表面上看啊,这五个大佬长得完全不一样,脾气秉性似乎也各不相同。但是这里有个超级反转, 不管你在用户态用得多花哨,当这些请求穿过内核的多斯蒂夫瓦这一层转换之后,它们就像被倒进了一个大漏斗,最终竟然全都挤向了同一扇巨大的工厂大门,也就是 kernel clunk 函数。 说白了,咱们前面提的那些各色各样的系统调用,在内核看来,无非就是递给同一个车间主人的不同图纸而已。那既然图纸都送到了同一个车间,咱们就进入第二阶段,好好扒一扒这些图纸之间到底藏着什么核心差异。 拿大家最熟悉的两张老图纸来说, fork 和 v fork。 fork 走的是稳妥路线,它讲究的是完整复制,背后依靠的是咱们常说的写实复制,也就是著名的 c o w 技术, 同时还会用到 c i g h c l d 信号。而 v fork 呢?这就是个极度追逐效率的急性子。为了快,他干脆直接共享附近城的内存空间,并且非常霸道地把附近城给原地挂起,必须等紫禁城干完活才放行。 他这种特权完全就是靠内部敲枪组合了 cln o m v m 和 cln o v fork 这两个标志位来实现的。 这其实就暴露出了一个非常核心的核心逻辑,核心底层是极其纯粹的,他根本不在乎你管自己叫现成还是近成,他眼里只有这些 clone 标志位。 比如 clone vm 决定了要不要直接共享内存, clone files 决定了要不要共享文件描述浮表。这些 c 语言里的红定义,简直就像是一组组极其精密的旋钮,让咱们能对内核资源的共享进行微操。 搞清楚了图纸是怎么回事,咱们直接进入第三阶段,亲自踏上 colonel clone 这个核心流水线,看看组装一台新进程的先后顺序到底是怎样的。在这条流水线上, colonel clone 扮演的就是那个极其严谨的车间主任, 开工第一件事,他会先核对 r l i m t n p r o c, 算算当前用户的进程数有没有超标,毕竟不能随便爆产能嘛。 产验无误后,他转手就把真正搬砖的重活外包给了流水线上的幕后大佬 copy process。 另外,要是他瞄到图纸上带有咱们刚才提的 clone vfork 标志,他还会顺手把 vfork 当这个信号量给提前出示化。好 思路可谓是滴水不漏。等到那个幕后大佬把重活干完,车间主任 colonel clon 就 该来收尾了。 新生命一旦成型,系统第一时间调用 wake up new task, 把这孩子唤醒,推向调度器去干活。但这时候要注意了,如果当初咱们要求了 clone v fork, 车间主任就会极其冷酷地调用 wait for v fork, 死死按住副进程不让他走。 一切尘埃落定之后,最后返回新生紫禁城的 p i d。 一个新进程的诞生仪式到这就全套揭除了。 大家肯定好奇,嗯,刚才咱们一直说那个默默干重活的大佬,他到底是怎么操作的?没问题,咱们马上进入第四阶段,去解剖一下整个流水线的绝对心脏。 copy process 的 核心策略干活可以说是极其的规律和严谨, 盖楼先得打地基嘛。所以他上来第一步,先调用 duop task struct, 把最基础的任务描述符,也就是 task struct 给分配出来,接着运行 schedule fork, 把那些关键的调度实体出示花好。 紧随其后的就是绝对关键的动作,执行 copy m m, 去处理最棘手的内存分配。 这里绝背要敲黑板,重点关注一下,因为 call p m m 里藏着整个机制的核心机密。 如果是标准的 fork, 它会聪明地布置好写实复制的陷阱。也就是说,紫丞丞刚生下来的时候,其实只是虚张声势地在跟富晋城共享物理内存,直到哪天有人真的要写数据了,才会真正去拷贝。但是 只要你塞给他一个 clone v m 标志,画风突变,他直接跳过复制,强行把两个任务绑死在同一个 m m structure 上。你看,多现成能共享内存的底层奥秘,就这么几行代码的事儿。 搞定内存这座大山之后, copy process 就 顺理成章地按部就班去复制剩下的家当了。 比如调用 copy underscore cress 复制权限, copy underscore name spaces 处理各种命名空间。接着还有文件系统、文件描述符、姓名处理机制,甚至还包括保存 c p u 现场那些架构相关的寄存器。 最精妙的一点是,这里的每一个具体的 copy 小 组,都在严格按照咱们最初递进来的 c l o n 标志位板式,让你共享绝不复制,让你复制绝不偷懒,边界感绝对拉满。 临近尾声, copy process 终于进入了最后的打磨验收阶段。首先,调用 alucid, 在 新任务对应的命名空间里给他发个独一无二的身份证号码,也就是 pid。 然后快速处理一下 c group 和安全审计的附加信息。最后把这个经过千锤百炼、里里外外塞得满满当当的 task structure 指征,恭恭敬敬地交还给 colonel cologne。 至此,新进程的数据结构在内核里算是彻底完美成型了。 听起来是不是特别顺利?但是在咱们核心开发的世界里,永远不要假设一切都会一帆风顺,不谈错误处理的解析,那都是耍流氓。所以,咱们果断进入第五阶段,看看失败清理和账回溯到底是怎么做的。 大家设想一个很极限的场景,万事开头难,刚进流水线准备大干一场,结果 duptask struct 在 申请最基础的内存时,可乐直接摊牌了,说不好意思没内存了,反手就丢回来一个 n o m e m 的 错误码。 这时候,我们的流水线该怎么办?在这个幽深的内核底层,咱们必须得有一个完美无暇的紧急制动按钮。 这时候, linux 内核会用极其精妙的勾图语句来化解这场危机,一旦捕捉到错误,系统会直接跳到对应的错误飘仙。比如 badforkfree, 接下来发生的事情简直就像是在看电影倒呆一样。系统会严格按照刚才分配资源的相反顺序,挨个执行 badfork、 cleanup 相关的撤销函数, 先释放 pid, 再释放任务描述符,干干净净清理完战场之后,最后把那个冷冰冰的错误码原入扔回给用户空间。可以说啊, 在 kernel fork c 里面,这条错误处理路径简直就是资源分配路径的一面完美镜像。这种见了多少我就只拆多少的系统性回溯,真的是把工程鲁邦性展现到了极致。 他既不会傻乎乎的浪费 cpu 周期去清理那些压根儿还没分配的东西,也绝对不会遗漏哪怕一个已经占用的字节,从根源上直接掐断了内存泄露的任何可能。 好了,今天这场深入的内核溯源之旅到这里就接近尾声了。讲了这么多底层的精妙设计,最后我想给大家留个有意思的思考题。 下次当你在业务代码里敲下 pthread create 或者是 fork 去拉起一个新任务的时候,不妨在脑子里默默问自己一句, 我现在这个进城里的各种家当,在刚才咱们走过的那条内河流水线上,到底哪些被彻彻底底的克隆了,哪些又只是被悄无声息的共享了? 相信带着这种底层视角去写代码,你会发现整个系统的运转变得前所未有的清晰。感谢大家收听本期解析,咱们下期硬核见!

欢迎来到本期解析,今天咱们直接进入正题来拆解极其复杂的 linux t t y 子系统,怎么拆呢?我们会一路追踪一个小小字节的奇妙旅程,从你敲击键盘的那一刹那,一直深挖到底层的裸机硬件。 大家发现没有啊?平时看底层驱动架构的原码简直就像在看一团烂麻对吧?但在今天的解析中,我们会把这些晦涩的技术细节全部转化成通俗易懂的物流大类比,保证让你轻松直观的搞懂整个底层逻辑。咱们今天的物流路线图非常清晰, 第一站核心枢纽 ttycor, 接着是第二站线路归程数据包装。第三站, termios 结构体解密,然后第四站, p l 一 零幺幺驱动于底层。第五站, dma, 提升传输性能。最后咱们再聊聊 ioctl 与故障排查, 好,咱们马上发车直奔第一站核心枢纽,也就是 ttycor。 来看看这个中央管理台到底是怎么追踪数据的。 大家现在看到的就是一张极其关键的您在此处大局脑航图,整个数据自上而下的流向说可以是一目了然, 你看最顶层的用户空间,就像是咱们的实体门店,往下走,穿过 t t y 核心层和线路归程,最后稳稳落到底层硬件的 a m p a b 总线和 d m a 引擎上。无论是什么样的数据传输,都绝对绕不开这张导航图的指引。 大家仔细观察一下这其中的数据流转非常有意思。想象一下,当你的程序调用 right 函数或者你敲击键盘的时候,就相当于你把一个包裹甩到了类似 deluxe ttys 零这样的门店柜台上, 紧接着 t t y core 这个中央管理台里的 t t y struck 结构体就会立刻接管,开始全程的登记追踪。随后包裹被送到线路归城那边进行专业打包,最后全部装载到 u a r t 送货卡车上,直接发往物理事件,是不是非常让流水线? 那么刚才提到的专业打包是怎么回事呢?这就来到了咱们的第二站线路归城,也就是数据包装环节。 在盒那儿里,这里其实就是个大型的物流分拣中心,大家看这里不同包装标准的对比简直太鲜明了。 左边这个默认的 n t t y 规程就像是在处理最普通的平线,专门对付控制台输入的简单文本回显啦、退格键这些基础信号。但是右边呢, n p p p 和 n s l i p 就 完全是另外一种画风了, 他们负责把数据组装成极其复杂的网络货运物资,让你竟然可以通过一根简单的创口线去跑复杂的 ip 网络协议,这其实就完美展现了咱们这个包装中心极其彪悍的灵活性。 当然了,就像邮局里总有个窗口专门对付那些奇形怪状的异形包裹一样,咱们的线路规城里也有 n mouse 这种超级特殊的专属通道,它存在的唯一使命就是去处理早期那些串行鼠标发出的奇特非结构化的乱码信号。 也就是说,不管你在用户层往里丢什么奇葩数据,线路规城总能精准匹配到一条合适的包装流水线来搞定它。 接下来进入第三站, termios 结构体揭秘系统到底是怎么知道该用多快的速度、什么规格去发货的呢?全靠这个决定命运的物流标签。 这里的核心要点就在于, termios 结构体绝对是每一个字节的终极物流标签。在整个数据旅程还没开始的时候,用户腾程去就已经通过 tcgettor 和 tcsettor 这俩接口把这个标签给死死盯上去了。 它极其严谨地规定了波特律,其有缴验位等等这些传输死规则。你想想要是波特律配错了会怎样?你的数据到了端端上绝对就是一堆乱毛,为啥?因为你底层卡车的行驶速度跟人家接收放预期的完全不在一个频道上嘛。 标签贴好了,包也打好了,接下来咱们该去装车了。第四站, p l 零幺幺驱动于底层,也就是咱们连接物理世界的送货卡车。 大家看这张表,咱们的车队阵容可以说是百花齐放,跟着平台走在老掉牙的 isa 时代,出战的是大名鼎鼎的八二五零驱动,换到高通平台呢,变成了 msm cereal, 要是到了英伟达那边,就是支持高速模式的 tiger hsu。 但是如果你玩的是 amba 总线的 p l 零幺幺卡车,它基本上就是系统的默认控制台。 底层的 pl 幺幺幺 driver 会亲自上手去配置硬件寄存器,让所有硬件随时待命。不过问题来了, 以前串口通信都是一个字接一个字接地往外扣,现在货运量这么大,纯靠手工装卸肯定是顶不住的。所以第五站,咱们来看看 dma 是 如何作为自动化传送带来提升传输性能的, 这儿必须炮出一个极其现实的物流难题。当 urt 卡车突然要一口气拉走一百万个包裹时,如果还让 cpu 去响应每一个单字节传输带来的中断会发生什么? 你想啊, cpu 可是咱们系统里最核心的高级管理人员,你让它去干这种按键计件的搬砖体力活儿,那整个系统的响应速度绝对会卡到让你怀疑人生。 怎么破局呢?超级聪明的解决方案就是 dma, 也就是直接内存访问技术。我们在 pl、 零幺幺、 underscore、 dma、 tx 和 rx 这类底层驱动里,直接架设了一条自动化传送带。 这条传送带直连内存和物理 u r t 硬件,专门搞大宗货物的批量转移。这样以来,完全绕开了 cpu 的 人工干预, c p u 只要在开头喊一句开始干活,结尾收个短信通知就行了。这觉得是极大地解放了 c p u 的 算力,让它能踏踏实实去处理真正复杂的核心业务。 就算有了传送带,真实环境里的物流仓库也难免会爆仓或者堵车,对吧?所以,最后一站,咱们翻出救生包,聊聊 i o c t l 与故障排查。咱们工程师在排障时,其实可以通过 t d y operations 结构体,掏出一个极其硬核的实用诊断工具箱。 举个例子,当已抓狂地发现串口一直在莫名其妙丢数据时,别慌,先去查查 right room, 看是不是底层的缓冲空间已经彻底见底了。 或者说,当你遇到那种让人极其头疼的中断延迟时,你可以直接甩出一个 wait until sent 命令,强制把队列里积压的包裹全部排空,瞬间搞定通信时效性的问题。 这里面特别值得一提的是 throttle 和 on throttle 机制,这就好比咱们仓库装卸大门上的红绿灯, 一旦硬件发送的速度实在跟不上软件狂写的速度,导致 x max buff 这个环形缓冲器眼看就要撑爆了的时候,系统就会果断亮起红灯,也就是 throttle 大 喊一声,停,别发了, 等到积压的数据消化得差不多了,再亮起绿灯, on throttle 恢复接收。这绝对是 t t y 内部极其聪明,也是最核心的自我保护机制。 回顾整个 t t y 子系统,它的设计可以说是把分层架构的艺术玩到了极致。在本期解析的最后,我想给大家留一个非常有意思的思考题, 如果在咱们的硬件物流链里,仅仅是因为贴错了一个小小的 termios 标签,就能让整条高大上的自动化传输线瞬间瘫痪,那么在你日常维护的那些系统深处,是不是也正潜伏着什么平时根本没察觉到的性能瓶颈呢? 大家不妨回去翻翻自己的配置。好了,感谢大家的观看,咱们下期解析不见不散!

欢迎各位内核开发老病来到本期的深度解析,今天咱们要啃一块硬骨头,也是大家日常开发中既熟悉又常常让人抓狂的领域。 linux usb 子系统架构 老师说,面对如此庞大复杂的代码库,最直观的理解方式就是把它想象成一座宏伟的全球跨海物流大桥,它在干嘛呢?就是在无缝连接软件层的各种请求和最底层的物理硬件。在接下来的解析中,咱们就以最硬核的内核工程师视角,彻底扒开它的底层逻辑。 咱们今天的路线图非常清晰,总共分五大块,首先从宏观的架构全景看起,然后一路向下,深入解析主机控制器与核心层的交互逻辑,接着翻转视角,揭秘设备端的 gadget 与 configfs, 随后直击 dwc 三控制器的硬件机制。最后也是最精彩的部分,我们会从头到尾把 urb 数据请求在底层的流转过程彻底拆解一遍。 好,咱们直接进入第一部分, linux usb 架构的宏观全景。先来建立一个从核心主机到设备的大局视野。 你看这张图特别有意思,宏观架构的精妙之处就在于它极其清晰的分层,从最上层的设备驱动咱们常用的负责存储的 usb storage 或者是处理视频流的 uvc video, 一 路往下穿过 usb 核心层, 延伸到主机控制器,最后直接扎进底层的二 m 六四硬件里。大家可以非常直观地看到左边的主机模式阵营和右边的设备模式阵营是如何以 usb car 为绝对中疏完美对称蓬开掌来的。 稍微对比一下这两大阵营啊,主机模式界边大家都很熟了,有扛大旗处理高速超高速数据的 x h c i, 当然也少不了老一代的 e h c i 和 o h c i 控制器。 而在设备模式这一侧呢,咱们主要依赖的是大名鼎鼎的 gadget 框架,以及像 dwc 三这种较为强悍的双角色设备控制器。 说真的,正是有了 dwc 三,像 rk 三三九九或者枭龙这类 arm sixty four 平台才能如此丝滑地在 host 和 device 身份之间反复横跳。接下来是第二部分,主机控制器与核心层。咱们凑近一点儿,看看核心层跟控制器到底是怎么握手交互的。 放心,咱们今天绝对不赚代码牛角尖,但有个结构题你必须得看,就是 drivers slash usb slash core 下的 struct usb underscore device。 这就好比是咱们物流系统的货物追踪,单 关注几个核心字段,它用 dev num 来精准管理设备地址,用一 p 零,也就是端点零来死死把控控制流,而且会随时记录当前的活跃配置 active config。 只要一个设备插上主机,这个数字身份就立刻被建立起来了。 视线转到控制 t 这一侧, struct usb h c d 就是 那个掌控大局的航运调度总监了。你看里面的 h c d buffer create 函数,它负责干嘛?专门给咱们的数据货物划拨及其关键的 dma 内存池。 同时,那个 usb hcd link herb to ep 函数就像是码头上的剧情起重机,负责把封装好的 usb 请求块儿,也就是 urb, 稳准狠地挂载到对应端点的队列里。 当然,所有的调度都绕不开物理法则,也就是这四种传输类型的硬件约束控制、传输管配置,批量传输,保数据准确,懂时传输,给音视频留足待宽。但重点来了,各位中断传输。 如果你在做 hid 设备,比如那种电竞级的高回报率鼠标,你的轮询间隔被硬件严格锁死在一到一百二十五维秒之间,在这个红线范围里搞事情,稍微越界一点,你的硬件表现绝对会惨不忍睹。 好了,跨过这座桥,来到第三部分,揭秘 gadget, 一个 configfs, 咱们来看看如何在用户态像捏泥人一样构建各种外设。 这张图简直把 gadget 核心的优雅展现得淋漓尽致。仔细看这里的顶层路由,它用一种极其美妙的解偶设计,把用户空间通过 concifss 的 一通目录操作,直接跟核心态的 usdc 核心以及底层硬件死死绑定在了一起。 这意味着什么?意味着你作为应用层开发,根本不需要去动底层的 c 代码,就能在板子上凭空变出一个 usb camera 或者网卡来。 到底怎么操作,其实就三步,第一,进到 system config usb gadget 目录,建个文件夹。第二,配置你需要的功能参数。第三步也是最爽的一下,当你把 u d c 控制器的名字 echo 进对应的配置节点时,叭这就相当于拉下了总电闸。 软件配置瞬间注入底层硬件,你的设备立刻就会在宿主机的设备管理器里弹出来,就这么简单粗暴。 其实刚才那些 configfs 操作在底层唤醒的是一个个特定的功能驱动, 比如说你拉起 usb 杠 fhed, 你 的板子就变成了键盘鼠标。拉起 usb 杠, fuvc 立马化身超高清网络摄像头。 并且啊,每个功能驱动一旦被激活,都会极度聪明地向系统动态申请它们赖以生存的端点资源。 接下来第四部分,咱们再硬核一点儿,下探到物理层 dwc 控制器硬件机制,去看看 designware usb 三 ip 的 庐山真面目。 不管上层软件王出什么花样,所有的命令最终都得老老实实汇聚到 dwc 三核心的控制积存器上。大家看这个 dcl on the run stop 位。这就是咱们刚才说的那个总电扎在物理层面的针身 内核仪。改写这个寄存器,整个外设控制器就在硅片层面上启动或者关停了。旁边的 d s t s 寄存器也没闲着,时刻向系统汇报当前的连接速度。 到了具体的端点操作层面, dw c 三在核内里把逻辑端点抽象成了 struct usb 杠一 p 但是真正扣动数据传输班机的是什么?是 d e p s t r t x f l 二、这个命令。 一旦这个指令砸给硬件控制器,就彻底接管了内存,开始如同机器一般无情地、疯狂地搬运咱们的数据货物 终于到了最激动人心的第五部分, urb 与数据流转全过程。我们将完整追踪 urb 与底层 trb 是 如何打通整条链路的, 各位看仔细啦,这里是整个系统运作的心脏图解,他把三个最核心的数据流彻底拨开了在了咱们面前向主机狂灌数据的 tx 发送流,默默接收主机数据的 rx 接收流以及同管大局的 set up 控制流, 顺便给大家分享个实战秘籍,在日常排查那种毫无头绪的 usb 驱动卡死问题时,会用 ftrace 去动态追踪这三条链路上的 urb 路径和中断事件,绝对能让你事半功倍,这可是保命的技巧啊! 咱们先拆解 tx 发送流程,就像一场完美的接力赛。第一棒,功能驱动,调用 usb underscore e p q q 把请求塞进队列。第二棒, udc 驱动,心领神会,立刻向 dwc 三硬件下发咱们刚才提到的第一 pst rtxfr 命令。 最后一棒,底层的 smm 又被唤醒, dma 绕过 cpu, 直接把包含在 trb 里的数据暴力推送到 usb 总线上。软件排队,硬件干活极其高效。 反过来, rx 接收流程走的是另一套哲学。主机那边发来一个凹凸令频,咱们的 usdc 控制器一声不吭,直接用 dma 把数据悄无声息地搬进咱们早就挖好的内存池。 搞定之后,硬件抛出一个事件环,重断 gadget 框架,立刻调用 usb gadget giveback request, 把装得满满当当的请求块儿双手奉还给上层软件。 整个链路几乎没 cpu 什么事儿,这就是性能压榨的极致。最后,绝对不能漏掉大楼级别的端点零,也就是 ep 零,它是整个控制流的超提大脑, 主机发来的 set up 包会最先触发 dwc 三的一批零事件。紧接着, composite underscore set up 函数就像个极其专业的拆信员,一层层拨开协议,分析这到底是标准请求还是类特定请求,然后精准无比地路由给对应的功能驱动,确保设备每举一次成功。 好了,各位,当你意识到此时此刻每秒钟都有成百上千万的 trb 和 urb 正在通过 dma 构筑的这座跨海大桥无缝狂奔时,你很难不为这种软硬件协同交织的精妙工程感到震撼。那么留给咱们内核工程师的一个终极问题来了, 在你下一次的侵入式系统架构设计中,当你试图把这套 usb 传输机制推向极限性能时,这段看似完美无瑕的流转念录里,到底还会暴露出哪些隐蔽的性能瓶颈呢?好好想想这个问题,感谢大家收看本期解析,咱们下期硬核基组局再见!


空间的核心那肯定是人啊,因为空间之所以叫空间,是因为有参照性,这个参照性的核心这种表达的接收点呢,就是人 就是一切的事物,一切的所谓的空间的材质、比例、光效,它都是通过人的视角向外去扩散。所以说人是空间的核心, 叫设计嘛,叫以人为本。但是以人为本,他又不是单纯是以人的这种一个主体为本,而是让人和这个环境产生一个有效的一个共鸣啊。我们也讲叫共情,或者叫互动, 互动不一定要动起来,比如说你去啊,跟他有这种对手的关系啊,可能是一种心灵的感受啊,或者说是气味啊,或者说是一种自然的光线, 哎,他让你产生了反应,这种就是一种有效的互动,那这个其实他才会跟人之间产生一个很好的一个粘性的一个表达,那就是我们所谓的空间。哎,有趣味性,然后觉得挺有意思的呀,然后想多看几次啊,就这种欲望会增强。对,就是这样。 呃,有句老话叫隔行如隔山。虽然说其实建筑建筑行业跟室内行业,他说建筑室内不分家吗?但是我感觉他也算是一种 跨界,但这个跨界他是比较模糊的,因为本身呃,建构是完成了空间的一个主体,但是其实室内设计他比较琐碎,他跟建筑还不太一样。 建筑吧,可能是完成了整个建构的外观,他考虑的是城市因素,或者说他的一个整体的一个构造的因素,但室内的话,他是解决空间的问题,空间的形式啊,内容,所以他是比较杂的一个行业啊,不太容易看着不容易,做起来其实 有点麻烦,也需要一个适应的过程,但是可能肯定比刚入行的这个呃学室内的小白要更快速一些,而且他可能后来做项目的话更具有 建筑的视角啊,对于空间这种结构能力上可能会更强一些啊,我是这种感觉的,美好生活的创造力。

嗨,大家好,欢迎来到本期图解,今天咱们要聊点硬核又非常有趣的底层机制,我们要揭开 linux 定时器子系统的神秘面纱。 你想想看,当你疯狂划手机、看高帧率视频,甚至当设备黑屏休眠的时候,底层到底是谁在精准掌控的时间? 可以说有一个你看不到的隐藏心跳,在后台默默跳动,指挥着整个操作系统的运转。今天我们就来把这台精密仪器的外壳拆开,带你从头到尾弄得明明白白。 因为这个底层架构天生就是分层的,所以今天的路线图也非常清晰。我们一共分六个模块。首先我们会从整体上理解时钟中断系统,对比一下传统与高精度计时。 接着以资深工程师的视角来看看系统调用的开销,探讨节能的无滴答模式。然后再硬核一点,揭秘 am 架构的定系器。 最后梳理一下中断的触发与处理流程。简单来说就是依次自顶向下,深浅到底层硬架,然后再自底向上反弹回来的完整探索。 好的第一步,对于初学者来说,咱们得先建立个宏观概念,看看时钟中断系统在整个架构里到底处于什么位置,也就是从用户空间到硬件的完整映射流程。 闭上眼睛,想象一下这个跨越用户空间与内核空间的交互路径啊!当你在最顶层的应用程序里敲下一行 clock get time 获取当前时间时,这个看似为不足道的用户请求其实就像瀑布一样向下奔涌, 它会干脆利落地的穿过内核的定时器核心,也就是 timer core。 接着流经时间保质层, time keeping 一 路直达节拍设备层,最终硬生生地触及最底层的 arv 八 a 裸机硬件。 掌握了这个宏观的上下游地图,我们接下来的细节探险就绝对不会迷路了。弄懂了大致路径,咱们进入第二部分,让我们来看看驱动刚才那个定时器核心的两种截然不同的引擎, 传统计时和高精度计时。这里我特别喜欢用一个类比来解释,传统的 timer list 是 基于 gifs, 也就是系统节拍的,你可以把它想象成一个慢悠悠、极具年代感的老爷钟。 它在内部使用一个包藏八个层级的时间轮机制,粗犷地把任务扔进不同的时间桶里,精度基本上在毫秒级。 老师说,在以前这绝对够用了,但是现在的计算任务多么严苛呀,所以内核引入了 hr tim。 高精度定时器这玩意儿简直就是一块原子秒表啊! 它跟特定的 cpu 是 绑定的,直接提供纳秒级的极致精度,专门用来搞定现代系统里那些对时间极其敏感的任务。那么问题就来了,精度这么高的原子秒表,怎么高效管理呢? 核心可不敢再用以前那种慢吞吞的桶状结构了,相反,它采用了一种能自我组织的智能档案系统红黑树。 红黑树能极其高效地管理这些高精度任务。它把每一个定时器严格按照到期时间排得整整齐齐, 这比以前那种八级时间轮快的不是一星半点。不仅如此,它还能完美支持每个 c p u 的 各种时钟精准,比如单调时钟 clock analogic, 或者实时时钟 clock real time。 说真的,这绝对是一种纯粹的架构暴力美学。 接下来是第三部分,咱们换个视角,听听内核大佬是怎么看待这套系统的。特别是绕过内核收费站这个极其精妙的优化, 任何一位在内核代码里摸爬滚打过的资深工程师,一定会把这句话奉为规撵,非必要绝不交系统调用这笔过路费。 为什么这么说?因为太贵了呀!你想想,仅仅为了查一下时间,系统就要从用户态硬生生切换到内核态,这种上下文切换的开销在性能上是极其昂贵的。 这就好比你就是想看一眼墙上的挂钟,结果非得让你穿上正装,经过重重安检走入银行金库才能看一样荒谬。为了解决这个痛点呢,系统引入了一个超级绝妙的机制, v d s o, 全称是虚拟动态共享对象。 通俗点说, v d s o 就 像是内核发给应用程序的一个 v i p 作弊码, 有了它,像 clock gettime 这样的函数,就能直接在用户空间把时间数据给读出来,完全绕过了刚才说的那种极度消耗性能的内核上下文切会儿传统方法开销高得吓人,而用了 vdso, 开销几乎微乎其微。 这就是真正懂行的高手优化系统性能的终极秘诀。第四部分,咱们聊点非常实际的节能的无滴答模式。 要知道,维持如此精准的时间记录可是个吃电大户。大家不妨想一个问题,如果底层时钟为了维持系统运行,必须一直在那滴答滴答的跳,那你晚上睡觉手机静静躺在床头柜上的时候,他又是怎么省电的呢? 如果这颗心脏一刻不停,电池不早就被抽干了吗?答案就在这里。 n o h z 模式,业内叫它无滴大空闲模式。当系统发现没啥活干进入空闲状态时,它会非常聪明地调用一个叫 tikno h z stop schedule tick 的 机制, 字面意思就是直接掐断自己的调度解开,它会主动让心跳停摆,把那些不着急的定时器任务往后延。这样以来, c p u。 终于可以喘口气,进入深度休眠状态, 也就是深度的 c 状态。这就是为什么你的手机在闲置时能极其顽强地保住电量的核心机密。第五部分,咱们得深浅到裸机硬件了, 一起来揭秘 a m。 架构下的定时器到底是怎么运作的。在阿尔姆硬件儿的绝对最底层,咱们主要面对两套时钟机制,物理定时器和虚拟基础器。 物理定时器用的是 c n t p c t l e l 零这个寄存器,它平时待在 e l e 也就是内核儿这个大管家的环境里。 但在其中真正大有文章的是那个运行在 e l。 零环境下的虚拟技术器, c n t v c t l。 零。它为啥特别?因为它的存在完完全全就是为了配合咱们前面刚夸过的那个 v d s o。 作弊码。它被精心设计成允许在用户空间直接访问, 在硬件儿层面上,极速读取时间,其实是一个真正的工程魔法。第一步,你个 v d s o 直接去摸那个 c n t v c t l。 零,微信虚拟计数器。 第二步,系统更等不理会那些繁杂的内核函数,而是直接套用一个极简极快的数学公式,一次乘法加上一次一位运算, 就这两步搞定。第三步,精准的挂钟时间瞬间更新在你眼前。整个过程行云流水,没有触发哪怕一次昂贵的系统调用,极致的优化莫过于此。 好的,最后,咱们来到第六部分,中断触发与处理流程。前面咱们是从上往下走,现在对于初学者来说,咱们必须看看一个实际的硬件中断是怎么自底向上反弹回系统高层的 定时器中断触发后的分发过程可以说是极其紧凑,当设定的时间一到底层的一二零或一二一定时器会在硬件中猛烈地触发一个 irq 中断请求。这股信号如同离弦之箭向上冲,瞬间撞击到节拍设为层。 到了这里,系统化身为一个眼疾手快的高效交警,动态地将中断分发出去,可能分发给单次广播,也可能交给急速的 hr timer interrupt。 最终系统会执行像 underscore、 underscore、 run timers 这样的回调函数,把你的应用程序等待的任务真正跑起来,这就完美完成了一个字,底向上的闭环。 看到这里,咱们真的不得不感叹,这台精密的机器内部简直不可思议。想象一下,你口袋里的那个小黑盒里面竟然藏着如此登峰造极的架构天才。 有在红黑树上跳舞的原子秒表,有巧妙绕开收费站的极速通道,还有能在你睡着时聪明地停掉自己心跳的底层机制, 这绝对会让人难不住去想,就在我们专注这期图解的这几分钟,你你的数字生活中还有多少期盼隐藏在幕后高度优化的神秘系统正在无声无息地为你飞速运转呢?感谢大家收看本期图解,我们下次再见,继续去探索系统底层那些让人着迷的风景吧!