導航:首頁 > 操作系統 > linux編寫驅動程序

linux編寫驅動程序

發布時間:2024-10-20 15:32:08

Ⅰ 怎樣編寫linux設備驅動程序

Linux是Unix操作系統的一種變種,在Linux下編寫驅動程序的原理和思想完全類似於其他的Unix系統,但它dos或window環境下的驅動程序有很大的區別。在Linux環境下設計驅動程序,思想簡潔,操作方便,功能也很強大,但是支持函數少,只能依賴kernel中的函數,有些常用的操作要自己來編寫,而且調試也不方便。本人這幾周來為實驗室自行研製的一塊多媒體卡編制了驅動程序,獲得了一些經驗,願與Linux fans共享
一、Linux device driver 的概念系統調用是操作系統內核和應用程序之間的介面,設備驅動程序是操作系統內核和機器硬體之間的介面。設備驅動程序為應用程序屏蔽了硬體的細節,這樣在應用程序看來,硬體設備只是一個設備文件, 應用程序可以象操作普通文件一樣對硬體設備進行操作。設備驅動程序是內核的一部分,它完成以下的功能:
1.對設備初始化和釋放。
2.把數據從內核傳送到硬體和從硬體讀取數據。
3.讀取應用程序傳送給設備文件的數據和回送應用程序請求的數據。
4.檢測和處理設備出現的錯誤。
二、實例剖析我們來寫一個最簡單的字元設備驅動程序。雖然它什麼也不做,但是通過它可以了解Linux的設備驅動程序的工作原理。

Ⅱ linux驅動編寫過程中遇到的幾個問題及解決

1、顯示錯誤:unknown field 'ioctl' specified in initializer
解決辦法,查看內核include/linux/fs.h文件,發現里邊定義的struct file_operations中沒有ioctl,這里我們用.unlocked_ioctl取代,形參去掉 struct inode*。
2、在應用程序中,將ioctl替換為unlocked_ioctl後,會出現以下錯誤:undefined reference to `unlocked_ioctl'。因為系統調用ioctl是沒有改變的,還是原來的系統調用介面,只是系統調用的實現中,ioctl()變成了unlocked_ioctl,在應用層你根本不用關注內核中的這些實現上的改變,你只需要按照系統調用的用法用就可以了。所以把應用程序里的unlocked_ioctl改為ioctl,編譯,OK,通過。
3、驅動編譯完成,在開發板上insmod,出現以下錯誤:
WARNING: at lib/kobject.c:595 kobject_put+0x50/0x64()
kobject: '撲' (cbc60a00): is not initialized, yet kobject_put() is being called.
---[ end trace da227214a82491b9 ]---
insmod: cannot insert 'led_dev.ko': Cannot allocate memory
原來是忘了寫內存申請的代碼,添加kmalloc和memset。
4、再次insmod,出現下列錯誤代碼:
Unable to handle kernel paging request at virtual address 7f008820
pgd = cbc70000
[7f008820] *pgd=00000000
Internal error: Oops: 5 [#1]
Moles linked in: led_dev(+)
CPU: 0 Tainted: G W (3.0.1 #439)
PC is at led_init+0xa8/0x108 [led_dev]
LR is at kobj_map+0x144/0x154
pc : [<bf0020a8>] lr : [<c0246e70>] psr: 60000013
sp : cbc6bf10 ip : cbc6beb0 fp : cbc6bf24
r10: 00000000 r9 : bf002000 r8 : cbc6a000
r7 : 00000000 r6 : bf0002bc r5 : 00000000 r4 : 00000000
r3 : 00000000 r2 : 00000000 r1 : 7f008000 r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 00c5387d Table: 5bc70008 DAC: 00000015
Process insmod (pid: 112, stack limit = 0xcbc6a268)
Stack: (0xcbc6bf10 to 0xcbc6c000)
bf00: 00000000 c07463c0 cbc6bf7c cbc6bf28
bf20: c00343c8 bf00200c cbc6bf64 cbc6bf38 c0073e24 00000000 00000000 00000000
bf40: 00000000 0000ef52 000d5bf9 bf0002bc 00000000 0000ef52 000d5bf9 bf0002bc
bf60: 00000000 c0034ce8 cbc6a000 00000000 cbc6bfa4 cbc6bf80 c0085960 c0034398
bf80: c00e8738 c00e8610 402004a8 000dfcf8 00000000 00000080 00000000 cbc6bfa8
bfa0: c0034b40 c00858e0 402004a8 000dfcf8 00b5d038 0000ef52 000d5bf9 ffff5f01
bfc0: 402004a8 000dfcf8 00000000 00000080 00000069 00000001 be9c2e64 be9c2e68
bfe0: be9c2e68 be9c2b14 00021cfc 402c1d74 60000010 00b5d038 5fffe821 5fffec21
[<bf0020a8>] (led_init+0xa8/0x108 [led_dev]) from [<c00343c8>] (do_one_initcall+0x3c/0x188)
[<c00343c8>] (do_one_initcall+0x3c/0x188) from [<c0085960>] (sys_init_mole+0x8c/0x1a4)
[<c0085960>] (sys_init_mole+0x8c/0x1a4) from [<c0034b40>] (ret_fast_syscall+0x0/0x30)
Code: e59f0060 eb52980e ea00000b e59f1058 (e5910820)
---[ end trace da227214a82491b9 ]---
Segmentation fault
最後是各種網路,各種谷歌,參考別人的驅動,發現它們的開發板硬體地址並不是自己寫的頭文件,而是調用mach中已經定義好的頭文件,好吧,尋找相應開發板,相應埠的地址頭文件,在驅動文件中添加以下頭文件:
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank-m.h>
Ok,打完收工,開發板,測試。運行無阻。完成。
5、在做到DS18B20溫度測試模塊驅動的時候,看到網上的代碼有些函數可以直接對引腳的功能進行設置,比如:s3c2410_gpio_cfgpin(DQ_PIN, DQ_PIN_OUTP); 但是對應於我的s3c6410的開發板就不知道用什麼函數了,網上找了半天,發現以上函數是在#include <plat/gpio-cfg.h>中,6410中對應的函數為:extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
6、最近學習移植linux內核,移植了新的linux內核以及掛載了新的NFS之後, 重新測試led驅動,發現安裝模塊以後,運行測試程序會出現以下錯誤:
-/bin/sh: ./main: not found(main為主機上編譯好的測試程序)
原因:
編譯busybox的時候選擇了靜態編譯:
Build Options->
Build BusyBox as a static binary (no shared libs)
Build with Large File Support (for accessing file>2GB)
如果選擇 Build BusyBox as a static binary (no shared libs) 方式進行編譯時,所需的庫已經與程序靜態地鏈接在一起,這些程序不需要額外的庫就可以單獨運行,但是自己編寫的程序在文件系統上運行必須採用靜態編譯,否則會報諸如:bin/sh: main :not found的錯誤。
靜態編譯如:
arm-linux-gcc –static main.c –o main
7.按照普通方法安裝配置tftp,並且關閉了防火牆,但是在開發板上tftp主機,總會報錯:
tftp: server error: (0) Permission denied

解決辦法:
修改文件 /etc/sysconfig/selinux,設定其中的
SELINUX=disabled
然後重啟電腦即可

Ⅲ 如何編寫Linux操作系統的設備驅動程序

Linux是Unix操作系統的一種變種,在Linux下編寫驅動程序的原理和
思想完全類似於其他的Unix系統,但它dos或window環境下的驅動程序有很大的
區別.在Linux環境下設計驅動程序,思想簡潔,操作方便,功能也很強大,但是
支持函數少,只能依賴kernel中的函數,有些常用的操作要自己來編寫,而且調
試也不方便.本人這幾周來為實驗室自行研製的一塊多媒體卡編制了驅動程序,
獲得了一些經驗,願與Linux fans共享,有不當之處,請予指正.
以下的一些文字主要來源於khg,johnsonm的Write linux device driver,
Brennan's Guide to Inline Assembly,The Linux A-Z,還有清華BBS上的有關
device driver的一些資料. 這些資料有的已經過時,有的還有一些錯誤,我依
據自己的試驗結果進行了修正.
一. Linux device driver 的概念
系統調用是操作系統內核和應用程序之間的介面,設備驅動程序是操作系統
內核和機器硬體之間的介面.設備驅動程序為應用程序屏蔽了硬體的細節,這樣
在應用程序看來,硬體設備只是一個設備文件, 應用程序可以象操作普通文件
一樣對硬體設備進行操作.設備驅動程序是內核的一部分,它完成以下的功能:
1.對設備初始化和釋放.
2.把數據從內核傳送到硬體和從硬體讀取數據.
3.讀取應用程序傳送給設備文件的數據和回送應用程序請求的數據.
4.檢測和處理設備出現的錯誤.
在Linux操作系統下有兩類主要的設備文件類型,一種是字元設備,另一種是
塊設備.字元設備和塊設備的主要區別是:在對字元設備發出讀/寫請求時,實際
的硬體I/O一般就緊接著發生了,塊設備則不然,它利用一塊系統內存作緩沖區,
當用戶進程對設備請求讀/寫時,它首先察看緩沖區的內容,如果緩沖區的數據
能滿足用戶的要求,就返回請求的數據,如果不能,就調用請求函數來進行實際
的I/O操作.塊設備是主要針對磁碟等慢速設備設計的,以免耗費過多的CPU時間
來等待.
已經提到,用戶進程是通過設備文件來與實際的硬體打交道.每個設備文件都
都有其文件屬性(c/b),表示是字元設備還蔤強檣璞?另外每個文件都有兩個設
備號,第一個是主設備號,標識驅動程序,第二個是從設備號,標識使用同一個
設備驅動程序的不同的硬體設備,比如有兩個軟盤,就可以用從設備號來區分
他們.設備文件的的主設備號必須與設備驅動程序在登記時申請的主設備號
一致,否則用戶進程將無法訪問到驅動程序.
最後必須提到的是,在用戶進程調用驅動程序時,系統進入核心態,這時不再是
搶先式調度.也就是說,系統必須在你的驅動程序的子函數返回後才能進行其他
的工作.如果你的驅動程序陷入死循環,不幸的是你只有重新啟動機器了,然後就

閱讀全文

與linux編寫驅動程序相關的資料

熱點內容
c游戲編程入門教程pdf 瀏覽:670
php框架安全 瀏覽:715
夢里和程序員談戀愛 瀏覽:173
特價伺服器什麼意思 瀏覽:379
程序員交接不想接怎麼辦 瀏覽:873
vb文件夾怎麼選擇 瀏覽:118
公眾號驗證碼登陸源碼 瀏覽:524
居民樓用電量與電纜演算法 瀏覽:357
安裝mysql步驟linux 瀏覽:192
模擬器開app卡頓是怎麼回事 瀏覽:432
安卓手機如何將應用安裝到sd卡 瀏覽:1002
調取命令符 瀏覽:720
核酸檢測報告怎麼能加密 瀏覽:96
單片機燒錄是什麼意思 瀏覽:454
phpmysqlmysqlnd 瀏覽:539
php獲取伺服器端ip 瀏覽:429
域控伺服器搭建好如何管理客戶機 瀏覽:737
30萬女程序員直播寫代碼 瀏覽:915
小米手機數據分區加密 瀏覽:867
php狀態機 瀏覽:690