当前位置: 首页 > news >正文

Linux内核驱动开发核心问题全解


📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry


Linux内核驱动开发核心问题全解

本文系统梳理了 Linux 驱动开发、内核同步、中断处理、内存管理、进程通信、系统启动等典型场景中的高频核心问题,涵盖中断上下文与进程上下文、下半部机制、锁与内存分配、网络通信、init 启动流程等内容,配以关键代码片段,适合工程实践参考。


在这里插入图片描述

一、中断与驱动开发

1. 中断上下文与进程上下文的区别

  • 中断上下文:由CPU响应外设信号进入,没有进程调度能力,不能休眠(不能 sleep / schedule),用于处理紧急、耗时短的操作。
  • 进程上下文:运行在内核线程或用户进程中,可以主动调度和休眠,适合处理复杂或耗时任务。

2. 中断下半部机制(tasklet、softirq、workqueue)

  • tasklet/softirq:在中断返回后、软中断上下文中调度执行,不能睡眠。
  • workqueue:由内核线程执行,可休眠,适合需要阻塞或耗时的操作。

示例:tasklet 调度下半部

void tasklet_handler(unsigned long data) {// 执行实际下半部工作
}
DECLARE_TASKLET(my_tasklet, tasklet_handler, 0);
irqreturn_t my_irq_handler(int irq, void *dev_id) {tasklet_schedule(&my_tasklet); // 调度下半部return IRQ_HANDLED;
}

3. request_irq 注册格式及参数

int request_irq(unsigned int irq, irq_handler_t handler,unsigned long flags, const char *name, void *dev);
  • irq:中断号
  • handler:中断服务函数,签名为 irqreturn_t func(int, void*)
  • flags:如 IRQF_SHARED
  • name:用于 /proc/interrupts
  • dev:设备标识

4. 中断处理流程

  • 硬件触发中断
  • 汇编入口 (arch/x86/entry/entry_64.S 等)
  • 通用分发 (kernel/irq/handle.c)
  • 调用驱动注册的 handler
  • 调度下半部(如 tasklet、napi、workqueue)

二、同步、锁与多核并发

5. 多核系统缓存一致性与内存屏障

  • 多核缓存一致性:依赖硬件协议(如 MESI),软件无需手动刷新缓存。
  • 内存屏障(如 mb()):用于保证CPU/编译器的内存操作顺序,防止乱序。

代码示例:内存屏障

#include <asm/barrier.h>
void sync_example(void) {a = 1;mb(); // 确保a的写操作对其他核可见b = 2;
}

6. 进程间共享内存同步与死锁防范

  • 共享内存不是线程安全,需加锁同步
  • 推荐 pthread_mutex_t,需 PTHREAD_PROCESS_SHARED 属性
  • 死锁风险:如进程异常退出未解锁,可用健壮互斥锁 PTHREAD_MUTEX_ROBUST

代码片段:进程间共享互斥锁

pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&shared->lock, &attr);
// 使用时加锁/解锁
pthread_mutex_lock(&shared->lock); // 临界区
pthread_mutex_unlock(&shared->lock);

7. 自旋锁与互斥锁适用场景

  • 自旋锁:适合内核临界区/中断上下文,不能睡眠
  • 互斥锁:适合进程/线程上下文,允许休眠

三、内存管理机制

8. kmalloc 与 vmalloc 的区别

对比项kmallocvmalloc
连续性物理+虚拟连续虚拟连续物理不连续
分配效率
适用场景小块/需DMA大块/无需DMA
分配器slab+buddy伙伴分配多个物理页

9. slab 与 buddy 分配器

  • slab:管理常用小对象缓存(如 kmalloc-32、kmalloc-64)
  • buddy:以页为单位(2^n),用于大块内存,支持拆分/合并

10. kmalloc(32) 和 kmalloc(4096) 行为差异

  • kmalloc(32):分配小对象,来自 slab 缓存池(如 kmalloc-32),实际为一页切片
  • kmalloc(4096):直接分配整页,调用 buddy 分配器

伪代码逻辑:

kmalloc(size)-> slab 分配(若 size 小于页)-> buddy 分配(若 size 大于等于页)

11. malloc、页表与物理内存关系

  • 应用层 malloc 在用户空间分配虚拟地址,由 glibc 切块
  • 真正物理内存分配由内核通过页表管理,内存页来自 buddy 分配器

四、进程通信与网络

12. 进程间通信方式

  • 管道(pipe, fifo)
  • 消息队列
  • 共享内存(shmget/shmat)
  • 信号量
  • 本地/网络 socket
  • 信号、文件锁等

13. TCP 与 UDP 的区别

对比项TCP(SOCK_STREAM)UDP(SOCK_DGRAM)
是否连接有连接无连接
可靠性可靠,顺序保证不可靠,可能丢包
速度
用途Web、SSH、文件传输DNS、直播、语音

14. socket() 返回值

  • 成功:返回文件描述符(>=0),不论 TCP 还是 UDP
  • 失败:返回 -1,需查 errno
  • 0/1/2 通常是标准输入/输出/错误

代码示例

int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) perror("socket error");

五、系统启动与 init 流程

15. init 进程的作用及根文件系统挂载

  • 内核挂载根文件系统(/)并启动 init 进程(如 /sbin/init, systemd, busybox init)
  • init 进程负责挂载 /proc、/sys、/dev 等虚拟文件系统,启动系统服务

真实内核片段:init 进程启动

// init/main.c (Linux 内核)
static const char * const init_paths[] = {"/sbin/init", "/etc/init", "/bin/init", "/bin/sh", NULL };
for (p = init_paths; *p; p++)if (!run_init_process(*p)) return 0;

结语

本文梳理了 Linux 驱动开发、同步机制、内存管理、通信协议、系统启动等多个核心环节及其典型代码实现,为深入理解与实践 Linux 内核提供参考。建议结合源码实际查阅、动手实验和知识串联,形成体系化认知。


📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry


http://www.lryc.cn/news/602687.html

相关文章:

  • Python全栈项目--基于深度学习的视频内容分析系统
  • 使用Docker在Rocky Linux 9.5上在线部署LangFlow
  • GoldenDB 分布式数据库详解
  • 在CentOS上以源码编译的方式安装PostgreSQL
  • <七> CentOS 8 安装最新版本Docker
  • 很妙的一道题 Leetcode234. 回文链表
  • 力扣 之 最小覆盖子串(变长滑动窗口,越短越好)
  • 电磁兼容五:仿真技术
  • Mac安装navicat17版本教程mac下载Navicat Premium for Mac v17.1.9【好用】
  • 微算法科技(NASDAQ:MLGO)利用基于区块链的机器学习模型进行交易分类,实现交易数据的匿名化
  • redis数据库的四种取得 shell方法
  • 安宝特案例丨户外通信机房施工革新:AR+作业流技术破解行业难题
  • 免费版酒店收银系统弹窗在押金原路退回流程中的应用价值探究 ——仙盟创梦IDE
  • 设计模式(二十一)行为型:状态模式详解
  • python生成 requirement.txt 文件
  • fchown/fchownat系统调用及示例
  • 技术总结|如何使用提升 strlen 的性能?
  • lesson26-2:使用Tkinter打造简易画图软件优化版
  • 数据链路层 和 ARP协议
  • MQTT的原理
  • 华为Huawei 6730交换机查看接口收发光命令 transceiver
  • 9.c语言常用算法
  • Anaconda创建环境报错:CondaHTTPEFTOT: HTTP 403 FORBIDDEN for url
  • Linux中配置haproxy
  • gitlab 在线合并分支a-分支b,解决冲突后,反向合并分支b-分支a
  • 数据结构——图(二、图的存储和基本操作)
  • 人机交互打字游戏
  • Leetcode——11. 盛最多水的容器
  • 力扣-39.组合总和
  • PhpStorm + PHP8.1 + XDebug3 实现断点调试(亲测可用)