小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

項目經(jīng)驗雜記

 心不留意外塵 2016-05-03

http://blog.sina.com.cn/s/blog_6a1837e90100onsb.html
2011
static spinlock_t RequestResponseLock = SPIN_LOCK_UNLOCKED;
spin_lock_bh(&RequestResponseLock); //spin_lock_bh 在獲取鎖之前禁止軟件中斷, 但是硬件中斷留作打開的.
spin_unlock_bh(&RequestResponseLock);
spin_lock(&RequestResponseLock);
spin_unlock(&RequestResponseLock);
//上層調(diào)用函數(shù)內(nèi)包含自旋鎖時使用spin_lock_bh,而內(nèi)核層底半步調(diào)用時使用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 = (unsigned long)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, struct RequestResponseEntry, 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 
insmod monitor.ko
mknod /dev/mapdrv0 c 250 0
rmmod monitor
--------------------------------------------------------------------------------------------------
內(nèi)核編程中:
#include <ctype.h>
存在錯誤,而
#include <linux/ctype.h>
正常
--------------------------------------------------------------------------------------------------
#ifdef __KERNEL__
#include <linux/ctype.h>
#else
#include <ctype.h>
#endif

宏__KERNEL__能夠區(qū)別當前程序是在用戶層還是內(nèi)核層。
上述代碼包含在.h中,此頭文件可以被用戶層和內(nèi)核層的程序包含。
--------------------------------------------------------------------------------------------------
在strnpcy之后,需在目標字符串的結(jié)尾加上'\0',即
strncpy(dest, src, size);
dest[size] = '\0'
--------------------------------------------------------------------------------------------------
2的n次方使用(1 << n)的形式
--------------------------------------------------------------------------------------------------
kmalloc只能申請128K的內(nèi)存,建議使用vmalloc
vfree()不能放在spin_lock_bh和spin_unlock_bh之間;
--------------------------------------------------------------------------------------------------
module_init()
module_exit()

函數(shù)module_init()和module_exit()是模塊編程中最基本也是必須的兩個函數(shù)。
module_init()向內(nèi)核注冊模塊所提供的新功能,
而module_exit()注銷由模塊提供的所有功能。

MODULE_LICENSE("GPL")用于聲明模塊的許可證
--------------------------------------------------------------------------------------------------
Linux內(nèi)核模塊的編譯需要給gcc指示-D__KERNEL__ -DMODULE -DLINUX參數(shù)
--------------------------------------------------------------------------------------------------
void *kmalloc(unsigned int len, int priority);
void kfree(void *__ptr);

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

put_user
get_user
--------------------------------------------------------------------------------------------------
內(nèi)核編程用printk替代printf

內(nèi)核一共有8個優(yōu)先級.如果優(yōu)先級數(shù)字比int console_loglevel變量小的話,消息就會打印到控制臺上。如果syslogd和klogd守護進程在運行的話,則不管是否向控制臺輸出,消息都會被追加進/var/log/messages文件。klogd 只處理內(nèi)核消息,syslogd 處理其他系統(tǒng)消息,比如應用程序。
--------------------------------------------------------------------------------------------------
include/linux/module.h中定義的宏MODULE_PARM(var,type) 用于向模塊傳遞命令行參數(shù)。var為接受參數(shù)值的變量名,type為采取如下格式的字符串[min[-max]]{b,h,i,l,s}。min及max用于表示當參數(shù)為數(shù)組類型時,允許輸入的數(shù)組元素的個數(shù)范圍;
b:byte;h:short;i:int;l:long;s:string。

有了MODULE_PARM,在裝載內(nèi)核模塊時,用戶可以向模塊傳遞一些參數(shù),如:
insmod modname var=value
--------------------------------------------------------------------------------------------------
# Makefile2.6
obj-m += hellomod.o        # 產(chǎn)生hellomod 模塊的目標文件
CURRENT_PATH := $(shell pwd)   #模塊所在的當前路徑
LINUX_KERNEL := $(shell uname -r)    #Linux內(nèi)核源代碼的當前版本
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) #Linux內(nèi)核源代碼的絕對路徑
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules   #編譯模塊了
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean    #清理

有了Makefile,執(zhí)行make命令,會自動形成相關(guān)的后綴為.o和.ko文件。
--------------------------------------------------------------------------------------------------
模塊和內(nèi)核都在內(nèi)核空間運行,模塊編程在一定意義上說就是內(nèi)核編程
模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。
模塊通常由一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)組成,用來實現(xiàn)一種文件系統(tǒng)、一個驅(qū)動程序或其他內(nèi)核上層的功能。
因為內(nèi)核版本的每次變化,其中的某些函數(shù)名也會相應地發(fā)生變化,因此模塊編程與內(nèi)核版本密切相關(guān)
內(nèi)置模塊:可加載模塊
--------------------------------------------------------------------------------------------------
這些變量和函數(shù)就統(tǒng)稱為符號。
其中宏定義EXPORT_SYMBOL()本身的含義是“移出符號”。為什么說是“移出”呢?因為這些符號本來是內(nèi)核內(nèi)部的符號,通過這個宏放在一個公開的地方,使得裝入到內(nèi)核中的其他模塊可以引用它們。
在模塊編程中,可以根據(jù)符號名從這個文件中檢索出其對應的地址,然后直接訪問該地址從而獲得內(nèi)核數(shù)據(jù)。
第三列“所屬模塊”指符號所在的模塊名,對于從內(nèi)核這一母模塊移出的符號,這一列為空。
模塊加載后,2.4內(nèi)核下可通過 /proc/ksyms、 2.6 內(nèi)核下可通過/proc/kallsyms查看模塊輸出的內(nèi)核符號
--------------------------------------------------------------------------------------------------
模塊依賴

為了確保模塊安全地卸載,每個模塊都有一個引用計數(shù)器
--------------------------------------------------------------------------------------------------
1.Insmod命令:
2. rmmod命令:
3.lsmod命令:讀取/proc文件系統(tǒng)中的文件/proc/modules中的信息
4.ksyms命令:讀取/proc文件系統(tǒng)中的文件/proc/kallsyms。
--------------------------------------------------------------------------------------------------
//MODULE_PARM_DESC(interface,”A network interface”);  2.4內(nèi)核中該宏的用法
molule_parm(interface,charp,0644) //2.6內(nèi)核中的宏
//MODULE_PARM_DESC(irq,”The IRQ of the network interface”);
module_param(irq,int,0644);

insmod myirq.ko interface=eth0 irq=9

if (request_irq(irq, &myinterrupt, SA_SHIRQ,interface, &irq)) //注冊中斷,中斷值為irq,中斷函數(shù)myinterrupt
free_irq(irq, &irq);

具體網(wǎng)卡 irq的值可以查看 cat /proc/interrupts

可動態(tài)更改
--------------------------------------------------------------------------------------------------
insmod(安裝 LKM),
rmmod (刪除 LKM),
modprobe(insmod 和 rmmod 的包裝器),加載當前當前模塊與其相關(guān)聯(lián)的其他模塊,單一模塊無關(guān)聯(lián)時,必須使用insmod,否則會報錯,當自寫編寫模塊時,建議不要使用。
depmod(用于創(chuàng)建模塊依賴項),
modinfo(用于為模塊宏查找值)。

LKM 只不過是一個特殊的可執(zhí)行可鏈接格式(Executable and Linkable Format,ELF)對象文件。

在模塊的加載和卸載期間,模塊子系統(tǒng)維護了一組簡單的狀態(tài)變量,用于表示模塊的操作。
--------------------------------------------------------------------------------------------------
內(nèi)核中有一個叫做 HZ 的頻率變量,它表示每秒的時鐘節(jié)拍數(shù)。一般的,在某種平臺上它會有一個固定值,這個固定值是人為設定的,
也就是可編程的(對系統(tǒng)定時器編程)。設定 HZ 的大小需要權(quán)衡。這個值設大了,帶來的好處是定時器間隔變小,
從而使進程(任務)的調(diào)度的精確性得以提高,但帶來的缺點是導致開銷過大,讓系統(tǒng)變得耗電,
這樣在一些經(jīng)常使用電池的設備來說(比如筆記本,平板電腦)是難以接受的。
在現(xiàn)在一般的 x86 平臺,2.6 內(nèi)核的 linux 下,這個值會被設為 100 。也就是說,一個時鐘節(jié)拍為 1/100 = 0.01s = 10ms 。
一個時鐘節(jié)拍也稱為 1 個 jiffy 。
內(nèi)核中還有一個重要的變量叫 jiffies 。它記錄了系統(tǒng)從啟動到當前所觸發(fā)定時器的次數(shù)。jiffies 每秒鐘增加 HZ 個計數(shù),
實際上就是 N 個 jiffy 。
--------------------------------------------------------------------------------------------------
中斷服務程序一般都是在中斷請求關(guān)閉的條件下執(zhí)行的,以避免嵌套而使中斷控制復雜化。

下半部運行時是允許中斷請求的,而上半部運行時是關(guān)中斷的,這是二者之間的主要區(qū)別。 
--------------------------------------------------------------------------------------------------
小任務(Tasklet)機制

Count域是小任務的引用計數(shù)器。如果它不為0,則小任務被禁止,不允許執(zhí)行;只有當它為零,小任務才被激活,并且在被設置為掛起時,小任務才能夠執(zhí)行。

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

DECLARE_TASKLET(my_tasklet, my_tasklet_handler, dev);
這行代碼其實等價于
struct tasklet_struct my_tasklet = { NULL, 0, ATOMIC_INIT(0), tasklet_handler, dev};

static void tasklet_handler (unsigned long data)
tasklet_init(&my_tasklet, tasklet_handler, 0);
tasklet_schedule(&my_tasklet);
tasklet_kill(&my_tasklet);
--------------------------------------------------------------------------------------------------
如果推后執(zhí)行的任務需要睡眠,那么就選擇工作隊列。如果推后執(zhí)行的任務不需要睡眠,那么就選擇tasklet。
另外,如果需要用一個可以重新調(diào)度的實體來執(zhí)行你的下半部處理,也應該使用工作隊列。

void work_handler(void *data); //工作隊列待執(zhí)行的函數(shù)

DECLARE_WORK(name, void (*func) (void *), void *data); //這樣就會靜態(tài)地創(chuàng)建一個名為name,待執(zhí)行函數(shù)為func,參數(shù)為data的work_struct結(jié)構(gòu)。
INIT_WORK(struct work_struct *work, woid(*func) (void *), void *data); //這會動態(tài)地初始化一個由work指向的工作。

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

schedule_work(&work);//把給定工作的待處理函數(shù)提交給缺省的events工作線程
schedule_delayed_work(&work, delay); //&work指向的work_struct直到delay指定的時鐘節(jié)拍用完以后才會執(zhí)行。
--------------------------------------------------------------------------------------------------

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多