免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5313 | 回复: 2
打印 上一主题 下一主题

【转】Writing a Linux device driver [复制链接]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-06 10:16 |只看该作者 |倒序浏览
Writing a Linux device driver

By Aditya Kulkarni <aditya@freeos.com>
Posted: ( 2000-11-13 22:10:47 EST by )
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


How init_module works?


init_module loads the relocated module image into kernel space and runs
the module's init function.
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.


How cleanup_module works?


cleanup_module attempts to remove an unused loadable module entry. If
name is NULL, all unused modules marked auto clean will be removed.
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.

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2008-11-06 10:16 |只看该作者
老外写的,应该很有指导意义,可以学习一下

论坛徽章:
1
2016科比退役纪念章
日期:2016-07-07 09:23:46
3 [报告]
发表于 2014-01-01 03:58 |只看该作者
学习下,全部都是英文啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP