Linux内核之设备树插件DTO
Linux内核之设备树插件DTO什么是DTO(Device Tree Overlay)Linux4.4以后引入了动态设备树(Dynamic DeviceTree),我们这里翻译为“设备树插件”,或者称“设备树叠加层”。设备树插件(Device Tree Overlay,叠加层)是一种用于设备树(Device Tree)的扩展机制,可以理解为主设备树的“补丁”它动态的加载到系统中,无需重新编译整个设备树。它允许在运行时动态修改设备树的内容,以便添加、修改或删除设备节点和属性,这样就提供了一种灵活的方式来配置和管理硬件设备,而无需重新编译整个设备树。
几个概念
FDT: Flattened Device Tree
DTS: Devicetree Sources,是用于描述 FDT(设备树) 的源文件
DTO: Devcie Tree Overlay,设备树插件(或者说叠加层)
DTC: Device Tree Compiler,顾名思义,是FDT(设备树) 的编译器
DTB: Device Tree Blob,DTS经过DTC编译后而生成
DTBO: Device Tree Bl ...
Linux内核之Kselftests
Linux内核之Kselftests简介Linux内核包含了一套开发者可用的单元测试和回归测试(Kselftests),这些测试位于内核源代码的tools/testing/selftest目录下。这些测试旨在针对内核中的各个代码路径进行小规模的测试。测试应该在构建、安装和启动内核之后运行。
它每天都会在不同的Linux内核树(即代码库)的内核集成测试环境上运行,主要是为了确保内核代码在合并到主干之前,在各种场景和配置下都能正常工作,从而提高内核的整体稳定性和可靠性。
kselftest的一些特性:
快速执行测试的能力(目前的目标是不到20分钟)
一些开发人员希望在几秒钟内运行测试
运行不同测试组的能力
测试源代码保存在内核源代码树中,任何使用内核源代码的人都可以很容易地访问它
可以在 Kselftest-wiki 上找到关于Kselftest框架的其他信息,以及如何使用该框架编写新的测试。
编译运行及安装相关的命令如下:
#编译
$ make headers
$ make -C tools/testing/selftests
#运行tests
$ make -C tools/t ...
重新梳理OpenHarmony的HDF
概述重新梳理下OpenHarmony下HDF的有关概念及从应用到驱动自上而下的整个流程。主要包括:
HDF架构
HDI接口
内核KHDF移植
以Light设备为例,看看整个调用流
注:这里讨论的只针对L2标准系统。
HDF架构图HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路,让驱动开发和部署更加规范,旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的驱动管理的开发环境,力求做到一次开发,多系统部署。
驱动加载HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能
驱动服务管理HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务
驱动消息机制HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息
配置管理HCS是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置 ...
Linux调试中的各种trace
Linux调试中的各种traceLinux中有很多调试手段,很多trace,很让人迷糊,弄得云里雾里。今天简单介绍下其中的几种trace:ptrace, strace, ltrace, ftrace 。只是简单介绍它们的基本概念,对其有基本的了解,后面有机会的话,再逐个深入。
ptrace官方手册说明:https://man7.org/linux/man-pages/man2/ptrace.2.html
The ptrace() system call provides a means by which one process (the “tracer”) may observe and control the execution of another process (the “tracee”), and examine and change the tracee’s memory and registers. It is primarily used to implement breakpoint debugging and system call tracing.进程跟踪器,类 ...
PulseAudio与蓝牙音频
PulseAudio与蓝牙音频背景Linux下面是怎么使用蓝牙音频的呢? 今天我们一起来看看,通过命令行使用 PulseAudio 来联动蓝牙音频。
PulseAudio与Bluetooth音频PulseAudio的所有蓝牙功能都依赖于BlueZ,此外,HFP支持还需要oFono。PulseAudio 支持3个主要的和音频相关的蓝牙profiles:
A2DP (Advanced Audio Distribution Profile)
HSP (Headset Profile)
HFP (Hands-Free Profile)
PulseAudio蓝牙后端
Bluetooth backend listens to BlueZ and oFono events on D-Bus and automatically creates PulseAudio cards, sources, and sinks for all discovered Bluetooth devices.PulseAudio的蓝牙后端会监听D-Bus上的BlueZ和oFono事件,然后对于多有发现的蓝牙设备自动地 ...
内核中的格式化打印
背景最近在调试个异常卡死的问题时,需要打印某个pcie link的,故学习了下内核里的打印,特此记录。
printk(“acpi_pci_link_set–>%pfwf, irq: %d\n”, &link->device->fwnode, irq);
内核中的格式化打印主要分为整型和指针。
整型signed char %d or %hhx
unsigned char %u or %x
char %u or %x
short int %d or %hx
unsigned short int %u or %x
int %d or %x
unsigned int %u or %x
long %ld or %lx
unsigned long %lu or %lx
long long %lld or %llx
unsigned long long %llu or %llx
size_t %zu or %zx
ssize_t %zd or %zx
s8 %d or %hhx
u8 %u or %x
s16 %d or %h ...
Linux内核调试工具之Kprobes简单使用
Linux内核调试工具之Kprobes简单使用上次看了下Kprobes的相关概念:Linux内核调试工具之Kprobes相关概念,这里看看它的简单使用
配置Kprobes内核需要打开以下配置:
CONFIG_KPROBES = y
#保证能加载和卸载基于Kprobes的模块
CONFIG_MODULES = y
CONFIG_MODULE_UNLOAD = y
#kprobe地址解析使用了kallsyms_lookup_name()
CONFIG_KALLSYMS_ALL = y
CONFIG_DEBUG_INFO = y
API请参考官方文档,这里不赘述了。
使用使用 kprobes主要有以下两种方式:
通过编写内核模块
kprobes on ftrace
通过编写内核模块通过编写内核模块,向内核注册探测点。探测函数可根据需要自行定制,使用灵活方便,官方例子就是这种方式。
官方例子内核源码中有2个关于kprobes的2个例子:
kprobes例子:内核源码/samples/kprobes/kprobe_example.c
...
Linux内核几个重要文件之System.map
Linux内核几个重要文件之System.mapWhat什么是System.map文件?
System.map是编译内核时生成,它记录了文件内核中的符号列表,以及符号在内存中的虚拟地址,这里的符号可以理解成函数名和变量。System.map文件不是一成不变的,每次编译内核都会重新生成System.map文件。
下面我们简单看看System.map文件里面的内容
System.map文件内容下面列出了我最近编译的6.8内核的System.map(前20行):
00000000009f5a00 A __pecoff_data_raw_size
0000000000a78000 A __pecoff_data_virt_size
ffffffff80000000 T _start
ffffffff80000040 t pe_head_start
ffffffff80000044 t coff_header
ffffffff80000058 t optional_header
ffffffff80000070 t extra_header_fields
ffffffff800000f8 t ...
Linux内核调试工具之Kprobes相关概念
Linux内核调试工具之Kprobes相关概念背景及概念Kprobes: Kernel Probes
背景
开发人员在内核或者模块的调试过程中,往往会需要要知道其中的一些函数有无被调用、何时被调用、执行是否正确以及函数的入参和返回值是什么等等。
比较简单的做法是在内核代码对应的函数中添加日志打印信息,但这种方式往往需要重新编译内核或模块,重新启动设备之类的,操作较为复杂甚至可能会破坏原有的代码执行过程。
而利用kprobes技术,用户可以定义自己的回调函数,然后在内核或者模块中几乎所有的函数中动态的插入探测点,当内核执行流程执行到指定的探测函数时,会调用该回调函数,用户即可收集所需的信息了,同时内核最后还会回到原本的正常执行流程。
如果用户已经收集足够的信息,不再需要继续探测,则同样可以动态的移除探测点。因此kprobes技术具有对内核执行流程影响小和操作方便的优点。
概念目前有两种类型的探针:kprobes和 kretprobes(也称为return probes)。
kprobe是最基本的探测方式,几乎可以插入到内核中的任何指令上。它提供了探测点的调用前、调用后和内存访问出错3种 ...
基于QEMU搭建RISC-V的Linux环境
基于QEMU搭建RISC-V的Linux环境背景和之前搭建x86的类似(基于QEMU的内核调试环境搭建),只是需要交叉编译即可,重点其实是在交叉编译工具链。
前提:QEMU已安装好!
准备工具链RISC-V支持GNU工具链和LLVM工具链,目前主流Linux发行版好像都没有预编译的二进制包可以下载安装,只能自己通过源码编译安装。
获取工具链源码$ git clone https://gitee.com/mirrors/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
注意上面 clone 的主仓库并不包含子仓库的内容,所以需要继续更新子仓库。注意这里首先排除了 qemu 这个子仓库,一来因为 qemu 完整下载太大;二来 qemu 对 toolchain 的编译本身来说其实并不需要。
$ git rm qemu
$ git submodule update --init --recursive
上面的过程可能要点时间,需要耐心等待。。。
编译安装工具链riscv-gnu-toolchain工具链分 elf-gcc、linux-gnu-gcc ...
让Windows成为更好用的Linux发行版之WSL2折腾NFS
让Windows成为更好用的Linux发行版之WSL2折腾NFS背景生命不息,折腾不止。前段时间,为了让WSL更好地来开发Linux和OH,折腾出了一系列文章:
WSL2相关
wsl2上折腾docker
解决WSL2网络和存储问题
上次把WSL2的网络弄好了,最近就准备将开发环境更进一步,开始折腾NFS。以为和Ubuntu主机上搭建NFS一样(嵌入式Linux基础开发环境搭建),简单的一条命令加配置就搞定了,但后面发现根本不是那么一回事。而且网上也很少有完整实用的借鉴参考,只能自己摸索,实战出真知。
启用systemdWSL2默认是没有启用systemd,但很多程序是依赖它的,特别是需要开机启动的。在发行版中添加配置文件/etc/wsl.conf,并加入如下内容:
[boot]
systemd=true
安装配置NFSsudo apt install nfs-common nfs-kernel-server rpcbind
新建一个目录(如这里的/home/xxx/nfs),作为NFS的目录,修改/etc/export,在最后添加如下一行:
/home/xxx/nfs * ...
使用GDB和VSCode调试内核
使用GDB和VSCode调试内核背景上一篇,已经搭建好QEMU的内核调试环境:https://notes.z-dd.online/2024/03/06/%E5%9F%BA%E4%BA%8EQEMU%E7%9A%84%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/
这篇主要在前面的基础上尝试用gdb来调试内核,躺了不少坑。
安装GDB这里安装支持多种硬件体系架构的GDB版本,也可直接使用系统自带的默认gdb。如架构不同,需使用交叉编译工具链中的gdb,后面有时间会更新不同架构下的调试。
sudo apt-get install -y gdb-multiarch # 支持多种硬件体系架构的GDB版本
准备调试内核在以前的基础上需修改一些内核配置才能调试:
打开CONFIG_GDB_SCRIPTS:在内核主目录下生成gdb脚本文件vmlinux-gdb.py,该脚本实现了一些便于内核调试的命令,它们都以lx-开头,这个暂时先没用,后面再研究看看
打开CONFIG_DEBUG_INFO:该选项用 ...