linux驱动开发之常见面试问题

linux驱动开发之常见面试问题

      • 新增驱动的基本操作
      • 寄存器基址怎么映射?
      • probe里的常规操作。
      • 驱动中通常会定义一个私有结构体,里面包含一些内核结构体,但注册的时候只注册了某个成员,怎么找到这个私有结构体。
        • 什么是container_of
      • 如何给应用层提供接口
        • 什么是ioctl?
      • 如何在shell下调用驱动
      • 如何解决内核启动时卡死问题
      • 简述MMU的工作原理

新增驱动的基本操作

先在设备树里新建一个节点,填写compatible和reg属性,然后在驱动里映射寄存器基址,后续就可以操作寄存器。
如果是linux发行版中没有的驱动
需要获取驱动源代码:

下载适用于你的内核版本的驱动源代码。
解压源代码:

使用tar命令解压下载的压缩包,如tar -xzvf driver.tar.gz
进入驱动目录:

使用cd命令切换到解压后的驱动目录。
配置驱动:

运行make configmake menuconfig命令配置驱动选项。
编译驱动:

运行make命令编译驱动。
安装驱动:

使用make install或手动将生成的模块文件复制到合适的目录,通常是/lib/modules/<kernel_version>/kernel/drivers
加载驱动:

运行modprobe driver_name加载驱动,或者使用insmod driver.ko命令。
检查驱动加载情况:

使用lsmod命令查看已加载的模块,确保新驱动在列表中。
配置自动加载:

将驱动名称添加到/etc/modules文件中,以便系统在启动时自动加载。
重启系统:

为了确保新驱动在系统启动时自动加载,最好重启系统。

寄存器基址怎么映射?

A:先用platform_get_resource获取IORESOURCE_MEM资源,然后用devm_ioremap_resource将基址映射为虚拟地址。

probe里的常规操作。

A:通常一个驱动都会有时钟,所以probe里映射完基址后,通常要进行时钟和复位的操作。调用devm_clk_get获取时钟源,然后调用devm_clk_prepare_enbale使能时钟,复位的话先调用devm_reset_control_get获取复位源,然后用reset_control_reset复位。

驱动中通常会定义一个私有结构体,里面包含一些内核结构体,但注册的时候只注册了某个成员,怎么找到这个私有结构体。

A:可以通过container_of宏找到这个私有结构体的指针。

什么是container_of

container_of 是 Linux 内核中一个常用的宏,用于从一个结构体中的某个字段获取该结构体的指针。这在实现容器数据结构时非常有用,尤其是在链表中。
具体的使用格式如下:

#include <stddef.h>#define container_of(ptr, type, member) \({ \const typeof(((type *)0)->member) *__mptr = (ptr); \(type *)((char *)__mptr - offsetof(type, member)); \})

其中:

ptr 是指向结构体中某个成员的指针。
type 是结构体的类型。
member 是结构体中的成员名。
这宏的作用是返回包含给定成员的结构体的指针。

这个宏在内核中广泛用于实现各种数据结构,尤其是在实现链表时,通过链表节点的成员指针可以找到整个结构体的指针。具体详细讲解可以自行百度。

如何给应用层提供接口

A:驱动给应用层提供接口,一般都是通过ioctl接口,应用层传入一个结构体,驱动解析

什么是ioctl?

ioctl(Input/Output Control)是Linux系统中的一个系统调用,用于对设备进行输入/输出的控制。它允许用户空间程序通过系统调用与设备驱动程序进行通信,提供一种灵活的设备控制机制。ioctl的使用方式是通过命令(或请求号)来指定要执行的操作,以及相应的参数。

基本的ioctl原型如下:

int ioctl(int fd, unsigned long request, ...);

fd 是文件描述符,指向要进行控制的设备或文件。
request 是命令或请求号,用于指定要执行的操作。
... 是可选参数,用于传递与请求相关的参数。

一些常见的ioctl使用场景包括:

  1. 设备设置:
    设置设备的一些特性,例如串口的波特率、数据位、停止位等。

  2. IO模式切换:
    控制设备的读写模式,例如切换到阻塞或非阻塞模式。

  3. 硬件信息查询:
    获取设备的硬件信息,例如查询磁盘的几何信息。

  4. 字符设备操作:
    对字符设备进行一些特定的操作,例如终端的清屏、设置光标位置等。

  5. 网络套接字设置:
    配置网络套接字的选项,例如设置套接字的超时时间、设置广播选项等。

  6. 图形设备控制:
    控制图形设备的一些操作,例如设置显示器的分辨率、颜色深度等。

使用ioctl需要查阅相关设备或系统调用的文档,以了解支持的命令和参数。在驱动程序的开发中,通常会实现相应的ioctl处理函数,用于处理不同的命令。

总体而言,ioctl提供了一个灵活的接口,使用户空间程序能够与内核中的设备驱动进行通信和控制。

如何在shell下调用驱动

A:可以提供procfssysfs或者debugfs这三个虚拟文件系统接口,根据具体用途提供

procfs接口一般是系统性的信息,主要是用来查看的,例如内存信息。
sysfs接口更多用于与驱动交互,可以传参给驱动,修改驱动中一些变量。
debugfs一般是用来调试用的,需要挂载debugfs

如何解决内核启动时卡死问题

A:卡住或者崩了,需要分析卡在哪里,从而找到原因。

在内核的initcall初始化函数中加打印,把initcalllevel函数指针打印出来,看内核跑到了哪个等级的初始化。

level等级是知道了,但这个等级执行的函数太多,而且打印出来的是地址,怎么知道具体跑到哪个函数?

A:把内核编译出来的vmlinux文件反汇编,反汇编文件包含函数名和对应地址,根据地址查找。

vmlinux 是 Linux 内核编译后的可执行文件,包含了完整的内核代码和数据。如果你想进行 vmlinux 文件的反汇编,可以使用工具如 objdump 或 gdb。

以下是使用 objdump 进行 vmlinux 反汇编的基本步骤:

objdump -D vmlinux > vmlinux_disassembly.txt

这将会生成一个包含反汇编代码的文本文件 vmlinux_disassembly.txt。你可以使用文本编辑器查看或搜索其中的代码。

如果你想在 gdb 中进行交互式的反汇编,可以按照以下步骤:

gdb vmlinux

在 GDB 中,你可以使用 disassemble 命令来查看反汇编代码:

(gdb) disassemble

你也可以指定地址范围来查看特定部分的代码:

(gdb) disassemble 0xffffffff81000000, 0xffffffff81010000

请注意,反汇编的结果可能会很庞大,因为它包含整个内核的代码。选择性地查看特定的函数或区域可能更有帮助。

内核调试方法?
A:printk、BUG_ON、devmem、dump_statck…

printk有打印等级,用法和printf一样,可以用pr_info、pr_err这些不同等级的函数加打印。在shell中可以通过echo的方式控制printk等级

devmem是一个命令,它可以在shell下直接读写寄存器
devmem应用程序会打开/dev/mem节点,这个设备实现了mmap接口,devmem应用程序打开/dev/mem后,会调用mmap函数将寄存器物理地址映射到用户空间,所以可以直接读写寄存器

dump_stack函数可以打印函数调用栈,可以分析函数调用关系
可以用工具链的add2line,查找地址对应的符号,就能看到函数名
内核配置打开CONFIG_KALLSYMS,这个配置是编入符号表,选上后,dump_stack就可以清楚看到调用关系和符合偏移。

简述MMU的工作原理

A:在一个三级页表的内存管理系统中,MMU(内存管理单元)通过访问页表基址寄存器(Page Table Base Register,简称PTBR)获取一级页表的基地址,然后通过虚拟地址中的一级页表索引(Page Global Directory Index,简称PGD index)找到相应的二级页表。

接着,MMU利用二级页表基址和虚拟地址中的二级页表索引(Page Table Entry Index,简称PTE index)找到相应的页表项(Page Table Entry,简称PTE)。在这个例子中,PTE 存储的是物理页框号(Page Frame Number,简称PFN),即该虚拟页对应的物理页框。

最后,MMU将物理页框号(PFN)与虚拟地址中的页内偏移相加,得到实际的物理地址。

这个过程可以总结为以下步骤:

MMU根据虚拟地址的高位来查找一级页表项(PGD),获取二级页表的基地址。
MMU再根据虚拟地址的中间位来查找二级页表项(PTE),获取物理页框号(PFN)。
MMU将物理页框号与虚拟地址的低位偏移相加,得到最终的物理地址。
这样,通过多级页表的层级结构,MMU能够实现对大型地址空间的映射和管理,从而提供了一种灵活、高效的内存管理方案。

页表基址寄存器存储第一级页表的基地址。
页表是软件创建的。MMU只是通过页表,将虚拟地址转换为了物理地址。
页表在物理内存中。
CPU先访问TLB,如果TLB中存在这个地址,则直接从TLB中取地址。如果没有,再访问内存,读取页表,将虚拟地址转为物理地址,从而访问到内存。
TLB在MMU中,本质是一块cache。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/678380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vector基本用法(可变长数组)

一.初始化 1.vector<数据类型> 变量名&#xff1b; 2.vector<数据类型> 变量名&#xff08;n&#xff09;&#xff1b; 3.vector<数据类型> 变量名 &#xff08;n,x); 例子&#xff1a;1.vector<int> v;——> v[ ] (空的) 2.vector<…

FreeRTOS.chg脚本出现意外状态

PE代码生成的时候遇到这么个问题 警报如下 Description Resource Path Location Type ERROR: Unexpected status of script: Beans\FreeRTOS\FreeRTOS.chg, please contact Freescale support. M18_BMCU FreeRTOS Processor Expert Problem 意思就是这个脚本文件有问题&…

Linux第45步_通过搭建“DNS服务器”学习图形化配置工具

学习的意义&#xff1a;通过搭建“DNS服务器”&#xff0c;来学习“图形化配置工具”。“DNS服务器”&#xff0c;我们用不到&#xff0c;但为后期移植linux系统服务&#xff0c;因为在移植系统时&#xff0c;需要用到这个“图形化配置工具”。 1、“menuconfig图形化配置工具…

93 log4j-slf4j-impl 搭配上 log4j-to-slf4j 导致的 StackOverflow

前言 呵呵 最近想要 做一个 mongo 低版本的客户端读取高版本的服务端传递过来的数据造成的一个错误的时候, 出现了这样的问题 引入了 mongo-java-driver 之后, 使用相关 api 的时候会触发 com.mongo.internal.connection.BaseCluser 的初始化, 其依赖的 Loggers 间接的依赖…

C++构造和折构函数详解,超详细!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家龙年好呀&#xff0c;今天我们来学习一下C构造函数和折构函数。 文章目录 1.构造函数 1.1构造函数的概念 1.2构造函数的思想 1.3构造函数的特点 1.4构造函数的作用 1.5构造函数的操作 1.6构造函数…

2.11作业

运算符 1、选择题 1.1、若有以下程序 main() { char a1,b2; printf("%c,",b); printf("%d\n",b-a); } 程序运行后的输出结果是 C A&#xff09;3,2 B&#xff09;50,2 C&#xff09;2,2 D&#xff09;2,50 1.2、有以下程序 main() { int a,b…

从零开始学howtoheap:fastbins的house_of_spirit攻击2

how2heap是由shellphish团队制作的堆利用教程&#xff0c;介绍了多种堆利用技术&#xff0c;后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;优化pwn虚拟机配置支持libc等指令-CSDN博客 1.fastbins的house_…

P1028 [NOIP2001 普及组] 数的计算题解

题目 给出正整数n&#xff0c;要求按如下方式构造数列&#xff1a; 只有一个数字n的数列是一个合法的数列。在一个合法的数列的末尾加入一个正整数&#xff0c;但是这个正整数不能超过该数列最后一项的一半&#xff0c;可以得到一个新的合法数列。 请你求出&#xff0c;一共…

提高效率!企业短信通道账单拆分一键处理,干货分享

**提高效率!企业短信通道账单拆分一键处理,干货分享! 昨天从硬盘里看到2019年写的 账单拆分案列,这里分享给大家 文章目录 **提高效率!企业短信通道账单拆分一键处理,干货分享!背景企业短信通道账单展示干货来了用python拆分短信账号最后短信通道账单拆分后的处理。最后…

C#,最大公共子序列(LCS,Longest Common Subsequences)的算法与源代码

1 最大公共子序列 最长的常见子序列问题是寻找两个给定字符串中存在的最长序列。 最大公共子序列算法&#xff0c;常用于犯罪鉴定、亲子鉴定等等的 DNA 比对。 1.1 子序列 让我们考虑一个序列S<s1&#xff0c;s2&#xff0c;s3&#xff0c;s4&#xff0c;…&#xff0c;…

常见性能优化策略

对于经常接触高并发服务的同学来学&#xff0c;会经常涉及到性能优化&#xff0c;但是由于平时很少总结&#xff0c;内容会比较分散&#xff0c;这里简单做一些总结 1&#xff1a;空间换时间 比如一些数据的访问需要很快返回结果&#xff0c;原本在磁盘上的数据&#xff0c;需…

算法------(11)并查集

例题&#xff1a; &#xff08;1&#xff09;Acwing 836.合并集合 并查集就是把每一个集合看成一棵树&#xff0c;记录每个节点的父节点。合并集合就是把一棵树变成另一棵树的子树&#xff0c;即把一棵树的父节点变为另一棵树的父节点的儿子。查询是否在同一集合就是看他们的根…

02.数据结构

一、单链表 作用&#xff1a;用于写邻接表&#xff1b; 邻接表作用&#xff1a;用于存储图或树&#xff1b; 1、用数组模拟单链表 #include<iostream> using namespace std;const int N 100010;// head 表示头结点的下标 // e[i] 表示结点i的值 // ne[i] 表示结点i的…

【OrangePi Zero2的系统移植】交叉编译工具链配置、wiringOP库、智能分类工程代码

一、交叉编译工具链配置 二、交叉编译wiringOP库 三、交叉编译智能分类工程代码 四、Makefile 用于编译 WiringPi 库 一、交叉编译工具链配置 1、关于编译 编译是指将源代码文件&#xff08;如C/C文件&#xff09;经过预处理、编译、汇编和链接等步骤&#xff0c;转换为可执…

开发JSP自定义标记

开发JSP自定义标记 您已经学习了如何用JavaBean处理JSP页面的业务逻辑。除此以外,您还可以用自定义标记处理JSP应用程序中反复出现的业务逻辑要求。 tag是程序中使用的执行重复性任务的可重用单元。例如, 是使主体文本在网页中间出现的HTML标记。JSP可用于创建于XML标记类似…

(c语言版)数组去重和排序 题目描述: 给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低

【编程题目 | 100分】数组去重和排序 [ 100 / 中等 ] 数组去重和排序 题目描述&#xff1a; 给定一个乱序的数组&#xff0c;删除所有的重复元素&#xff0c;使得每个元素只出现一次&#xff0c;并且按照出现的次数从高到低进行排序&#xff0c;相同出现次数按照第一次出现顺序…

R语言【utlis】——alarm():提示音或提示符

Package utils version 4.2.0 Description 给用户一个声音或视觉信号。 Usage alarm() Details alarm()通过向控制台发送一个“\a”字符来工作。在大多数平台上&#xff0c;这将向用户发出铃声、嘟嘟声或其他信号(除非重定向了标准输出)。 它尝试刷新控制台(请参阅flush.co…

极限的唯一性推导

定义推导 根据函数的 y f ( x ) yf(x) yf(x)的定义,x∈集合A,y∈集合B,集合A对应B的关系是单射即一个x只能对应一个y。固 lim ⁡ x − > ∗ f ( x ) A \lim\limits_{x->*}f(x)A x−>∗lim​f(x)A存在,那么其极限必定唯一 反证法 函数 f ( x ) 存在极限 lim ⁡ x −…

【Rust】——猜数游戏

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…