将用户空间代码移植到内核空间

时间:2013-02-08 12:30:24

标签: c linux linux-kernel rtai

到目前为止,我有一个主要用C语言编写的大型系统,该系统在用户空间中运行。现在我需要将代码编译为内核模块。为此,afaik,我至少应该重写代码,并将函数替换为malloccallocfreeprintf及其内核等价物,因为这些只是用户 - 太空功能。但问题是,我没有系统中使用的某些自定义库的源代码,并且这些库在其函数内调用malloc等。所以,基本上,我可能需要重新实现整个库。

现在的问题是:如果我将自己的malloc实现编写为kmalloc的包装,这将是一个非常脏的黑客,如下所示:

void *malloc(size_t size) {
    return kmalloc(size, GFP_USER);
}

然后将此实现链接到系统代码,这将消除模块错误中的所有未知符号。

实际上我认为这是一个常见的问题,而且有人已经写过这样的kmalloc包装,但是我已经在谷歌上搜索了几天而没有发现任何有用的东西。

编辑:这样做的原因是我所说的系统是在VxWorks实时操作系统上运行的实时应用程序,现在我们想将它移植到Linux RTAI上,其中应用程序主要在内核空间中运行。但我想有可能在用户空间中实时拥有,所以,我应该像迈克建议的那样做,并将代码分成内核和用户空间部分,并在它们之间与共享内存进行通信。

2 个答案:

答案 0 :(得分:8)

我以前从未见过这样做过。我确实必须在以前的工作中做类似的事情(在我们的手机中,出于省电的原因,我们不得不从内核中移植用户空间的一部分代码)但这就是我做的方式..我拿了 a代码的部分并移动了它,以及一小部分。

当我这样做时,我将用户空间调用更改为内核调用,原因有两个主要原因:

  1. 这种方式不那么令人困惑(其他人看着代码并不知道为什么我从内核调用“malloc”)

  2. mallockmalloc的工作方式完全不同。我的意思是

    2a上。 kmalloc获取flags参数,在上面的示例中,您对其进行了硬编码。如果您稍后决定要在某些地方更改它而不是其他地方,该怎么办? (假设您有许多不同的地方可以获得动态内存)。

    2B。 kmalloc并没有像malloc那样给你记忆。 malloc()将为您提供以size_t size传递的字节数。另一方面,kmalloc()位于内核中,因此正在处理系统的物理内存,该内存仅在页面大小的块中可用;因此,当您调用kmalloc()时,您将只获得某些预定义的固定大小的字节数组。如果您没有意识到这一点,您可能只需要 over 一个特定的块,从而获得比您需要的更多的内存......代码的直接端口将无法保护您。

    2c中。头文件也必须改变。显然你不能在内核中包含<stdlib.h>,所以只是因为你“包装”了malloc调用,你仍然需要去替换头文件。

  3. 上面2b中我的观点的简单例子:

    void * stuff;
    stuff = kmalloc(1,GFP_KERNEL);
    printk("I got: %zu bytes of memory\n", ksize(stuff));
    kfree(stuff);
    

    显示实际分配的内存量:

    [90144.702588] I got: 32 bytes of memory
    

    无论如何......从技术上讲,你如何形容它,应该可以正常工作。两者都需要size_t并返回void *所以它应该有效;但请注意,移动到内核中的代码越多,确定性越低,malloc()&lt; =&gt; kmalloc()似乎不是1:1。

答案 1 :(得分:0)

尝试在用户和内核空间(以及使用POSIX)中编写我的RTAI代码,我已经开发了URT,它基本上可以满足您的要求。它是实时系统的轻量级抽象级别(甚至是不一致的用户空间与内核空间RTAI函数)。