您的位置:首页 > 运维架构 > Linux

linux驱动程序开发环境配置【转载】

2012-05-20 00:20 375 查看
*********************************************************

特别提醒:

1、编译驱动需要先编译内核;

2、驱动的makefile要指定正确的:KERNELDIR := /lib/modules/所编译内核的版本/build

3、编译好的内核要安装进OS;

4、加载驱动时所运行的OS内核,要和编译驱动的内核版本相同;

5、驱动的 printk 输出,可能在 /var/log/syslog 里面。

(今天终于实现我人生的第一个hello world 驱动了



********************************************************

from: http://hi.baidu.com/hzxing1010/blog/item/efb6bf95c7ab756655fb96bb.html
刚看 O'REILLY 写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须 建立内核树。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。那怎么建立呢?为此上网“翻云覆雨”起来而结果却是“惨败而归“。
为此托了一天又4个小时(当然包括吃饭睡觉的时间),连个简单的 hello wrold 都没实现。(书中p22页最简单也最没用的驱动事列)
不过功夫不负有心人。在今天终于弄明白了怎么回事。下面就请让我慢慢道来吧。

先查看自己OS使用的内核版本

shana@shana:~$ uname -r
2.6.22-14-generic /* 这是我显示的结果 */

如果安装系统时,自动安装了源码。在 /usr/src 目录下有对应的使用的版本目录。例如下(我是自己下的)

shana@shana:/usr/src$ ls
linux-headers-2.6.22-14
linux-headers-2.6.22-14-generic
linux-source-2.6.22 /*这个就是解压后的源码目录 */
linux-source-2.6.22.tar.bz2 /* 这是我下的源码 包 */
shana@shana:/usr/src$

如果没有源码。(一般ubuntu 都没有吧)
查看一下可一下载的源码包(切记不要使用超级用户使用此命令否则……会提示没有此命令)

shana@shana:/usr/src$ apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
xen-source-2.6.16 - Linux kernel source for version 2.6.17 with Ubuntu patches
linux-source-2.6.22 - Linux kernel source for version 2.6.22 with Ubuntu patches
shana@shana:/usr/src$

我选择了 linux-source-2.6.22 - Linux kernel source for version 2.6.22 with Ubuntu patches 这个~
然后 install 之

shana@shana:/usr/src$ sudo apt-get install linux-source-2.6.22

下载完成后,在/usr/src下,文件名为:linux-source-2.6.22.tar.bz2,是一个压缩包,解压缩既可以得到整个内核 的源代码:

注意 已经切换到超级用户模式

root@shana:/usr/src# tar jxvf linux-source-2.6.20.tar.bz2

解压后生成一个新的目录/usr/src/linux-source-2.6.22,所有的源代码都在该目录下。

进入该目录

开始配置内核 选择最快的原版的配置(默认)方式 (我是如此)

root@shana:/usr/src/linux-source-2.6.22 # make oldconfig

当然你也可以使用 自己喜欢的配置方式 如 menuconfig , xconfig(必须有GTK环境吧)。反正不用剪裁什么,所以不管那种方式能配置它就行了。

完成后,开始make 吧 这儿比较久 一般有1一个小时吧。(保证空间足够 我编译完成后 使用了1.8G) 我分区时分给/目录30G的空间,我没遇到这问题。倒是我朋友遇到了。

shana@shana:/usr/src/linux-source-2.6.22$ make

shana@shana:/usr/src/linux-source-2.6.22$ make bzImage

当然,第一个make也可以不执行,直接make bzImage。执行结束后,可以看到在当前目录下生成了一个新的文件: vmlinux, 其属性为-rwxr-xr-x。

然后 :

root@shana:/usr/src/linux-source-2.6.22# make modules /* 编译 模块 */

root@shana:/usr/src/linux-source-2.6.22# make modules_install /* 安装 模块 */

执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.22-14-generic/ 。

****************************************************************************

上面几句红字好像有问题, 《Ubuntu下编译3.0.4内核》这篇文章【http://edsionte.com/techblog/archives/3289】

具体做法如下:

4.安装

安装过程分为两部分,首先对内核模块进行安装,这个过程会将刚刚编译内核模块时生成的内核模块复制到/lib/modules/3.0.4/目录下,其中3.0.4为对应的内核版本。使用的命令如下:
~/linux-3.0.4$sudo make modules_install
接着使用下述命令安装编译好的内核:
~/linux-3.0.4$sudo make install

安装内核的过程主要完成了以下的工作:
1).将编译内核时生成的内核镜像bzImage拷贝到/boot目录下,并将这个镜像命名为vmlinuz-3.0.4。
如果使用x86的cpu,则该镜像位于arch/x86/boot/目录下(处于正在编译的内核源码下)。

2).将~/linux-3.0.4/目录下的System.map拷贝到/boot/目录下,重新命名为System.map-3.0.4。该文件中存放了内核的符号表。
3).将~/linux-3.0.4/目录下的.config拷贝到/boot/目录下,重新命名为config-3.0.4。

5.创建initrd.img文件
initrd.img即为初始化的ramdisk文件,它是一个镜像文件,将一些最基本的驱动程序和命令工具打包到镜像文件里。该镜像文件的作用是在系统还没有挂载根分区前,系统需要执行一些操作,比如挂载scsi驱动,此时将initrd文件释放到内存中,作为一个虚拟的根分区,然后执行相关脚本,运行insmod命令加载需要的模块。

具体的创建方法如下:
~/linux-3.0.4$sudo mkinitramfs 3.0.4 -o /boot/initrd.img-3.0.4
6.更新grub
最后一步则是更新grub启动菜单,使用下面的命令则可以自动更新启动菜单:
sudo update-grub2 这一步好像不用做 make install 会自动完成

这样会将刚才编译好的内核放在启动菜单的首位,如果需要修改启动菜单中默认系统的启动顺序,则修改/boot/grub/grub.cfg文件中的set default=的值即可。

还有一步很重要: 修改 /boot/grub/grub.cfg的 【timeout】项,指定等待时间,否则只有一个内核可供你选择,之前的内核就不能启动了。

【2013/02/16】「grub.cfg」の編集はちょっとした工夫が必要と分かった。詳細は下記文章を参照すれば。

 <http://www.ychong.com/ubuntu-boot-grub-config/>(Ubuntu 中设置 GRUB 引导项顺序及超时

****************************************************************************

在随后的编译模块文件时,要用到这个路径下的build目录。至此,内核编译完成。可以重启一下系统。

至此 内核树就建立啦 原来不是很难.....

写一个 最简单 最没用的驱动吧
我在 /home/shana/linux_q/ 目录下创建2个文本文件 hello.c Makefile

//hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
printk(KERN_ALERT "Hello, world/n");
return 0;
}

static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world/n");
}

module_init(hello_init);
module_exit(hello_exit);

程序我就不解释了……

Makefile 文件

obj-m := hello.o
KERNELDIR := /lib/modules/2.6.22-14-generic/build
PWD := $(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

如果以上你都完成了在 make 时出现这样的错误

shana@shana:~/linux _驱动开发$ make
make: 没有什么可以做的为 `modules'。

原因很简单 你肯定是从我这直接复制的吧~~~呵呵,Makefile格式错误啦~
解决办法就是 你把如 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 移动到行首 然后按Tab 键自动对齐
这时里边的变量都变成绿色了~然后在 make 吧

shana@shana:~/linux _驱动开发$ make
make -C /lib/modules/2.6.22-14-generic/build M=/home/shana/linux_驱动开发 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.22-14-generic'
CC [M] /home/shana/linux_驱动开发/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/shana/linux_驱动开发/hello.mod.o
LD [M] /home/shana/linux_驱动开发/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.22-14-generic'
shana@shana:~/linux _驱动开发$

shana@shana:~/linux _驱动开发$ ls -l
总用量 124
-rw-r--r-- 1 shana shana 303 2008-03-16 10:43 hello.c
-rw-r--r-- 1 shana shana 49039 2008-03-16 12:11 hello.ko
-rw-r--r-- 1 shana shana 687 2008-03-16 12:11 hello.mod.c
-rw-r--r-- 1 shana shana 25840 2008-03-16 12:11 hello.mod.o
-rw-r--r-- 1 shana shana 24360 2008-03-16 12:11 hello.o
-rw-r--r-- 1 shana shana 8344 2008-03-16 09:17 linux_qudong_qu.txt
-rw-r--r-- 1 shana shana 266 2008-03-16 12:09 Makefile
-rw-r--r-- 1 shana shana 0 2008-03-16 12:11 Module.symvers
shana@shana:~/linux _驱动开发$

然后加载模块 (超级用户)

root@shana:/home/shana/linux _ 驱动开发# insmod ./hello.ko

按照书上的例子 会在终端显示 hello , world 但是运行后什么都没有出现 (原因不解)

root@shana:/home/shana/linux _ 驱动开发# insmod ./hello.ko
root@shana:/home/shana/linux _ 驱动开发#

查看加载模块

root@shana:/home/shana/linux _ 驱动开发# lsmod
Module Size Used by
hello 2560 0

已经加载上咯~~

删除模块

root@shana:/home/shana/linux _ 驱动开发# rmmod hello
root@shana:/home/shana/linux _ 驱动开发#

那程序的输出在那呢?书中说明 如果不出现在终端 则会写进 syslog 文件中  【2013/02/16】やはりsyslogへの出力だね。

shana@shana:~/linux _驱动开发$ cat /var/log/syslog |grep world
Mar 16 12:14:53 shana kernel: [ 5937.529297] Hello, world
Mar 16 12:16:05 shana kernel: [ 6009.439036] Goodbye, cruel world
shana@shana:~/linux _驱动开发$

至此 全部工作都完成了。是否对你有用呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: