【linux内核专栏 09】内核模块与 kbuild
Linux 内核专栏 · 持续更新中本系列从底层原理到源码实战逐篇拆解内核机制。 想系统追更戳这里查看完整目录【Linux 内核专栏 00】总目录本篇定位:天天写驱动,驱动要么编进内核要么做成模块(.o)。模块是 Linux 区别于裸机的关键——运行时加载/卸载代码,不改内核重编重启。本篇把 LKM 机制、Makefile/Kconfig、模块加载流程、符号导出、参数、依赖讲透。读完能写独立 .ko、能看懂内核 Makefile、能调模块加载失败。模块是 Linux 动态扩展的根基,裸机没这能力FreeRTOS/裸机:加功能 改源码 重编 重烧重启。Linux:模块(.ko)运行时 insmod 加载,rmmod 卸载,不用重启。这是宏内核保持单体内核性能的同时获得类微内核扩展性的关键。BSP 写驱动,90% 做成模块(开发快,出问题 rmmod 即卸),稳定后可编进内核。一、内核模块(LKM)是什么1.1 模块的本质LKM 的本质就是把内核模块当成一个“运行时动态链接的 ELF 可重定位对象”由内核模块加载器完成解析、内存分配、符号绑定、重定位最后执行 module_init 并挂入内核模块链表。一个.ko文件(内核对象,kernel object)ELF 格式,包含:代码段(.text)、数据段、符号表、重定位信息运行时被内核动态链接进内核地址空间加载后和内核其他代码同等权限(S 态,可访问一切)1.2 模块 vs 编进内核方式怎么做何时用编进内核(y)make menuconfig 选CONFIG_XXXy,编译进 vmlinux核心/必用/早期要用(根文件系统驱动)模块(m)选CONFIG_XXXm,编成 .ko,运行时加载多数驱动,可后装/可卸/省启动内存不编(n)选CONFIG_XXXn不需要1.3 模块的生命周期源码(.c) → Kbuild 编译 → .ko → insmod/modprobe 加载 → 内核分配内存,重定位,链接符号 → 调 module_init → 模块活 → 使用 → rmmod 卸载 → 调 module_exit → 清理 → 释放内存1.4 对照裸机裸机/FreeRTOSLinux 模块加功能改源码重编重烧insmod .ko重启必须不用代码权限全权全权(S 态)卸载不能rmmod开发调试烧录慢加载快,迭代快模块让你 BSP 开发飞起来裸机改驱动要重编重烧,慢。Linux 写驱动做 .ko,insmod加载,出错rmmod卸载改了再加载——秒级迭代。稳定后再决定编进内核还是留模块。这是 Linux BSP 开发效率的核心来源。二、最简单的模块2.1 hello.c#includelinux/module.h#includelinux/init.hstaticint__inithello_init(void){printk(KERN_INFOHello, kernel module!\n);return0;// 0 成功,负数失败}staticvoid__exithello_exit(void){printk(KERN_INFOGoodbye, kernel module!\n);}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE(GPL);// 必须,否则内核警告/不能用 GPL 符号MODULE_AUTHOR(XXX);MODULE_DESCRIPTION(A simple hello module);MODULE_VERSION(1.0);2.2 关键点__init:标记初始化函数,加载完进.init.text,加载后释放(省内存)__exit:标记退出函数,只有 rmmod 时才调;若编进内核(y)则不编译(永远不卸载)module_init/module_exit:注册加载/卸载入口MODULE_LICENSE(GPL):必须,否则:① 内核警告 “tainted”;② 不能调EXPORT_SYMBOL_GPL的符号printk:内核打印(不是 printf),走 dmesg2.3 __init 的内存优化staticint__inithello_init(void){...}__init把函数放.init.text段模块加载完,.init段释放(初始化函数只调一次,留着浪费)编进内核的__init在启动后由free_initmem()释放只对加载时调一次的函数用,常驻函数不能标三、Makefile(kbuild)3.1 最简 Makefileobj-m hello.o all: make -C /lib/modules/$(shell uname -r)/build M$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M$(PWD) cleanobj-m:要编成模块的目标(m);obj-y编进内核-C .../build:进内核源码树(用它的 kbuild 系统)M$(PWD):模块源码在外部目录(外部模块)3.2 多文件模块obj-m mydriver.o mydriver-objs : main.o irq.o buffer.o # mydriver.ko 由三个文件组成3.3 kbuild 变量变量含义obj-m编成模块obj-y编进内核obj-n不编xxx-objs复合模块的组成文件ccflags-y额外编译选项3.4 编译流程make → 内核 Kbuild 系统 → hello.c → hello.o(GCC) → hello.o → hello.ko(链接 加 modpost 生成符号信息)3.5 内核内模块 vs 外部模块树内(in-tree)外部(out-of-tree)位置内核源码drivers/...任意目录Kconfig有无(自己写 Makefile)谁用内核官方驱动你 BSP 自研驱动编译make modulesmake -C 内核 M外部嵌入式视角:BSP 驱动通常先外部,后树内开发期:驱动放外部目录,insmod 迭代快。产品化:把驱动合进内核源码树(drivers/…),配 Kconfig/Makefile,编进 BSP SDK。这是 BSP 工作流:外部开发 → 树内合入。四、模块加载机制(insmod 内部)4.1 insmod 做了什么insmod hello.ko → 用户态 insmod 工具 → 读 hello.ko 到内存 → syscall init_module(mod_image, len, params) → 内核: 1. 校验 ELF 头/魔数 2. 分配模块内存(module 结构 代码/数据) 3. 重定位(把符号地址填进去) 4. 解决未定义符号(查内核符号表 已加载模块) 5. 调 module_init() 6. 挂到全局模块链表4.2 符号解析 simplify_symbols模块里的符号分几类:本地符号模块内部可见地址在本模块内解析全局定义符号模块自己导出的函数/变量未定义符号引用内核或其他模块导出的符号如 printk、kmalloc、request_irq导出符号通过 EXPORT_SYMBOL() / EXPORT_SYMBOL_GPL() 暴露给其他模块。内核遍历模块符号表对每个未定义符号在内核符号表 kallsyms 和已加载模块的导出符号表中查找。未定义符号解析失败 → 加载失败(Unknown symbol)看失败:dmesg或modinfo4.3 重定位 apply_relocations符号解析只是把符号名映射成地址重定位才是把地址真正填进代码里。内核遍历 .rela.* / .rel.* 重定位节对每个重定位项做locationtarget_section_baserela-r_offset;symbol_addrresolve_symbol(rela);*locationsymbol_addrrela-r_addend;// 简化理解具体怎么修改指令取决于架构x86_64R_X86_64_64、R_X86_64_PC32 等ARM64R_AARCH64_CALL26、R_AARCH64_ADR_PREL_PG_HI21 等RISC-VR_RISCV_32、R_RISCV_PCREL_HI20、R_RISCV_PCREL_LO12_I 等。这也是为什么 .ko 必须针对特定内核版本和架构编译跨版本/跨架构基本不可用。4.4 执行初始化 do_init_module重定位完成后内核调用模块的 module_init 函数staticint__initmy_driver_init(void){// 注册字符设备、platform driver、中断、GPIO、I2C/SPI 设备等return0;}module_init(my_driver_init);如果初始化失败内核会回滚释放内存、注销已注册资源、卸载模块。成功后模块状态置为 MODULE_STATE_LIVE挂入全局模块链表lsmod 就能看到。4.5 释放 init 段模块加载完成后.init.text / .init.data 不再需要内核会释放这部分内存。所以驱动里把只在加载时用到的代码标成 __init能节省内核内存。4.6 modprobe vs insmodinsmodmodprobe输入.ko 全路径模块名(自动找)依赖不处理自动装依赖配置无读 /etc/modprobe.d/用途调试/手动生产insmod /lib/modules/.../hello.ko# 直接加载modprobe hello# 自动找 装依赖modprobe-rhello# 卸载(含依赖)insmod 比较原始读取 .ko 二进制直接调用 init_module() 系统调用。modprobe 更智能先读 /lib/modules/$(uname -r)/modules.dep递归加载依赖模块再调用 insmod。现代内核还有 finit_module()可以传入文件描述符减少一次性拷贝整个 .ko 的开销。4.7 卸载(rmmod)rmmod hello# 卸载(模块没在用才能卸)lsmod# 看已加载模块模块被使用(如设备打开)→ 卸载失败卸载调module_exit,清理资源(注销设备/释放内存/解中断)module_exit 必须彻底清理,否则内存泄漏/资源占用rmmod / modprobe -r 调用 delete_module 系统调用检查引用计数若仍被使用则拒绝卸载调用 module_exit 函数释放中断、注销设备、free 内存从模块链表移除释放模块占用的内核内存。module_exit 要和 module_init 对称init 里注册了什么,exit 必须注销什么:注册设备→注销,申请中断→释放,申请内存→释放,申请资源→释放资源。你裸机没有卸载概念(代码一直在),Linux 模块能卸,卸载清理是必修课。漏清理 卸载后内核崩(悬挂指针)。4.8 自动加载机制嵌入式或桌面系统里模块不一定手动 insmod。常见自动加载路径udev / mdev 收到 uevent 后调用 modprobe内核 kmod 机制在需要时触发用户态 modprobe驱动通过 MODULE_DEVICE_TABLE() 声明支持的设备 IDudev 据此匹配模块。4.9 嵌入式 / 驱动开发侧的注意点在板子上做驱动或底层开发时LKM 有几个实际坑.ko 必须和板子内核版本、配置、架构完全匹配否则报 Invalid module format交叉编译时要使用目标内核的 Module.symvers 和 .config驱动里不能用 libc只能用 kmalloc/kfree、printk、devm_* 等内核接口初始化函数不能长时间阻塞硬件探测建议用 devm_ 系列做资源管理调试时优先看 dmesg / journalctl -k模块 Oops 往往直接暴露空指针、非法地址、未导出符号若开启 CONFIG_MODULE_SIG未签名模块会被拒绝加载。4.10 总结LKM 不是“把代码直接塞进内核”而是内核里跑了一套精简的动态链接器它读入 ELF .ko校验版本和签名用 vmalloc 分配内核内存通过 kallsyms 解析符号按架构规则应用重定位执行 module_init最后把模块挂入内核模块链表卸载时反向执行 module_exit 并释放资源。五、符号导出(EXPORT_SYMBOL)5.1 为什么需要导出模块 A 要调模块 B 的函数,或模块要调内核函数——必须导出才能被其他模块用。内核默认不导出所有符号(防模块乱用内部接口)。5.2 两种导出// 在提供符号的代码里voidmy_func(intx){...}EXPORT_SYMBOL(my_func);// 任何模块可用intmy_gpl_func(void){...}EXPORT_SYMBOL_GPL(my_gpl_func);// 只有 GPL 许可模块可用EXPORT_SYMBOL:任何许可模块可用EXPORT_SYMBOL_GPL:只有MODULE_LICENSE(GPL)的模块可用(防闭源白嫖)导出后符号进内核符号表(/proc/kallsyms)5.3 看符号cat/proc/kallsyms|grepmy_func# 00000000abcdef00 r my_func [hello] # 模块 hello 的符号cat/proc/kallsyms|grepprintk# ffffff8001234560 T printk # 内核符号5.4 模块间依赖模块 B 依赖模块 A 的符号 → 加载顺序:A 先,B 后 modprobe 自动处理(insmod 不处理,报 Unknown symbol) 卸载顺序:B 先,A 后(被依赖的不能先卸)EXPORT_SYMBOL 是模块间协作的接口BSP 把公用驱动(如平台驱动底座)的接口EXPORT_SYMBOL,上层驱动调。这是 Linux 模块化设计。注意 GPL 导出:你若用闭源模块,只能调EXPORT_SYMBOL(非 GPL)的符号。六、模块参数6.1 传参给模块#includelinux/moduleparam.hstaticintdebug0;module_param(debug,int,0644);// 参数名,类型,权限MODULE_PARM_DESC(debug,Enable debug (0/1));staticchar*namedefault;module_param(name,charp,0644);staticintports[4]{0};staticintnum_ports;module_param_array(ports,int,num_ports,0644);// 数组参数6.2 加载时传insmod hello.kodebug1nametestmodprobe hellodebug1nametest# 持久化(开机自动加载带参)echooptions hello debug1/etc/modprobe.d/hello.conf6.3 运行时改权限含 0220/0644 的参数,可在/sys/module/name/parameters/改:echo1/sys/module/hello/parameters/debugcat/sys/module/hello/parameters/debug6.4 对照 FreeRTOS 配置FreeRTOSLinux 模块配置编译宏模块参数改重编运行时改持久烧录/etc/modprobe.d嵌入式视角:模块参数替代编译宏FreeRTOS 调参要改 config 宏重编。Linux 模块参数运行时传,不改代码不重编。调试利器:加 debug1 打印详情,调好关掉。产品化用 modprobe.d 持久化。七、模块信息与工具7.1 modinfomodinfo hello.ko# filename: hello.ko# license: GPL# author: Zhaoyuhan# description: A simple hello module# version: 1.0# srcversion: ABC123...# depends:# vermagic: 6.6.0 SMP mod_unload modversions riscv64vermagic:版本魔术,模块编译时的内核版本/配置,必须和运行内核匹配,否则加载失败depends:依赖的其他模块7.2 常用工具工具作用lsmod列已加载模块(读 /proc/modules)insmod加载 .kormmod卸载modprobe智能加载(带依赖)modprobe -r智能卸载modinfo看 .ko 信息depmod生成模块依赖索引(modules.dep)7.3 /proc/modules 和 /sys/modulecat/proc/modules# hello 16384 0 - Live 0x... (O)ls/sys/module/# hello/ 里面有 parameters/ sections/ ...八、模块的版本检查8.1 vermagic模块编译时记录内核版本/SMP/抢占等配置,生成 vermagic加载时内核比对 vermagic,不匹配拒绝加载防用别的内核的模块导致崩8.2 强制加载(危险)insmod--forcehello.ko# 跳过 vermagic 检查极度危险(符号地址可能不对 → 崩)只在确认兼容时用8.3 CONFIG_MODVERSIONS开启后,每个导出符号有 CRC 校验模块记录用到的符号 CRC,加载时比对比 vermagic 更细(符号级)九、模块的依赖与 depmod9.1 depmod 生成索引depmod-a# 扫 /lib/modules/$(uname -r)/,生成 modules.depmodules.dep 记录模块→依赖映射modprobe 读它决定加载顺序9.2 模块依赖文件# /lib/modules/$(uname -r)/modules.dep /kernel/drivers/net/mydriver.ko: /kernel/drivers/net/mylib.komydriver 依赖 mylib,modprobe mydriver 会先装 mylib十、内核 Kconfig(配置系统)10.1 Kconfig 语法树内模块用 Kconfig 描述配置选项,menuconfig 里显示:# drivers/my/Kconfig config MY_DRIVER tristate My device driver depends on ARCH_RISCV help This is my device driver. M: module, Y: built-in, N: exclude.tristate:三态(y/m/n)depends on:依赖其他配置select:选中本项自动选某项help:帮助文本10.2 menuconfig 流程makemenuconfig# 进菜单# 选 MY_DRIVER mmake# 编内核makemodules_install# 装 .ko 到 /lib/modules/10.3 .configmenuconfig 的选择存.configCONFIG_MY_DRIVERm→ Makefile 读到obj-mCONFIG_MY_DRIVERy→obj-y10.4 BSP 的配置工作流1. 写驱动 .c 2. 加 Kconfig(配 tristate 选项) 3. 加 Makefile(obj-$(CONFIG_MY_DRIVER) my.o) 4. make menuconfig 选 m 5. make modules → my.ko 6. 部署 .ko,insmodKconfig/Makefile 是你 BSP 必会BSP 加驱动,要改三处:① 源码 .c;② Kconfig(让人能在 menuconfig 选);③ Makefile(告诉 kbuild 怎么编)。这是树内驱动标准流程,面试必问,实战必做。十一、模块开发调试技巧11.1 printk 分级printk(KERN_EMERGpanic 级\n);// 0 最高printk(KERN_ALERTalert\n);// 1printk(KERN_CRITcrit\n);// 2printk(KERN_ERRerror\n);// 3printk(KERN_WARNINGwarn\n);// 4printk(KERN_NOTICEnotice\n);// 5printk(KERN_INFOinfo\n);// 6printk(KERN_DEBUGdebug\n);// 7 最低控制台只显示 console_loglevel 的dmesg看全部调模块:printk(KERN_INFO xxx)dmesg | tail11.2 pr_xxx / dev_xxx(推荐)pr_info(hello\n);// printk(KERN_INFO ...)pr_err(fail: %d\n,ret);pr_debug(debug\n);// 默认不打印,开 DEBUG 才打dev_info(pdev-dev,probe ok\n);// 带设备信息dev_err(pdev-dev,probe fail\n);11.3 加载失败排查insmod my.ko# Failed: ...dmesg|tail# hello: Unknown symbol some_func# → some_func 没导出,或模块没写 GPL# vermagic 不匹配# hello: version magic 5.15.0 should be 6.6.0# → 模块和内核版本不符,重编11.4 模块崩溃模块崩 内核崩(模块在内核态)崩了看 oops(16 篇),addr2line 定位开发时开 lockdep/KASAN(07 篇)嵌入式视角:模块崩和你裸机崩一样你裸机崩 → 死机。Linux 模块崩 → 内核 oops(可能死可能活)。模块代码和内核同等权限,bug 会拖垮整个内核。所以模块要严谨:① 资源对称(init/exit);② 中断上下文不睡;③ 指针校验。你裸机的严谨习惯直接用。十二、DM(设备模型)与模块的关系模块是代码载体,设备模型(10 篇)是组织框架:模块(.ko) ──加载── 注册驱动到 bus ──probe── 绑定设备 ──rmmod── 检查设备是否在用 在用 → 拒绝卸载 没用 → remove → 卸载模块卸载前,内核检查模块是否被引用(设备在用 引用 0)引用计数由设备模型自动管(try_module_get/module_put)设备模型管模块引用计数你不用手动管模块被几个设备用——设备模型的try_module_get/module_put自动增减引用。模块卸载时引用 0,内核拒绝卸载,防悬挂。这是 10 篇设备模型对模块的保护。十三、对照总表概念FreeRTOS/裸机Linux 模块加功能改源码重编重烧insmod .ko运行时加载❌✅卸载❌rmmod代码权限全权全权(S 态)函数导出链接器自动EXPORT_SYMBOL配置参数编译宏module_param配置系统无Kconfig/menuconfig构建系统Makefile/IDEKbuild崩溃影响死机内核 oops/死迭代速度慢(烧录)快(insmod)十四、本篇小结模块(.ko):ELF,运行时动态链接进内核,insmod 加载/rmmod 卸载,免重启模块 vs 编进:m 模块(灵活)/y 编进(必需)/n 不编模块入口:module_init/module_exit,__init/__exit标记省内存MODULE_LICENSE(GPL)必须,否则不能用 GPL 符号Makefile:obj-m xxx.o,多文件用xxx-objs,-C 内核 M外部加载流程:insmod → init_module syscall → ELF 校验 → 重定位 → 符号解析 → module_initmodprobe比 insmod 智能(自动依赖),生产用 modprobeEXPORT_SYMBOL/EXPORT_SYMBOL_GPL:导出符号给其他模块用,GPL 导出只给 GPL 模块module_param:运行时配参,/sys/module/…/parameters/ 可改Kconfig:tristate/depends on/select,menuconfig 选,存 .configvermagic:版本魔术,模块和内核必须匹配(否则加载失败)module_exit 必须对称清理init 注册的资源模块崩 内核崩,严谨度同裸机速查表想干啥用什么写模块入口module_init(fn) module_exit(fn)标记 init/exit 省内存__init / __exit声明许可MODULE_LICENSE(“GPL”)编模块 Makefileobj-m hello.o多文件模块xxx-objs : a.o b.o加载模块insmod hello.ko / modprobe hello卸载rmmod hello / modprobe -r hello列已加载lsmod看模块信息modinfo hello.ko导出符号EXPORT_SYMBOL(fn) / EXPORT_SYMBOL_GPL(fn)看内核符号cat /proc/kallsyms | grep xxx模块参数module_param(name, type, perm)改运行时参数echo val /sys/module/xxx/parameters/name持久加载带参/etc/modprobe.d/xxx.conf 里 options加 Kconfigconfig XXX \n tristate “desc”加 Makefileobj-$(CONFIG_XXX) xxx.o看加载失败原因dmesg | tail打印pr_info/pr_err/dev_info✨ 感谢你的阅读 ✨技术之路漫漫分享是为了更好地交流。如果本文的内容对你有启发希望能得到你的支持 点赞|⭐ 收藏| 关注如果你在调试过程中遇到了其他问题欢迎在评论区 留言我们一起探讨。关注我一起交流底层开发的那些事儿

相关新闻

DeepSeek漫画分镜实战:故事转6格JSON提示词模板,AI分镜脚本生成教程

DeepSeek漫画分镜实战:故事转6格JSON提示词模板,AI分镜脚本生成教程

你是不是已经会用 DeepSeek 输出分镜 JSON 了,但给它一段故事,它拆出来的 6 格要么像流水账,要么每格都在重复同一个画面? 别慌,我前三次用 DeepSeek 拆分镜,拆出来的东西自己都不想画。 这篇就干一件事:给你一套完整的“故事→分镜”拆解流程,从故事梗概到 6 格 JSON,…

2026/10/15 3:54:44 阅读更多 →
8路CVBS/AHD合成一路视频无线传输系统评测

8路CVBS/AHD合成一路视频无线传输系统评测

8路CVBS/AHD合成一路视频无线传输系统评测 文章目录8路CVBS/AHD合成一路视频无线传输系统评测前言8路CVBS/AHD采集合成一路视频编码核心原理:一、8路CVBS/AHD视频采集发送端:二、视频接收解码显示端:三、系统拓扑结构:四、延时测试…

2026/10/15 3:54:44 阅读更多 →
双馈风力发电机Simulink建模与动态特性分析

双馈风力发电机Simulink建模与动态特性分析

1. 项目背景与核心价值双馈风力发电机作为现代风电场的主力机型,其动态特性直接影响电网稳定性和发电效率。我在某风电整机厂担任控制系统工程师期间,曾负责多个型号的双馈机组仿真平台开发工作。通过Simulink搭建高精度模型并分析其动态波形&#xff0c…

2026/10/15 3:54:44 阅读更多 →

最新新闻

R语言算术运算在医学数据分析中的核心应用与实战技巧

R语言算术运算在医学数据分析中的核心应用与实战技巧

刚接触R的时候,很多人的第一反应是:“这不就是一门统计编程语言吗?重点应该先学tidyverse、ggplot2、建模包吧?”但真正拿医学数据上手跑过几轮之后,你会发现一个很朴素的真相:所有复杂分析——从清洗数据、…

2026/10/15 5:35:21 阅读更多 →
AI写作的最后一公里:文档导出自动化链路拆解

AI写作的最后一公里:文档导出自动化链路拆解

最近一年我和不少做内容的朋友聊,大家几乎都有同一个感受:AI写东西越来越快,但把AI写完的内容变成一份能交付的正式文档,反而成了整个流程里最磨人的环节。这个“最后一公里”涉及文档导出、格式转换、排版规范,很多人…

2026/10/15 5:35:21 阅读更多 →
三维重建从“算一次”到“一直算”:持续计算技术实践与架构解析

三维重建从“算一次”到“一直算”:持续计算技术实践与架构解析

三维重建正在从「算一次」变成「一直算」这个标题我想了很久应该怎么写。主要原因是,最近我扎进了一个城市级三维重建项目里,发现连续加班的两周时间,几乎全部花在琢磨同一件事:为什么以前那套“先采数据、再离线重建、最后交付模…

2026/10/15 5:35:21 阅读更多 →
信息真空下的项目启动:从模糊代号到可交付物的实操框架

信息真空下的项目启动:从模糊代号到可交付物的实操框架

1. 当标题只剩三个字母:一次“信息真空”下的项目复盘拿到“rea”这个标题的时候,我第一反应是愣了一下。没有正文,没有关键词,没有摘要,连一句像样的描述都没有,就孤零零三个小写字母摆在那儿。这种输入条…

2026/10/15 5:35:21 阅读更多 →
DeepSeek深度思考过程导出指南:从手动复制到API自动归档推理链路

DeepSeek深度思考过程导出指南:从手动复制到API自动归档推理链路

在DeepSeek里想把包括深度思考过程的推理链路文字也导出到文件中,这个需求我太熟悉了。深度思考过程就是每次回答前那段默认折叠起来的灰色推理文字,比如“用户想要导出完整对话记录,需要先确认包含思考链路,然后设计导出方案………

2026/10/15 5:35:21 阅读更多 →
AI写论文指南:10款工具实测拆解任务,专治开题报告与毕业论文拖延

AI写论文指南:10款工具实测拆解任务,专治开题报告与毕业论文拖延

每年到论文季,我都会收到一堆专科生发来的私信,内容几乎一模一样:论文还没动,开题报告也一点头绪都没有,怎么办。说实话,这类问题我答过很多次,最后发现几乎所有拖延都有一个共同根源——不是懒…

2026/10/15 5:34:21 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →