do{}while(0)主要用于宏中,定义多语句宏时,若不加{},则if语句将没有else,若加上大括号,则语句后加;是约定的,这样if又没有else对应了。因此,用do while(0)代替;
驱动注册时,如果用module_init( XXX_init),则该驱动可以被动态加载,也可以静态加载,如果确定为静态加载,如android中的binder驱动,可以用device_initcall(XXX_init)代替。这两者的注册顺序都是随机的,另外还有core_init(XXX_init)能保证该驱动能在较早的时刻进行注册,以免后面的程序在未注册时调用
#define __init __attribute__ ((__section__(".init.text")))//__init表示其连接的时候回放在.init.text区域,
//并在.initcall.init中保存了一份指针,初始化内核时会调用他们。
#ifdef MODULE
#define __exit __attribute__ ((__section__(".exit.text")))
#else
#define __exit __attribute_used __attribute__((__section__(".exit.text")))
linux模块组成:
MODULE_LICESE("GPL /*Dual BSD/GPL*/"); //必须
static int num=100;
static int /*__init*/ book_init(){printk("book num: %s",num);return 0;}
static void /*__exit*/ book_exit(){}
module_init(book_init); //必须
module_exit(book_exit); //必须
modu_param(num,int,S_IRUGO);
MODULE_AUTHOR("david");
MODULE_DESCRIPTION("this is a module");
MODULE_VERSION("V1.0");
MODULE_DEVICE_TABLE(table_info)
MODULE_ALIAS("xxx")
运行时:insmod book.ko num=500 ......
编译模块
make file:
obj-m:=myModule.o
module-objs:=file1.o file2.o
运行:make -C /usr/src/linux M=path modules
如果有项目被选择"M",除了make bzImage外,还要make modules
若让系统自动加载模块,需要修改rc脚本
struct file
{
...
struct dentry *f_dentry; //文件目录
struct file_operations *f_op; //文件相关操作
unsigned int f_flags; //文件标志o_rdonly,o_nonblock,o_sync//判断是否阻塞
mode_t f_mode; //读写模式 FMODE_READ,FMODE_WRITE //判断是否可读写
loff_t fpos; //当前读写位置
void* private_data;
....
}
stuct file_operations
{
struct module* ower;//=THIS_MODULE
loff_t (*llseek)(struct file*,loff_t,int);//修改当前读写位置
int (*open)(struct inode*,struct file*);//若没有,设备永远打开
ssize_t (*read)(struct file*,char __user*,size_t,loff_t);
ssize_t (*write)(struct file*,const char __user*,size_t,loff_t);
int (*ioctl)(struct inode*, struct file*, unsigned int,unsigned long);
int (*flush)(struct file*);
int (*release)(struct inode*,struct file*)
int (*mmap)(struct file*,struct vm_area_struct*);//将内存映射到地址空间
............
}
devfs范例:
static devfs_handle_t devfs_handle;
static int __init xxinit()
{
int ret=register_chrdev(xxxMAJOR,"deviceName",&xxx_fops);//向内核注册设备(过时),若xxxMAJOR为0,系统自动分配
devfs_handle_t dir=devfs_mk_dir(devfs_handle_t dir,const char* name, void* info);
//创建设备文件
devfs_handle = devfs_register(null/*dir*/,"deviceName",DEVFS_FL_DEFAULT/*flags*/,xxMAJOR,0/*次设备号*/,S_IFCHR|S_IRUSR|S_IWUSR/*umode_t mode*/,&xx_fops,null);
return 0;
}
static void __exit xx_exit()
{
devfs_unregister(devfs_handle);//撤销设备文件
unregister_chrdev(xxMAJOR,"deviceName");//注销设备 (过时)
}