我是内核模块编程的新手,对于我的工作,我需要编写一个多线程内核模块.所以我尝试了内核线程的一些主要用途.我写了以下内容.它应该在一个线程中打印1个,在另一个线程中打印2个,都是10次.
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/kthread.h>
struct task_struct *task1;
struct task_struct *task2;
static void thread_func(void* data)
{
int *n;
n = (int *)data;
int i = 0;
while(i < 10){
printk("%d\n", *n);
i++;
}
//do_exit();
}
static int t_start(void)
{
printk("Module starting ... ... ..\n");
int *p1, *p2;
int one = 1, two = 2;
p1 = &one;
p2 = &two;
task1 = kthread_run(&thread_func, (void*)p1, "thread_func_1");
task2 = kthread_run(&thread_func, (void*)p2, "thread_func_2"); …Run Code Online (Sandbox Code Playgroud) 我对内核模块编程很新,现在我正在尝试运行最基本的hello world模块程序,但是我无法获得任何输出.
我已经编写了Linux设备驱动程序第3版中介绍的hello world程序,并从本网站和本网站获得了一些帮助.
你好ç
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int hello_init(void){
printk("<1>Hello, world!\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "Goodbye, world..\n");
}
module_init(hello_init);
module_exit(hello_exit);
Run Code Online (Sandbox Code Playgroud)
该文件在/home/volkan/drive目录中.连同c文件,我有我的Makefile
Makefile文件
obj-m += hello.o
Run Code Online (Sandbox Code Playgroud)
从终端,我执行此命令来编译模块:
sudo make -C /lib/modules/3.8.0-19-generic/build M=/home/volkan/drive/ modules
Run Code Online (Sandbox Code Playgroud)
导致:
make: Entering directory `/usr/src/linux-headers-3.8.0-19-generic'
CC [M] /home/volkan/drive/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/volkan/drive/hello.mod.o
LD [M] /home/volkan/drive/hello.ko
make: Leaving directory `/usr/src/linux-headers-3.8.0-19-generic'
Run Code Online (Sandbox Code Playgroud)
我认为到目前为止,没有任何问题.现在,我插入我的模块,然后删除:
volkan@Varaquilex ~/drive $ sudo insmod ./hello.ko
volkan@Varaquilex ~/drive $ …Run Code Online (Sandbox Code Playgroud) 运行时,perf它会找到我的程序的内核符号和符号,但它找不到外部模块符号.我已经编写了一个内核模块,我加载了insmod如何使用perf它来查找其符号?
我正在运行2.6.37.6内核(无法升级),我perf还不支持矮人选项,但我认为它是一个符号问题.我已经编译了一切-g -fno-omit-frame-pointer
我需要重命名已经存在的驱动程序的内核模块(使用lsmod显示的名称),而不更改源文件的名称.
例如
# insmod xxx.ko
<<module loads successfully>>
# lsmod
Module Size Used by Tainted: P
xxx 191527 0
#
Run Code Online (Sandbox Code Playgroud)
我想将xxx重命名为yyy.
现在我知道更改驱动程序源文件的名称(当它涉及单个文件时)会更改模块的名称.
但我不想更改源文件的名称.
我经常读到Android内核模块必须编译-fno-pic才能工作.这是针对ARM体系结构的,还是为什么不需要/(什么时候)x86的内核模块需要使用该标志进行编译?
我在内核模块中有两个位置(Linux 3.13):
module_init我的代码是启用硬件性能计数器.当我把它module_init,代码工作正常.但是当我把它放到第二位时(通过运行带有无效操作码的指令触发),代码会permission denied出错(即错误:) -13.
由于这两个地方都在一个内核模块中,"即使在内核空间中,也有不同的权限?"
更新:值得一提的是,当我root在用户空间中运行无效操作码时,-13错误消失了; 否则,它会...
我推测"指令执行的特权决定了它的中断处理程序的执行."
尝试使用LDD3中最简单的内核模块,而无需对带有BusyBox v1.23.0的Beagle Bone板的自定义内核v4.1.0- rc6进行任何修改.该模块的代码如下:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Run Code Online (Sandbox Code Playgroud)
Makefile是:
ARCH := arm
CROSS_COMPILE := arm-cortex_a8-linux-gnueabi-
obj-m := hello.o
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) modules
clean:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) clean
Run Code Online (Sandbox Code Playgroud)
该模块正在rootfs上编译和安装就好了.也正在加载:
$ insmod hello.ko
[ 30.692404] Hello, world
Run Code Online (Sandbox Code Playgroud)
但是当我试图删除它时,我得到:
$ rmmod hello.ko
Segmentation fault
$modprobe -r hello.ko
Segmentation fault
$ …Run Code Online (Sandbox Code Playgroud) 我编写了如下所述的小型内核模块代码,我正在对其进行测试 ubuntu 14.04
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
int init_mod_func(void)
{
printk(KERN_INFO "My module inserted\n ");
return 0;
}
void cleanup_mod_func(void)
{
printk(KERN_INFO "My module removed\n ");
}
module_init(init_mod_func);
module_exit(cleanup_mod_func);
MODULE_AUTHOR("Ankur");
MODULE_DESCRIPTION("TEST MODULE");
MODULE_LICENSE("GPL");
Run Code Online (Sandbox Code Playgroud)
现在,当我使用上面的模块进行编译和插入时insmod,在dmesg中看不到printk消息。但是,在使用模块删除后,rmmod我看到了两个printk消息。
通过闭包外观,我发现它是由于在printk中出现spaceafter \n而引起的。
但是我不明白为什么会这样。
ankur:~/temp/tmp$
ankur:~/temp/tmp$
ankur:~/temp/tmp$ sudo dmesg -C /dev/null
ankur:~/temp/tmp$
ankur:~/temp/tmp$
ankur:~/temp/tmp$ sudo insmod testmod.ko
ankur:~/temp/tmp$ dmesg
ankur:~/temp/tmp$
ankur:~/temp/tmp$ sudo rmmod testmod
ankur:~/temp/tmp$ dmesg
[ 4062.140441] My module inserted
[ 4062.140441]
[ 4073.324994] My …Run Code Online (Sandbox Code Playgroud) 我正在尝试在安全启动模式下运行Ubuntu 18.04 /内核4.18.0-16的Intel Skylake计算机上降低CPU的性能,并且需要读取/写入MSR 0x150。我已经签名并加载了msr.ko内核模块,但是甚至不能以root /超级用户身份从msr-tools运行可执行文件rdmsr和wrmsr(我得到权限错误)。我所掌握的是,使用较新的内核(> 3.7?)无法从用户空间访问MSR。描述了一些解决方法:我尝试同时为rdmsr和wrmsr设置“ setcap cap_sys_rawio + ep”,但这没有帮助。我使用的工具iuvolt和UNDERVOLT,而且直接尝试WRMSR。
如何在安全启动模式下执行rdmsr / wrmsr?
我正在寻找一种在内核模块中分配大页面(2M或1G)的方法(我正在使用内核版本4.15.0)。
在用户空间中,我可以挂载hugetlbfs文件系统,然后使用分配大页面mmap(请参阅例如https://blog.kevinhu.me/2018/07/01/01-Linux-Hugepages/)。在内核空间中有类似的方法吗?
我知道我可以先在用户空间中分配它们,然后使用get_user_pages,将它们传递给内核,如在内核驱动程序中对宏页面的顺序访问中所述。但是,我正在寻找一种更直接的分配方式,因为我只在内核空间中需要它们。
kernel-module ×10
kernel ×5
linux ×4
linux-kernel ×4
c ×3
android ×1
code-signing ×1
embedded ×1
huge-pages ×1
module ×1
msr ×1
perf ×1
printk ×1
privileges ×1
symbols ×1
x86 ×1
x86-64 ×1