60 hand-built SVG figures in the anthropic-design language — for engineering docs, kernel & hardware work, product walkthroughs, and slide decks. Every figure follows the diagram-craft contract: sized to its content, ≥2 semantic hues, solid color dots, readable at every label. Copy any of them straight into your page. 60 张手工 SVG 图,覆盖工程文档、内核与硬件、产品演示、演讲汇报四类场合。每张都按 diagram-craft 工艺合约执行:画布贴内容、每图 ≥ 2 个语义色、实心色点、所有标签可读。点 Copy SVG 即可直接用进你的页面。
Architecture, flows, sequences, git history, states, deployment — one hue per layer or category, orange reserved for the focus, color always on solid dots and bars rather than flooded fills. 架构、流程、时序、git 历史、状态机、部署拓扑——一层一个色相,橙色只给焦点;颜色落在实心色点和色条上,不做大面积满填。
templates/diagrams/architecture.svg.
四层系统图。每层是 16-20% tint 容器加 4px 色条,节点是白卡加实心类别色点。模板:templates/diagrams/architecture.svg。
templates/diagrams/flow.svg.
带编号徽章的流水线,决策菱形是全图唯一的强调 tint 色块,失败回流走图下方灰虚线。模板:templates/diagrams/flow.svg。
templates/diagrams/railroad.svg.
唯一的规则:从起点环走到终点环,走得通的路径就是合法的——所以图上不需要任何条件标签。三种形状把活全干了:上方绕过 = 可省略、下方回环 = 可重复、并排分支 = 三选一;而在文法记号里,这三件事分别由方括号、花括号和竖线承担,长得都一样。它输在递归:记号一行就说清「term 里含 expr」,图只能指回上面那条轨。模板:templates/diagrams/railroad.svg。
The diagrams an embedded engineer actually draws: function control flow with error lanes, register bit fields, SoC blocks, bus waveforms, build chains, scheduler timelines. Real names, real offsets — copy and swap the content. 嵌入式工程师真正天天画的图:带错误车道的函数控制流、寄存器位域、SoC 框图、总线波形、编译链、调度时间线。真实的名字和偏移——复制后换内容即可。
return 0. Every diamond's yes branch drops straight down into the error lane, which is an unwind ladder read right to left — a request_irq failure enters at err_unmap and falls through err_free to err_out, while a kzalloc failure enters at err_out and returns immediately. The ladder's arrows point against the happy path because unwinding runs backwards. Vertical template: templates/diagrams/function-flowchart.svg.
驱动 probe() 横向排布:徽章 1 kzalloc、2 ioremap、3 request_irq,然后 return 0。每个菱形的 yes 分支垂直落进下方错误车道;车道是一把从右往左读的解绑梯 —— request_irq 失败从 err_unmap 进,依次落到 err_free、err_out;kzalloc 失败直接从 err_out 进、立刻返回。梯子的箭头与主路径反向,因为解绑就是倒着走。纵向模板:templates/diagrams/function-flowchart.svg。
templates/diagrams/register-bitfield.svg.
32 位控制寄存器拆两行:字段用 tint 跨格加实心顶条,保留位留白,访问权限 chip 和复位值放在数据手册该放的位置。协议帧格式同样适用。模板:templates/diagrams/register-bitfield.svg。
templates/diagrams/soc-block.svg.
子系统是 tint 分区,互连是中性脊柱——绝不画成饱和色带。唯一的橙色路径从 CPU 经 NoC 到 DDR,每个分区的内部连线用自己的色相。模板:templates/diagrams/soc-block.svg。
memcpy. The two strips are never merged: the same DRAM is 0x80_0000_0000 to the host and 0x18_0000_0000 to the device. Segment widths are not to scale. Template: templates/diagrams/interconnect-map.svg.
上半是拓扑,下半是每个视角各一条地址空间,中间那条虚线的落点就是这张图的结论:CPU 核用一条普通 store 就写得到斜纹那一段,指针可以直接递过去,不用 memcpy。两条带永不合并——同一块 DRAM 在 host 眼里是 0x80_0000_0000,在设备眼里是 0x18_0000_0000。段宽不按比例。模板:templates/diagrams/interconnect-map.svg。
templates/diagrams/protocol-stack.svg.
上面三条灰虚线是约定,不是线 —— 没有任何东西把 TLP 从一侧的传输层直接送到另一侧。全图唯一一条横向实线,是最底下那根 lane。跟着 ①→⑧ 读:字节在发送侧一层层下去,过一次线,再在接收侧一层层上来。协议分析仪只能挂在 lane 上、挂不到传输层,原因就在这张图里。模板:templates/diagrams/protocol-stack.svg。
4 GiB inside a region and three readings stay open (start, end, size). Symbol names sit in ink pills, literal constants in orange mono ones: TOLUD is a name, 0xC000_0000 is only what it happens to equal on this board. The orange line is the whole point: the gigabyte shadowed by the MMIO hole comes back above TOUUD — same DRAM, a second address. Heights are not to scale; low addresses at the bottom. Template: templates/diagrams/address-map.svg.
每条边界各拉一条引线,因为边界是一个地址、区域是一段范围 —— 把 4 GiB 写在某段中间,起点 / 终点 / 大小三种读法都成立。符号名走墨色药丸,字面常量走橙色等宽药丸:TOLUD 是名字,0xC000_0000 只是它在这块板上恰好等于多少。橙线是这张图的全部理由:被 MMIO 空洞盖住的那 1 GiB,在 TOUUD 之上重新露面 —— 同一块 DRAM,第二个门牌号。高度不按比例,低地址在下。模板:templates/diagrams/address-map.svg。
<g> at a time. Template: templates/diagrams/glyphs.svg.
一个圆角矩形能代表任何东西,所以它单独出现时什么也没说。这里每个字形都是一个意义固定的名词:梳齿承诺"深度有限、按序进出",尺状刻度承诺"这是被序列化的字节",骑在边界上的小标签承诺"这个接口属于这块 die"。在没有那样东西的地方画上它,就是在图上写了一句假话 —— 比画个方框糟得多。厂商 logo 一律不进:写型号文字,文件才改得动。用的时候复制一个 <g>。模板:templates/diagrams/glyphs.svg。
templates/diagrams/hw-timing-waveform.svg.
逻辑分析仪视角的 SPI 传输:一信号一行,片选承担橙色焦点,数据格里是真实 hex,建立/保持箭头标注关键边沿。模板:templates/diagrams/hw-timing-waveform.svg。
templates/diagrams/build-pipeline.svg.
内核编译从 .config 到可启动镜像:工具与产物沿橙色主链交替,设备树分支以金色汇入,最终交付物用焦点卡。模板:templates/diagrams/build-pipeline.svg。
templates/diagrams/sched-timeline.svg.
三条 CPU 泳道,ftrace 风格:任务块跨核保持同色,IRQ 抢占是唯一的橙色标记,迁移箭头画出负载均衡的动作。模板:templates/diagrams/sched-timeline.svg。
templates/diagrams/algorithm-ringbuffer.svg.
kfifo 环形缓冲画成直线阵列:占用格用 tint,in/out 用实心指针标记,回绕只画一条安静的箭头并写明掩码技巧。模板:templates/diagrams/algorithm-ringbuffer.svg。
templates/diagrams/soc-dataflow.svg.
没有 GPU 的显示通路,画成封装剖面:虚线以外是另一颗芯片。配置和数据故意画成两根不同的线——金色虚线是 APB,每帧 4 个字节;橙色实线是 AXI,每帧 8.3 MB。橙线从 p2 口进内存,那是 DDR 控制器给最高优先级的一个口,因为扫描输出等不了。模板:templates/diagrams/soc-dataflow.svg。
templates/diagrams/gpu-dataflow.svg.
同一块 DDR,多一个总线主设备。GPU 画成敞开的,好让人把它的 tile buffer(2 KiB)和 L2(256 KiB)跟一帧 8.3 MB 放在一起看——里面根本没地方装。七个徽章全部落在同一条地址条上,这就是整张图要说的:GPU 不是数据去的地方,它是第二个往内存里发地址的主设备。模板:templates/diagrams/gpu-dataflow.svg。
templates/diagrams/vram-dataflow.svg.
上一张图的对照:台式机显卡有自己的显存,于是有两条地址条、中间一根线,拷贝是真的。看清是谁在搬——徽章 ③ 是显卡自己的 SDMA 引擎在通过 PCIe 读主机内存,不是 CPU 把字节推出去。徽章 ② 那步最容易看漏:把页面锁住不让换出、再通过 GART 映射,就让它们变得可读,而一个字节都没搬——这也是左边两排装的是同一批页面的原因。图上每个符号名都是主线内核里的真名。模板:templates/diagrams/vram-dataflow.svg。
templates/diagrams/glyphs-memory.svg.
第二张构件表,管的是内存和地址怎么画。地址条给一段空间命名,边界值用黑药丸挂在条外——值属于边界,不属于哪一段。斜纹带是一扇窗,它不存东西,往那儿读会落到另一个空间去。页帧阵列一格一页,状态于是变成一眼看得见的图案。橙色 COPY 块是这张表上唯一一个「说了一句话」而不只是「一个形状」的构件:画上它就等于断言字节真的动了;不画,就等于说没动。模板:templates/diagrams/glyphs-memory.svg。
soc-block: not what is inside the chip, but what the chip talks to and over which interface. The DRAM and the panel are drawn as the parts they are — a green module with gold fingers and a notch, a sheet of glass with a driver IC and a flex cable — because a labelled rectangle makes you read before you recognise. Every link carries a black pill naming the interface, which is the part that carries information; the line itself carries none. Badges separate the two wires a pixel actually travels from the ones that only ever carry boot code or control bytes. Template: templates/diagrams/platform-block.svg.
soc-block 的板级对应:那张画片内有什么,这张画芯片跟外面的什么器件相连、走哪种接口。内存和屏按真实外形画——绿色模组带金手指和缺口,一片玻璃带驱动 IC 和排线——因为标了字的方框要先读才认得出。每条连线上骑一个黑药丸写接口名,那才是带信息的部分,线本身不带。编号把像素真正走的那两根线,跟只走引导代码或控制字节的线分开。模板:templates/diagrams/platform-block.svg。
address-map draws one space; this draws several, stacked, with dashed leaders joining the same block of content where it appears in each. That stacking is the whole point: “the device sees a different address” is impossible to show on one bar. A translation box sits between each pair of layers and names who does the translating. The closing line is the one to keep: a pointer alone is never enough, because it is only meaningful together with the space it came from. Template: templates/diagrams/address-spaces.svg.
address-map 画一个空间,这张画好几个空间叠起来,用竖虚线把同一块内容在各层的位置连上。叠起来正是关键:「设备看到的地址不一样」这件事,在一条地址条上根本画不出来。每两层之间放一个翻译盒,写清是谁做的翻译。要记住的是图脚那句:光有一个指针永远不够,它只有连同它所属的那个空间一起说,才有意义。模板:templates/diagrams/address-spaces.svg。
templates/diagrams/copy-vs-share.svg.
上下两半用完全相同的坐标,只差一处。上半在地址条的两段之间放了一个橙色 COPY 块,于是同一张图存了两遍;下半两条箭头落在同一段上,全图找不到一点橙色。之所以要这么画,是因为文字定不了这件事——「交给它」「发过去」「上传」对两种情况都说得通。读者学会这张图,就拿到了一个能用在别处的判断依据:没有橙块,就没有拷贝。模板:templates/diagrams/copy-vs-share.svg。
prefers-reduced-motion — so it halts for readers who ask for less motion, halts under html[data-motion-freeze], and halts in every screenshot, which keeps captures byte-identical between runs. All three were tested, not assumed. Template: templates/diagrams/dataflow-animated.svg.
这张图动,是因为动作本身带着一条信息——只有这种情况才允许动。流动的线是硬件一直在走的通路:每一帧、每一行,只要屏亮着就没停过。静止的线则是发生一次就完了:徽章 ② 是软件每帧唯一的那次寄存器写,它被刻意画成全图唯一不动的箭头。静态图说不出这个区别——两者都只是一根带箭头的线。动画用 CSS 写而不用 SMIL 也是刻意的,因为只有 CSS 认 prefers-reduced-motion:读者要求减少动效时它会停,页面加 html[data-motion-freeze] 时会停,截图时也会停,于是每次截出来的图逐字节相同。这三条都实测过,不是想当然。模板:templates/diagrams/dataflow-animated.svg。
templates/diagrams/page-flip.svg.
同一张底图画两遍,中间隔着 vsync。两半的地址条逐字节相同——两块缓冲,位置一样、大小一样。变的只有寄存器里的值,以及那条蓝色流动线拐弯的位置。拐点右移,就是整个「翻页」。线在流,是因为扫描输出从来没停过读;翻页改的只是它从哪儿读。两半用完全相同的坐标是刻意的:只留一处差别给眼睛找,而那一处差别的大小,就是这件事真实的大小。模板:templates/diagrams/page-flip.svg。
templates/diagrams/gpu-memory-flow.svg.
每条连线都是会流动的虚线,虚线段朝数据走的方向走——于是「方向」不再是要读出来的东西,而是看得见的东西。两头都传的连线画成上下两条反向流动,而不是一条双箭头线:一条线上的虚线只能朝一个方向走,画成双箭头等于在最容易误解的地方写「方向不明」。顺着箭头看,没有一条线从一个主设备连到另一个主设备——没有谁把东西交给谁,它们只是在同一批地址上碰面。模板:templates/diagrams/gpu-memory-flow.svg。
templates/diagrams/vram-copy-flow.svg.
独立显卡那种情况,画成方向不会读错的样子。那根线画成两条反向流动的:请求从显卡去主机内存,数据反向回来。请求发起在显卡这边,所以这次拷贝是拉不是推——发起方是显卡自己的搬运引擎,不是处理器。这跟片上系统是同一条规则:谁要数据谁发读请求,变的只是内存的块数。画成一条双箭头线就会含糊,而含糊正是误解住的地方。模板:templates/diagrams/vram-copy-flow.svg。
templates/diagrams/arm64-display-path.svg.
一颗 ARM64 手机芯片上一帧的全程,画成上下两行加中间一条内存。上面的往里写,下面的往外读,没有一根箭头从一个模块直接连到另一个模块。把内存画成横贯全图的一条、而不是流水线上的一站,正是这张图的用意:模块之间不传帧,它们只是轮流去碰同一批地址。每根线都标了总线类型和每帧多少字节。停 ⑥ 是那条内存,也是全程唯一装得下一整帧的地方;上面的 ①—⑤ 都在往里写,下面的 ⑦—⑩ 都在往外读。模板:templates/diagrams/arm64-display-path.svg。
templates/diagrams/what-is-a-frame.svg.
把一个关于大小的论证画出来而不是说出来。一帧变成一把 660 像素的尺子,片上每一块存储再按同一比例画在下面:L2 是 33 像素,显示控制器的行缓冲 8 像素,GPU 的 tile 缓冲 1 像素。下面一条把这三个放大 12 倍,否则根本看不见。同样这些数字列成表格,读者点点头就翻过去了;尺子不给这个机会。模板:templates/diagrams/what-is-a-frame.svg。
templates/diagrams/gpu-tile-render.svg.
GPU 怎么画一帧它装不下的东西。屏幕是 10 125 个小格,一格的光栅化、深度测试、混合全在片上的 tile 缓冲里做完,只有做完的那一格才写出去。下面对比的是立即模式:三层重叠就是每像素六次外部访存。分块是个带宽决策不是算力决策——这也是它先出现在手机上的原因。图里 ②③④ 三步全在片上做完,只有 ⑤ 碰了一次内存——这一格的全部访存就是那一次。模板:templates/diagrams/gpu-tile-render.svg。
templates/diagrams/display-controller-inside.svg.
六个硬件窗口各用自己的取数 DMA 从内存里拉自己那一层;选择器可以把任一层送到任一个槽;一个混合器在像素路过时把它们叠好。叠好的结果一个字节都没回内存,直接以像素流出芯片。结构照的是厂商自己写进驱动头部注释的那张框图——这比我推测「显示控制器里大概有什么」要可靠得多。模板:templates/diagrams/display-controller-inside.svg。
templates/diagrams/buffer-roles.svg.
三帧并排,两个矩形在每一列都画在完全相同的坐标上。地址只在行首标一次而不是每列一份,这件事本身就是论点:三列画的是同两块内存。变的只有颜色。坐标不动是刻意的——它只留一处差别给眼睛找,而那处差别是角色,不是位置。模板:templates/diagrams/buffer-roles.svg。
templates/diagrams/dsi-panel-inside.svg.
整条通路上唯一一处信号形态真的变了的地方:片内是 24 根并行线,出芯片是四对差分线上的串行比特,进屏又变回并行——源极驱动握着一整行子像素,栅极驱动决定 2400 行里哪一行接收它。只有一根线是朝回走的:TE 信号,屏反过来告诉芯片「我刚扫完一遍」。顺 ①②③ 看是串行化,④ 是屏里那颗把包解回并行的芯片,⑤⑥ 才是真正去点亮玻璃的两组驱动。模板:templates/diagrams/dsi-panel-inside.svg。
templates/diagrams/bus-tenants.svg.
共用一块内存的代价——这一组里其他每张图都把它当成免费的。六个主设备按同一把带宽尺子排开,一条深度有限的请求队列,一个按误了会有什么后果而不是按到达顺序服务的内存控制器。不对称正是重点:GPU 晚了掉一帧没人看得出来,扫描输出晚了行缓冲会空,而像素时钟不会等。模板:templates/diagrams/bus-tenants.svg。
templates/diagrams/display-vocabulary.svg.
术语表的地图。每个词挂在它所属的那个硬件下面,而有四个词底下什么都不挂——vsync、翻页、撕裂、欠载 是时刻不是地方。把这四个单拎出来正是这张图存在的理由:在框图上找一个时刻,是能把自己困住很久的一种找法。模板:templates/diagrams/display-vocabulary.svg。
templates/diagrams/display-triage.svg.
把同一组图倒过来读,变成一个排查顺序。每一行形状相同:症状、它其实是哪个机制在报警、先查哪一站、别先查哪里。第四列比前三列值钱——查显示问题最常见的浪费是从通路最末端开始,因为最后那几个寄存器最好读,而它们恰恰最不可能出错。模板:templates/diagrams/display-triage.svg。
templates/diagrams/cross-section.svg.
剖面图只有在读者知道「从哪儿切的」时才成立,所以平面图上要画剖切线,还要画两个箭头说明你朝哪边看。十二层里没有一层塞得下文字,于是名字一律用引线引到外面。TFT 玻璃上那个虚线框用两条线连到放大面板,不是一条——一条读起来是「指向某处的箭头」,两条才读成「这一块,放大」。真正的内容是放大面板本身:显示用的公共电极和触摸用的发射电极是同一片金属,所以显示侧一停,触摸跟着停,而触摸寄存器读回来全是正常值。模板:templates/diagrams/cross-section.svg。
templates/diagrams/exploded-view.svg.
剖面图能说清谁挨着谁,但说不了「先装哪个」和「还拆不拆得下来」——而这两件事才决定一块板子能不能修。所以所有件挂在同一根直轴上、间距相等;编号走的是装配顺序,不是从上到下 —— ① 基板、② 中介层、③ die、④ 填胶加盖、⑤ 最后整颗上板。边框把剩下的话说完:实线表示还能拆开,虚线表示胶固化或焊料回流之后就回不去了。左边那张成品缩略图不是装饰,没有它,右边只是一列矩形。模板:templates/diagrams/exploded-view.svg。
templates/diagrams/debug-map.svg.
一张不说「怎么看里面」的架构图,只让读者知道系统长什么样,还是不知道该敲什么。这张把具体路径钉在每张卡下面,药丸按后果上色:绿色只读,金色会改硬件或内核状态——这个区别在凌晨两点、在别人的板子上最要命。左边那一列才是真正的入口,因为没人是捧着方块图进调试现场的,进来时手里拿的是一个现象。模板:templates/diagrams/debug-map.svg。
templates/diagrams/magnitude-ruler.svg.
十二个数字跨了 1.5 亿倍,线性刻度放不下——底下那条小图就是硬放的结果,十一个点叠在同一个位置上。对数轴放得下,代价是一条义务:必须在图上写明「等距 = 十倍」,否则读者会不出声地把每一段都读小十倍。下面那排「换成人类尺度」的卡片,才是让这把尺子变成论据的东西。「慢十万倍」是一句话,「一秒 对 一百九十三天」是一张图。模板:templates/diagrams/magnitude-ruler.svg。
templates/diagrams/pinout.svg.
两样东西必须同时在页面上:按实物排布画出来的那一排焊盘,和「每一根是什么」的表。光有表,没法拿实物对着核;光有排布图,读者不知道每根是什么。差分对用一个括号括起来,而不是并排两行表格——一对被读成两根独立的脚,就会被当成两根独立的脚去布线。橙色那个框是整张图存在的理由:左右取决于你从哪一面看,所以不写清「从哪面看」、不标 1 脚的引脚图,是不能用的。模板:templates/diagrams/pinout.svg。
templates/diagrams/abstraction-ladder.svg.
任何技术页面都靠抽象运转,而每个抽象都是有人决定不再画里面的那个盒子。这个决定通常是隐形的:读者遇到那个三角形时它已经关着了,然后在第一个不按常理出牌的变体上卡住。三格就能补上——每一格打开上一格交过来的那个符号,而每个折起来的符号都带着自己的晶体管数,所以这条阶梯从不隐藏一层抽象的价钱。三级是实际的上限,再多读者就跟丢了「谁装着谁」。模板:templates/diagrams/abstraction-ladder.svg。
templates/diagrams/state-triptych.svg.
展示三个状态的常规做法是画三张图,常规结果是读者把电路重新找了三遍,却始终没注意到到底哪里变了。改成把每一个坐标都锁死:眼睛没有东西要重新解析,唯一还在动的就是那个差别。这里颜色承担了全部论证,所以它的含义对整张图只定义一次——在几格之间会变的图例,比没有图例更糟。三格从左到右还读成一个故事,而不是一份清单。模板:templates/diagrams/state-triptych.svg。
templates/diagrams/process-steps.svg.
六张独立的图,会让读者在每一格里重新找一次这个零件,到第三格他已经不再对比了。锁死坐标,这一排就不再是图片:眼睛不动,变化在动。然后只把这一步新增的东西描出来,读一步的代价就从「对比」降成「看一眼」。从 ① 读到 ⑥,读的是同一个零件被造出来,不是六个零件被介绍一遍。每格下面那行——这个零件还救不救得回来——是工序图通常会省掉的,也正是排期真正取决于的那一行。模板:templates/diagrams/process-steps.svg。
templates/diagrams/scale-ladder.svg.
一条放大链,每一跳都要三样东西:一个虚线框说明下一格看的是哪一块、两条线把这个框带进下一格、以及一个真实尺寸,好让「放大三倍」和「放大五十倍」区分得开。底下那把尺子不是装饰——四格在页面上等距排开,在现实里差得很远,没有尺子,排版自己就在宣称那个错误的比例。两条线这个约定,跟剖面图挂放大面板用的是同一个。模板:templates/diagrams/scale-ladder.svg。
templates/diagrams/see-inside.svg.
「把里面画出来」不是一种画法。切开答的是谁挨着谁、多厚,代价是只看得到那一刀所在的平面;透视答的是里面有几个、怎么摆,代价是重叠处会糊;拆开答的是什么顺序、还拆不拆得开,代价是真实的相邻关系没了。三种里最该少用的是透视——它是唯一一种失败得很安静的。模板:templates/diagrams/see-inside.svg。
templates/diagrams/highlight-in-place.svg.
密图每一步重画一次,读者每一格都要重新找,到第三格已经不再仔细看了。坐标全锁死、其余全中性,只让一行或一个单元站出来。第一格那个虚线框干的是另一半活:把一个抽象名词钉在物理结构上——这就是读者对「页」这个词点头,和真知道它在哪,之间的区别。模板:templates/diagrams/highlight-in-place.svg。
templates/diagrams/isometric-stack.svg.
正视图能说清每一层的厚度,却说不了那两颗芯片是并排还是前后。等距两样都能说,条件有四条:用真正的变换而不是随手画的斜边、每个标注保持正立、三个面用同一 hue 的三档平涂而不是假打光、以及必须有一条尺寸线——因为在这种投影里看起来一样大的两个面,实际可能差一倍。当初值得禁的从来不是投影,是投影阴影、透视和拿渐变冒充光源。模板:templates/diagrams/isometric-stack.svg。
Seven figures for the two things hardware and kernel work keeps asking for: what the silicon looks like inside, and what the code's data actually points at. Each one carries a rule you cannot see in a block diagram — a device card pinned to its own address window, a tile joined at its ring stop, an arrow that leaves the exact field holding the pointer. 七张图,画硬件和内核工作里反复要画的两样东西:芯片里面长什么样,代码里的数据到底指向哪。每一张都带一条方块图看不见的规矩——设备卡钉在自己的地址窗口上、瓦片挂在自己的站点上、箭头从真正持有指针的那一行出发。
templates/diagrams/system-topology.svg.
PCIe 树和物理地址空间画在同一张图里。每根线标接口宽度和总线号,每张设备卡标 BDF 和 BAR 大小,虚线引线从卡落到地址条上属于它的那一段。拆成两张图,读者就得自己在脑子里做这个映射——而出错的恰恰是这一步。模板:templates/diagrams/system-topology.svg。
templates/diagrams/die-floorplan.svg.
二十块瓦片,每块是一个核加它自己那片缓存,瓦片之间跑互连轨,交叉点就是站点。瓦片挂在自己的站点上、不是连在轨边上——一次访问的延迟取决于跳了几站,靠的就是这个区别。徽章 1–3 追一次未命中一路走到内存控制器。模板:templates/diagrams/die-floorplan.svg。
templates/diagrams/datapath.svg.
四路组相联查找画到器件一级:地址拆分、译码器选中一组、四个比较器同时比、匹配线一边驱动多路选择器一边进或门抬起 HIT。way 1 的 valid 是 0,它的比较器永远不会成立——故意留死这一路,valid 位才讲得清。徽章 A–E。模板:templates/diagrams/datapath.svg。
templates/diagrams/packet-encap.svg.
同一个报文走过三层,画在一把 8 px/字节的标尺上,所以每根条的宽度就是它的字节数。两条竖虚线钉住最初那 80 字节:下层加的东西一律长在外面,绝不进到里面。窄到装不下标签的字段用括线引到边上写,不缩字号。模板:templates/diagrams/packet-encap.svg。
templates/diagrams/terminal-annotated.svg.
十四行真实的 PCI 枚举输出,只加标注、一个字符不改。五个徽章把行钉到右栏说明;高亮块画在文字下面,位置由字符下标算出来——每行都用 textLength 锁死了字符步进。讲的事:一个 256 MiB 的 BAR 挂在 firmware 只给了 1 MiB 的桥窗口后面,接着就是 -12。正常的 nvme 那几行是故意留在画面里的。模板:templates/diagrams/terminal-annotated.svg。
templates/diagrams/struct-graph.svg.
task_struct → mm_struct → maple tree → 三个 VMA,每根箭头从真正持有指针的那一行出发,落在目标卡片的标题栏上。起点精确到字段、终点是整个对象——这个不对称就是重点。兄弟对象只详画一个,其余只留区分它们的那几行。字段名对过 v6.6 的 include/linux/mm_types.h。模板:templates/diagrams/struct-graph.svg。
templates/diagrams/bus-fabric.svg.
主设备在轨上方、从设备在下方,桥再往下接一条更窄的轨和它自己的外设。每条引下线用斜杠加数字标位宽,轨上写跑在它上面的通道名。一次读事务去程实线、回程虚线,离轨 12 px——8 px 时实测糊进轨里看不见。图脚明写:轨是一种画法,不是拓扑论断。模板:templates/diagrams/bus-fabric.svg。
Six figures for the two questions that follow every kernel bug: who calls whom across which boundary, and when did it actually run. Three draw structure — the kind of every edge, the place a stack stops being a call chain, the core everyone else waits on. Three draw time — the gap between raising work and running it, the deadline a frame has to beat, the order a panel has to be woken in. 六张图,回答内核问题后面永远跟着的两问:谁隔着什么边界调用了谁,以及它到底什么时候跑的。三张画结构——每条边是哪一种、栈从哪里起不再是调用链、大家在等哪个核。三张画时间——把活扔出去到它真跑之间的间隙、一帧要赶的 deadline、屏必须按什么顺序唤醒。
templates/diagrams/call-graph.svg.
三个驱动,每条边按种类画:细实线是同栈直接调用,空心箭头表示目标是运行时才定的结构体成员,金色虚线是换了执行上下文的异步交接,闪电是硬件事件,点线是完成通知往回走。结论在图脚:grep 只找得到黑色实线那几条。模板:templates/diagrams/call-graph.svg。
templates/diagrams/call-stack.svg.
九帧 oops backtrace,中间横着一条断层线。线以下是 kworker 骨架,那不是调用链——`process_one_work` 调用的是队列里排到的任何东西。你真正要找的调用者早些时候在别的上下文里跑了 `queue_work()`,它被画成旁边一张虚线幽灵卡,因为它根本不在这张栈上。模板:templates/diagrams/call-stack.svg。
templates/diagrams/runtime-timeline.svg.
一次 DMA 完成依次走过硬中断、软中断、kworker 和用户线程,共用一根微秒轴。轴下三条括线给数字:中断到 handler 8 µs,raise 到 tasklet 跑起来 6 µs,`queue_work()` 到 worker 真跑 65 µs。workqueue 不是「慢一点的 tasklet」,是晚一个数量级——worker 就是个普通线程,要排队等调度。模板:templates/diagrams/runtime-timeline.svg。
templates/diagrams/frame-pipeline.svg.
六条硬件泳道铺在一个帧周期上,下面同轴画 vsync 和 TE。内存那条拆成两根小条,因为它同时在服务两边——GPU 在写后台缓冲、扫描输出在读前台缓冲——GPU 一忙扫描输出就 underrun,原因就是这个争用。徽章 1 vsync 中断锁住帧缓冲地址,2 GPU 发出 fence,3 翻页入队,4 扫描输出结束,5 下一个 vsync 让后台缓冲上台。越过徽章 5,面板就重复上一帧。模板:templates/diagrams/frame-pipeline.svg。
templates/diagrams/multicore-calls.svg.
四条 CPU 泳道共用一根微秒轴。CPU 0 拿着自旋锁、向其余核发 IPI,然后等每一个应答。CPU 3 有一段长时间关中断,它的应答最晚到,于是 CPU 0 阻塞多久由它说了算。应答箭头必须画出来:只画扇出读作发完就走,画上应答才成为一次等待。模板:templates/diagrams/multicore-calls.svg。
templates/diagrams/power-sequence.svg.
电源轨、时钟、复位、链路状态、初始化命令、背光,按事件排而不按线性时间——约束跨了四个数量级,按真实比例画的话 10 µs 那段复位脉冲是 0 像素。括线带着不等号给真实数字,顶上那条横条说明每一段归哪个面板回调管。下电是严格逆序,每一步都要,包括那些等待。模板:templates/diagrams/power-sequence.svg。
templates/diagrams/flame-graph.svg.
一个方块有两个维度,大多数图只花掉一个。同一份采样在这里画了两遍:画成调用关系图,每个方块的宽度由名字长度决定;画成火焰图,宽度就是采样占比。横轴不是时间——相邻两块并没有先后关系,把它从左往右当时间线读,是这类图第一号误读。又高又细的塔是一条几乎不花时间的深调用链,而它恰恰最先抓住眼睛。模板:templates/diagrams/flame-graph.svg。
templates/diagrams/queue-pressure.svg.
三个负载下的三条队列,下面那条曲线是第三格为什么长那样的原因。从 50% 忙到 80% 忙,等待变成四倍;从 80% 到 95%,在此之上再乘五倍。轴是线性的,体验不是——而这恰恰是只画队列说不出来的事。这条形状的前提是单服务台、随机到达,真实系统有突发,弯得更早——把它当坏消息的下限,别当估计值。模板:templates/diagrams/queue-pressure.svg。
Window skeletons are the highest-yield figures: a browser frame, a terminal, a phone. Real labels beat gray placeholder bars — give the mock one orange action and let everything else stay quiet. 窗口骨架是性价比最高的图:浏览器框、终端、手机框。真实文字标签比灰色占位条更可信——给 mock 一个橙色动作,其余保持安静。
A slide gets one idea per figure: a big number, a single highlighted bar, a roadmap with today marked. Charts default to soft blue; orange appears once, where you want the room to look. 一页幻灯片一个观点:大数字、单根高亮柱、标出"今天"的路线图。图表默认柔蓝;橙色只出现一次,落在你想让全场看的地方。
templates/diagrams/hierarchy.svg.
编排树:一个协调者,每类 worker 一个色相,icon tile 替代裸盒子。换掉标签就是一张组织架构图。模板:templates/diagrams/hierarchy.svg。
templates/diagrams/cheatsheet.svg.
十二个读者可能带着来的问题,每个指向回答它的那种图。这个形式的意义在它背后那道检验:把一张图截下来,发给一个没读过这个页面的人,看他能不能据此做事。大多数图过不了,因为页面一直在悄悄替它们提供四样东西——标题、一句话说它答什么、带日期的出处、以及边界。一张要自己出门的卡,这四样得自己带上。模板:templates/diagrams/cheatsheet.svg。