The Notes of Linux Device Drivers

Overview

1.      The role of the device driver

User activities are performed by means of a set of standardized calls that areindependent of the specific driver;mapping thosecalls to device-specific operations that act on real hardware isthen the role of the device driver.

Therole of a device driver is providing mechanism, not policy.

2.      Mechanism vs. Policy

Mechanism:what capabilities are to be provided

Policy:how those capabilities can be used"

If the two issues are addressed by different parts of the program, or even bydifferent programs altogether, the software package is much easier to developand to adapt to particular needs.

3.      Kernel architecture


4.      Classes of Devices and Modules

TheLinux way of looking at devices distinguishes between three fundamentaldevice types. Each module usually implements one of these types, and thus isclassifiable asa char module, a block module, or a networkmodule.

Characterdevices: A character (char) device is one that canbe accessed as a stream of bytes (like a file); a char driver is in charge of implementing thisbehavior.

Blockdevices: A block device is a device (e.g., a disk) that can host a filesystem.In most Unix systems, a block device can only handle I/O operations thattransfer one or more whole blocks, which are usually 512 bytes (or a largerpower of two) bytes in length.

Networkinterfaces: Any network transaction is made through an interface, that is, adevice that is able to exchange data with other hosts.

 

Hello, World

1.      Set up your test system

Ubunto8.10 + Skyeye

http://code.google.com/p/ldd6410/wiki/SkyeyeInLdd6410

2.      Source codes (Using Linux-2.6.31)

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");

                        return0;

}

 

static void hello_exit(void)

{

                        printk(KERN_ALERT"Goodbye, cruel world\n");

}

 

module_init(hello_init);

module_exit(hello_exit);

 

Makefile

PWD := $(shell pwd)

KERNELDIR =/home/bambreeze/workspace/ldd6410-read-only/linux-2.6.31

INSTALLDIR =/home/bambreeze/workspace/skyeye/initrd/lib/modules

 

CROSS_COMPILE   = arm-linux-

CC     = $(CROSS_COMPILE)gcc

 

obj-m := hello.o

 

.PHONY: modules modules_install clean

 

modules:

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

 

modules_install:

                        cphello.ko $(INSTALLDIR)

 

clean:

                        rm-rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.orderModule.symvers

3.      Build

(1)  Prepare for the Root File System –initrd.img

$ sudo mount -o loop initrd.img initrd

(2)  Build Linux kernel image - vmlinux

$make vmlinux

$cp vmlinux /var/lib/tftpboot/

$cp vmlinux ~/workspace/skyeye/

(3)  Build module - hello.ko

$make modules

$ sudo make modules_install

(4)  Build the Root File System – initrd.img

$sudo umount initrd

4.      Run

We have two methods to run Skyeye with Linux.

(1)  Boot up vmlinux image directly

$sudo skyeye -e vmlinux -cskyeye-standalone.conf

(2)  Boot up u-boot firstly, then tftpdownload and boot up vmlinux image in the u-boot finally

$sudoskyeye -e u-boot -cskyeye-with-uboot.conf -l 0x30000000,0xFFFFFF

SMDK2410 # tftp 0xc0000000 vmlinux

TFTP from server 10.0.0.1; our IP addressis 10.0.0.2

Filename 'vmlinux'.

Load address: 0xc0000000

Loading:#################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #################################################################

                         #############################################

done

Bytes transferred = 3889865 (3b5ac9 hex)

SMDK2410 # bootelf 0xc0000000

Loading .text.head @ 0xc0008000 (992 bytes)

Loading .init @ 0xc00083e0 (142368 bytes)

Loading .text @ 0xc002b000 (2336392 bytes)

Loading __ksymtab @ 0xc0266000 (18704bytes)

Loading __ksymtab_gpl @ 0xc026a910 (7160bytes)

Loading __ksymtab_strings @ 0xc026c508(55521 bytes)

Loading __param @ 0xc0279dec (4628 bytes)

Loading .ARM.unwind_idx @ 0xc027b000 (80448bytes)

Loading .ARM.unwind_tab @ 0xc028ea40 (2424bytes)

Loading .data @ 0xc0290000 (117632 bytes)

Clearing .bss @ 0xc02acb80 (140392 bytes)

## Starting application at 0xc0008000 ...

Linux version 2.6.31.6-svn79(bambreeze@bambreeze-laptop) (gcc version 4.2.2) #9 Fri May 27 10:32:44 CST2011

CPU: ARM920T [41009200] revision 0(ARMvundefined/unknown), cr=00003177

5.      Test the modules

# pwd

/lib/modules

# insmod hello.ko

Hello, world

# lsmod

   Not tainted

hello 1088 0 - Live 0xc1128000

# rmmod hello

Goodbye, cruel world

# lsmod

   Not tainted

6.      Debug


 

Char Drivers (scull)

1.      Source codes

scull.c

 

scull_tests.c

 

Makefile

PWD := $(shell pwd)

KERNELDIR =/home/bambreeze/workspace/ldd6410-read-only/linux-2.6.31

INSTALLDIR =/home/bambreeze/workspace/skyeye/initrd/lib/modules

 

CROSS_COMPILE   = arm-linux-

CC     = $(CROSS_COMPILE)gcc

 

# Comment/uncomment the following line todisable/enable debugging

#DEBUG = y

 

# Add your debugging flag (or not) to CFLAGS

ifeq ($(DEBUG),y)

 DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expandinlines

else

 DEBFLAGS = -O2

endif

 

#CFLAGS += $(DEBFLAGS)

#CFLAGS += -I$(LDDINC)

#EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)

 

# call from kernel build system

ifneq ($(KERNELRELEASE),)

 

#scull-objs := main.o pipe.o access.o

obj-m           :=scull.o

 

else

 

modules:

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

 

endif

 

modules_tests: scull_tests.o

                        $(CC)-o scull_tests scull_tests.o

 

modules_install:

                        mount-o loop /home/bambreeze/workspace/skyeye/initrd.img/home/bambreeze/workspace/skyeye/initrd/

                        cpscull.ko $(INSTALLDIR)

                        cpscull_tests $(INSTALLDIR)

                        umount/home/bambreeze/workspace/skyeye/initrd/

 

clean:

                        rm-rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.markersmodules.order Module.symvers scull_tests

 

depend .depend dep:

                        $(CC)$(CFLAGS) -M *.c > .depend

 

ifeq (.depend,$(wildcard .depend))

include .depend

endif

 

.PHONY: modules modules_testsmodules_install clean

2.      Build

$make modules

$ sudo make modules_install

3.      Test & Verify

$sudo skyeye -e vmlinux -cskyeye-standalone.conf

# cd lib/modules

# ls -l

drwxr-xr-x    3 root    root         1024 Jan 16  2010 2.6.31.6-svn79

-rw-r--r--    1 root    root         2244 May 27  2011 hello.ko

-rw-r--r--    1 root    root         9027 May 27  2011 scull.ko

-rwxr-xr-x    1 root    root         9688 May 27  2011 scull_tests

# insmod scull.ko

# cat /proc/devices | grep scull

254 scull

# mknod -m 666 /dev/scull0c 254 0

# ./scull_tests

write ok! code=20

read ok! code=20

[0]=0 [1]=1 [2]=2 [3]=3 [4]=4

[5]=5 [6]=6 [7]=7 [8]=8 [9]=9

[10]=10 [11]=11 [12]=12 [13]=13 [14]=14

[15]=15 [16]=16 [17]=17 [18]=18 [19]=19


参考文献

1. Linux Device Drivers, Third Edition [LWN.net]

2. Linux Device Drivers (example fix)

3. Linux Device Drivers 牛人学习笔记

4. ldd6410 - Project Hosting on Google Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值