此标记用于解决Linux内核本身的内部问题 - 特别是关于编写在内核上下文中运行的代码(如内核模块或驱动程序)。关于在Linux中编写用户空间代码的问题通常应该标记为[linux]。由于Linux内核的内部不断变化,因此包含您感兴趣的精确内核版本会很有帮助。
x86_64 汇编:为什么当 char *buf 大于 size_t count 时会发生这种情况?
我正在我的 Linux 机器上尝试 x64 汇编中的一些东西。然而我遇到了一个小错误或意外的行为。 在 .bss 部分中,我在内存中保留了 16 个字节,我称之为“name&q...
cgroups v2 不支持elasticsearch 2.2.x
Elasticsearch < 5.2.x has a bug that prevents it to work with Linux kernel > 4.5 自 cgroup v2 引入以来 https://www.kernel.org/doc/Documentation/cgroup-v2.txt 它不会被修复,因为我...
最近,我的Linux机器上的Tomcat进程突然被杀死了。经过调查,我在 /var/log/messages 文件中发现以下错误消息: 内核:[1799319.246494]内存不足:杀死进程 2...
我是 Linux 内核模块编程的新手,许多关于该主题的入门指南都很少包含有关如何构建将在许多版本和 CPU 平台上运行的内核模块的信息...
我正在尝试编写内核模块,用于在给定地址设置硬件断点并在读/写访问时触发回调,寄存器看起来还不错,但访问时不会触发回调...
(initramfs)退出 /dev/sda2 包含一个有错误的文件系统,强制检查。 发现属于损坏的孤立链表的一部分的索引节点。 /dev/sda2:意外的不一致;手动运行 fsck。 (...
为什么 bootsect 在 linux(x86) 中将自身移至 0x90000?
我正在研究x86系统启动的过程 这是启动流程: BIOS 将 bootsect 从磁盘 MBR 加载到 0x7c00 内存地址 booect 将自身复制到 0x90000 内存地址并跳转到
使linux内核函数在ftrace中显示available_filter_function
我想使用 ftrace 跟踪 perf_event_open,但它没有显示在 available_filter_function 中。事实上,似乎只显示了模块中加载的函数。 是否有默认的黑名单...
我正在尝试学习Linux并用我的简单驱动程序编译内核。 不幸的是,我在日志中没有看到驱动程序,并且未创建编译文件。 #包括 #inc...
如何在 x86 上通过 Linux KVM API 实例化基于 ARM 的虚拟机?
假设我有一台 x86 机器。通过 Linux KVM API 可以轻松创建 x86 VM。 请参阅:kvm-host 中的 vm_init(): if ((v->kvm_fd = open("/dev/kvm", O_RDWR)) < 0) return throw_err(&q...
我正在尝试为我的小米 Mi4i 的内核编译 wlan 驱动程序。 我能够成功编译 wlan.ko 文件。 我还在手机上使用了我编译过的相同内核......
我想用mod_timer来定时器10毫秒,但是结果总是20毫秒
我的驱动测试代码,我想用mod_timer来定时器10毫秒,但结果总是20毫秒。它出什么问题了? .. #包括 #包括 我的驱动测试代码,我想用mod_timer来定时器10毫秒,但结果总是20毫秒。它出什么问题了? .. #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/timer.h> #include <linux/jiffies.h> #include <linux/unistd.h> #include <linux/delay.h> static struct timer_list my_timer; void my_timer_callback(struct timer_list *timer) { printk("my_timer_callback called (%lu).\n", jiffies); mod_timer(&my_timer, jiffies + msecs_to_jiffies(10)); } static int __init my_init(void) { printk("Timer module loaded\n"); timer_setup(&my_timer, my_timer_callback, 0); mod_timer(&my_timer, jiffies + msecs_to_jiffies(10)); return 0; } static void __exit my_exit(void) { printk("Timer module unloaded\n"); del_timer(&my_timer); } module_init(my_init); module_exit(my_exit); MODULE_AUTHOR("[email protected]"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); dmesg 结果: [ 70.391971] my_timer_callback called (4294944328). [ 70.411947] my_timer_callback called (4294944330). [ 70.431944] my_timer_callback called (4294944332). [ 70.451961] my_timer_callback called (4294944334). 内核版本:5.10 .配置: CONFIG_HZ=100 根据 OP 的经验,以及本电子邮件消息中所述,在调用计时器到期函数时,由于某些 CPU 正在读取旧的 jiffies 值,而另一个 CPU 正在更新它,因此可能会出现一 jiffy 延迟。 由于 OP 的计时器回调函数会在 jiffies 上添加一个相对量来设置下一个到期时间,因此回调之间的时间可能比所需的时间长一瞬间。可以通过将下一个到期时间设置为相对于前一个到期时间来缓解这种情况。如果一瞬间延迟一致,则所有回调函数将延迟一瞬间运行。但是,有些回调函数可能会按时运行,有些会延迟运行,这可能是不希望的。 如果用例需要更精确的计时,最好使用 hrtimer API,如下面 OP 代码的修改版本所示: #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/hrtimer.h> #include <linux/unistd.h> #include <linux/delay.h> static struct hrtimer my_timer; static enum hrtimer_restart my_timer_callback(struct hrtimer *timer) { s64 now = ktime_to_ns(hrtimer_cb_get_time(timer)); s64 expires = ktime_to_ns(hrtimer_get_softexpires(timer)); s64 diff = now - expires; printk("my_timer_callback called (now %lld, expired %lld, diff %lld).\n", now, expires, diff); hrtimer_add_expires_ns(timer, 10 * NSEC_PER_MSEC); return HRTIMER_RESTART; } static int __init my_init(void) { printk("Timer module loaded\n"); hrtimer_init(&my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); my_timer.function = my_timer_callback; hrtimer_start(&my_timer, ktime_add_ms(hrtimer_cb_get_time(&my_timer), 10), HRTIMER_MODE_ABS); return 0; } static void __exit my_exit(void) { printk("Timer module unloaded\n"); hrtimer_cancel(&my_timer); } module_init(my_init); module_exit(my_exit); MODULE_AUTHOR("[email protected]"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); 模块的 dmesg 输出示例如下所示: [ 7119.967286] my_timer_callback called (now 7119822903369, expired 7119822900229, diff 3140). [ 7119.977294] my_timer_callback called (now 7119832911804, expired 7119832900229, diff 11575). [ 7119.987347] my_timer_callback called (now 7119842964493, expired 7119842900229, diff 64264). [ 7119.997286] my_timer_callback called (now 7119852903102, expired 7119852900229, diff 2873). [ 7120.007348] my_timer_callback called (now 7119862964879, expired 7119862900229, diff 64650). [ 7120.017348] my_timer_callback called (now 7119872964924, expired 7119872900229, diff 64695). [ 7120.027347] my_timer_callback called (now 7119882964377, expired 7119882900229, diff 64148). [ 7120.037333] my_timer_callback called (now 7119892950004, expired 7119892900229, diff 49775). [ 7120.047348] my_timer_callback called (now 7119902964627, expired 7119902900229, diff 64398). [ 7120.057348] my_timer_callback called (now 7119912964748, expired 7119912900229, diff 64519). [ 7120.067337] my_timer_callback called (now 7119922952994, expired 7119922900229, diff 52765). [ 7120.077350] my_timer_callback called (now 7119932966586, expired 7119932900229, diff 66357). [ 7120.087348] my_timer_callback called (now 7119942964245, expired 7119942900229, diff 64016). [ 7120.097334] my_timer_callback called (now 7119952950074, expired 7119952900229, diff 49845). [ 7120.107351] my_timer_callback called (now 7119962966616, expired 7119962900229, diff 66387).
我有一个可加载的内核模块,其初始化如下所示 静态 int __init id_init(void) { 结构体身份*temp; /* 一些与问题无关的代码 */ 温度 =
Bluez HCI_CHANNEL_USER 套接字。文件描述符处于错误状态
我正在尝试在 hci 接口上创建和使用用户通道套接字。这是代码 在main.c中: int devsocket = open_dev(dev_id); if(devsocket < 0){ perror(&q...
我最近对我的 OpenMediaVault 机器进行了完整的系统升级。该更新包括内核更新。更新后,我意识到我的 nvidia 卡不再按预期工作,因为博士...
如何让 CLion 识别 linux/init.h 和其他 linux 内核头文件?
我正在尝试使用 CLion 进行一些 Linux 内核编程。我观察到一些标题,如 和 被正确识别,但其他一些标题,如 我正在尝试使用 CLion 进行一些 Linux 内核编程。我观察到一些标题,如 <linux/kernel.h> 和 <linux/module.h> 被正确识别,但其他一些标题,如 <linux/init.h> 则未被正确识别。 为了更清楚,这里有一个示例程序: 1 #include <linux/init.h> 2 #include <linux/kernel.h> 3 4 int init_module(void) { 5 printk("initializing"); 6 return 0; 7 } 这里,我的第 1 行和第 5 行以红色突出显示,并带有典型的“未找到文件”/“调用未声明的函数”错误,但第 2 行正确地未突出显示,并且如果我尝试编写链接到该库的内容完全没有问题。 我尝试为我的内核安装最新的标头,即sudo apt install linux-headers-$(uname -r),但它似乎不起作用。我能做什么? 编辑: 输出locate init.h | grep linux/init.h (some thimeshift things...) /usr/src/linux-headers-5.4.0-187/include/linux/init.h /usr/src/linux-headers-5.4.0-189/include/linux/init.h /usr/src/linux-headers-5.4.0-74/include/linux/init.h ...这很好奇,因为我的内核版本是5.4.0-190,并且sudo apt-get install linux-headers-$(uname -r)的输出如下(手动翻译成英文): ... linux-headers-5.4.0-190-generic is already at the most recent version (5.4.0-190.210). ... 编辑: 添加 CMake 文件有点有效 include_directories(/usr/src/linux-headers-5.4.0-187/include/),但这只是一个“补丁”,而不是解决方案,所以我将问题悬而未决,希望得到一些更“明确”的答案 事情没那么简单,有两个主要原因: CLion 想要使用 CMake,因此您必须编写一个自定义 CMakeLists.txt 来查找内核标头并调用 make 来调用内核 Makefile 并使用自定义命令构建模块。这并不容易,因为内核 Makefile 相当复杂,需要正确定义许多变量。 正如您似乎已经发现的那样,通常当前内核的内核头位于 /usr/src/linux-headers-$(uname -r)/。但是,.h C 头文件位于不同的目录中。在 headers 目录中,我知道至少有 4 个不同的包含目录:include、include/generated、arch/XXX/include 和 arch/XXX/include/generated。这些都需要包括在内。 使用 CLion 构建内核模块的 CMakeLists.txt 鉴于上述情况,构建内核模块的 CMakeLists.txt 应该执行以下操作: 查找当前的内核版本(使用 uname -r 命令)。 在 /usr/src/linux-headers-$(uname -r) 找到内核头文件。我们将此路径保存在 KDIR 变量中。 指定要构建的架构。我们将为此设置一个 ARCH 变量。没有简单的方法可以自动执行此操作,因为像 uname -m 这样的命令行工具会输出错误的名称(例如 x86_64 而不是 x86)。 使用 include_directories() 包含适当的目录。 生成 Kbuild(或 Makefile)文件来构建模块。 使用 make 运行自定义 custom_command() 命令来构建模块。 最后,声明一个 dummy_target 目标用于依赖性检查。 最终结果如下: cmake_minimum_required(VERSION 3.28) project(mymod C) set(CMAKE_C_STANDARD 99) add_definitions(-D__KERNEL__ -DMODULE) # Find running kernel release execute_process( COMMAND uname -r OUTPUT_VARIABLE KERNEL_RELEASE OUTPUT_STRIP_TRAILING_WHITESPACE ) set(KDIR "/usr/src/linux-headers-${KERNEL_RELEASE}") set(ARCH "x86") # Check that the headers are installed if (NOT EXISTS "${KDIR}/include/linux/module.h") message(FATAL_ERROR "Kernel headers dir not found: ${KDIR}") endif() # Check that the headers are for the specified arch if (NOT EXISTS "${KDIR}/arch/${ARCH}/include") message(FATAL_ERROR "Arch-specific include dir not found: ${KDIR}/arch/${ARCH}/include") endif() message(NOTICE "Building for arch: ${ARCH}") message(NOTICE "Kernel release: ${KERNEL_RELEASE}") message(NOTICE "Kernel headers: ${KDIR}") # Include generic kernel headers include_directories("${KDIR}/include") include_directories("${KDIR}/include/generated") # Include arch-specific kernel headers include_directories("${KDIR}/arch/${ARCH}/include") include_directories("${KDIR}/arch/${ARCH}/include/generated") # Set some useful variables set(MODULE_NAME mymod) set(SRC_FILE "${MODULE_NAME}.c") set(OBJ_FILE "${MODULE_NAME}.o") set(KO_FILE "${MODULE_NAME}.ko") # Generate Kbuild file in the source directory FILE(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Kbuild "obj-m := ${OBJ_FILE}") # Custom `make` command used to build the module add_custom_command( OUTPUT ${KO_FILE} COMMAND $(MAKE) -C ${KDIR} modules ARCH=${ARCH} M=${CMAKE_CURRENT_BINARY_DIR} src=${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${SRC_FILE} VERBATIM ) add_custom_target(mymod ALL DEPENDS ${KO_FILE}) add_library(dummy_target "${SRC_FILE}") 上面的CMakeLists.txt可以很好地构建以下mymod.c内核模块: #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> int __init myinit(void) { pr_info("Hello World!\n"); return 0; } void __exit myexit(void) { pr_info("Goodbye World!\n"); } module_init(myinit); module_exit(myexit); MODULE_VERSION("0.1"); MODULE_AUTHOR("Marco Bonelli"); MODULE_DESCRIPTION("Test module"); MODULE_LICENSE("GPL 2.0"); 注意,MODULE_LICENSE()是强制性的,如果没有指定许可证,内核Makefile将拒绝构建模块! 最终项目在 CLion 中应如下所示: 注意:Kbuild文件是由CMakeLists.txt自动生成的。您需要写入的唯一两个文件是 CMakeLists.txt 和 mymod.c。 唯一的问题(我不确定如何解决)是,正如您从上面的屏幕截图中看到的那样,CLion 似乎认为它还应该考虑用户空间包含诸如 /usr/include、/usr/x86_64-linux-gnu/include 等目录。这些绝对应该不被考虑用于内核模块,但我不确定如何使用CMakeLists.txt禁用/删除它们。
我可以在不修改以太网驱动程序的情况下将数据包注入Linux TCP堆栈吗?我可以使用图书馆或其他东西来做到这一点吗? 谢谢你
Linux 内核如何知道在 platform_data 中放入什么内容?
我正在分析设备驱动程序,例如TI TCA6408设备,驱动程序是gpio-pca953x。在 ->probe() 函数中,有一个从设备检索平台数据的部分: 静态整型
如何找出哪些所有线程在 2 个特定点之间获得了 CPU 时间?
我在linux 4.1上运行 我有一个用户模式应用程序。 在该应用程序中,我想找出哪些线程必须在 CPU 上运行,每个线程必须在 CPU 上运行多长时间,以及我的线程需要运行多长时间...
/lib64/ld-linux-x86-64.so.2:没有这样的文件或目录错误
背景 我正在使用 docker 来做一个学校项目。具体来说,我提取了一个 ubuntu 映像,这是系统配置: 然后我登录到 docker 容器(ubuntu)并设置elasticsearch...