简体   繁体   English

在Linux中编译内核代码

[英]Compiling Kernel code in Linux

Okay, I'm reading about Linux kernel development and there are some code snippets using kernel's data structures and stuff. 好的,我正在阅读有关Linux内核开发的内容,并且有一些使用内核数据结构和内容的代码片段。 Let's say I'd like to experiment with them, eg there's a very simple snippet: 假设我想尝试一下,例如,有一个非常简单的片段:

#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);
}

Seems pretty simple, eh? 看起来很简单,嗯? Now then, I can't possibly build the thing. 现在,我无法构建这个东西。 I am using NetBeans. 我正在使用NetBeans。 The sched.h is the correct file as if one can CTRL+clicks on it, one is brought to the right file. sched.h是正确的文件,好像可以用CTRL +点击它,一个被带到正确的文件。

Do I need to include somehow my sample file and build the whole kernel from the Makefile? 我是否需要以某种方式包含我的示例文件并从Makefile构建整个内核? I just wished to see that it builds and possibly that it would work. 我只是希望看到它的构建,并可能它会起作用。 If I need to build the whole kernel how would I actually test my stuff? 如果我需要构建整个内核,我将如何实际测试我的东西?

I must be making something really stupid as I am very new to kernel development. 因为我对内核开发很陌生,所以我必须做一些非常愚蠢的事情。 I am quite a bit lost. 我有点失落。

Thanks guys! 多谢你们!

You do not need to compile the whole kernel, but you have to at least create a kernel module, which is far easier to compile. 您不需要编译整个内核,但您必须至少创建一个内核模块,它更容易编译。 You should have a look at a tutorial, such as this , or even a full blown book like this . 你应该看看教程,比如 ,甚至是一个完全成熟的书像这样

Keep in mind that not all kernel code can be moved to a module - just those that use the public (exported) interfaces of the kernel. 请记住,并非所有内核代码都可以移动到模块 - 只是那些使用内核的公共(导出)接口的模块。 Code that is intrinsic to the kernel core parts (eg the VM or the scheduler) is probably inaccessible from the rest of the kernel. 内核核心部分(例如VM或调度程序)固有的代码可能无法从内核的其余部分访问。

Also keep in mind that trying out kernel code on your development machine is not advised - a slight mistake can easily bring the whole system down. 还要记住,不建议在开发机器上尝试内核代码 - 轻微的错误很容易导致整个系统崩溃。 You should look at trying out your kernel code in a separate virtual machine eg in VirtualBox . 您应该在单独的虚拟机中尝试尝试内核代码,例如在VirtualBox中

A detail that makes thing harder: in general you can only insert a module in the kernel that it was built for. 使事情变得更难的细节:通常,您只能在为其构​​建的内核中插入模块。 A module compiled on the host system can be used on the testing VM if and only if the kernel is identical, ie the same kernel package version from the same distribution. 当且仅当内核相同时, 才能在测试VM上使用在主机系统上编译的模块,即来自相同分发的相同内核包版本。 Considering that you will want to upgrade your host distribution, in my opinion it is just simpler to build the module on the testing system. 考虑到您将要升级主机分发,我认为在测试系统上构建模块更简单。

Since you need a full development suite for C , you should probably install one of the popular Linux distrbutions. 由于您需要一个完整的C开发套件 ,您应该安装一个流行的Linux分发版。 It should be more stable and you can have access to its user community. 它应该更稳定,您可以访问其用户社区。 If you want to keep its size down, you can just install the base system without an X server or graphical applications. 如果要保持其大小,可以只安装没有X服务器或图形应用程序的基本系统。

BTW Netbeans is designed to develop userspace applications. BTW Netbeans旨在开发用户空间应用程序。 You can probably adapt it for kernel code, but it will never be as suited as it is for userspace programming. 您可以根据内核代码调整它,但它永远不会像用户空间编程那样适合。 As a matter of fact, no IDE is really suitable. 事实上,没有IDE真的适合。 Kernel code cannot be run from userspace (let alone using a separate VM), which breaks down the normal edit->compile->run->debug workflow cycle that IDEs automate. 无法从用户空间运行内核代码(更不用说使用单独的VM),这会破坏IDE自动化的正常edit-> compile-> run-> debug工作流程周期。

Most kernel developers just use a souped-up editor with syntax highlighting for C, such as Vim or Emacs . 大多数内核开发人员只使用带有C语法高亮的加强编辑器,例如VimEmacs Emacs is actually an IDE (and so much more) but, as I mentioned above, you cannot easily use an IDE-based workflow for kernel code development. Emacs实际上是一个IDE(以及更多),但是,正如我上面提到的,你不能轻易地使用基于IDE的工作流来进行内核代码开发。

如果您不想构建整个内核,可以构建可加载的内核模块 - 例如,请参阅http://www.linux-tutorial.info/modules.php?name=Howto&pagename=Module-HOWTO

All the code you write, compile and run as user programs run as ... well, user programs, in user mode. 您编写,编译和运行的所有代码作为用户程序运行为......用户程序,在用户模式下运行。 The kernel runs in kernel mode. 内核以内核模式运行。 Both modes are separated and cannot see each other directly. 两种模式都是分开的,不能直接看到对方。 They communicate through defined interfaces. 它们通过定义的接口进行通 These interfaces are the C system calls (as opposed to the C library calls). 这些接口是C系统调用(与C库调用相反)。

To be able to access the task_struct structures, your code has to be running in kernel mode. 为了能够访问task_struct结构,您的代码必须以内核模式运行。 The best choice for this is to write a kernel module, and to load it in the kernel. 最好的选择是编写内核模块,并将其加载到内核中。

Very little kernel code can run outside the kernel in any form. 很少的内核代码可以以任何形式在内核之外运行。 Most kernel code is very 'intertwingled' (to use a phrase I learned from a coworker years ago to describe excessive coupling) with other portions of kernel code. 大多数内核代码与内核代码的其他部分非常 “交织”(使用我多年前从同事那里学到的用来描述过度耦合的短语)。 Functions 'know' structure definitions for many many structures away from what they are working on. 功能“知道”结构定义适用于许多远离他们工作的结构。 Typical software engineering people hate code like this: 典型的软件工程人员讨厌这样的代码:

    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;
    }

This routine has to know how to destroy inodes through three structures and the calling convention of a function pointer on the other end of the chain. 这个例程必须知道如何通过三个结构销毁inode 以及链的另一端的函数指针的调用约定。 The kernel community knows all these functions very well, and are quite happy to modify member names in structures all throughout the kernel when changes are made, but this sort of tight coupling makes running portions of the kernel in userspace on their own extremely difficult. 内核社区非常了解所有这些函数,并且非常乐意在进行更改时修改整个内核中的结构中的成员名称,但是这种紧密耦合使得在用户空间中运行内核部分非常困难。 (And believe me, sometimes I wish I could write tests on my small portions of kernel code that would run in userspace.) (并且相信我,有时我希望我可以在我的用户空间中运行的一小部分内核代码上编写测试。)

If you want to play around, it's not too hard to get a virtual system up and running these days with qemu+kvm or virtualbox or uml to try making modifications to the kernel. 如果你想玩游戏,现在使用qemu + kvm或virtualbox或uml来启动和运行虚拟系统并不难以尝试对内核进行修改。 It is pretty hard to just "play" with structures on a live running system, but it is much more feasible than trying to compile portions of the kernel in userspace. 在实时运行的系统上“玩”结构很难,但是比在用户空间中编译部分内核要可行得多。

Good luck. 祝好运。 :) :)

You might enjoy using systemtap as a wrapper for small bits of kernel module code: 您可能喜欢使用systemtap作为少量内核模块代码的包装器:

# stap -g -e 'probe begin { your_function() exit() }
%{
#include <linux/whatever.h>
%}
function your_function() %{
   ... insert safe c code here ...
%}'

It can automatically cross-compile too (if you use stap --remote=VIRTMACHINE ... ). 它也可以自动交叉编译(如果你使用stap --remote=VIRTMACHINE ... )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM