ldd3學習之二 構造和執行模組

2021-07-29 17:31:24 字數 4634 閱讀 5237

①設定一套核心原始碼樹,比如/usr/src/linux-2.6.x,參考

eg:uname -r  --->2.6.32-27-generic

wget

pub/linux/kernel/v2.6/linux-2.6.32.27.tar.gz

②直接用發行版的核心原始碼包,比如

/lib/modules/$(shell uname -r),包含核心目標鏈結檔案。 #

include

#include

module_license(

"dual bsd/gpl");

static

int hello_init(

void

)static

void hello_exit(

void

)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編譯,然後用insmod安裝,用dmesg可以在終端看到輸出資訊,或者輸出到某個日誌檔案裡比如/var/log/messages.

linux的模組並不複雜,

②核心函式不支援浮點運算。

③unix使用兩個級別,核心態和使用者態。當處理器有多個級別時,使用最高端別和最低級別。

④每當應用程式執行系統呼叫或者被硬體中斷掛起時,unix從使用者空間切換到核心空間。

⑤系統呼叫的**執行在程序上下文,可以訪問程序所有資料。而處理硬體中斷的核心**和程序是非同步的,與任乙個特定程序無關。

⑥乙個驅動程式要執行兩類任務:模組中的某些函式作為系統呼叫的一部分執行(實現使用者api),而其他函式則負責中斷處理。

⑦核心具有非常小的棧,可能只有4k大小頁。我們自己的函式必須和整個核心空間呼叫鏈一同共享這個棧,如果需要大的結構,應該在呼叫時動態分配。

linux2.6中核心**已經是可搶占的。

①編寫核心**時,時刻銘記:同一時刻,可能會有許多事情正在發生。

②linux核心**(包括驅動**)必須是可重入的。

核心**可通過訪問全域性項current來獲得當前程序,current在

中定義,是乙個指向struct task_struct的指標。

在2.6中,current不再是乙個全域性變數,指向task_stuct結構的指標隱藏在核心棧中,current是乙個可以獲得這個結構的巨集,包含

即可引用。 #

include

printk(kern_info"the process is \"%s\" (pid %i)\n"

,current-

>comm,current-

>pid);

對hello world模組,makefile只要一行就可以了:obj-m := hello.o

如果要構造的模組名module.ko由兩個原始檔生成,file1.c,file2.c,則:

obj-m :

= module.o

module.o-objs :

= file1.o file2.o

裝載:sudo insmod hello.ko

檢視:lsmod

解除安裝:sudo rmmod hello

公共核心符號表中包含了所有的全域性核心項(函式和變數)的位址,模組被裝載後,它所匯出的任何符號都會變成核心符號表的一部分。

模組層疊技術在複雜專案中非常有用,modprobe是處理層疊技術的乙個使用工具,功能類似insmod.通過層疊技術,可以將模組劃分為多個層,通過簡化每個層,可縮短開發時間。8

#include

//

#include

//

//所有模組**中都包含這兩行

module_license(

"dual bsd/gpl"

);//制定許可證,一般用"gpl"或者

static

int __init hello_init(

void

)     //__init表示初始化函式執行完之後就釋放記憶體

static

void __exit hello_exit(

void

) //__exit表示在解除安裝是執行,編譯器把這類函式放在特殊的elf段中

module_init(hello_init)

;module_exit(hello_exit)

;//如果註冊設施時遇到任何錯誤,首先判斷模組是否可以繼續初始化,通常,在某個註冊失敗後可以通過降低功能來繼續執行。因此,只要可能,模組應該繼續向前並盡可能提供功能。

若發生的特定型別錯誤之後無法繼續裝載模組,則出錯之前的任何註冊工作都要撤銷(未撤銷,核心可能不穩定)。

void

)void

)struct something * item2;

void my_cleanup(

void

)int __init my_init(

void)

static

char

*whom =

"world"

;static

int howmany = 10;

module_param(howmany,

int,s_irugo)

;module_param(whom,charp,s_irugo)

;module_param(name,type,num,perm)

;name-

-陣列名字

type-

-陣列元素型別

num-

-陣列個數

perm-

-訪問許可值

insmod hello.ko whom=yuyunbo howmany=5

本章新符號總結(函式,變數,巨集等)

insmod,modprobe,rmmod,lsmod,dmesg

用來裝載模組到正執行的核心和移除模組的使用者空間工具

#include

module_init(init_function);

module_exit(cleanup_function);

用於指定模組的初始化和清除函式的巨集。

__init,__initdata,__exit,__exitdata

僅用於模組初始化或清除階段的函式(__init和_exit)和資料(__initdta和__exitdata)標記。

#include

最重要的標頭檔案之一,該檔案包含驅動程式使用的大部分核心api的定義,包括睡眠函式以及各種變數宣告。

struct task_struct *current;

當前程序

current->pid

current->com

當前程序的程序id和命令名。

obj-m

由核心構造系統使用的makefile的符號,用來確定當前目錄中應構造那些模組

/sys/module是sysfs目錄層次結構中包含當前已裝載模組資訊的目錄

/proc/modules是早期的用法,在單個檔案中包含模組名稱,每個模組記憶體總量以及引用計數等。

vermagic.o核心源**目錄中的乙個目標檔案,描述了模組的構造環境。

#include

必須的標頭檔案,它必須包含在模組源**中。

#include

包含說構造核心版本資訊的標頭檔案。

linux_version_code整數巨集,用在處理版本以來的預處理條件語句中。

export_symbol (symbol);

匯出單個符號到核心的巨集

export_symbol_gpl(symbol);僅用於gpl許可證下的模組

module_author(author);

module_description(desctiption);

module_version(version_string);

module_device_table(table_info);

module_alias(alternate_name);

在目標檔案中新增關於模組的文件資訊。

module_init(init_function);

module_exit(exit_function);

宣告模組初始化和清除函式的巨集

#include

module_param(variable,type,perm);

用來建立函式模組的巨集,在裝載模組時調整引數

#include

int printk(const char * fmt,...);

函式printf的核心**

0

給主人留下些什麼吧!~~

LDD3學習筆記 模組的編譯

新手上路,ldd3學習之旅開始,以下內容純屬筆記,若有錯誤,望見諒!1.什麼是 模組 可以在系統執行時加入到核心中的 故 模組包括但不限於裝置驅動程式。2.如何寫乙個模組?1 c檔案 2 實現module init,module exit3.ldd3中makefile編寫規則 照搬 ifneq ke...

ldd3第二章 建立核心原始碼樹,編譯模組

ubuntu編譯核心樹 首先我實驗的hello和scull模組都不需要建立核心原始碼樹,只需系統自帶的標頭檔案就可。ubuntu 10.04 確認你當前使用ubuntu系統的核心版本 當模組 要鏈結至不同版本的核心時,必須要做的就是對這個模組 重新進行編譯。這是因為模組對某一版本核心中定義的一些資料...

第二章 構造和執行模組(筆記)

如果讀者正在編寫乙個只適用於某特定發行版的驅動程式,則應該針對相關核心建立和測試自己的驅動程式。2.6.x核心構造模組,必須在自己的系統中配置並構造好核心樹 因為2.6核心的模組要和核心源 樹中的目標檔案連線 先前的核心只需要一套核心標頭檔案就夠了。module license用來告訴核心,該模組採...