c - 构建静态库并在编译时将其链接到内核模块

我正在尝试构建一个纯 C 代码(无标准 c 头文件)的静态辅助库,然后在编译时在 Makefile 中将其与内核模块链接,但我似乎无法让它工作.

假设我有一个库,它就是这个头文件 utils.h:

#ifndef __UTILS__
#define __UTILS__

int initialize(int value);
void increment(void);
int get(void);

#endif // __UTILS__

及其实现utils.c:

#include "utils.h"

int g_value;

int initialize(int value) {
  g_value = value;
  return 0;
}

void increment(void) {
  g_value++;
}

int get(void) {
  return g_value;
}

我正在使用这个 Makefile 从中构建库:

BIN_DIR := .

# Specify extensions of files to delete when cleaning
CLEANEXTS   = o a

# Specify the target file and the install directory
OUTPUTFILE  = libutils.a
INSTALLDIR  = ../

# Default target
.PHONY: all
all: $(OUTPUTFILE)

# Build libutils.a from uilts.o
$(OUTPUTFILE): utils.o
    ar cr $@ $^
    ranlib $@

# No rule to build utils.o from .c 
# files is required; this is handled by make's database of
# implicit rules

.PHONY: install
install:
    mkdir -p $(INSTALLDIR)
    cp -p $(OUTPUTFILE) $(INSTALLDIR)

.PHONY: clean 
clean:
    for file in $(CLEANEXTS); do rm -f *.$$file; done

# Indicate dependencies of .c files on .h files
utils.o: utils.h

我运行 make all 来构建库,我得到了 libutils.autils.o 文件。

然后我有一个简单的内核模块,它使用 utils 库 mymodule_main.c

#include <linux/kernel.h>
#include <linux/module.h>

MODULE_LICENSE("GPL");

#include "utils/utils.h"

int init_module(void) {
  int i;
  initialize(1);
  for(i = 0; i < 10; ++i) {
    increment();
  }
  return 0;
}

void cleanup_module(void)
{
  pr_info("value=%d\n", get());
}

和它的Makefile:

NAME        := mymodule
target      := $(shell uname -r)
KERNEL_DIR  ?= /lib/modules/$(target)/build

obj-m       := $(NAME).o
$(NAME)-y   := mymodule_main.o libutils.a

all:
    make -C $(KERNEL_DIR) M=$(shell pwd)
clean:
    make -C $(KERNEL_DIR) M=$(shell pwd) clean

现在当我尝试构建这个内核模块时 make all 我得到了这些错误:

ERROR: "initialize" [/home/mosa/dev/mymodule.ko] undefined!
ERROR: "get" [/home/mosa/dev/mymodule.ko] undefined!
ERROR: "increment" [/home/mosa/dev/mymodule.ko] undefined!

然后我尝试使用 utils.o 文件代替 libutils.a 并相应地更新了内核模块的 Makefile,我收到这些警告:

WARNING: "g_value" [/home/mosa/dev/mymodule] is COMMON symbol
WARNING: could not find /home/mosa/dev/.utils.o.cmd for /home/mosa/dev/utils.o

如果我尝试 insmod 生成的内核模块,我会在日志中收到此错误: mymodule: 请使用-fno-common 编译

我尝试将 ccflags-y += -fno-common 添加到 Makefile 中,但仍然出现同样的错误。

我读到过可以这样做,但我无法让它工作。

我在这里要做的是不分发实用程序源代码,只分发内核模块代码以及实用程序的 header 和库目标文件。我该怎么办?

最佳答案

内核模块只能通过 syscalls 或 sysfs 或 ioctl 访问,....你不能将用户空间代码链接到内核,cf。 How to Link static or shared library to Kernel Module?

https://stackoverflow.com/questions/65216947/

相关文章:

php - 如何在 Laravel 中使用 Angular

amazon-web-services - 如何在外部公开 NATS 服务器

javascript - 未捕获的 ReferenceError,Splide 未在 HTMLDoc

delphi - Delphi Sydney 10.4.1 上的 QuickReport

python-3.7 - 操作系统错误 : no library called "cairo" er

javascript - Tailwind CSS 不能用 React 和 Express 编译?

javascript - 在 URL 中传递 Javascript 变量

ios - 在真实设备上运行应用程序时 Xcode : No code signature foun

reactjs - 为什么我的自定义路由没有将正确的路径传递给子组件?

c++ - 如何使用 GDB 进入一个函数而不是它的参数