【Linux 驅動】驅動開發第一步—-開發環境搭配

來源:互聯網
上載者:User

一,環境搭建步驟

      1)下載Linux源碼 

            1> ~#apt-cache search linux-source

出現:linux-source - Linux kernel source with Ubuntu patches
           linux-source-3.0.0 - Linux kernel source for version 3.0.0 with Ubuntu patches

             2>~#apt-get   install linux-source-3.0.0

                  下載完成後,在/usr/src/下會出現一個linux-source-3.0.0.tar.bz2。解壓:      tar  jxvf   linux-source-3.0.0.tar.bz2

             3>然後在Linux核心源碼目錄/usr/src/linux-source-2.6.32目錄下面用老的方法配置好Linux核心:

                 ~#make oldconfig

      4>編譯核心:~#make     //大概需要一個小時

      5>編譯模組:~#make modules

      6>安裝模組:~#make modules_install

  以上步驟完成後,會在/lib/modules 目錄下產生一個檔案夾3.0.0-12-generic

二,hello.c

#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){   printk(KERN_ALERT "Hello, world\n");  //printk 跟printf 類似,只是printk運行在核心態   return 0;}static void hello_exit(void){   printk(KERN_ALERT "Goodbye, cruel world\n");}module_init(hello_init);module_exit(hello_exit);


三,Makefile

ifneq ($(KERNELRELEASE),)  obj-m :=hello.o  else  KERNELDIR ?= /lib/modules/$(shell uname -r)/build  PWD := $(shell pwd)  default:  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  endif 

四,~#make   //組建檔案如下

hello.c   hello.ko     hello.mod.o  Makefile   modules.order
hello.c~  hello.mod.c  hello.o      Makefile~  Module.symvers

1>裝載目標模組:~#insmod  ./hello.ko

     ~#lsmod  //查看目前安裝的驅動模組,有hello

2>模組裝載觸發hello.c的init()方法,輸出hello world,如果沒有的話,是因為其將輸出放到/var/log/syslog中去了。開啟便可以看見你的結果!

卸載目標模組命令是:~#rmmod ./hello.ko


 總結:從此我們邁出了Linux驅動開發的第一步


代碼深度解析:

1)尋找檔案位置:

#include <linux/init.h>//這個標頭檔包含了你的模組初始化與清除的函數#include <linux/module.h>//包含了許多符號與函數的定義,這些符號與函數多與載入模組有關

     find / -name  module.h

     我的檔案位置在:/usr/src/linux-source-3.0.0/include/linux/module.h   //其餘的位置也有好多,但是這個檔案位置才是正解

                                   
/usr/src/linux-source-3.0.0/include/linux/in.h

2)另外,如果你的模組需要用到參數傳遞,那麼你可能就要聲明moduleparam.h這個標頭檔了。

3)模組裡常包含一些描述性聲明,如:

MODULE_LICENSE("GPL");          // "GPL" 是指明了 這是GNU General Public License的任意版本

                                                            // “GPL v2” 是指明 這僅聲明為GPL的第二版本

                                                            // "GPL and addtional"

                                                            // "Dual BSD/GPL"

                                                            // "Dual MPL/GPL"

                                                            // "Proprietary"  私人的

                                                            // 除非你的模組顯式地聲明一個開源版本,否則核心會預設你這是一個私人的模組(Proprietary)。

MODULE_AUTHOR                        // 聲明作者

MODULE_DESCRIPTION              // 對這個模組作一個簡單的描述,這個描述是"human-readable"的

MODULE_VERSION                        // 這個模組的版本

MODULE_ALIAS                               // 這個模組的別名

MODULE_DEVICE_TABLE            // 告訴使用者空間這個模組支援什麼樣的裝置


       MODULE_聲明可以寫在模組的任何地方(但必須在函數外面),但是慣例是寫在模組最後。

4)

Linux KERN_ALERT 什麼意思

訊息列印層級:
fmt----訊息層級:

#define KERN_EMERG     "<0>"
#define KERN_ALERT     "<1>"
#define KERN_CRIT      "<2>"
#define KERN_ERR       "<3>"
#define KERN_WARNING   "<4>"
#define KERN_NOTICE    "<5>"
#define KERN_INFO      "<6>"
#define KERN_DEBUG     "<7>"

 不同層級使用不同字串表示,數字越小,層級越高。
printk輸出跟輸出的記錄層級有關係,當輸出記錄層級比控制台的層級高時,就會顯示在控制台上,當比控制台低時,則會記錄在/var/log/message中.但是當系統同時運行了klogd和syslogd時,都追加到/var/log/message.在/proc/sys/kernel/printk檔案中,前兩個整數為當前的記錄層級和預設的記錄層級(預設的記錄層級即為printk的輸出層級). 

注意:
需要開啟klogd和syslogd服務才能正常輸出。通過klogd可以改變系統訊息輸出層級。

 linux0.11為什麼在核心態使用printk()函數,而在使用者態使用printf()函數?
(1)    答:printk()函數是直接使用了向終端寫函數tty_write()。而printf()函數是調用write()系統調用函數向標準輸出裝置寫。所以在使用者態(如進程0)不能夠直接使用printk()函數,而在核心態由於他已是特權級,所以無需系統調用來改變特權級,因而能夠直接使用printk()函數。

printk是核心輸出,在終端是看不見的。  
  你可以看一下系統日誌。/var/log/message。  
  或者使用dmesg命令看一下

不管你可能怎麼想,printk()並不是設計用來同使用者互動的,雖然我們在 hello-1就是出於這樣的目的使用它!它實際上是為核心提供日誌功能, 記錄核心資訊或用來給出警告。因此,每個printk() 聲明都會帶一個優先順序,就像你看到的<1>和KERN_ALERT 那樣。核心總共定義了八個優先順序的宏, 所以你不必使用晦澀的數字代碼,並且你可以從檔案linux/kernel.h查看這些宏和它們的意義。如果你 不指明優先順序,預設的優先順序DEFAULT_MESSAGE_LOGLEVEL將被採用。

閱讀一下這些優先順序的宏。標頭檔同時也描述了每個優先順序的意義。在實際中, 使用宏而不要使用數字,就像<4>。總是使用宏,就像 KERN_WARNING。

當優先順序低於int console_loglevel,資訊將直接列印在你的終端上。如果同時 syslogd和klogd都在運行,資訊也同時添加在檔案 /var/log/messages,而不管是否顯示在控制台上與否。我們使用像 KERN_ALERT這樣的高優先順序,來確保printk()將資訊輸出到 控制台而不是只是添加到記錄檔中。 當你編寫真正的實用的模組時,你應該針對可能遇到的情況使用合 適的優先順序。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.