
Linux内核
文章平均质量分 68
Linux内核相关的文章
北冥的备忘录
善读者,玩索而有得焉,则终身用之,有不能尽者矣。
本博客是笔者的个人实践记录,文笔随意,严谨度一般,仅供参考,不喜勿喷
展开
-
【代码模板】如何通过netlink从内核态主动发送消息到用户态?(netlink_kernel_create、nlmsg_new、nlmsg_put、netlink_unicast)
本文通过一个简单的例子介绍了Netlink机制的使用,展示了内核态与用户态之间的异步通信。主要流程包括:内核态驱动注册Netlink用户自定义消息组,用户态程序通过写入字符设备将PID发送给内核态驱动,内核态使用Netlink单播或广播机制通知对应的PID,用户态收到消息后打印出来自内核的信息。内核态程序通过netlink_kernel_create创建Netlink套接字,并通过字符设备接收用户态的PID。用户态程序通过socket创建Netlink套接字,并通过ioctl触发内核态发送消息。最终,用户态原创 2025-05-18 00:13:20 · 840 阅读 · 0 评论 -
【代码模板】Linux内核中对PCIe BAR空间通用打印函数?(pci_resource_start、pci_resource_len、pdev)
Linux内核态操作PCIe配置空间非常方便,接口也比较成熟。本文简单记录一个打印bar空间的函数,入参是标准的pci_dev。打印PCI设备所有BAR(Base Address Register)空间信息。该函数会遍历并打印每个BAR的基址、大小和类型等信息。原创 2025-05-02 23:03:27 · 406 阅读 · 0 评论 -
【问题记录】如何从Anolis8.4升级到Anolis8.6的失败记录?
参考:https://www.yuque.com/anolis-docs/manual/upgrade-8.2-to-8.4。然后重启:reboot。原创 2025-05-01 17:51:41 · 213 阅读 · 0 评论 -
【微知】如何写一个用户态扫描PCIe设备读取PCIe配置空间的程序?
PCIe设备交互需要基于TLP报文,读取PCIe设备配置空间这些操作在linux内核比较方便,在用户态也有lspci、setpci等工具。如何自己手写一个用户态的PCIe设备,来扫描PCIe设备实现类似lspci的效果,本文是一个简单的实验借助 pciutils 库来扫描并显示系统里 PCI 设备的相关信息。原创 2025-05-02 22:18:50 · 294 阅读 · 0 评论 -
【代码拾遗】linux内核中延时机制之msleep?如何利用msleep实现间歇性确认硬件状态的函数?(不可中断方式睡眠)
如果超时时间到达,进程会被内核调度器唤醒。msleep 函数的核心逻辑是将毫秒数转换为内核的 jiffies 单位,并通过 schedule_timeout_uninterruptible 让当前进程进入不可中断的睡眠状态。下面例子实现一个等待函数,指定一个最长等待时间T1后,就会退出,但是等待期间会被分成多个时间窗口,每个时间窗口检测一次,每个时间窗口间隔T2;这里是网卡的驱动程序定义了一个等待行为,以阻塞方式,间歇性的读取硬件状态是否就绪,但是在等待期间会让出调度器,并且不希望被信号中断。原创 2025-05-01 11:30:08 · 1109 阅读 · 0 评论 -
【微知】为什么64位的操作系统一般只使用48bit作为虚拟地址的长度?(映射转换开销大)
对于处理器字长64位的芯片,最大虚拟地址空间理论上可以到2^64这么大。但是实际上一般只用了其中的48Bit来表示虚拟地址空间。对于处理器字长32位的芯片,最大虚拟地址空间只有4GB。原创 2025-04-17 00:30:59 · 507 阅读 · 0 评论 -
【微知】ARM CPU是如何获取某个进程的页表的?(通过TTBR寄存器,MMU进行处理)
当CPU访问虚拟内存的时候,如果tlb misss,MMU(Memory Management Unit 内存管理单元)会根据TTBR寄存器的值(是硬件提供给软件配置的接口)MMU能够动态的根据配置去获取不同进程页表的一级页表地址,然后依次根据偏移逐级获取到虚拟地址对应的物理地址,或者对应的IO地址。TTBR0用户空间的一级页表基址,1是内核页表。当通过MMU将虚拟地址转化为物理地址的最后一级页表的时候,如果发现当前页表不在内存中(比如被换出到swap分区),页表的标记位present位0表示不在内存中。原创 2025-04-02 08:53:45 · 1221 阅读 · 0 评论 -
【问题解决】qemu-system-aarch64启动qcow2格式的系统卡在qemu_monitor解决办法(-bios ./QEMU_EFI.fd)?
使用qemu-system-x86_64在启动Anolis的qcow2的系统的时候能够直接启动。但是使用qemu-system-aarch64启动arm架构的qcow2就一直卡在qemu monitor中。经过一段摸索最后发现是因为没有指定bios,aarch64需要指定qemu_efi.fd的efi文件。原创 2025-03-11 00:59:08 · 453 阅读 · 0 评论 -
【微知】MAC上brew install安装命令报错Error: homebrew-core is a shallow clone如何解决?MAC上如何安装qemu?
本来有这个报错,但是使用–build-from-source能够一定程度解决问题,但是–build-from-source编译总是会因为环境问题有些无法编译。那么本质就是之所以要用–build-from-source是说明本地没有,探后brew下载后自己编译。在git中,blob对象是版本控制的基本单元之一,每个blob对象可以看作是一个文件的快照,包含了文件在某个特定版本下的内容。有些时候还提示要用brew install --build-from-source xxx来安装?原创 2025-03-11 00:35:13 · 333 阅读 · 0 评论 -
【微知】如何根据内核模块ko查看所依赖其他哪些模块?(modinfo rdma_ucm |grep depends)
有些情况下查看某个模块被哪些模块依赖可以用lsmod看到后面的列表,但是反向查看就要麻烦一些,比如某个模块依赖哪些其他模块?通过modinfo xxx.ko获取里面的depends相关信息。原创 2025-03-11 00:04:11 · 352 阅读 · 0 评论 -
【微知】Mellanox OFED驱动中eq的event与中断关系?通过什么机制调用不同event处理?注册的2种形式?(mlx5_eq_notifier_register、MLX5_NB_INIT)
注册的一些事件和处理函数以及对应的notifier block下面这些事件和处理函数通过MLX5_NB_INIT定义一个notifier block,并且用mlx5_eq_notifier_register将这个nb注册到eq table中,会被挂在eq table的notifier header中,每个nh可能挂载多个nb(notifier block)event typefuncCMDCQ_ERRORFPGA_ERROR&esw->nbNOTIFY_ANYPPS_EVENT¬ifier->nb。原创 2025-03-09 02:48:56 · 1007 阅读 · 0 评论 -
【微知】Mellanox OFED驱动中使用的8种日志打印函数以及涉及的6种内核日志打印函数盘点?(mlx5_core_info)
printk是内核中最基本的打印函数,用于将消息输出到内核日志中。本文总结了Mellanox OFED驱动中使用的8种日志打印函数以及涉及的6种内核日志打印函数。以一个为例:是直接封装的dev_xxx系列的debug日志,添加了dev设备。封装的dev系列的比如dev_info,加了个E-Switch: 的前缀。这里也说明了,不同模块要定义自己的打印函数的根本动机在于定义自定义的字段。是直接封装的dev_xxx系列的debug日志,添加了dev设备。是封装的mlx5_core_info系列。原创 2025-03-09 02:01:40 · 992 阅读 · 0 评论 -
【微知】Mellanox驱动中的iseg是什么?如何指定哪些PCIe设备绑定到驱动?如何获取固件Firmware版本?(Initialization segment)
首先,PCIe设备在BIOS阶段会被扫描枚举到PCIe设备并且放在ACPI(Advanced Configuration and Power Interface,高级配置与电源接口)模块中的acpi_pci中管理,并且会给PCIe设备根据bar空间的内容预留物理内存的地址空间。Mellanox网卡驱动主要是PCIe的驱动,驱动mlx5_core.ko主要负责PCIe驱动的管理,他会注册一个PCIe驱动到Linux内核的PCIe框架中,然后如果有PCIe设备热插拔或者rescan触发热插后就会调用。原创 2025-03-06 23:46:04 · 919 阅读 · 0 评论 -
【微知】如何将Linux PCIe驱动与PCIe设备解绑?(echo 0000:01:00.0 > /sys/bus/pci/drivers/mlx5_core/unbind)
有些场景需要将PCIe驱动与PCIe设备进行接绑,接绑的意思就是不使用某个驱动来管理某个PCIe设备。比如要使用vfio从用户态来处理驱动,或者就是要接绑驱动。通过在/sys/bus/pci/drivers目录下指定的驱动比如mlx5_core.ko的目录下查看有哪些子目录。实操效果,可以看到实操后01:00.0设备已经被接绑,并在驱动中无法查看。就查看驱动目录下是否有pcie设备,比如下面的就没有。接绑的时候会调用PCIe驱动模块的exit函数。再次绑定的的时候会调用PCIe的probe函数。原创 2025-03-06 22:41:18 · 295 阅读 · 0 评论 -
微知-Linux内核中.data..percpu代码段什么?怎么定义的?(DEFINE_PER_CPU/DECLARE_PER_CPU/this_cpu_inc/this_cpu_dec)
在定位linux crash问题过程中,在使用rd读取堆栈(比如rd -s 0xffffabcd 64)这种的时候经常会看到.data…percpu的字段,是什么?怎么定义的?有什么问题?如何获取实际地址?原创 2025-01-09 02:27:13 · 878 阅读 · 0 评论 -
微知-Linux内核中常用的container_of的实现原理与常见用法?(container_of三个参数,已知地址,struct的名字和成员变量)
假设指导子成员cg_item的地址,要得到父的base地址就用container_of获取,第一个参数是已知地址,然后用类似。container_of三个参数,分别是已知地址,然后减去后面两个参数组合的struct的offset,并且是struct的名字和成员变量。但是如果要从b获取a,就得计算,也就是先获取b地址Addr1,然后获取a到b的偏移offset2,然后用Addr1-offset2得到地址就是a的地址。假设有一个struct a的结构,起始地址是0,那么a到b的偏移就是a->b。原创 2025-01-09 01:27:11 · 283 阅读 · 0 评论 -
代码模板-Linux内核模块添加参数的方法、原理与内部细节?(smod x.ko param1=xxx;MODULE_PARM_DESC;module_param)
可见定义了一个module_param_cb的函数,将名字以及比如param_ops_int的处理函数传入(包括地址和权限),然后进行处理。比如自定义module_param_cb替换module_param来定义一个struct kernel_param,以及他自己的处理函数。的这个变量,而这个变量的实际值是:“param1”,也就是module_param的第一个参数,然后THIS_MODULE是一个指针指向。的ops,他是一个struct kernel_param_ops 的结构具体参考后文。原创 2025-01-02 22:36:07 · 1221 阅读 · 0 评论 -
代码模板-Linux内核中如何启动一个kernel thread?(#include <linux/kthread.h> ; kthread_run(func, &data, “name“);)
Linux内核模块中有些时候需要启动一个thread来处理事务。本文提供一个模板,方便未来快速取用。原创 2024-12-27 08:49:38 · 241 阅读 · 0 评论 -
代码模板-Linux内核中代码流程如何sleep随机时间?(#include <linux/delay.h> usleep_range(1000, 2000))
linux内核提供了很多delay的技术,本文是第二篇使用usleep_range的方式,之前还提供过一种用completion的timeout机制实现的。usleep_range的机制可以提供一个随机delay的时间值。原创 2024-12-27 08:11:18 · 268 阅读 · 0 评论 -
【1000个Linux内存知识-018】-IOMMU是什么?其中的两个单元分别是什么?作用是什么?
IOMMU(Input/Output Memory Management Unit)输入输出内存管理单元。原创 2024-12-14 13:23:59 · 1783 阅读 · 0 评论 -
微代码-Linux pcie驱动是如何将driver和device绑定到一起,以及何时调用的?(pci_device_id table、配置空间)
设备中通过在PCIe配置空间的前四个字段来配置对应的vendorid和deviceid(这个信息是出厂的时候写入的,而且一般是先写入eeprom,然后网卡固件加载的时候写入pcie的配置空间)。driver通过指定vendorid和deviceid告诉内核pci子模块,该驱动支持的绑定的设备有哪些,以便有对应设备的时候可以直接调用。驱动注册的时候指定的PCIe驱动描述结构中会指定一个id表,这个表可以表示当前驱动可支持多个设备的id信息。本文零散的记录了一些Pcie设备和驱动是如何匹配的以及热插拔的流程。原创 2024-12-08 13:27:23 · 1492 阅读 · 0 评论 -
微代码-Linux PCIe驱动模块注册的两种方式?(pci_register_driver、module_pci_driver、pci_unregister_driver)
PCIe驱动可以通过内核模块标准的init exit里面调用注册接口注册,也可以通过更高效的pcie模块专用初始化定义接口。本文以rtl8168网卡为例简要说明。原创 2024-12-08 11:31:32 · 835 阅读 · 0 评论 -
微知-如何使用grubby修改系统启动的默认参数?(grubby --update-kernel=xxx --args=xxx; grubby --info=ALL)
有些内核不使用grub或者启动使用UEFI等配置后,造成使用经典的/etc/default/grub不生效。有些时候有办法找到真正的/boot目录下的文件,直接修改问题。还有可以使用grubby给Linux系统的启动参数添加参数。比如以iommu等参数为例。原创 2024-11-22 02:55:30 · 588 阅读 · 0 评论 -
微知-Linux内核自带的模块被压缩为ko.xz后如何恢复成不压缩版本?(xz -d xxx.ko.xz)
在使用crash定位问题的时候需要使用ko使用对应的符号信息。直接用ko.xz无法正确加载。需要恢复成ko文件。本文介绍如何解压缩。原创 2024-10-25 00:48:55 · 652 阅读 · 0 评论 -
微知SOP-定位Linux crash问题的几个常用方面和常用命令?
尤其其中的结合SP堆栈指针SP + rd + struct能够看到表面现象背后很多隐藏的数据,打开了一闪通往真相的大门,灵活运用并结合反汇编和操作系统函数调用应该算一个高阶功法了。然后用struct 获取数据:(这里因为用了内核自带的mlx的代码,没有源码,如果用OFED自己编译便能打印详细的详细的数据),下次自己编译后再处理。这里的SP是堆栈指针,堆栈是从上到下长的。周边的数据,可能找到参数,另外就是读取出来的地址有0或者1这些非0xfff等比较大的地址,就要注意,可能是突破点。说明堆栈读取的还不够。原创 2024-10-24 23:35:17 · 794 阅读 · 0 评论 -
【微码】Mellanox中的ib_device_ops是如何“分工实现,合作初始化”的?
从上面多个ib_set_device_ops可以看到,同一个dev的操作函数,会使用多个dev_ops进行set,并且set方式是设置方都定义自己的ib_dev_ops,并把自己支持的ib_dev_ops赋值,其他的为空不设置。通用Linux驱动大多采用类似file_ops的方式解耦驱动具体实现和驱动上层业务实现,但是在Mellanox中可能由于驱动模块的复杂性,涉及到多个子模块。my_set_device_ops(dev, modulea_ops)调用完就分工初始化一个完整的device_ops。原创 2024-10-19 08:15:30 · 249 阅读 · 0 评论 -
微知-如何查看mellanox网卡独立中断数量,中断号,绑定在哪个CPU,每个中断在不同CPU产生数量?
在主机侧中断数量 中断号可以在/proc/interrupt文件中查看,该文件每一行对应一个中断号,最后两列显示中断类型和中端名字。关于中断绑定问题,mellanox网卡将中断根据CPUID顺序绑定,每个中断在具体哪个CPU可以在/proc/irq/xxx/sm_affinity_list文件中,如果是1表示该中断绑定到CPU1的。要查看所有的eth中断可以先在proc interrupts文件中得到eth所有的中断号之后,遍历irq目录,在每个中断目录下打印前面提到的s a l文件中的绑定CPU。原创 2024-09-27 09:07:03 · 476 阅读 · 0 评论 -
微知-linux内核中PCIe驱动扫描后驱动加载为什么有两种类型的resource?分别是什么?
因为当应用程序访问某个地址空间的时候 CPU访问地址的时候 通过host bridge发送地址,mmu会自动过滤掉io空间的地址,经由pcie host bridge进行访问io设备的资源。所以本文开始提出的在扫描中驱动加载显示bar资源的需要的两种内存类型,是设备用来表示它所使用的两种内存介质,一种是用自己的配置空间的地址,另外一种是使用物理内存的地址。在PCIE的配置空间的bar(基础地址寄存器)空间里面 每一个伴都会告诉内核,他所需要的空间大小 以及它所使用的空间类型。原创 2024-08-24 02:05:15 · 447 阅读 · 0 评论 -
微知-如何给某个文件打开linux内核的动态打印开关?(echo -n ‘file probe.c +p‘ > /sys/kernel/debug/dynamic_debug/control)
printk 只能支持7个等级,并且是全局统一开关。粒度太粗。如何做到动态开关某个文件的debug?linux内核提供了dynamic debug的机制(后文称dd)。本文以pci驱动中的probe.c为例子介绍 开启内核中已使用了dd模块并且并已编译到内核的模块如何直接开启打印。原创 2024-08-22 08:54:51 · 893 阅读 · 0 评论 -
Linux eth接口的sysfs文件中rx_page_cache/log_mult_limit作用是什么?(倍数限制,rx page cache对于ing buffer的膨胀系数)
本文介绍Linux内核协议栈标准实现中,关于rx_page_cache的log_mult_limit参数的作用、机理和常见值。以对Linux内核协议栈同网卡之间进行数据交互的资源有一个切片认识。原创 2024-08-14 03:09:51 · 1381 阅读 · 0 评论 -
【微知识】Linux网络驱动中的3个主要层次结构与主要函数?dev_queue_xmit->hard_start_xmit->xxx_xmit、netif_rx
fill:#333;color:#333;color:#333;fill:none;网络协议网络协议接口层网络设备接口层设备驱动层是设备接口层的实现网卡硬件。原创 2024-07-01 00:37:54 · 704 阅读 · 0 评论 -
【微代码】Linux异步执行机制work基本用法?
Linux内核提供诸多异步执行机制,work就是其中一种。work的提供避免了启动多个内核线程造成资源占用等问题。内核提供一个专门的work来进行处理。本文主要记录work的基本用法。原创 2024-06-28 23:58:51 · 257 阅读 · 0 评论 -
【微代码】Linux同步机制complete基本用法,以及如何封装一个内核态sleep的工具函数ksleep?
Linux提供了多种同步机制,其中complete就是一种。complete能够阻塞等待状态同步,并且等待对方释放中会调用schedule让出CPU。如果想在内核中等待一个固定时长继续执行他是一个非常不错的选择。有点类似用户态的sleep功能。可以定义一个函数,在函数中定义,等待来达到类似sleep的效果。下面的代码可以直接copy后使用。原创 2024-06-28 23:49:00 · 427 阅读 · 0 评论 -
sysrq的常见参数-快速查询版
参考:原创 2024-06-26 01:09:52 · 393 阅读 · 0 评论 -
【微记录】linux如何使用ebpf观测你的某个命令调用了内核的ioctl?(bpftrace sys_enter_ioctl)
对于工程实践中需要查看某些ioctl是否被调用,尤其是一个新的模块初次调试,在不添加调试命令debug的情况下如何观测?另外就是对于外部提供的二进制程序,如何观测该程序是否调用ioctl以及何时调用?这些都通过ebpf能够良好的观测。原创 2024-05-15 02:13:26 · 288 阅读 · 0 评论 -
Linux动态观测神器bpftrace的5种探针、7个常见内置变量和常见操作?
bpftrace使用 LLVM 作为后端将脚本编译为 BPF 字节码,利用 BCC(BPF Compiler Collection)与 Linux BPF 系统进行交互。原创 2024-05-08 00:26:29 · 973 阅读 · 0 评论 -
关于Linux内核调试中几个工具kprobe、ftrace、ebpf关系的简单记录(本质是预留的nop)
最近和行业大佬探讨关于Linux内核中kprobe、ftrace、ebpf关系的一些,特此记录:原创 2024-04-23 01:14:23 · 480 阅读 · 0 评论 -
编译Linux内核模块遇到/lib/modules/.../build: No such file or directory怎么办?以及kernel-devel和kernel-header作用?
那么就依赖/lib/module/uname−rbuild有相关的编译信息,比如所有的symbol等以及编译框架。libmodules(shell uname -r)/build是一个软连接,指向实际的内核源码。实际的内核源码在 /usr/src/kernels/uname−r而这个usrsrckernels(uname -r)就是kernel-devel的rpm安装后的内核信息。原创 2024-04-17 01:24:04 · 5623 阅读 · 1 评论 -
Linux的3个debug rpm包有什么区别kernel-debuginfo-common、kernel-debuginfo、kernel-debug-debuginfo?(源码、库、库)
kernel-debug-debuginfo 是debug版本linux的debuginfo库,本质是库,同kernel-debuginfo。kernel-debuginfo-common 主要是编译linux的与架构无关的,本质就是源码。yum源列出的mirror上的rpm包:(注意yum本质只是一个包管理框架,包本质都是这些rpm包)kernel-debuginfo 主要是vmlinux、所有的ko等,会copy文件到。原创 2024-04-17 00:27:58 · 1066 阅读 · 0 评论 -
【1000个GDB技巧之】如何在远端服务器打开通过vscode动态观测Linux内核实战篇?
(也可以直接在vscode中配置,忽略)主要步骤:在~/.ssh/config中添加服务端的host,以便vscode的remote中能够登录。原创 2024-04-14 10:22:58 · 1105 阅读 · 0 评论