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

Linux 字符设备驱动中 “主次设备号的静态 / 动态分配” 实验

这个实验是Linux 字符设备驱动中 “主次设备号的静态 / 动态分配” 实验,核心是验证 “手动指定设备号” 和 “内核自动分配设备号” 两种方式,步骤如下:

一、环境准备

和之前的信号量实验一致:

  1. 安装对应架构的交叉编译工具链(如aarch64-linux-gnu-)。
  2. 准备开发板对应的Linux 内核源码,记录其路径(后续MakefileKDIR需填写)。

二、代码准备

将实验代码保存为dev_t_test.c(代码与实验一致,仅补全注释):

#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/kdev_t.h> static int major; //静态分配时的主设备号 static int minor; //静态分配时的次设备号 //向模块传递参数(主/次设备号 权限为用户可读) module_param(major,int,S_IRUGO); module_param(minor,int,S_IRUGO); static dev_t dev_num; //存储设备号,主设备和从设备的组合 //驱动入口函数,分配设备号、 static int __init dev_t_init(void) { int ret; //情况1:手动传入了major参数 静态分配设备号 if(major){ dev_num = MKDEV(major,minor); printk("major is %d\n",major); printk("minor is %d\n",minor); //静态分配设备号 /*int register_chrdev_region(dev_t first, unsigned int count, \ char *name); 参数: 1. dev_t first: 起始的设备号,包括主设备号 (MAJOR,默认最大511) 和次设备号 (MINOR)。 2. unsigned count: 需要分配的连续设备号的数量。 3. const char *name: 注册的设备名称,用于用户态与内核交互时的设备识别。 返回值: - 返回 0 表示成功。 - 如果失败,返回一个负的错误码。 */ ret = register_chrdev_region(dev_num,1,"major_minor_name"); if(ret < 0){ printk("register_chrdev_region is error\n"); } printk("register_chrdev_region is ok\n"); } //情况2:未传入major参数 动态分配设备号 else{ //动态分配设备号,起始设备号为0 /* int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) 参数解析: 1. dev_t *dev: - 用于返回分配的设备号(包含主设备号和次设备号)。 - 主设备号通过自动分配的方式确定。 - 次设备号起始值通过 baseminor 指定。 2. unsigned baseminor: - 指定起始的次设备号。 3. unsigned count: - 要分配的连续设备号的数量。 4. const char *name: - 设备的名称,用于用户态和内核的设备识别。 返回值: - 返回 0 表示成功。 - 返回负数表示失败,失败值是一个错误码(通过 PTR_ERR 提供)。 */ ret = alloc_chrdev_region(&dev_num,0,1,"major_minor_name"); if(ret < 0){ printk("alloc_chrdev_region is error\n"); } printk("alloc_chrdev_region is ok\n"); major = MAJOR(dev_num); minor = MINOR(dev_num); printk("major is %d\n",major); printk("minor is %d\n",minor); } return 0; } //驱动出口函数,释放设备号 static void __exit dev_t_exit(void) { unregister_chrdev_region(dev_num,1); printk("guo module exit\n"); } module_init(dev_t_init);//注册入口函数 module_exit(dev_t_exit);//注册出口函数 MODULE_LICENSE("GPL v2");//遵循GPL协议

三、编写 Makefile(编译驱动模块)

创建Makefile文件(注意替换KDIR为你的内核源码路径):

makefile

# 1. 补充:导出ARM64架构(必须) export ARCH=arm64 # 2. 补充:用export导出交叉编译器(必须,子进程才能继承) export CROSS_COMPILE=/home/alientek/rk3568_linux5.10_sdk/buildroot/output/rockchip_atk_dlrk3568/host/bin/aarch64-buildroot-linux-gnu- # 内核源码目录(你的路径保持不变) KERNELDIR := /home/alientek/rk3568_linux5.10_sdk/kernel # 当前目录(你的定义保持不变) CURRENT_PATH := $(shell pwd) # 要编译的模块(你的定义保持不变) obj-m := dev_t_test.o # 目标定义(你的形式保持不变) build: kernel_modules kernel_modules: $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules clean: $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

四、编译驱动模块

dev_t_test.cMakefile所在目录执行:

make

编译完成后,会生成dev_t_test.ko(驱动模块文件)。

五、部署与测试(开发板上操作)

dev_t_test.ko传到开发板,然后分两种情况测试:

情况 1:静态分配设备号(手动指定 major/minor)

加载模块时直接传入主 / 次设备号(比如major=200,minor=0):

insmod dev_t_test.ko major=200 minor=0

执行dmesg查看输出,会显示:

plaintext

major is 200 minor is 0 register_chrdev_region is ok
情况 2:动态分配设备号(不指定参数)

直接加载模块,内核自动分配设备号: 如果手动分配主设备号20000失败

动态分配了3616

rmmod dev_t_test # 先卸载之前的模块 insmod dev_t_test.ko

执行dmesg查看输出,会显示内核分配的主 / 次设备号(比如):

plaintext

alloc_chrdev_region is ok major is 240 minor is 0

六、收尾

测试完成后,卸载驱动模块:

rmmod dev_t_test

http://www.gsyq.cn/news/183260.html

相关文章:

  • Java毕设项目:基于SpringBoot的房屋租赁系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • ThinkLink 正式上线 Docker 安装版本:快速部署的一体化 LoRaWAN 物联网平台
  • Pyenv管理多个Python版本?不如试试Miniconda-Python3.10专用环境
  • 科研团队协作首选:统一Miniconda-Python3.10环境杜绝差异
  • Conda与Pip混合使用指南|Miniconda-Python3.10环境下PyTorch安装策略
  • SCI检索号怎么看?
  • Java毕设选题推荐:基于Spring Boot与MySQL的二手车销售管理系统的设计与实现车源管理 - 评估定价 - 交易签约 - 售后跟踪【附源码、mysql、文档、调试+代码讲解+全bao等】
  • SSH连接Miniconda-Python3.10容器进行远程深度学习开发
  • 通信原理篇---常见的图像信源编码
  • APS1604M-SQR-ZR产品特点
  • 1111111
  • 通信原理篇---星座图
  • 设置推荐奖励机制实现老带新裂变增长
  • 1230日报
  • 自学Python做游戏有哪些注意事项
  • 怎么创建一个测试用例?
  • 对比不同Python发行版对大模型推理的影响
  • 2025最新云南环境影响评价报告品牌top5榜单公布,服务覆盖昆明/曲靖/文山/保山/昭通等地优质公司专业评测及选择指南,助力云南企业合规发展新征程 - 全局中转站
  • HTTP 和 TCP/IP的区别
  • 学长亲荐10个AI论文软件,助你搞定本科毕业论文!
  • 如何在云服务器部署Miniconda-Python3.10并安装PyTorch?
  • 【计算机毕业设计案例】基于java+springboot的高校网络设备管理系统基于SpringBoot的高校校园网故障管理系统(程序+文档+讲解+定制)
  • 使用Miniconda-Python3.10镜像快速验证GitHub开源项目
  • 录制视频教程补充图文内容,提升用户留存
  • 基础HTTP get接口测试
  • 上银滚珠丝杆生产厂家如何保障原厂正品?重负荷型号寿命多久?
  • 大模型训练前必做:配置稳定可靠的Miniconda环境
  • 10415_基于Springboot的停车场管理系统
  • CUDA安装总是出错?试试预配置Miniconda-Python3.10镜像
  • 使用弹窗或浮动按钮提示限时优惠活动