Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Linux中编译内核代码_C_Linux_Build_Linux Kernel - Fatal编程技术网

C 在Linux中编译内核代码

C 在Linux中编译内核代码,c,linux,build,linux-kernel,C,Linux,Build,Linux Kernel,好的,我正在阅读关于Linux内核开发的文章,这里有一些使用内核数据结构的代码片段。假设我想用它们做实验,例如,有一个非常简单的片段: #include <../../linux-2.6.37.1/include/linux/sched.h> struct task_struct *task; for_each_process(task) { printk("%s[%d]\n", task->comm, task->pid); } #包括 结构任务\u结构*任务

好的,我正在阅读关于Linux内核开发的文章,这里有一些使用内核数据结构的代码片段。假设我想用它们做实验,例如,有一个非常简单的片段:

#include <../../linux-2.6.37.1/include/linux/sched.h>
struct task_struct *task;
for_each_process(task) {
    printk("%s[%d]\n", task->comm, task->pid);
}
#包括
结构任务\u结构*任务;
对于每个流程(任务){
printk(“%s[%d]\n”,任务->通信,任务->pid);
}
看起来很简单,是吗?现在,我不可能建造这个东西。我正在使用NetBeans。sched.h是正确的文件,就像可以按住CTRL键并单击它一样,一个被带到正确的文件

我是否需要以某种方式包含示例文件并从Makefile构建整个内核?我只是希望看到它能够构建,并且可能能够工作。如果我需要构建整个内核,我将如何实际测试我的东西

我一定是在做一些非常愚蠢的事情,因为我对内核开发非常陌生。我有点迷路了


谢谢大家

如果您不想构建整个内核,您可以构建一个可加载的内核模块-例如,请参阅

您编写、编译和运行的所有代码都是作为用户程序运行的。。。用户程序,在用户模式下。内核以内核模式运行。这两种模式是分开的,不能直接看到对方。它们通过定义的接口进行通信。这些接口是C系统调用(与C库调用相反)


为了能够访问任务结构,代码必须在内核模式下运行。最好的选择是编写一个内核模块,并将其加载到内核中。

您不需要编译整个内核,但至少必须创建一个内核模块,这要容易得多。你应该看一看教程,比如,甚至是一本完整的书

请记住,并非所有的内核代码都可以移动到一个模块中,只是那些使用内核的公共(导出)接口的代码。内核核心部分(例如VM或调度器)固有的代码可能无法从内核的其余部分访问

还请记住,在您的开发机器上尝试内核代码是不可取的-a 轻微的错误很容易使整个系统崩溃。您应该考虑在一个单独的虚拟机中试用您的内核代码,例如在

一个让事情变得更难的细节:一般来说,您只能在为其构建的内核中插入一个模块。当且仅当内核相同(即来自同一发行版的同一内核包版本)时,在主机系统上编译的模块才能在测试VM上使用。考虑到您希望升级主机发行版,我认为在测试系统上构建模块更简单

因为您需要一个,所以您可能应该安装一个流行的Linux发行版。它应该更稳定,您可以访问它的用户社区。如果您想减小它的大小,您可以只安装基本系统而不安装X服务器或图形应用程序

顺便说一句,Netbeans是为开发用户空间应用程序而设计的。您可能可以将其用于内核代码,但它永远不会像用于用户空间编程那样适合。事实上,没有一个IDE是真正合适的。内核代码不能从用户空间运行(更不用说使用单独的VM了),这会破坏IDE自动化的正常编辑->编译->运行->调试工作流周期


大多数内核开发人员只是使用一个增强的编辑器来突出显示C的语法,比如or。Emacs实际上是一个IDE(以及更多),但是,正如我前面提到的,您不能轻松地使用基于IDE的工作流来开发内核代码。

很少有内核代码可以以任何形式在内核之外运行。大多数内核代码与内核代码的其他部分非常“交织”(用我几年前从同事那里学到的一个短语来描述过度耦合)。函数“知道”许多结构的结构定义,而不是它们正在处理的结构。典型的软件工程人员讨厌这样的代码:

    if (unlikely(inode_init_always(sb, inode))) {
            if (inode->i_sb->s_op->destroy_inode)
                    inode->i_sb->s_op->destroy_inode(inode);
            else
                    kmem_cache_free(inode_cachep, inode);
            return NULL;
    }
这个例程必须知道如何通过链的另一端的函数指针的三种结构和调用约定来销毁inode。内核社区非常了解所有这些函数,并且在进行更改时非常乐意在整个内核的结构中修改成员名称,但是这种紧密耦合使得在用户空间中运行内核的各个部分变得极其困难。(相信我,有时候我希望我能对运行在用户空间中的内核代码的一小部分编写测试。)

如果您想玩游戏,那么现在使用qemu+kvm或virtualbox或uml启动并运行一个虚拟系统来尝试修改内核并不难。在实时运行的系统上“玩”结构是相当困难的,但这比在用户空间中编译内核的部分要可行得多


祝你好运

您可能喜欢使用systemtap作为少量内核模块代码的包装器:

# stap -g -e 'probe begin { your_function() exit() }
%{
#include <linux/whatever.h>
%}
function your_function() %{
   ... insert safe c code here ...
%}'
#stap-g-e'探测开始{your_function()exit()}
%{
#包括
%}
函数你的函数(){
…在此处插入安全的c代码。。。
%}'

它也可以自动交叉编译(如果您使用
stap--remote=VIRTMACHINE…
)。

谢谢您的详细回答。对于通过VirtualBox进行内核实验的小型linux发行版,有什么建议吗?我是说,在功能齐全的Ubuntu上进行测试毫无意义,是吗?您是否考虑使用更合适的IDE?因为您需要开发工具(gcc、make等),所以大多数“小型”发行版并不真正合适。我只想安装一个流行的linux发行版,比如Ubuntu,但没有X服务器或图形应用程序。这将保持较小的大小,同时仍然允许您访问主要发行版的社区。就IDE而言,我所知道的大多数内核开发人员(包括我自己)只使用增强的文本编辑器