【嵌入式Linux内核驱动】内核模块三要素与验证测试

嵌入式Linux内核模块开发实战:从Hello World到硬件驱动 内核模块是Linux内核的核心扩展机制,它允许在不重启系统或重新编译整个内核的情况下,动态地添加或移除功能。其工作原理在于,模块作为独立的可加载对象,通过预定义的接口与内核核心进行交互,从而扩展内核的功能或添加新的硬件驱动。这一机制的技术价值在于极大地提升了系统的灵活性和可维护性,使得硬件支持、文件系统、网络协议等功能的增删变得高效且风险可控。在嵌入式系统开发,尤其是基于特定SoC(如瑞萨RZ/G2L)的工业应用中,内核模块技术是实现深度硬件定制和功能迭代的关键。开发者通过掌握交叉编译、设备树配置和模块签名 阅读详情

内核模块

Linux内核模块是一种可以动态加载和卸载的软件组件,用于扩展Linux操作系统的功能。Linux内核本身只包含了必要的核心功能,而内核模块则允许开发者在运行时向内核添加新的功能、驱动程序或文件系统支持,而无需重新编译整个内核或重新启动系统。

内核模块是一段独立的代码,可以被编译为共享目标文件,并且遵循Linux内核的特定接口和标准。它们可以通过加载器(如insmod或modprobe)动态地插入到内核中,并通过卸载器(如rmmod)从内核中移除。一旦加载到内核中,模块可以访问和修改内核的数据结构、函数和服务,以提供额外的功能或驱动支持。

内核模块在许多方面都非常有用。它们使得开发者可以通过加载适当的模块来添加硬件设备的支持,如网卡、声卡等。此外,内核模块还可以添加新的文件系统支持,以便访问特定的文件系统类型。开发者还可以使用内核模块扩展内核的功能,添加新的系统调用、网络协议或安全功能等。

使用内核模块的好处是可以减小内核的大小,并允许系统仅加载需要的模块,从而提高系统的性能和灵活性。内核模块也可以动态加载和卸载,使得系统可以根据需要动态地添加或删除功能,而无需重新启动。

NFS挂载

bootargs启动参数设置

  • root=/dev/nfs #指定rootfs所在的设备是NFS,也就是从NFS启动

  • nfsroot=192.168.9.119:/nfs/rootfs #指定nfs rootfs的位置 (是在ip 是192.168.9.119的机器上 的/nfs/rootfs目录下).

    ​ 注意/nfs/rootfs必须和前面NFS服务配置文件设置一致(见环境安装)

  • v3 #ubuntu 20.04,nfs版本的问题需在bootargs 里加v3

  • console=ttyS0,115200 #指定内核启动后串口信息从串口0输出,波特率115200

  • init=/linuxrc #指定第一个应用程序

  • ip=192.168.9.9 #需设置为板子u-boot自己的IP(通过pri ipaddr查看)


  • ext4load mmc 1:1 0x84000000 /boot/Image //读ext 文件系统中的 /boot/Image 到内存 0x84000000

    ​ //这个镜像是烧录在TF卡上的官方镜像

    ​ //fstype mmc 1:1 //查看emmc设备(flash) 1号设备的1号分区

  • ext4load mmc 1:1 83100000 /boot/tegra210-p3448-0002-p3449-0000-b00.dtb //和上面一个道理

  • booti 0x84000000 - 83100000 /*启动Image格式的内核 booti,

    引导ARM64 kernel image----Image; bootz,

    引导ARM kernel image----zImage; bootm,

    引导u-boot自定义的kernel image----uImage。

# setenv bootargs  root=/dev/nfs rw nfsroot=192.168.9.119:/nfs/rootfs,v3 console=ttyS0,115200 init=/linuxrc ip=192.168.9.9
# setenv nfsboot ext4load mmc 1:1 0x84000000 /boot/Image \; ext4load mmc 1:1 83100000 /boot/tegra210-p3448-0002-p3449-0000-b00.dtb \; booti 0x84000000 - 83100000
# pri bootcmd /*备份原来的,方便恢复
   bootcmd=run distro_bootcmd
    */
# set bootcmd run nfsboot  
# saveenv
# run nfsboot  //能nfs挂载成功	

内核三要素

  • module_init(led_init); //模块加载入口声明
  • module_exit(led_exit); //模块卸载入口声明
  • MODULE_LICENSE(“GPL”); //模块免费开源声明
//led.c
#include <linux/kernel.h>
#include <linux/module.h>

static int led_init(void)
{
    printk("led init yhai 1\n");
    return 0;
}

static void led_exit(void)
{
    printk("led exit\n");
}

module_init(led_init); //模块加载入口声明
module_exit(led_exit); //模块卸载入口声明
MODULE_LICENSE("GPL"); //模块免费开源声明
MODULE_AUTHOR("bbcen"); //模块作者声明(可选)

Makefile

  • KERNELDIR ?= ~/linux 第二行这里的目录要选一个已经编译过的内核目录
  • obj-m := led.o 这里的.o文件名要和.c的文件名一样
//Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= ~/linux 
PWD := $(shell pwd)

all:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules* a.out 

else
    obj-m := led.o
endif

验证测试

SourceInsight编辑代码,cp到nfs目录编译生成ko文件插入内核

  • make的时候不要在共享文件夹,会报错,可以直接复制到nfs共享目录下编译
$ make              //编译生成 模块文件 led.ko
$ file led.ko       //查看一下格式,看编译的是 电脑的, 还是板子的(ARM)

# insmod led.ko     /*加载模块 
提示: loading out-of-tree module taints kernel    -> 提示内核污染,出问题时你自己驱动的问题,不是内核的问题。方便内核开放者排查 
可添加   MODULE_INFO(intree, "Y"); 去除提示,但最好别这样做                
                     */
# lsmod  /*查看已加载模块列表 -> 检测是否已加载
		等效于 cat /proc/modules
     */
# rmmod  led         //卸载模块     
  
# dmesg      //查看内核日志
Linux内核中Lockdep死锁检测 死锁的检测以及使用锁存在的问题。通过两个实例分析循环锁和AB-BA锁异常的检测。 阅读详情

相关推荐

深入了解Linux内核编译与管理

电脑真正在工作的东西其实是 “硬件”,例如数值运算要使用到CPU、储存资料要用到硬盘、图形显示要用到显卡、音频需要声卡、连接Internet需要网卡等等。那么如何控制这些硬件呢?那就是内核的工作了。你想让计算机进行的工作,都必须要内核支持才行,这个标准不论是LInux还是Windows都一样。其实内核就是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的检测程序与驱动模块。在开机流程分析中,这个文件被读入主存储器的时机,当系统读完BIOS并加载MBR内的引导装载程序后,就能够加载内核到内存当中。

m0_74282605的博客 935

浏览器内核检测(Trident,Gecko,WebKit,Blink)

浏览器内核的种类很多,如加上没什么人使用的非商业的免费内核,可能会有 10 多种,但是常见的浏览器内核可以分这四种:Trident、Gecko、Blink、Webkit。 网站地址:http://mybrowse.osfipin.com (我的浏览器)不是根据浏览器的请求头(user-agent)判断浏览器的内核,版本和相关的功能。适应移动端和PC端显示。 一些浏览器的截图

osfipin note 1万+

从内核模块到用户空间:深入解析Linux USB串口驱动的加载与udev规则定制

本文深入解析Linux USB串口驱动的加载与udev规则定制,涵盖CH341驱动编译、内核模块加载、udev设备管理及权限配置。通过详细的调试步骤和Python测试代码,帮助开发者解决串口通讯中的常见问题,实现稳定的设备访问和自动化管理。

v6b7n8m9q0的博客 1206

浏览器内核版本检测 (用于排查问题)

https://www.index0.cn/core/ 或者 https://liulanmi.com/labs/core.html (谷歌浏览器)以上是检测出浏览器版本内核图片 复制粘贴到浏览器即可查看相关版本。

CharisJIM的博客 4504

树莓派5内核模块编译与加载操作指南

深入讲解树莓派5环境下如何交叉编译并加载内核模块,涵盖环境搭建、配置匹配与实机操作步骤,帮助开发者高效完成树莓派5的底层功能扩展与驱动开发。

weixin_42497762的博客 1104

ARM平台XDMA驱动编译实战:从源码到内核模块

本文详细介绍了在ARM平台上编译XDMA驱动的完整流程,从环境准备、源码获取到Makefile修改、交叉编译配置,再到模块验证与部署。特别针对ARM架构(如RK3588)的编译难点提供了实用解决方案,包括内核头文件路径配置、交叉编译工具链设置等关键技巧,帮助开发者高效完成驱动编译工作。

weixin_30776273的博客 1229

Linux驱动开发 2 - 从零实现内核模块

本文介绍如何创建一个简单的Linux字符设备驱动,并提供了一个完整的misc设备驱动示例

u014034516的博客 1018

玩转Android10源码开发定制(六)修改内核源码绕过反调试检测

一、Android反调试 反调试在代码保护中扮演着非常重要的角色,虽然不能完全阻止攻击者,但是能加大攻击者的分析时间成本。目前绝大多数Android app都加固了,为了防止App被调试分析,加固功能中添加了各种反调试功能,比如:自己ptrace自己、检查函数执行时间、读取/proc/$pid/wchan或者/proc/$pid/task/$pid/wchan文件信息判断调试状态、读取/proc/$pid/stat或者/proc/$pid/task/$pid/stat文件信息判断调试状态、读取/...

xiaomaNo01的专栏 1584

嵌入式linux系统交叉编译内核驱动模块笔记,以一个完全的新手姿势记录

序言 最近终于成功的在自己的手中将一个hello的内核模块成功的编译并加载进自己的嵌入式linux系统,教程翻了无数篇,果然理论的了解和实际上的知道怎么做之间,还存在着很大的差距。。鉴于在查找资料中看到不少的教程中都存在着部分知识缺失的问题,总的来说就是:“我觉得某些东西太过简单我没有必要再讲”,而这一部分又直接导致我一个萌新给完全的给看懵了,因此在这里写一下自己的笔记,着重讲一些当时自己走了弯路的地方。 准备工作 为了能够交叉编译内核驱动,首先你需要: 你的对应的硬件平台的内核源码 对应硬件平台的交叉编

wmdscjhdpy的博客 2939

autoDL算力云装Xinference[坑与步骤]

在页面直接点击下载会出现下着下载进度条消失,试了几次才出现这个报错,现在我们就继续安装缺少的包吧。这一步成功绕开了系统盘空间限制。先租用一个合适的服务器,建议不要选最新版本,跟我选的一样即可,不然后面会出现。最近在 AutoDL 上尝试部署。🚫 不要直接使用以下命令。点击下面链接即可打开。

ngadminq的博客 2382

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图 画好后效果图 实现代码如下 import matplotlib.pyplot as plt #算法平均排名 _alg_=[1.405,2.643,2.786,2.167] y=[1,2,3,4]#alg1,alg2,alg3,alg4 通过Nemenyi测试计算得到的临界值CD CD=1.024 h_CD=CD/2 plt.figure(figsize=(10,6)) plt.scatter(_alg_,y,s=10

大模型天花板 4464

【嵌入式Linux内核驱动】01_内核模块

嵌入式Linux内核驱动基础 内核模块 基于Nvidia jetson nano

Hi 612

语义分割(Semantic Segmentation)近年发展综述

目标:为图像中每个像素分配一个语义类别标签(如“道路”、“行人”、“天空”),不区分同类实例。关键挑战精确边界恢复(高空间分辨率)全局上下文理解(大感受野)计算效率与精度平衡小样本/弱监督泛化语义分割的十年演进,是一条从专用→通用、封闭→开放、慢速→实时、像素→语义2015:FCN/U-Net 奠基;2018:DeepLabv3+/PSPNet 实现高精度;2020:HRNet+OCR 登顶竞赛;2021:SegFormer 开启 Transformer 新纪元;2023+

浩瀚之水的专栏 976

【Linux 驱动开发】二. linux内核模块

本文概括Linux驱动从需求、原理图到内核框架的全流程,梳理Source Insight创建与同步技巧,解析LED硬件电路与GPIO寄存器映射,并给出字符设备模块编写、编译、加载及参数传递、设备节点创建等步骤,助你快速落地驱动开发实践。

猫猫的小茶馆 760

RK3588与FocalTech触摸屏代码适配全解析:从原理到实战

摘要:本文详细介绍了瑞芯微RK3588处理器与FocalTech触摸屏的适配过程,包括硬件特性、驱动加载、设备树配置和常见问题解决方案。RK3588作为8nm工艺的高性能处理器,具备强大的计算能力和丰富的接口资源;FocalTech触摸屏则采用电容式技术,支持I2C/SPI接口。适配关键步骤包括驱动程序加载、硬件连接检查、设备树配置和内核版本兼容性处理,并提供了代码示例和问题排查方法。随着嵌入式设备智能化发展,该适配技术将持续优化,为智能交互提供更优解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 272

智能小车避障功能的实现(cpp,ubuntu)

智能小车避障功能的实现(cpp,ubuntu)

weixin_62135607的博客 4374

从零构建嵌入式Linux驱动:揭秘内核模块加载的底层机制

本文深入解析嵌入式Linux驱动开发中的内核模块加载机制,从动态模块加载的核心价值到module_init宏的底层实现,详细介绍了字符设备注册和sysfs设备节点创建的完整流程。通过实战案例和调试技巧,帮助开发者掌握嵌入式Linux驱动开发的关键技术,特别适合STM32MP157等嵌入式平台开发者参考。

t8u9v0的博客 782

windows中通过docker部署LocateAnything-3B模型

windows中通过docker部署LocateAnything-3B模型

yilvyangguang520的博客 483

Linux字符设备驱动程序及测试程序:开启Linux内核模块开发之旅

Linux字符设备驱动程序及测试程序:开启Linux内核模块开发之旅 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在Linux系统编程领域,设备驱动程序的开发是核心技能之一。今天,我们将向您推荐一个开源项目——Linux字符设备驱动程序及测试程序,它提供了一个简单的字符设备驱动程序实例,并附有测试程序,助您轻松入门Linux内核模块开发。 项目技术分析 Linux字...

gitblog_06754的博客 946

华为面试手撕真题【字符串压缩】

华为面试手撕真题【字符串压缩】

MISAYAONE的博客 1万+

windows server 2012安装升级MySQL

本篇文章主要介绍的是windows server 2012 R2操作系统安装升级以及过程中遇到的问题和对应的解决方法。(数据库低版本为:mysql-5.7.27-winx64;数据库数据库高版本为:mysql-5.7.44-winx64;提示:以下是本篇文章正文内容,下面案例可供参考。

qq_42776231的博客 780

LKMPG嵌入式:树莓派内核模块开发实践

你还在为树莓派传感器驱动开发烦恼吗?本文基于LKMPG项目提供的[examples/](https://link.gitcode.com/i/62e2e882fde48dd21ca853c114a8bd2d)示例代码,带你从零实现一个能读取温湿度数据的内核模块,掌握设备树配置、GPIO操作和内核模块调试的完整流程。读完本文你将获得: - 树莓派内核模块的编译与加载方法 - 设备树(Device T...

gitblog_00891的博客 713

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

手把手教你给OpenWRT添加自定义内核模块(基于Qemu测试)

本文详细介绍了在OpenWRT系统中添加自定义内核模块的全流程实践,重点讲解了如何利用Qemu虚拟环境进行高效仿真与测试。通过源码级集成和模块化包管理,开发者可以在无需物理硬件的情况下,完成从代码编写、系统构建到功能验证的完整开发闭环,并深入探讨了内核源码级调试等高级技巧。

k8s6orchestrator的博客 1031

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

CH341SER驱动深度解析:从内核模块到Arduino实战

还在为CH340/CH341 USB转串口设备在Linux系统上无法识别而烦恼吗?CH341SER驱动正是为解决这一问题而生。这款开源驱动程序专门修复了原厂驱动的兼容性问题,让您的Arduino、ESP32等嵌入式设备轻松连接Linux系统。 ## 🚀 快速入门:5分钟搞定驱动安装 **环境检查清单**: 在开始安装前,请确认以下准备工作已完成: | 检查项 | 验证命令 | 预期结果 |

gitblog_00004的博客 815

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Linux内核驱动——内核编译与设备驱动

本文详细介绍了Linux内核驱动开发的全流程。主要内容包括:1.内核编译过程,从源码获取、配置到编译和部署;2.设备驱动分类及架构,包括字符设备、块设备和网络设备;3.设备号管理和设备节点创建方法;4.通过demo_driver.c和demo1.c实例,演示了字符设备驱动的开发流程和测试方法。文章完整呈现了从内核编译到驱动开发的实践过程,为Linux驱动开发提供了系统指导。

lufrednow_的博客 843

从零编写Linux字符设备驱动:内核模块实战与开发指南

最近在做一个嵌入式项目,需要为一块自定义的硬件板卡编写驱动程序。在查阅资料时,发现网上关于 Linux 驱动开发的教程要么过于理论,要么代码片段零散,很难直接上手实践。对于很多从应用层开发转向底层驱动的朋友来说,如何从零开始,写一个真正能加载、能运行的驱动程序,往往是第一个拦路虎。 本文将从一个最基础的“Hello World”式内核模块出发,手把手带你编写、编译、加载和卸载你的第一个 Linux 驱动程序。我们会深入理解内核模块的机制,并在此基础上,构建一个简单的字符设备驱动框架。无论你是嵌入式开发者,还

xpp02的专栏 529
上一篇: 【C++/嵌入式梳理】一、31.C++相关基础 | 函数 | 封装
下一篇: 【C++/嵌入式梳理】一、32.封装
赛博二哈
博客等级 码龄8年 5768粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值