模块的概述

来源:互联网 发布:淘宝网 iphone4 屏 编辑:程序博客网 时间:2024/06/05 14:44

一、什么是驱动?

驱动就是让硬件运动起来的那部分软件。就好比一辆车,有司机车就能动起来,驱动就好比是那个司机;而车开往哪里,由乘客决定,也就是应用程序。
在操作系统中,驱动是直接和硬件打交道程序,硬件的具体运动方式由应用程序通过和驱动打交道实现。


二、linux驱动的类型

三种类型:字符设备驱动、块设备驱动、网络设备驱动。


三、运行在内核里的程序的方法?

方法1:直接在源码中加入程序,然后再编译内核,这种方法不可取。
方法2:将程序写成模块,然后动态插入正在运行的内核,不用时卸载模块。

四、写模块必要的三个要素?
1.模块的初始化函数,在模块被加载后运行的函数。
2.模块的清理函数,在模块被卸载时运行的函数。
3.模块的许可声明。要求所有加载的模块都要符合开源协议。

PS:模块和普通程序不同的是,没有main函数。不能调用c库,只能使用linux源码自带的函数。

五、使用Makefile方式编译模块?
在项目文件夹下创建一个Makefile文件。
内容如下:
KERN=/root/linux-3.0.8/
#KERN=/usr/src/kernels/`uname -r`
SRC=`pwd`
obj-m+=mymodule.o

all:
make -C $(KERN) M=$(SRC) modules
clean:
make -C $(KERN) M=$(SRC) clean

六、模块的加载卸载以及查询

加载:insmod *.ko
卸载:rmmod 模块名(无后缀)
查询:lsmod

七、模块的结构体

struct module

{

enum module_state state;

 

/* Member of list of modules */

struct list_head list;

 

/* Unique handle for this module */

char name[MODULE_NAME_LEN];

 

/* Sysfs stuff. */

struct module_kobject mkobj;

struct module_attribute *modinfo_attrs;

const char *version;

const char *srcversion;

struct kobject *holders_dir;

 

/* Exported symbols */

const struct kernel_symbol *syms;

const unsigned long *crcs;

unsigned int num_syms;

 

/* Kernel parameters. */

struct kernel_param *kp;

unsigned int num_kp;

 

/* GPL-only exported symbols. */

unsigned int num_gpl_syms;

const struct kernel_symbol *gpl_syms;

const unsigned long *gpl_crcs;

 

#ifdef CONFIG_UNUSED_SYMBOLS

/* unused exported symbols. */

const struct kernel_symbol *unused_syms;

const unsigned long *unused_crcs;

unsigned int num_unused_syms;

 

/* GPL-only, unused exported symbols. */

unsigned int num_unused_gpl_syms;

const struct kernel_symbol *unused_gpl_syms;

const unsigned long *unused_gpl_crcs;

#endif

 

/* symbols that will be GPL-only in the near future. */

const struct kernel_symbol *gpl_future_syms;

const unsigned long *gpl_future_crcs;

unsigned int num_gpl_future_syms;

 

/* Exception table */

unsigned int num_exentries;

struct exception_table_entry *extable;

 

/* Startup function. */

int (*init)(void);

 

/* If this is non-NULL, vfree after init() returns */

void *module_init;

 

/* Here is the actual code + data, vfree'd on unload. */

void *module_core;

 

/* Here are the sizes of the init and core sections */

unsigned int init_size, core_size;

 

/* The size of the executable code in each section.  */

unsigned int init_text_size, core_text_size;

 

/* Size of RO sections of the module (text+rodata) */

unsigned int init_ro_size, core_ro_size;

 

/* Arch-specific module values */

struct mod_arch_specific arch;

 

unsigned int taints; /* same bits as kernel:tainted */

 

#ifdef CONFIG_GENERIC_BUG

/* Support for BUG */

unsigned num_bugs;

struct list_head bug_list;

struct bug_entry *bug_table;

#endif

 

#ifdef CONFIG_KALLSYMS

/*

 * We keep the symbol and string tables for kallsyms.

 * The core_* fields below are temporary, loader-only (they

 * could really be discarded after module init).

 */

Elf_Sym *symtab, *core_symtab;

unsigned int num_symtab, core_num_syms;

char *strtab, *core_strtab;

 

/* Section attributes */

struct module_sect_attrs *sect_attrs;

 

/* Notes attributes */

struct module_notes_attrs *notes_attrs;

#endif

 

/* The command line arguments (may be mangled).  People like

   keeping pointers to this stuff */

char *args;

 

#ifdef CONFIG_SMP

/* Per-cpu data. */

void __percpu *percpu;

unsigned int percpu_size;

#endif

 

#ifdef CONFIG_TRACEPOINTS

unsigned int num_tracepoints;

struct tracepoint * const *tracepoints_ptrs;

#endif

#ifdef HAVE_JUMP_LABEL

struct jump_entry *jump_entries;

unsigned int num_jump_entries;

#endif

#ifdef CONFIG_TRACING

unsigned int num_trace_bprintk_fmt;

const char **trace_bprintk_fmt_start;

#endif

#ifdef CONFIG_EVENT_TRACING

struct ftrace_event_call **trace_events;

unsigned int num_trace_events;

#endif

#ifdef CONFIG_FTRACE_MCOUNT_RECORD

unsigned int num_ftrace_callsites;

unsigned long *ftrace_callsites;

#endif

 

#ifdef CONFIG_MODULE_UNLOAD

/* What modules depend on me? */

struct list_head source_list;

/* What modules do I depend on? */

struct list_head target_list;

 

/* Who is waiting for us to be unloaded */

struct task_struct *waiter;

 

/* Destruction function. */

void (*exit)(void);

 

struct module_ref {

unsigned int incs;

unsigned int decs;

} __percpu *refptr;

#endif

 

#ifdef CONFIG_CONSTRUCTORS

/* Constructor functions. */

ctor_fn_t *ctors;

unsigned int num_ctors;

#endif

};


在驱动中可以通过THIS_MODULE指针来获取本模块的struct module结构体,例:THIS_MODULE->name模块名称。


八、printk知识

printk是内核里的打印函数,通常会打印到日志。和printk不同的是,这个函数有等级之分。

#define KERN_EMERG "<0>" /* system is unusable */

#define KERN_ALERT "<1>" /* action must be taken immediately */

#define KERN_CRIT "<2>" /* critical conditions */

#define KERN_ERR "<3>" /* error conditions */

上面这些打印到终端会马上显示

 

下面这些打印到终端不马上显示

#define KERN_WARNING "<4>" /* warning conditions */

#define KERN_NOTICE "<5>" /* normal but significant condition */

#define KERN_INFO "<6>" /* informational */

#define KERN_DEBUG "<7>" /* debug-level messages












原创粉丝点击