乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      項(xiàng)目經(jīng)驗(yàn)雜記

       心不留意外塵 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)包含自旋鎖時(shí)使用spin_lock_bh,而內(nèi)核層底半步調(diào)用時(shí)使用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>
      存在錯(cuò)誤,而
      #include <linux/ctype.h>
      正常
      --------------------------------------------------------------------------------------------------
      #ifdef __KERNEL__
      #include <linux/ctype.h>
      #else
      #include <ctype.h>
      #endif

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

      函數(shù)module_init()和module_exit()是模塊編程中最基本也是必須的兩個(gè)函數(shù)。
      module_init()向內(nèi)核注冊(cè)模塊所提供的新功能,
      而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個(gè)優(yōu)先級(jí).如果優(yōu)先級(jí)數(shù)字比int console_loglevel變量小的話,消息就會(huì)打印到控制臺(tái)上。如果syslogd和klogd守護(hù)進(jìn)程在運(yùn)行的話,則不管是否向控制臺(tái)輸出,消息都會(huì)被追加進(jìn)/var/log/messages文件。klogd 只處理內(nèi)核消息,syslogd 處理其他系統(tǒng)消息,比如應(yīng)用程序。
      --------------------------------------------------------------------------------------------------
      include/linux/module.h中定義的宏MODULE_PARM(var,type) 用于向模塊傳遞命令行參數(shù)。var為接受參數(shù)值的變量名,type為采取如下格式的字符串[min[-max]]{b,h,i,l,s}。min及max用于表示當(dāng)參數(shù)為數(shù)組類型時(shí),允許輸入的數(shù)組元素的個(gè)數(shù)范圍;
      b:byte;h:short;i:int;l:long;s:string。

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

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

      為了確保模塊安全地卸載,每個(gè)模塊都有一個(gè)引用計(jì)數(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)) //注冊(cè)中斷,中斷值為irq,中斷函數(shù)myinterrupt
      free_irq(irq, &irq);

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

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

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

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

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

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

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

      DECLARE_TASKLET(my_tasklet, my_tasklet_handler, dev);
      這行代碼其實(shí)等價(jià)于
      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í)行的任務(wù)需要睡眠,那么就選擇工作隊(duì)列。如果推后執(zhí)行的任務(wù)不需要睡眠,那么就選擇tasklet。
      另外,如果需要用一個(gè)可以重新調(diào)度的實(shí)體來執(zhí)行你的下半部處理,也應(yīng)該使用工作隊(duì)列。

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

      DECLARE_WORK(name, void (*func) (void *), void *data); //這樣就會(huì)靜態(tài)地創(chuàng)建一個(gè)名為name,待執(zhí)行函數(shù)為func,參數(shù)為data的work_struct結(jié)構(gòu)。
      INIT_WORK(struct work_struct *work, woid(*func) (void *), void *data); //這會(huì)動(dòng)態(tài)地初始化一個(gè)由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指定的時(shí)鐘節(jié)拍用完以后才會(huì)執(zhí)行。
      --------------------------------------------------------------------------------------------------

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多