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

ARM 裸机与 Linux 驱动对比及 Linux 内核入门

目录

ARM裸机代码和驱动的区别

Linux系统组成

内核五大功能

设备驱动分类

内核类型

驱动模块

驱动模块示例

Makefile配置

命令

编码辅助工具

内核中的打印函数

printk 函数

修改打印级别

​编辑

打印级别含义

 驱动多文件编译

示例

 模块传递参数

命令行传递参数

支持的数据类型

module_param 函数

MODULE_PARM_DESC 函数

示例

module_param_array 函数

字符设备驱动

Linux系统中一切皆文件

字符设备驱动步骤

字符设备驱动的注册

​编辑

字符设备驱动的注销


以下是本人学习时的一些笔记,对初入门的驱动可能会有一些帮助,希望可以帮到大家~

ARM裸机代码和驱动的区别

共同点

  • 都能够操作硬件。

不同点

  • 裸机编程是直接用C语言给寄存器写值。
  • 驱动编程遵循一定的框架和规范,通过往寄存器写值来控制硬件。
  • 裸机代码独立编译和执行,而驱动依赖于内核进行编译和执行。
  • 裸机程序一次只能执行一个任务,而驱动可以支持并发执行多个任务。
  • 裸机程序只需一个main函数即可,而驱动需要遵循内核的框架和流程。

Linux系统组成

  • 用户空间(0-3G):每个进程独占0-3G的虚拟地址空间。

  • 内核空间(3-4G):所有进程共享3-4G的虚拟地址空间。
  • 系统调用:应用程序通过系统调用(软中断SWI)与内核交互。

内核五大功能

  • 进程管理:负责进程的创建、销毁和调度。
  • 文件管理:通过文件系统(如ext2/ext3/ext4/YAFFS/JFFS等)来管理文件。
  • 网络管理:通过网络协议栈(如OSI/TCP/IP)处理数据包的封装和拆解。
  • 内存管理:负责用户空间和内核空间内存的分配和回收。
  • 设备管理:管理设备驱动,如字符设备、块设备和网络设备。

设备驱动分类

  • 字符设备驱动:如LED、鼠标、键盘、LCD、触摸屏等。
    • 按照字节为单位访问,支持顺序访问。
    • 创建设备文件,通过openreadwriteclose等操作访问。
  • 块设备驱动:如摄像头、U盘、eMMC等。
    • 按照块(通常是512字节)访问,支持顺序和随机访问。
    • 创建设备文件,通过openreadwriteclose等操作访问。
  • 网络设备驱动:如网卡。
    • 按照网络数据包进行收发。

内核类型

  • 宏内核:将主要功能集成在一个内核中。
    • 优点:运行效率高。
    • 缺点:任何一个部分出错都可能导致整个内核崩溃。
    • 示例:Ubuntu, Android
  • 微内核:只包含最基本的功能,其他功能通过服务的形式在用户空间实现。
    • 优点:更高的稳定性和安全性。
    • 缺点:相对较低的运行效率。
    • 示例:HarmonyOS, QNX

驱动模块

  • 三要素:入口、出口、许可证。
  • 入口:资源的申请。
  • 出口:资源的释放。
  • 许可证:通常使用GPL许可。

__init可以不指定,及可以不写,但是正常是写的)

驱动模块示例

#include <linux/init.h>
#include <linux/module.h>//__init将hello_init放到.init.text段中
static int __init hello_init(void) {// 初始化函数return 0;
}//__exit将hello_exit放到.exit.text段中
static void __exit hello_exit(void) {// 清理函数
}//告诉内核驱动的入口地址(函数名为函数首地址)
module_init(hello_init);//告诉内核驱动的出口地址
module_exit(hello_exit);//许可证
MODULE_LICENSE("GPL");

Makefile配置

KERNELDIR := /lib/modules/$(shell uname -r)/build/
PWD := $(shell pwd)all:make -C $(KERNELDIR) M=$(PWD) modulesclean:make -C $(KERNELDIR) M=$(PWD) cleanobj-m += hello.o

命令

  • 安装驱动模块sudo insmod hello.ko
  • 卸载驱动模块sudo rmmod hello

  • 查看已加载的模块lsmod
  • 查看内核消息dmesg
  • 清空内核消息sudo dmesg -C 或 sudo dmesg -c
  • 持续查看内核消息:sudo dmesg -w

编码辅助工具

  • 创建索引文件ctags -R
  • 在vi中跳转至标签ctrl + ] 和 ctrl + t

Ubuntu内核所对应的内核路径

内核中的打印函数

printk 函数

  • 函数原型

    printk(打印级别 "内容")
  • 示例

    printk(KERN_ERR "Fail%d", a);
    printk(KERN_ERR "%s:%s:%d\n", __FILE__, __func__, __LINE__);
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
  • 查看内核打印级别

    vi -t KERN_ERR
  • 内核打印级别定义

    #define KERN_EMERG  "<0>"   /* system is unusable        */
    #define KERN_ALERT  "<1>"   /* action must be taken immediately */
    #define KERN_CRIT   "<2>"   /* critical conditions          */
    #define KERN_ERR    "<3>"   /* error conditions         */
    #define KERN_WARNING    "<4>"   /* warning conditions           */
    #define KERN_NOTICE "<5>"   /* normal but significant condition */
    #define KERN_INFO   "<6>"   /* informational            */
    #define KERN_DEBUG  "<7>"   /* debug-level messages         */

  • 打印级别范围

    • 从 <0> 到 <7><0> 为最高级别,<7> 为最低级别。
修改打印级别
  • 查看当前打印级别

    cat /proc/sys/kernel/printk
  • 打印级别的含义

    • 第一个数字:终端的级别。
    • 第二个数字:消息的默认级别。
    • 第三个数字:终端的最大级别。
    • 第四个数字:终端的最小级别。
  • 修改系统默认的级别

    su root
    echo 4 3 1 7 > /proc/sys/kernel/printk
  • 添加修改级别命令

echo 4 3 1 7 > /proc/sys/kernel/printk
打印级别含义
  • 终端的级别:只有当消息的级别大于或等于终端级别时,消息才会在终端上显示。
  • 消息的默认级别:如果没有特别指定,消息将采用此级别。
  • 终端的最大级别:终端可以显示的最高级别。

安装驱动和卸载驱动时,消息会打印。

 驱动多文件编译

示例
  • 文件列表

    • hello.c
    • add.c
  • Makefile

    obj-m := demo.o
    demo-y += hello.o add.o
  • 说明

    • -y 作用:将 hello.o 和 add.o 文件合并到 demo.o 中。
    • 最终生成demo.ko 文件。

 模块传递参数

命令行传递参数
  • 命令示例
    sudo insmod demo.ko hello world
支持的数据类型
  • 标准类型
    • byteshortushortintuintlongulong
    • charp: 字符串指针
    • bool: 布尔值,接受 0/1y/nY/N
    • invbool: 布尔值,接受 0/1y/nY/N,但意义相反(N 表示真)

module_param 函数
  • 函数原型
    module_param(name, type, perm);
  • 参数
    • name: 变量的名字。
    • type: 变量的类型。
    • perm: 权限,如 06640775

MODULE_PARM_DESC 函数
  • 函数原型
    MODULE_PARM_DESC(_parm, desc);
  • 参数
    • _parm: 变量。
    • desc: 描述字段。
示例
  • 命令行参数

    sudo insmod hello.ko a=20 b=30 c=65 p="hello_world"
  • 注意事项

    • 传递字符时使用 ASCII 码值。
    • 传递字符串时不能包含空格。
module_param_array 函数
  • 函数原型
    module_param_array(name, type, nump, perm);
  • 参数
    • name: 数组名。
    • type: 数组的类型。
    • nump: 参数的个数,变量的地址。
    • perm: 权限。

练习:

        1.byte类型如何使用 (传递参数用ascii)

        2.如何给一个指针传递一个字符串

  •  命令行参数
sudo insmod hello.ko a=121 b=10 c=65 p="hello" ww=1,2,3,4,5

传参成功~

字符设备驱动

Linux系统中一切皆文件
  • 应用层

    fd = open("led驱动的文件", O_RDWR);
    read(fd);
    write(fd);
    close(fd);
  • 内核层

    • 驱动文件led_driver.c
    • 驱动函数
      driver_open();
      driver_read();
      driver_write();
      driver_close();
  • 结构体定义

    struct file_operations {int (*open)(struct inode *, struct file *);ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);int (*release)(struct inode *, struct file *);
    ;
  • 设备号

    • 32位无符号数字
      • 高12位:主设备号,用于区分设备类别。
      • 低20位:次设备号,用于区分同一类别中的不同设备。
  • 硬件层

    • LEDUARTADCPWM 等设备。
字符设备驱动步骤
  1. 注册字符设备驱动 - 得到一个字符设备驱动的框架,并获得设备号。
  2. 确定操作的硬件设备 - 如 LED 灯(初始化灯)。
  3. 初始化灯 - 建立灯实际物理地址和虚拟地址之间的映射。
  4. 用户空间与内核空间数据交互 - 当用户使用时,驱动会被真正运行,涉及数据交互。
  5. 在应用层创建设备文件(设备节点)。
字符设备驱动的注册
  • 函数原型

    int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops);
  • 参数

    • major:主设备号。
      • 如果填写的值大于0,它认为这个就是主设备号。
      • 如果填写的值为0,操作系统会分配一个主设备号。
    • name:设备名称。
    • fops:操作方法结构体。
  • 返回值

    • major > 0:成功返回0,失败返回错误码(负数)。
    • major = 0:成功返回分配的主设备号,失败返回错误码(负数)。
  • 查看设备信息

    cat /proc/devices
字符设备驱动的注销
  • 函数原型

    void unregister_chrdev(unsigned int major, const char *name);
  • 参数

    • major:主设备号。
    • name:设备名称。
  • 返回值:无。

就分享到这,希望可以帮到你吧~

相关文章:

ARM 裸机与 Linux 驱动对比及 Linux 内核入门

目录 ARM裸机代码和驱动的区别 Linux系统组成 内核五大功能 设备驱动分类 内核类型 驱动模块 驱动模块示例 Makefile配置 命令 编码辅助工具 内核中的打印函数 printk 函数 修改打印级别 ​编辑 打印级别含义 驱动多文件编译 示例 模块传递参数 命令行传递参数…...

0101DNS TCP fallback on UDP query timeout disabled-redission-中间件

文章目录 1.问题描述2.临时解决方案 结语 1.问题描述 Springcloud 项目&#xff0c;微服务模块使用redission&#xff0c;启动报错 DNS TCP fallback on UDP query timeout disabled. Upgrade Netty to 4.1.105 or higher.相关软件版本如下 软件版本描述springboot2.7.18spr…...

位运算

x1010 原码&#xff1a;000...1010 &#xff08;一共32位&#xff09; 反码&#xff1a;111...0101 &#xff08;~x&#xff09; 补码&#xff1a;111...0110 &#xff08;反码1&#xff09;&#xff08;-x&#xff09; 1、n 的二进制表示中第 k 位是几 #include<iost…...

MemFire Cloud是否真的可以取代后端

近年来&#xff0c;随着前端技术的迅速发展&#xff0c;前端工程师们越来越多地开始思考一个问题&#xff1a;“我还能不能不依赖后端&#xff1f;” 这种想法并非空穴来风&#xff0c;尤其是随着像MemFire Cloud这样的工具出现&#xff0c;它不仅能让开发者在没有后端的情况下…...

数据结构(邓俊辉)学习笔记】优先级队列 06——完全二叉堆:批量建堆

文章目录 1. 自上而下的上滤&#xff1a;算法2. 自上而下的上滤&#xff1a;效率3. 自下而上的下滤&#xff1a;算法4. 自下而上的下滤&#xff1a;实例5. 自下而上的下滤&#xff1a;效率 1. 自上而下的上滤&#xff1a;算法 在介绍过完全二叉堆标准的静态和动态操作接口之后…...

Java | Leetcode Java题解之第344题反转字符串

题目&#xff1a; 题解&#xff1a; class Solution {public void reverseString(char[] s) {int n s.length;for (int left 0, right n - 1; left < right; left, --right) {char tmp s[left];s[left] s[right];s[right] tmp;}} }...

定制开发AI智能名片O2O商城小程序:基于限量策略与个性化追求的营销创新

摘要:随着科技的飞速发展和消费者需求的日益多元化&#xff0c;传统商业模式正经历着前所未有的变革。在数字化转型的大潮中&#xff0c;定制开发AI智能名片O2O商城小程序作为一种新兴的商业模式&#xff0c;凭借其独特的个性化定制能力、高效的线上线下融合&#xff08;O2O&am…...

Spring MVC Controller返回json日期格式配置失效的解决办法

如题&#xff0c;Spring MVC 4.3.0版本&#xff0c;配置jackson读写json。Controller层方法返回值对象包含java.util.Date类型的属性&#xff0c;并且在applicationContext.xml中配置了jackson的日期格式&#xff1a; <mvc:annotation-driven><mvc:message-converters…...

3.Default Constructor的构造操作

目录 1. 问题引入 2. 4种implicitly声明的default constructor 1. 问题引入 “default constructors......在需要的时候被编译产生出来”。关键词是“在需要的时候”&#xff0c;被谁需要&#xff0c;做什么事情&#xff1f;看看下面的代码&#xff0c;然后梳理下思路。 cl…...

CSS的:current伪类:精准定位当前活动元素

CSS&#xff08;层叠样式表&#xff09;是控制网页样式的核心语言。随着CSS4的提出&#xff0c;一系列新的选择器被引入&#xff0c;其中:current伪类便是这些新特性之一。:current伪类允许开发者选择当前处于活动状态的元素&#xff0c;这在创建动态和交互性网页时非常有用。本…...

搭建个人网站

一 个人搭建网站需要进行的操作 详细步骤&#xff1a; 1 网站目标&#xff1a;搭建在线查看法拍房拍卖价格的预测模型&#xff0c;输出预测结果 2 实际功能&#xff1a;在线爬取 阿里法拍网站的信息 3 根据实时模型建模预测法拍价格和成交概率 要搭建一个能够在线查看法拍房拍卖…...

机器学习课程学习周报八

机器学习课程学习周报八 文章目录 机器学习课程学习周报八摘要Abstract一、机器学习部分1.1 self-attention的计算量1.2 人类理解代替自注意力计算1.2.1 Local Attention/Truncated Attention1.2.2 Stride Attention1.2.3 Global Attention1.2.4 聚类Query和Key 1.3 自动选择自…...

福泰轴承股份有限公司进销存系统pf

TOC springboot413福泰轴承股份有限公司进销存系统pf 绪论 1.1 研究背景 现在大家正处于互联网加的时代&#xff0c;这个时代它就是一个信息内容无比丰富&#xff0c;信息处理与管理变得越加高效的网络化的时代&#xff0c;这个时代让大家的生活不仅变得更加地便利化&#…...

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息&#xff0c;但是从节点无法获取&#xff0c;且报错“error: You must be logged in to the server (Unauthorized)” 排查思路&#xff1a; 当时证书过期了&#xff0c;只处理的主节点的证书过期&#xff0c;没有处理从节点的 kubeadm alpha …...

风清扬/基于Java语言的光伏监控系统+光伏发电预测+光伏项目+光伏运维+光伏储能项目

基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 介绍 基于Java语言的光伏监控系统光伏发电系统光伏软件系统光伏监控系统源码光伏发电系统源码 基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 安装教程 参与贡献 Fork 本仓库新…...

Datawhale X 魔搭 AI夏令营第四期 魔搭-AIGC方向全过程笔记

task1: 传送门 task2&#xff1a; 传送门 task3: 传送门 目录 Task1 赛题内容 可图Kolors-LoRA风格故事挑战赛 baseline要点讲解(请配合Datawhale速通教程食用) Step1 设置算例及比赛账号的报名和授权 Step2 进行赛事报名并创建PAI实例 Step3 执行baseline Step4…...

数组---怎么样定义和引用数组

一怎么定义数组 例 int a[10]; //定义了一个一维数组&#xff0c;数组名为a&#xff0c;此数组包含10个整型元素 所以我们了解到数组的基本定义为 类型符 数组名 [常量表达式] 定义数组可以包括常量和符号常量如 int [ 35 ];但是不能利用变量定义如 int n&#xff1b; …...

Nginx—Rewrite

目录 一、Nginx—Rewrite概述 1、常用的Nginx正则表达式 2、Rewrite功能 3、Rewrite跳转实现 4、Rewrite执行顺序和语法格式 二、location概述 1、location分类 2、location 常用的匹配规则 3、location 优先级 案例一&#xff1a; 案例二&#xff1a; 案例三&…...

《深入浅出WPF》读书笔记.5控件与布局(上)

《深入浅出WPF》读书笔记.5控件与布局(上) 背景 深入浅出WPF书籍学习笔记附代码。WPF中数据是核心是主动的,UI是数据的表达是被动的。 程序的本质是数据算法&#xff1b;控件的本质是数据行为&#xff1b; 5.控件与布局 一、6类控件派生关系 1.布局控件:可以容纳多个控件…...

二叉树的判断

二叉树的判断 判断一颗二叉树是不是搜索二叉树 &#xff08;左边的比根小&#xff0c;右边的比根大&#xff09; 中序遍历一下&#xff0c;如果是的话就一定是升序的 如何判断一颗二叉树是否是完全二叉树 1.遍历任意的节点时候&#xff0c;如果返回右孩子没有左孩子&#x…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...