Tag: linux kernel

线程通过sysfs调用内核信号量的死锁

源于这个问题 (和我的解决方案 ),我已经意识到可能存在死锁,但我无法理解为什么以及如何避免它。 简而言之,内核空间中有一个semaphore ,即内核模块(它们实际上是在内核空间中运行的应用程序)可以采用,但用户空间应用程序也需要使用相同的信号量来保护全局共享内存。 我通过公开给出正确字符的sysfs文件,在内核空间中down或up信号量来完成此操作。 用户空间应用程序只是保持此文件打开并为锁定write适当的字符。 这是一个用于演示的示例内核模块: #include #include #include #include MODULE_LICENSE(“GPL”); MODULE_AUTHOR(“Shahbaz Youssefi”); MODULE_DESCRIPTION(“Test module”); static struct kobject *_kobj = NULL; static struct semaphore sem; static ssize_t _lock_op(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { switch (buf[0]) { case ‘0’: printk(“down (%u)\n”, sem.count); if (down_interruptible(&sem)) printk(“error: sem wait interrupted\n”); […]

并发I / O – 缓冲损坏,阻止设备驱动程序

我开发块分层设备驱动程序。 因此,我拦截WRITE请求并加密数据,并在end_bio()例程中解密数据(在处理和READ请求期间)。 所以一切都在单流中正常工作。 但是如果尝试同时从两个或多个进程执行I / O,我会得到缓冲区内容损坏。 我没有缓冲区的本地存储空间。 我是否需要在我的驱动程序中计算BIO合并? Linux I / O子系统是否有一些与并发I / O请求相关的要求? 是否有一些与堆栈使用或编译相关的技巧和窍门? 这是在内核4.15下。 当时我使用下一个收缩来运行磁盘扇区: /* * A portion of the bio_copy_data() … */ for (vcnt = 0, src_iter = src->bi_iter; ; vcnt++) { if ( !src_iter.bi_size) { if ( !(src = src->bi_next) ) break; src_iter = src->bi_iter; } src_bv = bio_iter_iovec(src, src_iter); […]

帮助理解宏

我有问题要理解MTD驱动程序中的一些代码 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) … static struct mtd_partition my_parts[] = { { .name = “boot”, .size = 0, .offset = 0, .mask_flags = MTD_WRITEABLE }, { .name = “linux”, .size = 0, .offset = 0 }, { .name = “rootfs”, .size = 0, .offset = 0, .mask_flags = MTD_WRITEABLE }, { .name = “nvram”, […]

在64位拱上投射指向整数问题警告的指针

我正在编写一个使用导出符号open_exec的linux内核模块 struct file *open_exec(const char *name) 它返回一个指针,我可以检查IS_ERR宏的错误: if (IS_ERR(file)) return file; 在编译期间,我收到此警告: warning: return makes integer from pointer without a cast 这是因为我的函数返回一个整数。 如果我尝试施放它: return (int) file; 我没有在我的32位机器上收到警告,但我在我的64位机器上发出警告: warning: cast from pointer to integer of different size 这是因为int和指针的sizeof在32位上是相同的,但它们在64位机器上是不同的。 无论是否投射,代码似乎都有效。 我只是想摆脱警告。 如何正确地转换指向整数的指针并获得我期望的值,同时没有得到编译器警告? 我期望的值本质上是linux内核代码库的include/asm-generic/errno-base.h中列出的整数。 由于我只是在IS_ERR()为真的情况下将指针看作是一个整数,我可以肯定它实际上只保存一个整数值。

Linux内核使用Eclipse构建配置

我尝试使用Eclipse来浏览Linux内核源代码。 如何让Eclipse知道在.config设置的构建配置分别在include/linux/autoconf.h #define ed? 我在Debian(稳定版)上使用Eclipse的Juno Service Release 1(Build id:20120920-0800)。 有用的是像项目库中gcc的选项-include 。

是否可以在Linux上使用C ++开发可加载的内核模块(LKM)?

当我开发一个可加载的内核模块(LKM)时,我应该使用C吗? 是否可以在Linux上使用C语言之外的其他语言(例如C ++)开发可加载内核模块(LKM)?

一起使用wait_event_interruptible和wake_up_all

对于涉及使用阻塞和锁定调度进程的类项目,我们应该使用两个内核函数: int wait_event_interruptible(wait_queue_head_t q, CONDITION); void wake_up_all(wait_queue_head_t *q); wait_event_interruptible的解释是: 阻止等待队列上的当前任务,直到CONDITION变为true。 这实际上是一个宏。 它重复计算CONDITION,它是C代码的一个片段,如foo == bar或function()> 3.一旦条件为真,wait_event_interruptible返回0.如果条件为false,则将当前任务添加到wait_queue_head_t列表与状态TASK_INTERRUPTIBLE; 当前进程将阻塞,直到调用wake_up_all(&q),然后它将重新检查CONDITION。 如果当前任务在CONDITION变为true之前收到信号,则宏返回-ERESTARTSYS。 而wake_up_all的解释是: 通过将状态设置为TASK_RUNNABLE来唤醒等待队列中的所有任务。 我很难弄清楚这些function究竟是如何工作的,以及如何将它们结合使用。 例如,何时检查CONDITION? wait_event_interruptible是否连续轮询,还是仅在调用wake_up_all时重新检查条件? 这个解释有点不清楚。 如果您可以举例说明如何将这些function结合使用,那将非常有用。

计算ARM Cortex-a8 BeagleBone Black上的时钟周期计数

我想计算我的c代码中特定函数的时钟周期计数,该函数将在BeagleBone Black上编译和运行。 我不知道我怎么能这样做。 我在网上搜索,发现了这条指令: Arndale板上的时钟读取方法: 步骤1:插入内核模块以启用对PMU计数器的用户空间访问。 解压附件文件“arndale_clockread.tar.bz2”,该文件包含Makefile和enableccnt.c。 在Makefile中用您的内核源目录更改“KERNELDIR”,例如/ usr/src/linux-kernel-version然后运行命令。 linaro@linaro-server:~/enableccnt$ make 上面的命令应该输出为enableccnt.ko ,这是内核模块,用于启用用户空间访问PMU计数器。 然后运行该命令。 linaro@linaro-server:~/enableccnt$ sudo insmod enableccnt.ko 以下命令应显示正在运行的内核中插入enableccnt模块。 linaro@linaro-server:~/enableccnt$ lsmod 步骤2:从用户空间应用程序中读取计数器。 一旦设置了内核模块。 以下function可用于读取计数器 static void readticks(unsigned int *result) { struct timeval t; unsigned int cc; if (!enabled) { // program the performance-counter control-register: asm volatile(“mcr p15, 0, %0, c9, c12, 0” :: “r”(17)); //enable […]

获取内核中当前运行程序的绝对路径

为了检索正在运行的程序的文件权限,我需要在当前运行的程序上执行kstat 。 然后我需要获取加载的ELF图像的绝对路径。 那可能吗? current->comm仅记录没有路径的程序名称。 或者其他什么方法呢?

如何在内核代码中获取子进程列表

我想到一个进程的子任务(进程)列表,这里是代码: void myFunc() { struct task_struct* current_task; struct task_struct* child_task; struct list_head children_list; current_task = current; children_list = current_task->children; child_task = list_entry(&children_list,struct task_struct,tasks); printk(“KERN_INFO I am parent: %d, my child is: %d \n”, current_task->pid,child_task->pid); } 当前的pid是正确的,但是孩子的pid不正确。 我究竟做错了什么?