Writing a Linux device driver

转载 2007年09月29日 11:25:00

Does the idea of writing a Linux device driver sound difficult? If
you have some basic programming experience, the task is
simpler than you think. Get started with this quick primer on
device driver programming.

What do I need to know about writing drivers?

Basic knowledge of kernel compilation, a good deal of programming
experience in C under Linux and lastly, the right techniques of data
structures, like linked list is essential along with their data types.

The first thing a programmer must know before attempting to write a
driver, is to know how the Linux kernel source compiles, paying attention
to the compilation process (the gcc compiler flags).

Choosing the device type

a) Block drivers

A block device is something that can host a filesystem such as a disk. A
block device can only be accessed as multiples of a block, where a block
is usually one kilobyte of data .

b) Character drivers

A character device is one that can be accessed like a file, and a char
driver is in charge of implementing this behaviour. This driver implements
the open, close, read and write system calls. The console and parallel
ports are examples of char devices.

Device drivers in Linux are known as modules and can be loaded dynamically
into the kernel using the insmod command.

A single module can be compiled alone, and also can be linked to the
kernel (here, care has to be taken on the type of driver).

eg: A simple module

#define MODULE
#include <linux/module.h>

int init_module (void) /* Loads a module in the kernel */
{
printk("Hello kernel n");
return 0;
}

void cleanup_module(void) /* Removes module from kernel */
{
printk("GoodBye Kerneln");
}

Compiling the module

# gcc -c hello.c
# insmod hello.o

The output is

Hello kernel

# rmmod hello.o

GoodBye Kernel

(注:这个例子放到2.6.x的内核下是不行的,内核模块改为xxx.ko文件具体是从哪个版本开始的,我还不知。希望有知道的能告诉我,谢谢!这里有举一个可以在2.6.x下运行的"Hello, world!",我在Fedora 5(2.6.15)下运行通过。如果要在刚装好的Fedora 5下编译内核模块,请参考<<使用Fedora Core 5 (FC5)编译新的模块>>

eg: A simple module

#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/$(shell uname -r)/build
PWD       := $(shell pwd)

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

clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

此例出自<<Linux Device Drivers, Third Edition>>中的第二章.

注完!)



init_module loads the relocated module image into kernel space and runs
the module's init function.

How init_module works?

 

The module image begins with a module structure and is followed by code
and data as appropriate.

The module structure is defined as follows:

struct module
{
unsigned long size_of_struct;
struct module *next;
const char *name;
unsigned long size;
long usecount;
unsigned long flags;
unsigned int nsyms;
unsigned int ndeps;
struct module_symbol *syms;
struct module_ref *deps;
struct module_ref *refs;
int (*init)(void);
void (*cleanup)(void);
const struct exception_table_entry *ex_table_start;
const struct exception_table_entry *ex_table_end;
#ifdef __alpha__
unsigned long gp;
#endif
};


All of the pointer fields, with the exception of next and refs, are
expected to point within the module body and be initialized as appropriate
for kernel space, i.e. relocated with the rest of the module.

Return Values

On success, zero is returned. On error, -1 is returned
and errno is set appropriately.

Errors

EPERM The user is not the superuser.

ENOENT No module by that name exists.

EINVAL Some image slot filled in incorrectly, image->name
does not correspond to the original module name,
some image->deps entry does not correspond to a
loaded module, or some other similar inconsistency.

EBUSY The module's initialization routine failed.

EFAULT name or image is outside the program's accessible
address space.



cleanup_module attempts to remove an unused loadable module entry. If
name is NULL, all unused modules marked auto clean will be removed.

How cleanup_module works?

 

Return Values

On success, zero is returned. On error, -1 is returned and errno is
set appropriately.

Errors

EPERM The user is not the superuser.

ENOENT No module by that name exists.

EINVAL name was the empty string.

EBUSY The module is in use.

EFAULT name is outside the program's accessible address
space.

This simple module is called skull, short for Simple Kernel Utility For
Loading Localities.

General flags used for compiling any driver are

-D__KERNEL__ _DMODULE -O -Wall -I$(INCLUDEDIR)

Note: The INCLUDEDIR should contain the header files of the kernel source.

Module code has to be recompiled for each version of the kernel that it
will be linked to. Each module defines a symbol called kernel_version
which is defined in <linux/module.h>. In case of a version mismatch, use
the insmod -f (force) option to load the module.

Writing a Linux device driver By Aditya Kulkarni <aditya@freeos.com>
Posted: ( 2000-11-13 22:10:47 EST by )

原文地址:http://www.freeos.com/articles/2677/

 

Writing device drivers in Linux: A brief tutorial(一)

最近看到一篇国外关于Linux内核入门的比较好的指南,于是就尝试翻译了一下。由于是第一次尝试翻译,加之英语水平有限,错误在所难免,欢迎拍砖! 由于没有大段的时间来做这个,一下翻译完是肯定不可能的,故...
  • yxz329130952
  • yxz329130952
  • 2012年08月27日 21:25
  • 1408

Writing device drivers in Linux: A brief tutorial(五)

一个并口驱动程序:并行接口的描述          我将继续修改我之前创建的那个驱动程序从而使它可以在真正的设备上执行真正的任务。我将使用常见计算机的并口,并将这个驱动命名为“parleport” ...
  • yxz329130952
  • yxz329130952
  • 2012年09月13日 16:43
  • 1763

Writing a Linux device driver

 By Aditya Kulkarni aditya@freeos.com> Posted: ( 2000-11-13 22:10:47 EST by ) Does the idea of writi...
  • johndiyang
  • johndiyang
  • 2006年11月19日 16:33
  • 681

Writing a SCSI Device Driver

http://tldp.org/LDP/khg/HyperNews/get/devices/scsi.htmlWriting a SCSI Device DriverCopyright (C) 199...
  • xianfengdesign
  • xianfengdesign
  • 2007年08月25日 01:35
  • 2466

linux bus、driver、device及三者的关系

一、概念 1、bus     总线是处理器和设备之间的通道。总线有多种类型,每种总线可以挂载多个设备。 2、driver     驱动程序是在CPU运行时,提供操作的软件接口。所有的设备必须有...
  • lindonghai
  • lindonghai
  • 2012年10月25日 17:25
  • 3313

【Linux device driver】设备驱动程序概述(一)

  • fengyv
  • fengyv
  • 2006年07月01日 10:01
  • 4306

Linux Device Drivers 3rd edition 设备驱动 源代码

Linux Device Drivers 3rd edition is a very good book by Jonathan Corbet, Alessandro Rubini and Greg ...
  • YAJUN0601
  • YAJUN0601
  • 2011年06月22日 00:55
  • 1310

linux下bus,device,driver三者关系

linux下bus,device,driver三者关系                                1.bus:   总线作为主机和外设的连接通道,有些总线是比较规范的...
  • lin111000713
  • lin111000713
  • 2014年05月30日 09:49
  • 1088

Writing Solaris Device Driver: Basic

Device Driver BasicsThis section introduces you to device drivers and their entry points on the Sola...
  • hotsolaris
  • hotsolaris
  • 2007年09月05日 15:14
  • 586

Writing a Linux device driver module for kernels 2.6 or later with udev

This is a short tutorial for a sample character device module aimed at Linux kernels 2.6 and later (...
  • CaspianSea
  • CaspianSea
  • 2016年06月27日 03:42
  • 348
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Writing a Linux device driver
举报原因:
原因补充:

(最多只允许输入30个字)