乙個linux 核心模組程式設計的手記, 未寫完不斷更新中…
一 相關命令
0 檢視系統裝載了哪些 核心模組
lsmod modulename
1 載入核心模組
insmod modulename
2 解除安裝核心模組
rmmod modulename
3 建立裝置檔案
mknod filename dev_type major_number minor_number
說明: 引數 filename 建立的裝置檔名稱
dev_type 裝置檔案的型別,
c character device (字元裝置)
b block device (塊裝置)
兩種檔案型別的主要區別, block device 有 buffer
major_number 主要號碼 用於標記那個驅動可以使用此裝置(每乙個驅動只有唯一的 )
minor_number 映象號碼 the driver to distinguish between the various hardware it controls(不能準確翻譯)
———————————————
例:ls -l /dev/hda[1-3]
brw-rw—- 1 root disk 3, 1 jul 5 2000 /dev/hda1
brw-rw—- 1 root disk 3, 2 jul 5 2000 /dev/hda2
brw-rw—- 1 root disk 3, 3 jul 5 2000 /dev/hda3
b 表示裝置型別
3 表示 major number
1,2,3 表示 minor number
———————————————-
5 自動載入模組(除錯好了再用, 要不系統容易掛)
depmod -a (檢查核心 依賴關係是否正確) 生成 /lib/modules/version/modules.dep 檔案
modprobe 在 insmod之前掛載 (核心模組也有依賴性~~) 可以編輯 /etc/modules.conf 讓系統啟動時載入 重要的,比如驅動
modprobe -a msdos (載入 於msdos有依賴關係的所有模組)
二 相關檔案
1 /proc/modules.
存放載入核心的資訊。 lsmod 就是讀的這個檔案
2/etc/modules.conf
讓系統啟動時載入 重要的,比如驅動
3/lib/modules/version/modules.dep
核心依賴關係 ( 猜的, 沒看)
4/var/log/message
我是用turbo 10 桌面版本 作的測試 所以 printk() 函式 輸出時不能顯示在我的kde的終端上
這個問題曾經鬱悶 我 20 分鐘, 後來 情急之下 檢視 message檔案 才發現都printk輸出資訊都記錄在 這裡了, 我也夠笨的:(
當知道怎麼建立使用 "字元裝置檔案" 之後 就能寫自己的 printx函式了。也知道為什麼不能顯示在 kede的終端上了 :)
5 /proc/devices
已經使用的裝置檔案 裡面資料的結構是 major number device name
三 使用者空間 vs 核心空間 | 系統呼叫 (有趣)
核心可以訪問所有的資源,使用者程式也是如此, 只不過,要借助驅動來訪問。
核心要管理所有的資源,他是使用者程式於硬體的乙個橋梁。乙個使用者程式執行過程當中, 他把通過系統呼叫,把資料傳送給核心空間, 然後核心處理這個請求, 之後又把結果返回給使用者空間。核心可以捕獲到所有的這些資訊, 你可以替換到原來的系統呼叫, 你可一
讓open打不開檔案, 你可以讓mkdir建立不了目錄!!
三 該死的makefile!!!
一開始看的所有相關的文章,幾乎都是基於2.4版本的,照著2。4版本的makefile寫,但是我的核心是2.6的, 所以我百試不爽,編譯完了不能載入,鬱悶了好久,差一點沒換掉核心,後來找到了2。6 的手冊才知道問題所在。
2.6 版本核心模組的makefile 編譯成.ko檔案
————————————————————
ifneq ($(kernelrelease),)
obj-m:= test.o #模組名稱
else
kdir:= /lib/modules/$(shell uname -r)/build #核心路徑
pwd:= $(shell pwd)
default:
$(make) -c $(kdir) subdirs=$(pwd) modules
endif
————————————————————
2.4 版本核心模組的makefile 編譯成.o檔案
————————————————————
arget =test
warn =-w -wall -wstrict-prototypes -wmissing-prototypes
include=-isystem /lib/modules/2.6.0-1/build/include #核心路徑
cflag =-o2 -dmodule -d__kernel__ $ $
cc =gcc
$.o: $.c
$ $ -c $.c
.phony: clean
clean:
rm -rf $.o
————————————————————
四 核心模組程式結構
————————————————-
/** hello-1.c - 簡單的hello the world 程式摘自手冊
*/#include /* 所有的核心模組都需要的 */
#include /* needed for kern_alert */
//初始化程式,載入模組時執行
int init_module(void)
//清除函式,解除安裝模組時執行
void cleanup_module(void)
——————————————————
2.6 版本有更多的書寫方法,比如加入載入引數, 加入核心說明等等,可以參考相關文件
五 應用字元裝置檔案
5.1 資料結構
1 file_operations 在中定義
說明: 這個結構體中包含對裝置操作的函式指標, 可以通過他的配置和實現操作函式來完成對裝置的操作
把你不使用的入口 設為null。
靠,這傢伙也太難記了,我曾經3次看到這,就去論壇灌水了,不想往下看了。 今兒耐著性子把他看完,才發現自己是個笨蛋!
在新的驅動程式中,你可能會看到一更簡單,更友好的給file_operations 賦值的方式,看下面的這個結構,手冊上說這玩意是
gcc extension gcc 擴充套件 (gnu c), 是這個意思吧, 反正我理解的就是,gcc在編譯它的時候 先把下面這個玩意翻譯正標準的c,然後再編譯。 哀,可憐的 c標準!不過話又說回來,這東西除了linux別的也沒什麼用處。
——————————————
struct file_operations fops = ;
——————————————
手冊上說 下面的這個是 c99 特性寫法!(這玩意bsd 也用不了吧? 為什麼還要這麼亂!) 注意:低版本的 gcc 可能會不正常編譯地!因為它超出了gnu c 標準 (http://www-900.ibm.com/developerworks/cn/linux/l-c99/index.shtml c99 標準參考)
——————————————
struct file_operations fops = ;
——————————————
俺選擇 的是第一種寫法!
2 *file* 結構 在 中定義
說明:* 它不同於file (glibc 中定義的)
* 它是核心級的結構體
* 它表示抽象的 'file'
* 它不是磁碟上的那個 file
* 驅動用結構體來給這個東西賦值,****** 完善理解 *******
* 指向它的指標型別 為 filp , 也可以直接寫成 struct file file
5.2 相關函式
1 註冊裝置函式
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
還記得之前寫的建立裝置檔案的命令吧,
引數說明: major: 它就是 major number 對應唯一的驅動,記住!
name: 它就是 filename 可以在 /proc/devices 裡面找到它(叫device name 更好點)
fops: file_operations 結構體, 這個可以理解為操作裝置的 核心入口,可以用上面說的兩種方法去填充它
函式返回: 1 major 為 0: 動態分配的 major number 值
2 major 為 指定值:
3 major 為特殊數值:
特殊說明: 因為乙個驅動只能有一 個 major值,所以有以下三種建立方法
1 先建立裝置檔案,你可以分配乙個固定的major值
2 動態分配 major值, 讀取 /proc/devices 檔案 找到major值, 用指令碼建立(在使用者空間建立裝置檔案)
3 動態分配 major值,使用系統呼叫函式,直接建立裝置檔案 (在核心空間執行)
第 1 種方法不可取, 因為你不可預知 是否將來要 用到這個major number
第 2 種方法,需要在使用者空間建立
第 3 種方法最好,可以動態的建立,銷毀裝置檔案,不過麻煩
2 取消註冊裝置函式
關於:counter
linux 2 6 核心模組程式設計探索
乙個linux 核心模組程式設計的手記,未寫完不斷更新中 一 相關命令 0 檢視系統裝載了哪些 核心模組 lsmod modulename 1 載入核心模組 insmod modulename 2 解除安裝核心模組 rmmod modulename 3 建立裝置檔案 mknod filename d...
linux2 6核心模組的編譯
首先將下面的程式寫進乙個hello1.c的檔案裡 vim hello1.c include linux module.h include linux kernel.h include linux init.h static int init lkp init void static void exi...
Linux 2 6核心驅動之hello模組
終於開始在鍾愛的linux上學習寫驅動程式了。本來以為寫乙個hello模組是異常簡單的事情,結果折騰了幾天才編譯通過。首先為了測試安裝了虛擬機器 核心程式是很危險滴,我可不想讓自己的愛本頻繁崩潰 裝fedora17 fedora18的live版在虛擬機器上始終跑不起來 來回來去幾次也裝不上virtu...