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

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

    • 分享

      ldd3之模塊學(xué)習(xí)總結(jié)(頁 1) - 文檔專區(qū) - 無分類文檔 - Linux論壇 - p...

       jijo 2009-04-28
      china_long
      ldd3之模塊學(xué)習(xí)總結(jié)

      ldd3之模塊學(xué)習(xí)總結(jié)
        一個學(xué)習(xí)Linux設(shè)備驅(qū)動程序都會碰到的第一個例程:
         
      #include linux/init.h>
      #include linux/module.h>
      MODULE_LICENSE("Dual BSD/GPL");
      static int hello_init(void)
      {
          printk(KERN_ALERT "Hello, Tekkaman Ninja !\n");
          return 0;
      }
      static [color=#ff0000]void[/color] hello_exit(void)
      {
          printk(KERN_ALERT "Goodbye, Tekkaman Ninja !\n Love Linux !Love ARM ! Love KeKe !\n");
      }
      module_init(hello_init);
      module_exit(hello_exit);

      1、Makefile書寫:
         KERNELDIR = /usr/src/linux_2.6.26/linux-2.6.26 #內(nèi)核原代碼樹位置
         PWD = $(shell pwd)
         INSTALLDIR = /lib/modules/2.6.26linux2.6.26

         #1   obj-m := hello.o   模塊只有一個文件
         #2   obj-m := hello.o
              hello-objs := one.o two.o three.o  模塊有多個文件
         #3  如果模塊是由一個目錄(online)組成的寫法如下
              a、在這個目錄的上一級目錄中的makefile中加入
                   [color=#000000]obj-m += online/  #告訴在編譯的時候找到online目錄[/color]
      [color=#000000]             obj-$(CONFIG_USB_GADGET_ONLINE) += online/  這種方式是用配置選項(kconfig文件中添加配置選項)來判斷是否編譯這個子目錄(即模塊)[/color]
      [color=#000000]        b、最后,我們在online/下創(chuàng)建新文件Makefile,并且添加下面一行到其內(nèi)。
                     obj-m += netmeeting.o[/color]
      [color=#000000]               netmeeting-objs := one.o two.o three.o 如果有多個文件[/color]
          modules:
             [TAB] $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
          modules_install:
             [TAB] cp hello.ko $(INSTALLDIR)      
          clean:
             [TAB] rm -rf *.o *.ko *.mod.c *.o.cmd .tmp_versions *.mod.o .cmd
          .PHONY :modules modules_install clean


         2、編譯運行
            insmod
            rmmod
            lsmod
         3、調(diào)試查看輸出信息
            a、在模塊中添加調(diào)試輸出語句 printk  
                 cat /proc/kmsg   (rsyslog沒有運行)
                 dmesg (syslogd進(jìn)程已經(jīng)運行  /etc/rc.d/init/rsyslog 開啟)
                 cat /var/log/message
            注意:
                [color=#000000]printk[/color]([color=#000000]KERN_ALERT[/color]"xxxx“);
      宏的定義等級如下(printk.c):         
      #define KERN_EMERG "" /* system is unusable   */
      #define KERN_ALERT "" /* action must be taken immediately */
      #define KERN_CRIT "" /* critical conditions   */
      #define KERN_ERR "" /* error conditions   */
      #define KERN_WARNING "" /* warning conditions   */
      #define KERN_NOTICE "" /* normal but significant condition */
      #define KERN_INFO "" /* informational   */
      #define KERN_DEBUG "" /* debug-level messages   */

         當(dāng)指定的等級小于console_level(默認(rèn)4)時候,就可以直接在tty上面打印輸出語句
      console_level設(shè)置方式:
          通過對/proc/sys/kernel/printk的訪問來改變[color=#000102]console_loglevel的值:[/color]
      [Tekkaman2440@SBC2440V4]#echo 1 > /proc/sys/kernel/printk
      [Tekkaman2440@SBC2440V4]#cat /proc/sys/kernel/printk
      1       4       1       7
      [Tekkaman2440@SBC2440V4]#insmod hello.ko
      [Tekkaman2440@SBC2440V4]#rmmod hello
      [Tekkaman2440@SBC2440V4]#echo 7 > /proc/sys/kernel/printk
      [Tekkaman2440@SBC2440V4]#cat /proc/sys/kernel/printk7       4       1       7
      [Tekkaman2440@SBC2440V4]#insmod hello.ko
      Hello, Tekkaman Ninja !
      [Tekkaman2440@SBC2440V4]#rmmod hello
      Goodbye, Tekkaman Ninja !
      Love Linux !Love ARM ! Love KeKe !
      四個數(shù)字的含義:當(dāng)前的loglevel、默認(rèn)loglevel、最小允許的loglevel、引導(dǎo)時的默認(rèn)loglevel。
        
         4、模塊中使用的頭文件
            
      #include linux/init.h>
      #include linux/module.h>

        5、模塊中使用的描述性定義
         MODULE_AUTHOR("");
         MODULE_DESCRIPTION("");
         MODULE_VERSION("");
         MODULE_ALIAS("");
         MODULE_DEVICE_TABLE("");
          描繪性定義一般放在最后面

         6、模塊中的參數(shù)
          (內(nèi)核允許對驅(qū)動程序指定參數(shù),而這些參數(shù)可在裝載驅(qū)動程序模塊時改變[color=#000000]。 example : insmod hello-param.ko howmany=2 whom="KeKe" TNparam=4,3,2,1[/color])
           [color=#000000]對于如何向模塊傳遞參數(shù),Linux kernel 提供了一個簡單的框架。其允許驅(qū)動程序聲明參數(shù),并且用戶在系統(tǒng)啟動或模塊裝載時為參數(shù)指定相應(yīng)值,在驅(qū)動程序里,參數(shù)的用法如同全局變量。這些模塊參數(shù)也能夠在sysfs中顯示出來。結(jié)果,有許許多多的方法用來創(chuàng)建和管理模塊參數(shù)。
          通過宏module_param()定義一個模塊參數(shù):
      module_param(name, type, perm);
          這里,name既是用戶看到的參數(shù)名,又是模塊內(nèi)接受參數(shù)的變量; type表示參數(shù)的數(shù)據(jù)類型,是下列之一:byte, short, ushort, int, uint, long, ulong, charp, bool, invbool。這些類型分別是:a byte, a short integer, an unsigned short integer, an integer, an unsigned integer, a long integer, an unsigned long integer, a pointer to a char, a Boolean, a Boolean whose value is inverted from what the user specifies. The byte type is stored in a single char and the Boolean types are stored in variables of type int. The rest are stored in the corresponding primitive C types. 最后,perm指定了在sysfs中相應(yīng)文件的訪問權(quán)限。訪問權(quán)限用通常的八進(jìn)制格式來表示,例如,用0644(表示ower具有讀寫權(quán)限,group和everyone只讀權(quán)限), 或者用通常的S_Ifoo定義,例如,S_IRUGO | S_IWUSR (表示everyone具有讀權(quán)限,用戶具有寫權(quán)限)。用0表示完全關(guān)閉在sysfs中相對應(yīng)的項。
          其實宏不會聲明變量,因此在使用宏之前,必須聲明變量。所以,典型地用法如下:
      static unsigned int use_acm = 0;   
      module_param(use_acm, uint, S_IRUGO);
          這些必須寫在模塊源文件的開頭部分。即use_acm是全局的。
          我們也可以使模塊源文件內(nèi)部的變量名與外部的參數(shù)名有不同的名字。這通過宏module_param_named()定義。
      module_param_named(name, variable, type, perm);
          這里name是外部可見的參數(shù)名,variable是源文件內(nèi)部的全局變量名。例如:
      static unsigned int max_test = 9;
      module_param_name(maximum_line_test, max_test, int, 0);
          如果模塊參數(shù)是一個字符串時,通常使用charp類型定義這個模塊參數(shù)。內(nèi)核復(fù)制用戶提供的字符串到內(nèi)存,并且相對應(yīng)的變量指向這個字符串。例如:
      static char *name;
      module_param(name, charp, 0);
          另一種方法是通過宏module_param_string()讓內(nèi)核把字符串直接復(fù)制到程序中的字符數(shù)組內(nèi)。
      module_param_string(name, string, len, perm);
          這里,name是外部的參數(shù)名,string是內(nèi)部的變量名,len是以string命名的buffer大小(可以小于buffer的大小,但是沒有意義),perm表示sysfs的訪問權(quán)限(或者perm是零,表示完全關(guān)閉相對應(yīng)的sysfs項)。例如:
      static char species[BUF_LEN];
      module_param_string(specifies, species, BUF_LEN, 0);
          上面說得只是給模塊傳入一個參數(shù)的情況,如果給模塊傳入多個參數(shù),那該怎么辦呢?可以通過宏module_param_array()給模塊傳入多個參數(shù)。 用法如下:
      module_param_array(name, type, nump, perm);
          這里,name既是外部模塊的參數(shù)名又是程序內(nèi)部的變量名,type是數(shù)據(jù)類型,perm是sysfs的訪問權(quán)限。指針nump指向一個整數(shù),其值表示有多少個參數(shù)存放在數(shù)組name中。值得注意是name數(shù)組必須靜態(tài)分配。例如:
      static int finsh[MAX_FISH];
      static int nr_fish;
      module_param_array(fish, int, &nr_fish, 0444);
          通過宏module_param_array_named()使得內(nèi)部的數(shù)組名與外部的參數(shù)名有不同的名字。例如:
      module_param_array_named(name, array, type, nump, perm);
          這里的參數(shù)意義與其它宏一樣。
          最后,通過宏MODULE_PARM_DESC()對參數(shù)進(jìn)行說明:
      static unsigned short size = 1;
      module_param(size, ushort, 0644);
      MODULE_PARM_DESC(size, “The size in inches of the fishing pole” \
      “connected to this computer.” );
          使用這些宏時需要包含頭文件。[/color]

      [color=#ff0000]注意:[/color]
         由于模塊參數(shù)指的是外部向模塊傳遞參數(shù),模塊聲明的變量能否被內(nèi)核其他代碼和模塊使用呢?(是不是只要是非靜態(tài)的且導(dǎo)出符號,內(nèi)核和其他模塊就能共享這個變量呢?)

        example code :
         
      #include linux/init.h>
      #include linux/module.h>
      #include linux/moduleparam.h>
      MODULE_LICENSE("Dual BSD/GPL");
      static char *whom = "Tekkaman Ninja";
      static int howmany = 1;
      static int TNparam[] = {1,2,3,4};
      static int TNparam_nr = 4;
      module_param(howmany, int, S_IRUGO);
      module_param(whom, charp, S_IRUGO);
      module_param_array(TNparam , int , &TNparam_nr , S_IRUGO);
      static int hello_init(void)
      {
          int i;
          for (i = 0; i  howmany; i++)
              printk(KERN_ALERT "(%d) Hello, %s !\n", i, whom);
          for (i = 0; i ; i++)
              printk(KERN_ALERT "TNparam[%d] : %d \n", i, TNparam[i]);
          return 0;
      }
      static void hello_exit(void)
      {
          printk(KERN_ALERT "Goodbye, Tekkaman Ninja !\n Love Linux !Love ARM ! Love KeKe !\n");
      }
      module_init(hello_init);
      module_exit(hello_exit);

      編譯完成后
      測試1
         insmod hello-param.ko howmany=2 whom="KeKe" TNparam=4,3,2,1
      測試2
        [Tekkaman2440@SBC2440V4]#insmod hello-param.ko howmany=2 whom="KeKe"  TNparam=4,3,2,1,5,6,7,8
      TNparam: can only take 4 arguments
      hello_param: `4' invalid for parameter `TNparam'
      insmod: cannot insert 'hello-param.ko': Invalid parameters (-1): Invalid argument
      注意:
         這個測試說明module_param_array(TNparam , int , &TNparam_nr , S_IRUGO),參數(shù)[color=#ff0102]TNparam_nr不能自己限制參數(shù)的個數(shù),而需要程序員自己確定參數(shù)的個數(shù),否則數(shù)組[/color][color=#0000cc]TNparam可能會越界。(個人認(rèn)為如果傳送數(shù)組形式的參數(shù)最好再定義一個宏來確定數(shù)組的大小)[/color]

      7、導(dǎo)出符號
        [color=#000000]  當(dāng)裝載模塊的時候,模塊動態(tài)地鏈接入內(nèi)核之中。動態(tài)鏈接的二進(jìn)制代碼只能調(diào)用外部函數(shù),然而,外部函數(shù)必須明確地輸出,在內(nèi)核中,通過EXPORT_SYMBOL()和EXPORT_SYMBOL_GPL來達(dá)到這個目的。
      輸出的函數(shù)可以被其它模塊調(diào)用。沒有輸出過的函數(shù)不能被其它模塊調(diào)用。模塊比核心內(nèi)核映像代碼具有更嚴(yán)格的鏈接和調(diào)用規(guī)則。因為所有核心源文件鏈接成一個單一的作為基礎(chǔ)的映像,因此在內(nèi)核中核心代碼可以調(diào)用任何非靜態(tài)的接口。當(dāng)然,輸出符號也必須是非靜態(tài)屬性。
      一套輸出的內(nèi)核符號稱之為輸出的內(nèi)核接口,甚至稱之為kernel API。
      輸出一個內(nèi)核符號是舉手之勞之事。當(dāng)函數(shù)聲明之時,在其后用EXPORT_SYMBOL()把函數(shù)輸出。
      例如:
      /* it will receive control requests including set_configuration(), which enables non-control requests.
      */
      int usb_gadget_register_driver(struct usb_gadget_driver *driver)
      {

      }
      EXPORT_SYMBOL(usb_gadget_register_driver) ;
          從此以后,任何模塊都可以調(diào)用函數(shù)usb_gadget_register_driver(),只要在源文件中包含聲明這個函數(shù)的頭文件,或者extern這個函數(shù)的聲明。
          有些開發(fā)者希望他們的接口只讓遵從GPL的模塊調(diào)用。通過MODULE_LICENSE()的使用,內(nèi)核鏈接器能夠強制保證做到這點。如果你希望前面的函數(shù)僅被標(biāo)有GPL許可證的模塊訪問,那么你可以用如下方式輸出符號:
      EXPORT_SYMBOL_GPL(usb_gadget_register_driver);
          如果你的代碼配置為模塊方式,那么必須確保:源文件中使用的所有接口必須是已經(jīng)輸出的符號,否則導(dǎo)致在裝載時鏈接錯誤。[/color]





      [b]本文來自ChinaUnix博客,如果查看原文請點:[/b][url]http://blog./u2/83200/showart_1679685.html[/url]

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多