高效學(xué)習(xí)Linux內(nèi)核——內(nèi)核模塊編譯

原創(chuàng) 2020-03-16 16:23:00 Linux內(nèi)核 內(nèi)核模塊

本文主要講解什么是Linux內(nèi)核,以及通過(guò)多張圖片展示Linux內(nèi)核的作用、功能及基本編程方法,以便于讀者能快速理解什么是Linux內(nèi)核,能看懂Linux內(nèi)核。
擁有超過(guò)1300萬(wàn)行的代碼,Linux內(nèi)核是世界上最大的開(kāi)源項(xiàng)目之一,但是內(nèi)核是什么,它用于什么?

一、什么是linux內(nèi)核模塊

內(nèi)核是與計(jì)算機(jī)硬件接口的易替換軟件的最低級(jí)別。它負(fù)責(zé)將所有以“用戶模式”運(yùn)行的應(yīng)用程序連接到物理硬件,并允許稱為服務(wù)器的進(jìn)程使用進(jìn)程間通信(IPC)彼此獲取信息。

 Linux內(nèi)核與硬件的關(guān)系

內(nèi)核可以通過(guò)所謂的中斷來(lái)管理系統(tǒng)的硬件。 當(dāng)硬件要與系統(tǒng)接口時(shí),會(huì)發(fā)出一個(gè)中斷,中斷處理器,從而對(duì)內(nèi)核執(zhí)行相同的操作。 為了提供同步,內(nèi)核可以禁用中斷,無(wú)論是單個(gè)中斷還是全部中斷。 但是,在Linux中,中斷處理程序不是在進(jìn)程上下文中運(yùn)行,而是在不與任何進(jìn)程相關(guān)聯(lián)的中斷上下文中運(yùn)行,這種特殊的中斷上下文僅是為了讓中斷處理程序快速響應(yīng)單個(gè)中斷然后最終退出而存在 。

linux內(nèi)核整體非常龐大,包含組件特別多,當(dāng)我們把需要的部分包含到內(nèi)核中,直接把需要的所有功能都編譯到內(nèi)核中會(huì)導(dǎo)致內(nèi)核很大,而且當(dāng)需要新增或者刪除功能,又要重新編譯,非常麻煩,因此linux提供了模塊(Modele)的機(jī)制。

可以把內(nèi)核比喻成一個(gè)很長(zhǎng)的火車,每個(gè)車廂就是一個(gè)內(nèi)核模塊,內(nèi)核在運(yùn)行這個(gè)火車就會(huì)一直在開(kāi)動(dòng),但是我們想在火車開(kāi)動(dòng)的情況下增加新的車廂,這個(gè)時(shí)候就需要insmod,意思就是往這個(gè)長(zhǎng)長(zhǎng)的火車車廂增加一個(gè)內(nèi)核模塊。

模塊的特點(diǎn):不編譯入內(nèi)核鏡像;一旦加載和內(nèi)核其他部分完全一樣。

為了使讀者對(duì)模塊有個(gè)感性認(rèn)知,先看一下簡(jiǎn)單的HelloWorld模塊,代碼如下:

二、Linux內(nèi)核模塊組成結(jié)構(gòu)

一個(gè)Linux內(nèi)核模塊主要由以下幾個(gè)部分組成。

1)模塊加載函數(shù)(必須)

當(dāng)通過(guò) insmod 或 modprobe命令加載內(nèi)核模塊時(shí),模塊的加載函數(shù)會(huì)自動(dòng)被內(nèi)核執(zhí)行,完成本模塊的相關(guān)初始化工作。模塊加載函數(shù)一般以__init標(biāo)識(shí)聲明

static int __init FuntionA(void)

{

}

module_init( FuntionA);


2)模塊卸載函數(shù)(必須)

當(dāng)通過(guò) rmmod 命令卸載某模塊時(shí),模塊的卸載函數(shù)會(huì)自動(dòng)被內(nèi)核執(zhí)行,完成與模塊加載函數(shù)相反的功能。 模塊卸載函數(shù)一般以__exit標(biāo)識(shí)聲明:

static void __exit  FuntionB(void)

{

}

module_exit( FuntionB );

通常來(lái)說(shuō),模塊卸載函數(shù)要完成與模塊加載函數(shù)相反的功能,如下所示。

a)若模塊加載函數(shù)注冊(cè)了XXX,則模塊卸載函數(shù)應(yīng)該注銷XXX。

b)若模塊加載函數(shù)動(dòng)態(tài)申請(qǐng)了內(nèi)存,則模塊卸載函數(shù)應(yīng)釋放該內(nèi)存。

c)若模塊加載函數(shù)申請(qǐng)了硬件資源(中斷,DMA通道,I/O端口和I/O內(nèi)存等)的占用,則模塊卸載函數(shù)應(yīng)釋   放這些硬件資源。

d)若模塊加載函數(shù)開(kāi)啟了硬件,則卸載函數(shù)中一般要關(guān)閉硬件。


3)模塊許可證聲明(必須)

模塊許可證(LICENSE)聲明描述內(nèi)核模塊的許可權(quán)限,如果不聲明 LICENSE,模塊被加載時(shí),將收到內(nèi)核被污染的警告。大多數(shù)情況下,內(nèi)核模塊應(yīng)遵循GPL 兼容許可權(quán)。

Linux2.6 內(nèi)核模塊最常見(jiàn)的是以MODULE_LICENSE(“Dual BSD/GPL”)語(yǔ)句聲明模塊采用BSD/GPL 雙LICENSE


4)模塊參數(shù)(可選)是模塊被加載的時(shí)候可以被傳遞給它的值,它本身對(duì)應(yīng)模塊內(nèi)部的全局變量

用“module_param(參數(shù)名,參數(shù)類型,參數(shù)讀/寫(xiě)權(quán)限)”為模塊定義一個(gè)參數(shù)

例如: module_param(num,int,S_IRUGO);


5)模塊導(dǎo)出符號(hào)(可選)可以導(dǎo)出符號(hào)(symbol,對(duì)應(yīng)于函數(shù)或變量),這樣其它模塊可以使用本模塊中的變量或函數(shù)

可以使用如下宏導(dǎo)出符號(hào)到內(nèi)核符號(hào)表:

EXPORT_SYMBOL(符號(hào)名);

EXPORT_SYMBOL_GPL(符號(hào)名);


6)模塊作者等信息聲明(可選)

我們可以使用MODULE_AUTHOR,MODULE_DESCRIPTION,MODULE_VERSION,MODULE_DEVICE_TABLE,MODULE_ALLAS

分別聲明模塊的作者,描述,版本,設(shè)備表和別名

例如:

MODULE_AUTHOR(author);

MODULE_DESCRIPTION(description);

三、Linux內(nèi)核模塊的編譯

首先為HelloWorld模塊編寫(xiě)MakeFile文件

該MakeFile文件應(yīng)該與源碼位于同一目錄

在Makefile中,在obj-m := helloworld.o這句中,.o的文件名要與編譯的.c文件名一致。 

如果一個(gè)模塊包含多個(gè).c文件(如file1.c、file2.c)則應(yīng)該使用如下方式編寫(xiě)MakeFile:

Obj -m :=modulename.o

Modulename -obj :-file1.o file2.o

KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r)指示當(dāng)前l(fā)inux系統(tǒng)內(nèi)核的源碼位置。 

1.在Makefile及helloworld.c所在目錄下,直接make,成功后查看當(dāng)前目錄下有無(wú)helloworld.ko文件產(chǎn)生,有則內(nèi)核模塊生成成功。

2.使用insmod命令,把此內(nèi)核模塊程序加載到內(nèi)核中運(yùn)行。結(jié)合lsmod及管道命令,查看內(nèi)核模塊程序在內(nèi)核中是否正確運(yùn)行。

四、總結(jié)

本文主要講解了linux內(nèi)核模塊的概念和基本編程方法、內(nèi)核模塊組成結(jié)構(gòu),由于linux設(shè)備驅(qū)動(dòng)以內(nèi)核模塊的形式存在,因此了解本文內(nèi)容是編寫(xiě)任何設(shè)備驅(qū)動(dòng)的必需。



相關(guān)產(chǎn)品 >

  • FETT507-C核心板

    推薦T507,全志T507核心板采用工業(yè)級(jí)處理器設(shè)計(jì)開(kāi)發(fā),提供T507規(guī)格書(shū),T507各類設(shè)計(jì)資料。FETT507-C核心板集成全志T507四核工業(yè)級(jí)處理器設(shè)計(jì)開(kāi)發(fā),Cortex-A53架構(gòu),主頻1.5GHz,集成G31 GPU,內(nèi)存2GB DDR3L,存儲(chǔ)8GB eMMC。整板工業(yè)級(jí)運(yùn)行溫寬,支持絕大部分當(dāng)前流行的視頻及圖片格式解碼,具有穩(wěn)定可靠的工業(yè)級(jí)產(chǎn)品性能、低功耗以及豐富的用戶接口等優(yōu)勢(shì),搭載Linux、Android、Ubuntu*操作系統(tǒng),適用于車載電子、電力、醫(yī)療、工業(yè)控制、物聯(lián)網(wǎng)、智能終端等領(lǐng)域 了解詳情
    FETT507-C核心板
  • FETMX8MP-C核心板

    iMX8MP核心板基于 NXP  i.MX 8M Plus 處理器設(shè)計(jì),  采用4核Cortex-A53 和 Cortex-M7架構(gòu)。支持雙千兆網(wǎng)口,iMX8MP性能強(qiáng)勁最高運(yùn)行速率可達(dá)2.3TOPS,并且i.MX8MP功耗更低≤2W 。iMX 8M Plus系列專注于機(jī)器學(xué)習(xí)和視覺(jué)、高級(jí)多媒體以及具有高可靠性的工業(yè)自動(dòng)化。它旨在滿足智慧家庭、樓宇、城市和工業(yè)4.0應(yīng)用的需求。飛凌iMX8MP核心板提供用戶手冊(cè),iMX8MP原理圖,引腳定義等。
    了解詳情
    FETMX8MP-C核心板

推薦閱讀 換一批 換一批