地址映射控制硬件/内核传参(4)
一、简介在单片机和裸机通过操作寄存器进而操作硬件但是在Linux上是不行的在Linux上如果想要操作硬件需要先把物理地址转换为虚拟地址因为Linux使能了MMU所以在linux上不能直接操作物理地址问题使能了MMU以后的好处1让虚拟地址成为了可能2可以让系统更加的安全因为有了MMU上层应用能看到的内存都是虚拟内存应用不能直接访问硬件所以保证了系统的安全问题MMU非常复杂那么我们如何完成物理地址到虚拟地址的转换呢内核提供的相关函数ioremap,iounmap二 相关函数2.1 ioremap/iounmap函数头文件#include asm/io.h函数原型void __iomem *ioremap(resource_size_t phys_addr, size_t size);函数作用建立映射,将一段物理地址(通常是外设寄存器空间)映射到内核的虚拟地址空间函数参数param1phys_addr: 要映射的起始物理地址param2size: 要映射的区域长度字节数返回值成功返回一个void __iomem *类型的内核虚拟地址指针。失败返回NULL。__iomem: 这是一个重要的代码空间标识用于提醒开发者和代码检查工具该指针指向的是“I/O内存”空间其访问行为可能与普通内存不同头文件#include asm/io.h函数原型void iounmap(volatile void __iomem *addr);函数作用解除映射释放由ioremap建立的映射防止内存泄漏和地址错误访问函数参数addr:ioremap返回的地址指针即要解除映射的虚拟地址起始位置返回值无注意物理地址只能被映射一次多次映射会失败问题如何查看哪些物理地址被映射过直接通过命令cat /proc/iomem 查看已经被映射的物理地址三、实践需求1.通过杂项设备完成一个LED的驱动2.完成一个上层测试应用应用要求在上层传如参数1为LED亮传入参数为0LED灭思路填充杂项设备的结构体文件操作集结构体、使用设备节点完成open,read,write函数驱动框架#include linux/module.h #include linux/init.h #include linux/miscdevice.h #include linux/fs.h #include linux/uaccess.h #include linux/io.h /*5.定义LED引脚的宏该宏对应LED引脚的物理地址需要通过地址映射为虚拟地址才可以操作*/ #define GPIO0_DR 0xFD060020 unsigned int *vir_gpio_dr; //定义一个指针变量用于保存映射后的虚拟地址 /*2.定义文件操作函数当在应用层使用open,close,read,write等函数时会在驱动层执行对应函数对应*/ static int misc_open(struct inode *inode, struct file *file){} static int misc_release(struct inode *inode, struct file *file){} static ssize_t misc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { /*当在应用层调用read函数时会执行当前函数*/ //char __user *buf:指向用户缓冲区的指针用于存放读取到的数据 //size_t count用户请求读取的字节数 char kbuf[64]嵌入式Linux驱动 printk(misc device is read:hello misc read\n); /*当用户层read时通过copy_to_user函数将kbuf中的内容拷贝到buf中从而实现驱动层向应用层传数据*/ if(copy_to_user(buf,kbuf,sizeof(kbuf))!0) { printk(misc device copy to user error\n); return -1; } return 0; } static ssize_t misc_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /*当在应用层执行write函数时驱动层会执行当前函数*/ //const char __user *buf:指向用户空间缓冲区的指针用户要写入的数据就存放在这里 //size_t count:用户层请求写入的字节数 char kbuf[64]{0}; /*通过copy_from_user函数将buf中的内容拷贝到kbuf中从而实现应用层向驱动层传数据*/ if(copy_from_user(kbuf,buf,count)!0) { printk(misc device copy from user error\n); return -1; } /*6*得到映射后的地址后可以对地址的位进行|、|操作*/ if(kbuf[0]1) *vir_gpio_dr |(17); else if(kbuf[0]0) *vir_gpio_dr ~(17); printk(misc device is write:hello misc write\n); return 0; } /*3.填充struct file_operations结构体*/ struct file_operations xxx_fops { //该结构体里面包含了在驱动层里面定义的open,close,read,write函数 .owner THIS_MODULE, //固定写法 .open .release .read .write } /*4.填充杂项设备结构体*/ struct miscdevice misc_dev { .minor MISC_DYNAMIC_MINOR, //自动分配次设备号 .name hello_misc, //定义自己的杂项设备节点名称 .fops misc_fops //设备操作函数集合 }; /*1.定义模块加载函数与模块卸载函数*/ static int misc_init(void) { //加载模块时会执行该函数 int ret; ret misc_register(misc_dev); //注册杂项设备 if(ret0) { printk(misc device is register error\n); return -1; } vir_gpio_dr ioremap(GPIO0_DR,4); //映射寄存器虚拟地址 if(vir_gpio_dr NULL) { printk(ioremap failed\n); return -EBUSY; } printk(ioremap succeed\n); return 0; } static void misc_exit(void) { //卸载函数时会执行该函数 misc_deregister(misc_dev); //注销杂项设备 iounmap(vir_gpio_dr); //取消映射 } module_init(misc_init);//模块加载函数 module_exit(misc_exit);//模块卸载函数 MODULE_LICENSE(GPL);应用层框架#include stdio.h #include fcntl.h #include unistd.h #include sys/stat.h #include sys/types.h #include stdlib.h int main(int argc, char *argv[]) { int fd; char buf[64]{0}; /*当执行open函数时会执行驱动层对应open函数*/ fd open(/dev/hello_misc, O_RDWR); //打开驱动对应的设备文件 if(fd 0) { printf(misc device open failed\n); return -1; } printf(app layer device open success\n); /*当执行write函数时会执行驱动层对应write函数*/ buf[0]atoi(argv[1]); write(fd,buf,sizeof(buf)); printf(app layer write data : %s\n,buf); /*当执行close函数时会执行驱动层对应release函数*/ close(fd); return 0; }四、内核传参Linux 内核提供了 module_param(name, type, perm)、 module_param_array(name, type, nump, perm)宏和 module_param_string(name, string, len, perm)宏 分别进行基本类型、 数组和字符串参数的传递。头文件 #includelinux/module.h名称module_param(name, type, perm)功能将模块的全局变量声明为可加载参数允许在加载模块时通过命令行指定参数值参数:name全局变量名type参数类型int, bool, charp等permsysfs文件系统的访问权限如06440表示不在sysfs中创建文件参数读写权限头文件 #includelinux/module.h名称 module_param_array(name, type, nump, perm)功能将模块的数组类型全局变量声明为可加载参数允许在加载模块时通过命令行指定多个参数值参数:name数组变量名type数组元素类型int, bool, charp等nump指向整数变量的指针用于记录实际传入的数组元素个数方向由该函数内到外permsysfs文件系统的访问权限如06440表示不在sysfs中创建文件参数读写权限头文件 #includelinux/module.h名称module_param_string(name, string, len, perm功能将模块的字符串类型全局变量声明为可加载参数允许在加载模块时通过命令行指定字符串值参数:name参数名称在命令行中使用的名称type字符数组变量名程序中定义的len字符串缓冲区的最大长度permsysfs文件系统的访问权限如06440表示不在sysfs中创建文件参数读写权限问题什么是驱动传参就是传递参数给我们的驱动eg:insmod LED.ko a1问题驱动传参有什么作用1设置驱动的相关参数比如设置缓冲区的大小2设置安全校验防止写的驱动被盗用问题怎么给驱动传参数1传递普通的参数比如char,int类型使用module_param(name, type, perm)函数2传递数组使用module_param_array函数3传递字符串module_param_string(name, string, len, perm)#include linux/init.h #include linux/module.h static int a; static int arr[10]; static char para[10]; static int num; module_param(a,int,0644); module_param_array(arr,int,num,0644); module_param_string(hehe, para, sizeof(para), 0644); static int param_init(void) { int i; printk(param init insmod succeed!\n); for(i0;inum;i) { printk(arr[%d]%d\n,i,arr[i]); } printk(para%s\n,para); return 0; } static void param_exit(void) { printk(param exit rmmod succeed!\n); } module_init(param_init); module_exit(param_exit); MODULE_LICENSE(GPL);问题若是多传进去参数导致数组越界会发生什么会发生错误加载不成功

相关新闻

毕业生福利!2026年高口碑AI论文网站推荐,助力高效写作

毕业生福利!2026年高口碑AI论文网站推荐,助力高效写作

还在为写论文发愁?实用AI论文写作工具来了! 还在为写期刊论文、毕业论文或者职称论文发愁吗?用传统方法写论文的时候,要查好多资料,找文献就像大海捞针一样,格式要求复杂得让人头疼,还得反复修…

2026/8/22 14:02:42 阅读更多 →
HumanInput性能优化指南:单实例架构、零开销状态追踪与5个省电设置清单

HumanInput性能优化指南:单实例架构、零开销状态追踪与5个省电设置清单

HumanInput性能优化指南:单实例架构、零开销状态追踪与5个省电设置清单 【免费下载链接】HumanInput A JavaScript library for handling keyboard shortcuts and other human-generated events 项目地址: https://gitcode.com/gh_mirrors/hu/HumanInput Hum…

2026/8/22 14:02:42 阅读更多 →
Pygame Zero开发环境搭建:pgzrun.go()的IDE模式、flake8内置名配置与5个实用技巧

Pygame Zero开发环境搭建:pgzrun.go()的IDE模式、flake8内置名配置与5个实用技巧

Pygame Zero开发环境搭建:pgzrun.go()的IDE模式、flake8内置名配置与5个实用技巧 【免费下载链接】pgzero A zero-boilerplate games programming framework for Python 3, based on Pygame. 项目地址: https://gitcode.com/gh_mirrors/pg/pgzero Pygame Zer…

2026/8/22 14:02:41 阅读更多 →

最新新闻

如何系统掌握高级数据结构?AlgorithmsAndDataStructuresInAction官方代码库入门指南

如何系统掌握高级数据结构?AlgorithmsAndDataStructuresInAction官方代码库入门指南

如何系统掌握高级数据结构?AlgorithmsAndDataStructuresInAction官方代码库入门指南 【免费下载链接】AlgorithmsAndDataStructuresInAction Advanced Data Structures Implementation 项目地址: https://gitcode.com/gh_mirrors/al/AlgorithmsAndDataStructuresI…

2026/8/22 15:26:20 阅读更多 →
Apktool 反编译后多出的 apktool.yml,到底该不该改?

Apktool 反编译后多出的 apktool.yml,到底该不该改?

Apktool 反编译后多出的 apktool.yml,到底该不该改? 【免费下载链接】Apktool A tool for reverse engineering Android apk files 项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool 当你第一次执行 apktool d app.apk,反编…

2026/8/22 15:26:20 阅读更多 →
OpenBoardView 新手完整指南:用免费开源 PCB 查看器快速打开 .brd 文件

OpenBoardView 新手完整指南:用免费开源 PCB 查看器快速打开 .brd 文件

OpenBoardView 新手完整指南:用免费开源 PCB 查看器快速打开 .brd 文件 【免费下载链接】OpenBoardView View .brd files 项目地址: https://gitcode.com/gh_mirrors/op/OpenBoardView OpenBoardView 是一款免费开源的 PCB 文件查看器,用于打开并…

2026/8/22 15:26:20 阅读更多 →
136、洞察驱动的实战标题——色彩校正的“矩阵玄机“——3x3 vs 3x4 vs 3D-LUT的场景选择,以及如何用灰阶卡+肤色卡标定矩阵

136、洞察驱动的实战标题——色彩校正的“矩阵玄机“——3x3 vs 3x4 vs 3D-LUT的场景选择,以及如何用灰阶卡+肤色卡标定矩阵

136、洞察驱动的实战标题——色彩校正的"矩阵玄机"——3x3 vs 3x4 vs 3D-LUT的场景选择,以及如何用灰阶卡+肤色卡标定矩阵 上周三晚上十一点,产线那边打来电话,说某款车载环视摄像头在傍晚时分拍出来的天空偏紫,柏油路面发绿。我第一反应是白平衡漂了,但看了lo…

2026/8/22 15:26:20 阅读更多 →
137、洞察驱动的实战标题——锐化的“overshoot检测“——如何用边缘梯度方向直方图自动识别过度锐化产生的白边/黑边,并自适应抑制

137、洞察驱动的实战标题——锐化的“overshoot检测“——如何用边缘梯度方向直方图自动识别过度锐化产生的白边/黑边,并自适应抑制

137、洞察驱动的实战标题——锐化的"overshoot检测"——如何用边缘梯度方向直方图自动识别过度锐化产生的白边/黑边,并自适应抑制 上周在调试一款车载前视相机的夜间模式时,客户反馈路牌边缘出现“发毛”现象——白字边缘外侧有一圈亮线,内侧又压出一道暗痕。我盯…

2026/8/22 15:26:20 阅读更多 →
从零到跑通仅需5分钟:mdc-maui快速入门教程,搭建你的第一个Material Design界面

从零到跑通仅需5分钟:mdc-maui快速入门教程,搭建你的第一个Material Design界面

从零到跑通仅需5分钟:mdc-maui快速入门教程,搭建你的第一个Material Design界面 【免费下载链接】mdc-maui Material design components for .NET MAUI 项目地址: https://gitcode.com/gh_mirrors/md/mdc-maui mdc-maui(Material.Comp…

2026/8/22 15:25:20 阅读更多 →

日新闻

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

沉金PCB工艺实战指南:从设计到SMT焊接的可靠性保障

在电子硬件开发领域,PCB(印制电路板)的沉金工艺是提升产品可靠性和焊接质量的关键环节。对于需要高密度互连、长期稳定运行或高频信号传输的板卡,如“黍姐仿通行证”这类可能涉及身份识别、数据交互的硬件项目,选择正确…

2026/8/22 0:00:11 阅读更多 →
电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

电气考研电路八月强化四步法:从知识体系到真题实战的闭环攻略

这次我们来看一个针对电气考研电路科目的学习规划项目。它不是软件工具,而是一套聚焦于8月份关键节点的备考策略。对于电气工程考研的同学来说,电路分析是专业课的重中之重,也是拉开分差的关键。进入8月,复习进入强化阶段&#xf…

2026/8/22 0:00:11 阅读更多 →
消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

消除AI代码的“AI味”:Claude Code设计优化技能配置与实战指南

大家好,我是专注于前端开发与AI工具实践的技术博主。在日常使用 Claude Code 等AI编程助手时,你是否也遇到过这样的困扰:生成的代码功能上没问题,但代码风格、组件设计、交互逻辑总透着一股“AI味”——布局单调、样式简陋、交互生…

2026/8/22 0:00:11 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/21 3:21:33 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/22 8:09:09 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/21 6:07:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/21 16:42:28 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/22 7:31:03 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →