我正在尝试执行我创建的linux模块的一个函数。但我没有成功。这是project
我创建了一个小函数来将int转换为str float:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include "service.h"
#include "fp_printk.h"
#define OURMODNAME "fp_printk"
MODULE_AUTHOR("Guilherme Giacomo Simoes <trintaeoitogc@gmail.com>");
MODULE_DESCRIPTION("This lib will show float-point in printk()");
MODULE_LICENSE("MIT");
MODULE_VERSION("0.4.1");
void fp_printk(int number, int decimal_places, char* destination)
{
static char buffer[32] = { 0 };
int buf_index = 30;
int count_decimal_place = 0;
int point_include = 0;
for (; number && buf_index; --buf_index, number /= 10) {
count_decimal_place++;
if (!point_include && count_decimal_place > decimal_places) {
buffer[buf_index] = '.';
buf_index--;
point_include = 1;
}
buffer[buf_index] = "0123456789"[number % 10];
}
strcpy(destination, &buffer[buf_index + 1]);
}
static int __init fp_printk_init(void)
{
printk(KERN_INFO "%s: initial execute module", OURMODNAME);
return 0;
}
static void __exit fp_printk_exit(void)
{
printk(KERN_INFO "%s: module end", OURMODNAME);
}
module_init(fp_printk_init);
module_exit(fp_printk_exit);
EXPORT_SYMBOL(fp_printk);
转换后,将str复制到目标参数。
在我的测试模块中,我调用:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/fpu/api.h>
#include <linux/slab.h>
#include "../fp_printk.h"
MODULE_AUTHOR("Guilherme Giacomo Simoes <trintaeoitogc@gmail.com>");
MODULE_DESCRIPTION("LKP book:ch5/fp_in_lkm: no performing FP \
(floating point) arithmetic in kernel mode");
MODULE_LICENSE("Dual MIT/GPL");
MODULE_VERSION("0.1");
static int __init fp_in_lkm_init(void)
{
const int number = 1234;
const int decimal_places = 2;
char *r = (char*) kmalloc(sizeof("12.34"), GFP_KERNEL);
printk(KERN_INFO "antes de executar\n");
extern void fp_printk(number, decimal_places, r);
printk(KERN_INFO "teste apos a conversao");
printk(KERN_INFO "%s",r);
printk(KERN_INFO "teste apos o printk");
return 0;
}
static void __exit fp_in_lkm_exit(void)
{
printk(KERN_INFO "removed\n");
}
module_init(fp_in_lkm_init);
module_exit(fp_in_lkm_exit);
但是当我运行sudo dmesg查看printks时,我只查看:
[1210228.128703] test_fp_printk: antes de executar
[1210228.128712] test_fp_printk: teste apos a conversao
它不打印字符串
如果我在module_init中调用fp_printk(),它就会工作。
static int __init fp_printk_init(void)
{
printk(KERN_INFO "%s: initial execute module", OURMODNAME);
char *dest = kmalloc(sizeof("12.34"), GFP_KERNEL);
fp_printk(1243, 2, dest);
printk(KERN_INFO, "%s", dest);
return 0;
}
1条答案
按热度按时间anauzrmj1#
在
fp_in_lkm_init()
函数中,您试图调用fp_printk()
。就像这样:但是,这不是调用函数的正确方法。在这里,您只是(不必要地)为函数添加一个函数原型,而不是调用它。
您只需要:
请注意,测试模块需要知道
fp_printk
模块导出了哪些符号。通常,符号在内核附带的Module.symvers
文件中可用。但你的新符号在那里是不存在的。有几个选项,可以在内核模块文档的6.3 Symbols From Another External Module部分看到。对你来说最简单的方法可能是:
使用额外的Module.symvers文件构建外部模块时,会生成一个Module.symvers文件,其中包含内核中未定义的所有导出符号。要访问bar.ko中的符号,请将编译bar.ko的Modular.symvers文件复制到构建foo.ko的目录中。在模块构建期间,kbuild将读取外部模块目录中的Module.symvers文件,当构建完成时,将创建一个新的Module.symvers文件,其中包含所有定义的符号的总和,而不是内核的一部分。