这行不好学,往往不是因为难,是因为不知道从哪一层下手。从应用到底层跨度比 MCU 大一个数量级。我把它切成四层,每层给一个能验证的出口。
这一层不涉及内核,但它是后面所有层的地基。跳过它直接学驱动的人,写出来的驱动没人用得顺手。
必须掌握:文件 IO(open / read / write / ioctl / mmap)、进程与线程(fork / pthread)、进程间通信(管道、消息队列、共享内存、信号)、socket 编程(TCP / UDP / unix domain)、信号处理。
工程能力:Makefile 与 CMake、gdb 调试(断点、backtrace、attach 到运行中进程)、valgrind 查内存、strace 看系统调用、top / ps 定位 CPU 占用。
验收:写一个多线程的串口采集程序,支持热插拔、断线重连、日志轮转,并能在 gdb 里定位一次真实的内存泄漏。
这一层决定你做的是 demo 还是产品。核心是把「阻塞」和「并发」这两件事彻底想清楚。
必须掌握:select / poll / epoll 的区别与适用场景、非阻塞 IO、信号的安全用法(async-signal-safe 函数)、mmap 共享内存与文件映射、线程同步(互斥量、条件变量、读写锁)、原子操作。
性能相关:零拷贝(sendfile、splice)、CPU 亲和性、实时调度策略(SCHED_FIFO)、优先级与 nice、内存分配器行为。
验收:写一个单进程处理 200 路并发连接的服务,CPU 占用稳定,压测 24 小时不崩、内存不涨。
提示:「内存不涨」比「不崩」难得多。泄漏往往出在错误分支和超时路径上。
从这一层开始,你的错误会让整台机器挂掉,而不是一个进程崩掉。心态要从「调试」切换到「预防」。
必须掌握:模块的编译与加载(Kbuild、insmod / rmmod、模块参数)、字符设备(cdev + file_operations + 自动建节点)、proc / sysfs 接口、内核内存分配(kmalloc / vmalloc / GFP 标志)、并发与竞态(spinlock、mutex、原子变量、RCU 的适用场景)。
设备模型:platform 总线与 platform_driver、设备树匹配(compatible / of_match_table)、pinctrl、regulator、clk 框架。
中断与 DMA:request_irq 的触发方式与共享标志、中断上半部 / 下半部(tasklet、工作队列、线程化中断)、DMA 引擎与一致性内存。
验收:给一个真实传感器写 platform 驱动,走设备树配置,用 IIO 或 input 子系统上报数据,能通过 rmmod / insmod 循环 100 次不泄漏。
这一层的工作听起来杂,但它是「一个人能独立 bring-up 一块板」的能力,也是薪资差别最大的地方。
Bootloader:U-Boot 的启动流程、SPL / TPL、环境变量与分区、从多种介质启动(eMMC / SD / NFS / USB)、fastboot 与量产烧录。
内核:配置与裁剪(defconfig、menuconfig)、移植(board 目录、dts、驱动使能)、内核命令行、initramfs。
根文件系统:BusyBox 构建、库裁剪、只读根 + overlay、分区布局、掉电保护。
产品化:启动时间优化(从 uboot 到应用起来的每一段都要量)、双分区 OTA、看门狗与复位原因记录、量产测试模式。
验收:拿一块空板,从零把它 bring-up 起来:串口有输出、能进 U-Boot、能起内核、能挂根文件系统、应用自启、断电 200 次能正常恢复。
做到 LAYER 4 一定会被要求「开机再快两秒」。先按阶段打点,别凭感觉改。下表的耗时取自常见的 ARM 板子,你的板子会不一样。
| 阶段 | 常见耗时 | 怎么量 | 能省的地方 |
|---|---|---|---|
| ROM → SPL | 50 – 200 ms | 串口打点、GPIO 翻转后示波器看 | 关调试串口、缩短 DDR 训练、减少完整性校验范围 |
| SPL → U-Boot | 200 – 500 ms | U-Boot 的 bootstage | 关掉用不上的驱动、环境变量读进内存、跳过 USB 枚举 |
| U-Boot → 内核 | 100 – 400 ms | bootstage + 内核 early printk | 精简 initcall、关未用子系统、镜像压缩换 lz4 |
| 内核 → init | 0.5 – 3 s | initcall_debug、printk 时间戳 | 去掉 probe 里的延时、驱动改异步 probe、少等电源稳定 |
| init → 应用起来 | 0.2 – 2 s | systemd-analyze 或自己打点 | 少跑 shell 脚本、把必须的初始化挪进应用里并行做 |
留言 / 提问
写你卡住的地方:什么芯片、什么现象、已经试过什么。频率高的问题我会写进页面。昵称不填也能发。