打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
项目经验杂记

http://blog.sina.com.cn/s/blog_6a1837e90100onsb.html
2011
static spinlock_tRequestResponseLock = SPIN_LOCK_UNLOCKED;
spin_lock_bh(&RequestResponseLock);//spin_lock_bh 在获取锁之前禁止软件中断, 但是硬件中断留作打开的.
spin_unlock_bh(&RequestResponseLock);
spin_lock(&RequestResponseLock);
spin_unlock(&RequestResponseLock);
//上层调用函数内包含自旋锁时使用spin_lock_bh,而内核层底半步调用时使用spin_lock。bh指bottom_half,即底半。
--------------------------------------------------------------------------------------------------
create_proc_info_entry( REQUEST_RESPONSE_STATUS_NAME, 0,proc_dir, RequestResponseCacheStatus );
remove_proc_entry(REQUEST_RESPONSE_STATUS_NAME,proc_dir);
--------------------------------------------------------------------------------------------------
init_timer(&m->timer);
m->timer.function =&RequestResponseEntryExpired;
m->timer.data = (unsignedlong)m;
mod_timer(&m->timer,jiffies + GetRadiusResponseTimeout());
del_timer(&m->timer);
--------------------------------------------------------------------------------------------------
struct list_head e;
list_add(&m->e,&RequestResponseCache.hash_list[h].head);
while(!list_empty(&RequestResponseCache.hash_list[i].head))
m =list_entry(RequestResponseCache.hash_list[i].head.next, structRequestResponseEntry, e);
list_for_each_entry(m,&RequestResponseCache.hash_list[h].head,e)
list_del(&m->e);
--------------------------------------------------------------------------------------------------
insmod/lib/modules/2.6.18-8.el5/kernel/drivers/rtc/rtc-lib.ko 
insmodmonitor.ko
mknod /dev/mapdrv0 c250 0
rmmod monitor
--------------------------------------------------------------------------------------------------
内核编程中:
#include<ctype.h>
存在错误,而
#include<linux/ctype.h>
正常
--------------------------------------------------------------------------------------------------
#ifdef __KERNEL__
#include<linux/ctype.h>
#else
#include<ctype.h>
#endif

宏__KERNEL__能够区别当前程序是在用户层还是内核层。
上述代码包含在.h中,此头文件可以被用户层和内核层的程序包含。
--------------------------------------------------------------------------------------------------
在strnpcy之后,需在目标字符串的结尾加上'\0',即
strncpy(dest, src,size);
dest[size] ='\0'
--------------------------------------------------------------------------------------------------
2的n次方使用(1<< n)的形式
--------------------------------------------------------------------------------------------------
kmalloc只能申请128K的内存,建议使用vmalloc
vfree()不能放在spin_lock_bh和spin_unlock_bh之间;
--------------------------------------------------------------------------------------------------
module_init()
module_exit()

函数module_init()和module_exit()是模块编程中最基本也是必须的两个函数。
module_init()向内核注册模块所提供的新功能,
而module_exit()注销由模块提供的所有功能。

MODULE_LICENSE("GPL")用于声明模块的许可证
--------------------------------------------------------------------------------------------------
Linux内核模块的编译需要给gcc指示-D__KERNEL__-DMODULE -DLINUX参数
--------------------------------------------------------------------------------------------------
void *kmalloc(unsigned int len, intpriority);
void kfree(void*__ptr);

priority:
GFP_KERNEL
GFP_ATOMIC
--------------------------------------------------------------------------------------------------
unsigned long copy_from_user(void *to,const void *from, unsigned long n);
unsigned longcopy_to_user (void * to, void * from, unsigned longlen);

put_user
get_user
--------------------------------------------------------------------------------------------------
内核编程用printk替代printf

内核一共有8个优先级.如果优先级数字比intconsole_loglevel变量小的话,消息就会打印到控制台上。如果syslogd和klogd守护进程在运行的话,则不管是否向控制台输出,消息都会被追加进/var/log/messages文件。klogd只处理内核消息,syslogd 处理其他系统消息,比如应用程序。
--------------------------------------------------------------------------------------------------
include/linux/module.h中定义的宏MODULE_PARM(var,type)用于向模块传递命令行参数。var为接受参数值的变量名,type为采取如下格式的字符串[min[-max]]{b,h,i,l,s}。min及max用于表示当参数为数组类型时,允许输入的数组元素的个数范围;
b:byte;h:short;i:int;l:long;s:string。

有了MODULE_PARM,在装载内核模块时,用户可以向模块传递一些参数,如:
insmod modnamevar=value
--------------------------------------------------------------------------------------------------
#Makefile2.6
obj-m += hellomod.o      # 产生hellomod 模块的目标文件
CURRENT_PATH :=$(shell pwd)   #模块所在的当前路径
LINUX_KERNEL :=$(shell uname -r)   #Linux内核源代码的当前版本
LINUX_KERNEL_PATH :=/usr/src/linux-headers-$(LINUX_KERNEL)#Linux内核源代码的绝对路径
all:
make -C$(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules  #编译模块了
clean:
make -C$(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean   #清理

有了Makefile,执行make命令,会自动形成相关的后缀为.o和.ko文件。
--------------------------------------------------------------------------------------------------
模块和内核都在内核空间运行,模块编程在一定意义上说就是内核编程
模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。
模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。
因为内核版本的每次变化,其中的某些函数名也会相应地发生变化,因此模块编程与内核版本密切相关
内置模块:可加载模块
--------------------------------------------------------------------------------------------------
这些变量和函数就统称为符号。
其中宏定义EXPORT_SYMBOL()本身的含义是“移出符号”。为什么说是“移出”呢?因为这些符号本来是内核内部的符号,通过这个宏放在一个公开的地方,使得装入到内核中的其他模块可以引用它们。
在模块编程中,可以根据符号名从这个文件中检索出其对应的地址,然后直接访问该地址从而获得内核数据。
第三列“所属模块”指符号所在的模块名,对于从内核这一母模块移出的符号,这一列为空。
模块加载后,2.4内核下可通过/proc/ksyms、 2.6 内核下可通过/proc/kallsyms查看模块输出的内核符号
--------------------------------------------------------------------------------------------------
模块依赖

为了确保模块安全地卸载,每个模块都有一个引用计数器
--------------------------------------------------------------------------------------------------
1.Insmod命令:
2.rmmod命令:
3.lsmod命令:读取/proc文件系统中的文件/proc/modules中的信息
4.ksyms命令:读取/proc文件系统中的文件/proc/kallsyms。
--------------------------------------------------------------------------------------------------
//MODULE_PARM_DESC(interface,”A networkinterface”);  2.4内核中该宏的用法
molule_parm(interface,charp,0644) //2.6内核中的宏
//MODULE_PARM_DESC(irq,”The IRQ of the networkinterface”);
module_param(irq,int,0644);

insmod myirq.kointerface=eth0 irq=9

if(request_irq(irq, &myinterrupt, SA_SHIRQ,interface,&irq)) //注册中断,中断值为irq,中断函数myinterrupt
free_irq(irq,&irq);

具体网卡 irq的值可以查看cat /proc/interrupts

可动态更改
--------------------------------------------------------------------------------------------------
insmod(安装 LKM),
rmmod (删除LKM),
modprobe(insmod和 rmmod的包装器),加载当前当前模块与其相关联的其他模块,单一模块无关联时,必须使用insmod,否则会报错,当自写编写模块时,建议不要使用。
depmod(用于创建模块依赖项),
modinfo(用于为模块宏查找值)。

LKM只不过是一个特殊的可执行可链接格式(Executable and LinkableFormat,ELF)对象文件。

在模块的加载和卸载期间,模块子系统维护了一组简单的状态变量,用于表示模块的操作。
--------------------------------------------------------------------------------------------------
内核中有一个叫做 HZ的频率变量,它表示每秒的时钟节拍数。一般的,在某种平台上它会有一个固定值,这个固定值是人为设定的,
也就是可编程的(对系统定时器编程)。设定 HZ的大小需要权衡。这个值设大了,带来的好处是定时器间隔变小,
从而使进程(任务)的调度的精确性得以提高,但带来的缺点是导致开销过大,让系统变得耗电,
这样在一些经常使用电池的设备来说(比如笔记本,平板电脑)是难以接受的。
在现在一般的 x86平台,2.6 内核的 linux 下,这个值会被设为 100 。也就是说,一个时钟节拍为 1/100 = 0.01s = 10ms。
一个时钟节拍也称为 1 个jiffy 。
内核中还有一个重要的变量叫jiffies 。它记录了系统从启动到当前所触发定时器的次数。jiffies 每秒钟增加 HZ 个计数,
实际上就是 N 个 jiffy。
--------------------------------------------------------------------------------------------------
中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。

下半部运行时是允许中断请求的,而上半部运行时是关中断的,这是二者之间的主要区别。 
--------------------------------------------------------------------------------------------------
小任务(Tasklet)机制

Count域是小任务的引用计数器。如果它不为0,则小任务被禁止,不允许执行;只有当它为零,小任务才被激活,并且在被设置为挂起时,小任务才能够执行。

DECLARE_TASKLET(name, func, data)
DECLARE_TASKLET_DISABLED(name, func, data)

DECLARE_TASKLET(my_tasklet, my_tasklet_handler,dev);
这行代码其实等价于
structtasklet_struct my_tasklet = { NULL, 0, ATOMIC_INIT(0),tasklet_handler, dev};

static voidtasklet_handler (unsigned long data)
tasklet_init(&my_tasklet,tasklet_handler, 0);
tasklet_schedule(&my_tasklet);
tasklet_kill(&my_tasklet);
--------------------------------------------------------------------------------------------------
如果推后执行的任务需要睡眠,那么就选择工作队列。如果推后执行的任务不需要睡眠,那么就选择tasklet。
另外,如果需要用一个可以重新调度的实体来执行你的下半部处理,也应该使用工作队列。

voidwork_handler(void *data); //工作队列待执行的函数

DECLARE_WORK(name, void (*func) (void *), void *data);//这样就会静态地创建一个名为name,待执行函数为func,参数为data的work_struct结构。
INIT_WORK(struct work_struct *work, woid(*func) (void *),void *data); //这会动态地初始化一个由work指向的工作。

queue =create_singlethread_workqueue(“helloworld”);
if(!queue)
gotoerr;
destroy_workqueue(queue);

schedule_work(&work);//把给定工作的待处理函数提交给缺省的events工作线程
schedule_delayed_work(&work, delay);//&work指向的work_struct直到delay指定的时钟节拍用完以后才会执行。
--------------------------------------------------------------------------------------------------

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Essayteam>>Linux驱动程序开发
Linux内核之旅 ? Blog Archive ? 内核模块编程之进阶(四)-编写带参数...
Linux内核模块开发(笔记)
Linux设备驱动Hello World程序介绍
linux设备驱动归纳总结(六):3.中断的上半部和下半部——tasklet
Linux内核开发之中断与时钟(一)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服