原文网址:http://blog.csdn.net/nexttake/article/details/8181008

刚看 O’REILLY 写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须 建立内核树。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。

先查看自己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,是一个压缩包,解压缩既可以得到整个内核的源代码:

可以使用apt-get purgelinux-source-2.6.22 卸载。
注意 已经切换到超级用户模式
root@shana:/usr/src#sudo 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或者 make defconfig
当然你也可以使用 自己喜欢的配置方式 如  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/
。 在随后的编译模块文件时,要用到这个路径下的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  文件

  1. obj-m := hello.o
  2. KERNELDIR := /lib/modules/2.6.38-8-generic/build/
  3. PWD := $(shell pwd)
  4. modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  5. modules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

其实如果使用这个命令编译,Makefile一行即可

  1. obj-m := hello.o

shana@shana:~/linux_驱动开发$make -C /lib/modules/2.6.38-8-generic/build/  M=/home/yzy/mydriver  
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 4Array03Array 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 0Array:17 linux_qudong_qu.txt
-rw-r--r-- 1 shana shana   266 2008-03-16 12:0Array 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   或者sudo -s先切换到root用户
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 文件中
shana@shana:~/linux_驱动开发$  dmesg
[ 2266.586863] Hello, world\n
[ 2389.281426] Goodbye, cruel world\n
 
至此 全部工作都完成了。

【转】第一个Linux内核驱动程序的更多相关文章

  1. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  2. 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)

    简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中.接着,在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)一文中举例子说明了如何在 ...

  3. 在Ubuntu上为Android系统编写Linux内核驱动程序

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6568411 在智能手机时代,每个品牌的手机都有 ...

  4. 为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序

    在Android硬件抽象层(HAL)概要介绍和学习计划一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法.简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的 ...

  5. 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)

    在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序.在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文 ...

  6. 为Android系统内置C可执行程序测试Linux内核驱动程序

    在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序.在这个名为hello的Linux内核驱动程序中, 创建三个不同的文件节点来供用户空间访问,分别是传统的设备 ...

  7. 如何成为一个Linux内核开发者

    你想知道如何成为一个Linux内核开发者么?或者你的老板告诉你,“去为这个设备写一个Linux驱动.“这篇文档的目的,就是通过描述你需要 经历的过程和提示你如何和社区一起工作,来教给你为达到这些目的所 ...

  8. 一个linux内核编译时遇到的perl语法导致的编译问题解决

    在编译linux内核时,遇到了一个比较诡异的问题.具体log如下: Can't locate strict.pm in @INC (you may need to install the strict ...

  9. NULL指针引起的一个linux内核漏洞

    NULL指针一般都是应用于有效性检测的,其实这里面有一个约定俗成的规则,就是说无效指针并不一定是 NULL,只是为了简单起见,规则约定只要指针无效了就将之设置为NULL,结果就是NULL这个指针被用来 ...

随机推荐

  1. OOP三类继承的区别

    OOP继承的区别提纲: 1. 普通类继承,并非一定要重写父类方法.2. 抽象类继承,如果子类也是一个抽象类,并不要求一定重写父类方法.如果子类不是抽象类,则要求子类一定要实现父类中的抽象方法.3. 接 ...

  2. SQL重复记录查询(转载)

     1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people )  例二:  select * from testtable  where ...

  3. 【Passport】微软过时的技术

    虽然已过时,没来得及体验,摘录一段别人的文章,假装对passport的了解 微软在过去的身份验证服务上,一直采用的Passport验证,但已经是N年前推出来的一个软件架构,当然也被软件界很多地方采用到 ...

  4. 【NHibernate】应用层面需要掌握的知识汇总

    休息接待区 欢迎加入NHibernate中文社区!在讨论中寻找乐趣!在问题中寻找答案! 旅途站点路线 第一站:熟悉NHibernate NHibernate之旅(1):开篇有益 第二站:接触NHibe ...

  5. EXTJS 资料 combo 点一次触发一次

    { xtype: 'combo', id: 'ApplyToModel', name: 'ApplyToModel', store: comStoreApplyToModel, valueField: ...

  6. Tiny6410 LED字符设备驱动

    1.查看用户手册 led1.led2.led3.led4 连接的分别是 GPK4.GPK5.GPK6.GPK7 2.查询6410芯片手册 下面还需要3个步骤: 1.设置GPIO为OUTPUT. 将GP ...

  7. how to make form:checkboxes in JSP

    retransmitTable.jsp file: <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix=&qu ...

  8. objective-c 在线视频 学习资料...

    ---视频 http://www.lanou3g.com/newslist.php?cid=7 http://edu.51cto.com/lesson/id-15489.html http://www ...

  9. 【mysql的设计与优化专题(3)】字段类型与合理的选择字段类型

    本篇博客稍微有点长,它实际上包括两个内容:一是mysql字段类型的介绍,二是在mysql建表过程中是如何正确选择这些字段类型; 字段类型 数值 MySQL 的数值数据类型可以大致划分为两个类别,一个是 ...

  10. 使用程序获取整型数据和浮点型数据在内存中的表示---gyy整理

    使用程序获取整型数据和浮点型数据在内存中的表示. C++中整型(int).短整型(short int).单精度浮点数(float).双精度浮点数(double)在内存中所占字节数不同,因此取值范围也不 ...