Articles of kernel

Linux内核模块/ IOCTL:不适用于设备的ioctl

我正在编写一个作为伪驱动程序的Linux内核模块(LKM) – 我无法弄清楚如何在LKM( wait.c )和用户级程序( user.c )之间进行IOCTL调用)。 设备驱动程序的幻数是0xBF – LKM不与物理块/字符设备通信,这只是一个练习。 从我所知道的情况来看,调用KERN_IOCTL_CREATE_EVENT的IOCTL格式不正确,幻数也不正确。 我尝试使用的IOCTL调用是: #include <sys/ioctl.h> #define KERN_IOCTL_CREATE_EVENT _IOWR(WAIT_DEVICE_MAGIC, 1, int) int main(){ int ret; int fd; fd = open("/dev/wait", 0); if(fd < 0){ return -1; } ret = ioctl(fd, KERN_IOCTL_CREATE_EVENT, 0); 错误: [fail]: KERN_IOCTL_CREATE_EVENT: Inappropriate ioctl for device 用户模式应用程序可以打开/closures指向设备的文件描述符: /dev/wait但case / switch语句不接受IOCTL调用。 有什么build议么? 这是# uname -a的输出 […]

Hello World是Raspberry Pi 3上常用的时钟框架驱动程序

我正在尝试为通过I2C连接到Raspberry PI 3的时钟编写通用时钟框架驱动程序。 注:我对Linux和内核编程都很新。 更新:成功! 下面的代码适用于Hello World驱动程序,为了让我的驱动程序加载,我必须对设备树进行的唯一更改是添加i2c1节点的子节点(位于arch / arm / boot / dts / bcm2708_common.dts ): i2c1: i2c@7e804000 { compatible = "brcm,bcm2708-i2c"; reg = <0x7e804000 0x1000>; interrupts = <2 21>; clocks = <&clk_core>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; myclock: clock-generator@6a { #clock-cells = <0>; compatible = "dbc,myclock"; reg = <0x6a>; clock-frequency […]

使用可加载的内核模块修改framebuffer(/ dev / graphics / fb0)参数

问题:我必须configurationAndroid平台使用的各种LCD显示器。 几乎在所有情况下都没有关于液晶显示器的免费电气规格。 但是通过经验和逆向工程,参数可以被合理地猜测出来。 我正在尝试使用可加载的内核模块来微调显示参数(任何其他build议也欢迎)。 请在下面find相关信息。 硬件:爱特梅尔SAMA5D31-EK(ARM 5处理器) SW: Andriod Linux(目标),Ubuntu(主机系统),Sourcery CodeBench(交叉编译器)代码片段,从board-dt.c文件 static struct fb_videomode at91_tft_vga_modes[] = { ….. .xres =435; .yres =235; …. } static struct fb_monspecs at91fb_default_monspecs = { ……… .modedb = at91_tft_vga_modes, …… } static struct atmel_lcd_fb_info __initdata ek_lcdc_data = { ………. .default_monspecs = & at91fb_default_monspecs; ……… } 我添加了这个代码,所以可加载的内核模块可以访问lcdc_data结构 extern void set_fb_video(struct fb_videomode […]

for_each_process – 它是否迭代线程和进程?

我想迭代内核中的所有任务(线程和进程),并使用for_each_processmacros打印tid / pid和名称: #define for_each_process(p) \ for (p = &init_task ; (p = next_task(p)) != &init_task ; ) 我怎样才能区分线程和进程? 所以我会这样打印: if (p->real_parent->pid == NULL) printk("PROCESS: name: %s pid: %d \n",p->comm,p->pid); else printk("THREAD: name: %s tid: %d \n",p->comm,p->pid);

编译并build立“android”设备的“iw”?

我需要在Android 4.1设备上安装iw无线包。 但我不知道如何和什么是要安装的软件包的版本! 也是需要linux平台才能做到这一点,或者是足够build立和安装在adbshell上的android root设备。 我看到这个链接,但是当我从adbterminal做到这一点,我看到,混帐和一些贝壳找不到? 怎么做 ? 似乎没有人有任何想法?

如何在Linux内核中打印当前线程堆栈跟踪?

我希望能够在Linux内核中打印一个线程的堆栈跟踪。 具体来说:我想添加代码到特定的函数(例如swap_writepage() ),这将打印线程的完整堆栈跟踪,这个函数被调用。 像这样的东西: int swap_writepage(struct page *page, struct writeback_control *wbc) { /* code goes here to print stack trace */ int ret = 0; if (try_to_free_swap(page)) { unlock_page(page); goto out; } if (frontswap_store(page) == 0) { set_page_writeback(page); unlock_page(page); end_page_writeback(page); goto out; } ret = __swap_writepage(page, wbc, end_swap_bio_write); out: return ret; } 我的故事:最近,Linux内核开发人员在改进内核时采用了面向对象的原则,这是用C语言编写的。由于C不是面向对象的语言,所以开始看起来非常难看,难以理解,可以分析C代码的IDE。 我不想在debugging器下开始运行Linux。 注意:如果你是一个内核开发新手,想要在debugging器下运行Linux,不要付出努力…这将被certificate是徒劳无功的(步调毫无意义)。

在用户空间启用写入组合IO访问

我有一个用户空间驱动程序的PCIe设备。 我通过BAR向设备写入命令,这些命令对延迟敏感,数据量很小(〜64字节),所以我不想使用DMA。 如果我使用ioremap_wc重新映射内核中BAR的物理地址,然后将64字节写入内核中的BAR,则可以看到64字节被写为单个PCIe上的TLP。 如果我允许我的用户空间程序使用MAP_SHARED标志MAP_SHARED区域,然后写入64字节,则在PCIe总线上看到多个TPL,而不是单个事务。 根据内核PAT文档,我应该能够将写入组合的页面导出到用户空间: 希望将某些页面导出到用户空间的驱动程序通过使用mmap界面和其组合来完成 1) pgprot_noncached() 2) io_remap_pfn_range()或remap_pfn_range()或vm_insert_pfn() 通过PAT支持,正在添加一个新的API pgprot_writecombine 。 因此,驱动程序可以继续使用上述顺序,在步骤1中使用pgprot_noncached()或pgprot_writecombine() ,然后使用步骤2。 基于这个文档,从我的mmap处理程序相关的内核代码如下所示: vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); return io_remap_pfn_range(vma, vma->vm_start, info->mem[vma->vm_pgoff].addr >> PAGE_SHIFT, vma->vm_end – vma->vm_start, vma->vm_page_prot); 我的PCIe设备在lspci中显示,BAR按预期标记为可预取: Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 11 Region 0: Memory at d8000000 (64-bit, prefetchable) [size=32M] Region 2: Memory […]

alignmentmacros内核

我无法理解这个macros是什么。 这些是在linux-kernel中定义的,但是我的疑问是独立于此的。 我无法理解(((x)+(mask))&~(mask))行是干什么的。 #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 任何帮助赞赏。

如何在Linux内核模块中分配由1GB HugePages支持的DMA缓冲区?

我正在尝试为HPC工作负载分配一个DMA缓冲区。 它需要64GB的缓冲空间。 在计算之间,一些数据被卸载到PCIe卡上。 我不想将数据复制到由pci_alloc_consistent给出的一堆4MB缓冲区,我只想创build64个1GB的缓冲区,由1GB的HugePages支持。 一些背景信息:内核版本:CentOS 6.4 / 2.6.32-358.el6.x86_64内核启动选项:hugepagesz = 1g hugepages = 64 default_hugepagesz = 1g 相关部分的/ proc / meminfo:AnonHugePages:0 kB HugePages_Total:64 HugePages_Free:64 HugePages_Rsvd:0 HugePages_Surp:0 Hugepagesize:1048576 kB DirectMap4:848 kB DirectMap2M:2062336 kB DirectMap1G:132120576 kB 我可以挂载-t hugetlbfs nodev / mnt / hugepages。 CONFIG_HUGETLB_PAGE是真的。 MAP_HUGETLB被定义。 我已经阅读了关于使用libhugetlbfs在用户空间中调用get_huge_pages()的一些信息,但理想情况下,这个缓冲区将在内核空间中分配。 我尝试使用MAP_HUGETLB调用do_mmap(),但似乎并没有改变免费的巨大页面的数量,所以我不认为它实际上是支持大页面的mmap。 所以我猜我在想什么,有什么办法可以将缓冲区映射到内核空间中的1GB HugePage,还是必须在用户空间中完成? 或者如果有人知道任何其他方式,我可以得到一个巨大的(1-64GB)连续的物理内存作为内核缓冲区?

了解file_operations的loff_t * offp

我正在devise一个简单的读写字符缓冲区的设备驱动程序。 然而我的问题是关于file_operations结构read的两个函数。 我真的不明白什么loff_t *offp真的是。 我知道,对于读取和写入操作, *offp是文件偏移量,意味着文件的当前读/写位置,但是我甚至不确定写入或从设备文件读取的意味着什么。 从我所收集的内容来看,这就是我如何编写和从我的设备上读取的,是我创build了一个代表我的设备的结构,我将其称为my_char_struct ,如下所示。 struct my_char_structure{ struct cdev my_cdev; struct semaphore sem; char *data; ssize_t data_size; unsigned int access_key; unsigned long size; }; 这是一个静态结构,当我的驱动程序被insmod时,这个静态结构被初始化并指向。 static dev_t dev_num; static struct my_char_structure Dev; int start_mod(void){ //Because we are dealing with a fictitious device, I want //the driver to create my two devices with […]