使用Eclipse编写适用于2.6内核的“Hello World”设备驱动程序。

目标

我正在尝试在Ubuntu上编写一个简单的设备驱动程序。我希望使用Eclipse(或适用于驱动程序编程的更好的集成开发环境)。以下是代码:

#include <linux/module.h>

static int __init hello_world( void )
{
  printk( "hello world!\n" );
  return 0;
}

static void __exit goodbye_world( void )
{
  printk( "goodbye world!\n" );
}

module_init( hello_world );
module_exit( goodbye_world );

我的努力
经过一些研究,我决定使用Eclipse CTD来开发驱动程序(虽然我还不确定它是否支持多线程调试工具)。所以我:
  1. 在VMWare虚拟机上安装了Ubuntu 11.04 desktop x86
  2. 使用Synaptic Package Manager安装了eclipse-cdtlinux-headers-2.6.38-8
  3. 创建了一个名为TestDriver1C项目,并将上述代码复制粘贴到其中,
  4. 将默认构建命令make更改为以下自定义构建命令:
make -C /lib/modules/2.6.38-8-generic/build M=/home/isaac/workspace/TestDriver1 问题所在
我在使用eclipse构建这个项目时遇到了一个错误。以下是构建的日志:
**** Build of configuration Debug for project TestDriver1 **** make -C /lib/modules/2.6.38-8-generic/build M=/home/isaac/workspace/TestDriver1 all make: 进入目录'/usr/src/linux-headers-2.6.38-8-generic' make: *** 没有规则可以生成目标文件'vmlinux',需要它来完成'all'。停止。 make: 离开目录'/usr/src/linux-headers-2.6.38-8-generic'
有趣的是,当我使用shell而不是eclipse构建这个项目时,没有出现错误。要使用shell,我只需创建一个包含"obj-m += TestDriver1.o"的Makefile,并使用上述的make命令进行构建。
所以,eclipse的Makefile肯定有问题。也许它正在寻找"vmlinux"架构(?),而当前架构是x86。也许是因为VMWare的原因?
据我所理解,eclipse会自动创建makefile,如果手动修改可能会导致将来出现错误或者使得管理makefile变得困难。
那么,在eclipse上如何编译这个项目呢?
4个回答

我和你的情况几乎一样。按照this的指示,我成功地构建了内核本身和一个单独的模块。
我在主文中添加了三个步骤(40~42),以使Eclipse编译特定的驱动程序,而不是整个内核。
  1. 下载并安装Eclipse以及CDT。
  2. 配置和构建内核以定义CONFIG_*并生成autoconf.h。这可以在下载和安装Eclipse之前或之后完成。
  3. 确保您拥有正确的内核源代码(例如,确保您位于正确的git分支上)。如果稍后切换到另一个分支,没关系,但您需要重新索引源代码,这大约需要20分钟。
  4. 启动Eclipse。
  5. 点击File->New->C Project
  6. 填写一个项目名称,如my_kernel
  7. 取消选中“Use default location”框,并将内核的根目录路径输入到Location框中。
  8. 在“Project type:”窗格中,点击Makefile project并选择Empty Project
  9. 在右侧选择Linux GCC
  10. 点击Advanced settings...,会弹出一个属性对话框。
  11. 在左侧选择Resource,然后在Text file encoding部分中选择Other,并在框中选择ISO-8859-1,然后点击Apply
  12. 打开左侧的C/C++ General选项。
  13. 点击Preprocessor Include Paths
  14. 在Languages列表中选择GNU C
  15. 在Setting Entries列表中选择CDT User Setting Entries
  16. 点击Add.... 从左上角的下拉菜单中选择Preprocessor Macros File,从右上角的下拉菜单中选择Project Path,然后将include/generated/autoconf.h输入到File文本框中。(注意:对于旧版本的内核[2.6.36之前?],autoconf.h的位置为include/linux/autoconf.h
  17. 还要添加您正在使用的任何其他宏文件。
  18. 点击Indexer
  19. 选中Enable project specific settings框。
  20. 取消选中Index source files not included in the build
  21. 清空Files to index up-front框。
  22. 点击左侧的Paths and Symbols。
  23. 选择Includes选项卡,然后选择GNU C
  24. 点击Add...
  25. 点击Workspace...,然后选择您的内核的include目录
  26. 再次点击Add,选择Workspace并添加arch/architecture/include,例如arch/powerpc/include
  27. 点击# Symbols选项卡
  28. 点击Add...
  29. 将名称设置为__KERNEL__
  30. 将值设置为1,然后点击OK
  31. 点击Source Location选项卡
  32. 展开您的项目。
  33. 选择Filter项目并点击Edit Filter...
  34. 点击Add Multiple...,然后选择您内核源代码中将不使用的所有arch/*目录(即,所有与您正在使用的架构无关的目录)
  35. 点击两次OK来关闭该对话框。
  36. 在属性对话框上点击OK。
  37. 在C Project对话框上点击Finish。
  38. 右键单击项目,选择Index,然后选择Rebuild
  39. 这大约需要20分钟左右来完成。
  40. 打开您的项目设置,转到C/C++ build -> Behaviour (tab)
  41. 勾选Build (Incremental buil)复选框,并将您的模块路径添加到文本框中(在我的情况下是M=

如果你想在Eclipse中进行驱动程序开发,你将不得不采取另一种方式。
你需要了解automake、autogen、pkg-config等工具,并创建一个autotools项目并将其导入到Eclipse中。Eclipse CDT应该提供这个功能,否则你可能忘记安装'autotools-plugin'(具体名称不确定,我是凭记忆写的)。
放弃那种认为Eclipse CDT可以管理一个合适的Makefile的想法吧,C语言可不是Java,不管是好是坏。

谢谢。我很快就会检查“autotools”插件。
你知道有哪些更好的用于驱动程序编程的IDE吗?
你认为像我这样一个懒惰的VS用户,没有在Linux上的经验,可以管理“makefile”吗?
在大型项目中,真的可以管理“makefile”吗?
- Isaac
我也曾经是一个懒惰的VS用户,我必须承认掌握自动工具确实有一个陡峭的学习曲线,但它非常值得,不仅适用于Linux。Eclipse是最好的集成开发环境之一,但自动工具项目如此多样化,没有任何一个IDE能够解析所有可能性。如果你想做得正确,试试Geany;如果你喜欢VS6,可以尝试Anjuta和CodeLite,但始终要熟练掌握命令行编译。 - aquaherd

我也是新手在Linux驱动程序编程方面,我发现有一种新的方法来部署内核模块(这些模块不在官方的Linux树中),叫做DKMS。该模块将以源代码的形式安装,并且DKMS会负责为每个内核进行编译。这意味着模块的Makefile将需要手动编写,而其源代码则不包含在自动工具中。

http://linux.dell.com/dkms/

更新...

DKMS已迁移到http://en.community.dell.com/techcenter/os-applications/w/wiki/2463.linux-projects.aspx

这是有关DKMS的教程/快速介绍(链接来自Dell项目页面): Linux Journal文章Power Solutions论文Ottawa Linux Symposium论文

DKMS用于快速部署驱动程序。例如,在我的Ubuntu机器上使用DKMS的内核模块:

dkms status

bcmwl, 6.20.155.1+bdcom, 3.5.0-41-generic, x86_64: installed
bcmwl, 6.20.155.1+bdcom, 3.5.0-42-generic, x86_64: installed
bcmwl, 6.20.155.1+bdcom, 3.5.0-43-generic, x86_64: installed
nvidia, 313.26, 3.5.0-42-generic, x86_64: installed
nvidia, 313.26, 3.5.0-43-generic, x86_64: installed
vboxhost, 4.3.0, 3.5.0-42-generic, x86_64: installed
vboxhost, 4.3.0, 3.5.0-43-generic, x86_64: installed

这是我之前写的代码,它可能对DKMS Hello World有帮助。 https://github.com/sneetsher/RTD-DM5408-Driver-Port-for-Linux

1> 你可以尝试使用这个命令
"make" --> "/usr/bin/make"
/usr/bin/make -C /lib/modules/2.6.38-8-generic/build M=/home/isaac/workspace/TestDriver1

2> 在目录中存储你的hello world代码,创建文件名为"Makefile"的文件。
obj-m := NameofyourHelloWold.o 

KDIR  := /lib/modules/2.6.38-8-generic/build

PWD   := $(shell pwd)

default:
    $(MAKE) -C $(KDIR) M=$(PWD) modules