发新话题
打印

[其他语言] linux学习笔记-驱动(1)原创

linux学习笔记-驱动(1)原创

要编写linux驱动程序,首先要在自己的系统中配置并构造好内核树。
本人使用的是FC5,默认是不安装内核源代码的,可以上网下载一个,在源代码光盘4上也有内核源代码。
将光盘上的 kernel-2.6.15-1.2054_FC5.src.rpm 拷贝到 /usr/src 目录下。
# rpm -i   kernel-2.6.15-1.2054_FC5.src.rpm
# cd /usr/src/redhat/SPECS
# ls
kernel-2.6.spec
# rpmbuild -bp --target i686 kernel-2.6.spec
# cd ..
# cd  BUILD
# ls
kernel-2.6.15
# cd kernel-2.6.15
# ls
Config.mk  linux-2.6.15.i686  vanilla  xen  xen-vanilla
# cd linux-2.6.15.i686
这里就是linux的内核树了。
接下来是编译内核,一定要编译内核,否则无法编译驱动程序。
# make
一个小时后内核就编译好了。
# cd /usr/src
# ln -s /usr/src/redhat/BUILD/kernel-2.6.15/linux-2.6.15.i686 linux
建立一个符号连接,这样就可以通过 /usr/src/linux 直接访问内核树了。

好了,现在可以开始编写内核模块了。

让我们从Hello World 开始吧。

/*hello.c*/
#include <linux/kernel.h>
#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 World\n" );
}

module_init(hello_init);
module_exit(hello_exit);

这个模块什么也不做,只是在加载时显示"Hello,World",卸载时显示"Goodbye World"。
这个模块定义了两个函数,其中一个在模块被装载到内核时调用hello_init(),而另一个则在模块被移出时调用hello_exit()。
module_init 和 module_exit 行使用了内核的特殊宏来表示上述两个函数所扮演的角色。另外一个宏 MODULE_LICENSE 用来告诉内核,该模块采用自由许可证,如果没有这样的声明,内核在装载该模块时会产生抱怨。函数printk()在 linux/kernel.h 中定义,功能和标准C库函数printf()类似。需要说明一点,写内核或内核模块不能用写应用程序时的系统调用或函数库,因为我们写的就是为应用程序提供系统调用的代码。内核有专用的函数库,如<linux/kernel.h>, <linux/fs.h>, <linux/sche.h>等。KERN_ALERT 定义了这条消息的优先级,我们需要在模块代码中显示地指定高优先级的原因在于:具有默认优先级的消息可能不会输出在控制台上。需要特别指出的是,printk 只能输出到文本控制台上,图形界面下的终端仿真器是不会看到printk 的输出的。

接下来是编写makefile:

TARGET = hello
KDIR = /usr/src/linux
PWD = $(shell pwd)
obj-m      := $(TARGET).o
default:
        make -C $(KDIR) M=$(PWD) modules

输入:
# make
好了模块已经编译好了,输入ls -a 可以看到hello.ko,现在就让我们来加载这个模块看看效果,按 ctrl+alt+F2 切换到文本界面,输入root 和密码,cd 到hello.ko 所在目录。
# insmod ./hello.ko
Hello World
# rmmod hello
Goodbye World

我们已经看到,编写一个模块并没有现象的那么困难——至少当模块不需要完成什么有价值的工作时。真正的困难在于理解设备并最大化其性能。
六根不净,五谷不分,四体不勤,三天打鱼,两天晒网,一无是处。

TOP

顶一下,
继续!

TOP

回复 #1 birdcage 的帖子

一定要顶顶
把握每一天

TOP

有时间写一个小型操作系统。嘿嘿

TOP

我完全按照你的步骤做的,怎么会有下面的错误,没事帮帮忙
make -C /boot M=/xc/hello modules
make[1]: Entering directory `/boot'
make[1]: *** 没有规则可以创建目标“modules”。 停止。
make[1]: Leaving directory `/boot'
make: *** [default] 错误 2

TOP

正想学这方面的东东,顶了

TOP

请问:FC4内核编译问题

参考文件:
《编译内核操作流程--为新手指南》
《linux学习笔记--驱动》 基于FC5
我使用的是FC4(kernel-2.6.11.1369_FC4-i686)
我在
http://download.fedora.redhat.com/pub/fedora/linux/core/4/
上下载升级包:
kernel-2.6.17-1.2142_FC4.src.rpm和kernel-2.6.17-1.2142_FC4.i686.rpm
还有工具module-init-tools-3.1-3.src.rpm
把他们复制到/usr/src目录下,
按照"操作流程"中说的:
然后执行命令:rpm -ivh kernel-2.6.17-1.2142_FC4.i686.rpm
#rpm -ivh kernel-2.6.17-1.2142_FC4.src.rpm
顺便问一下:这两个文件都是什么啊,是不是用第一个就可以了呢?和操作流程中的kernel-devel和kernel是什么关系呢?
然后就安装工具:rpm -ivh module-init-tools-3.1-3.src.rpm
这样就算把工具安装了吗,好像还没做完也,它被安装到什么地方了呢,怎么用呢?
接下来我按照"学习笔记"中的做法操作,
#cd /usr/src/redhat/SPECS
#rpmbuild -bp --target i686 kernel-2.6.spec
#cd ..
#cd BUILD
#ls kernel-2.6.17
kernel-2.6.17目录下只有两个文件夹(linux-2.6.17.i686和vanilla),比"学习笔记"中讲的要少三个文件:Config.mk xen xen-vanilla;
然后进入/usr/src/redhat/BUILD/kernel-2.6.17/linux-2.6.17.i686
按"学习笔记"中说的这就是linux的内核树了,我对linux还不太了解,就想直接用make编译,按照"学习笔记"讲的也是可以编译的,这个过程就像按照"操作流程"中讲的不做配置(我想都用默然配置)直接编译内核;
#make 但报错如下:
CC fs/read_write.o
CC fs/file_table.o
CC fs/buffer.o
CC fs/bio.o
fs/bio.c: 在函数 ‘bio_alloc_bioset’ 中:
fs/bio.c:169: 警告:‘idx’ may be used uninitialized in this function
CC fs/super.o
CC fs/block_dev.o
CC fs/char_dev.o
CC fs/stat.o
CC fs/exec.o
CC fs/pipe.o
CC fs/namei.o
CC fs/fcntl.o
CC fs/ioctl.o
CC fs/readdir.o
CC fs/select.o
fixdep: inclu: No such file or directory
make[1]: *** [fs/select.o] 错误 2
make: *** [fs] 错误 2
[root@localhost linux-2.6.17.i686]#
我的操作过程中哪些地方出错了呢?
重新用#make编译,错误还不同,如下:
CC [M] drivers/block/ub.o
LD drivers/block/aoe/built-in.o
CC [M] drivers/block/aoe/aoeblk.o
CC [M] drivers/block/aoe/aoechr.o
CC [M] drivers/block/aoe/aoecmd.o
CC [M] drivers/block/aoe/aoedev.o
CC [M] drivers/block/aoe/aoemain.o
CC [M] drivers/block/aoe/aoenet.o
LD [M] drivers/block/aoe/aoe.o
LD drivers/block/paride/built-in.o
CC [M] drivers/block/paride/paride.o
CC [M] drivers/block/paride/aten.o
CC [M] drivers/block/paride/bpck.o
cc1: 编译器内部错误:段错误
Please submit a full bug report,
with preprocessed source if appropriate.
See for instructions.
The bug is not reproducible, so it is likely a hardware or OS problem.
make[2]: *** [drivers/block/paride/bpck.o] 错误 1
make[1]: *** [drivers/block/paride] 错误 2
make: *** [drivers] 错误 2
[root@localhost linux-2.6.17.i686]#
这是怎么回事呢??

另外能介绍一下/usr/src/kernels和redhat文件夹下的目录吗?
另外我安装FC4后kernels目录下是22.4M的内容,是内核树吗,编译也不能通过,为什么呢?
根据这两周的了解,module-init-tools还要安装的,我前段安装过3.0版的,是在kernel.org上下的,这次的3.1版我用过rpm命令还要安装吗;另外有文档(编译内核全过程中)提示说还要安装modutils-2.4.21-23.src.rpm,在FC4下,我没安装上去,不安装可以吗;他说的环境是redhat9升级到2.6?
我前几天在kernel.org上下linux-2.6.11.12.tar.bz2配置后,编译也是出错,第一次的错误和这次好象一样,然后我又编译,又提示有关I2C的错误,但我确认过,我没有选择Device Drivers中有关I2C的内容.
[root@localhost linux-2.6.11.12]# make bzImage
SYSMAP System.map
SYSMAP .tmp_System.map
AS arch/i386/boot/setup.o
LD arch/i386/boot/setup
OBJCOPY arch/i386/boot/compressed/vmlinux.bin
GZIP arch/i386/boot/compressed/vmlinux.bin.gz
LD arch/i386/boot/compressed/piggy.o
LD arch/i386/boot/compressed/vmlinux
OBJCOPY arch/i386/boot/vmlinux.bin
BUILD arch/i386/boot/bzImage
Root device is (253, 0) Boot sector 512 bytes.
Setup is 5471 bytes.
System is 1662 kB
Kernel: arch/i386/boot/bzImage is ready

[root@localhost linux-2.6.11.12]# make modules
CC [M] fs/ext3/acl.o
CC [M] fs/ext3/xattr_security.o
LD [M] fs/ext3/ext3.o
CC [M] fs/jbd/transaction.o
CC [M] fs/jbd/commit.o
CC [M] fs/jbd/recovery.o
CC [M] fs/jbd/checkpoint.o
CC [M] fs/jbd/revoke.o
CC [M] fs/jbd/journal.o
LD [M] fs/jbd/jbd.o
CC [M] drivers/i2c/i2c-core.o
In file included from drivers/i2c/i2c-core.c:29:
include/linux/i2c.h:58: 错误:数组元素的类型不完全
include/linux/i2c.h:197: 错误:数组元素的类型不完全
drivers/i2c/i2c-core.c: 在函数 ‘i2c_transfer’ 中:
drivers/i2c/i2c-core.c:594: 错误:实参 2 的类型不完全
drivers/i2c/i2c-core.c: 在函数 ‘i2c_master_send’ 中:
drivers/i2c/i2c-core.c:620: 错误:实参 2 的类型不完全
drivers/i2c/i2c-core.c: 在函数 ‘i2c_master_recv’ 中:
drivers/i2c/i2c-core.c:649: 错误:实参 2 的类型不完全
make[2]: *** [drivers/i2c/i2c-core.o] 错误 1
make[1]: *** [drivers/i2c] 错误 2
make: *** [drivers] 错误 2
[root@localhost linux-2.6.11.12]#


编译内核操作流程 ──为新手指南
http://fedora.linuxsir.org/main/?q=node/66#comment-465

TOP

好贴,楼主继续写啊,加个精
Once upon a man.

TOP

我3个月没来这了吧,3个月前我找到一份做手机的工作,可惜不是做smart phone,也就是说没有再和linux打交道了。希望以后能转到linux方面发展。
由于工作忙,一直没有时间回复网友的问题,我已经3个月没进linux了。。。。
六根不净,五谷不分,四体不勤,三天打鱼,两天晒网,一无是处。

TOP

顶...!,好东西大家来分享。共同学习
永远不孤单

TOP

发新话题