1. 程式人生 > >linux裝置驅動makefile入門解析

linux裝置驅動makefile入門解析

以下內容僅作參考,能力有限,如有錯誤還請糾正。
對於一個普通的linux裝置驅動模組,以下是一個經典的makefile程式碼,使用下面這個makefile可以
完成大部分驅動的編譯,使用時只需要修改一下要編譯生成的驅動名稱即可。只需修改obj-m的值。


ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
#generate the path
CURRENT_PATH:=$(shell pwd)
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build
#complie object
default:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif


說明:
當我們在模組的原始碼目錄下執行make時,make是怎麼執行的呢?
假設模組的原始碼目錄是/home/study/prog/mod/hello/下。
先說明以下makefile
中一些變數意義:
(1)KERNELRELEASE在linux核心原始碼中的頂層makefile中有定義
(2)shell pwd會取得當前工作路徑
(3)shell uname -r會取得當前核心的版本號
(4)LINUX_KERNEL_PATH變數便是當前核心的原始碼目錄。
關於linux原始碼的目錄有兩個,分別為"/lib/modules/$(shell uname -r)/build"和"/usr/src/linux-header-$(shell uname -r)/",
但如果編譯過核心就會知道,usr目錄下那個原始碼一般是我們自己下載後解壓的,而lib目錄下的則是在編譯時自動copy過去的,
兩者的檔案結構完全一樣,因此有時也將核心原始碼目錄設定成/usr/src/linux-header-$(shell uname -r)/。關於核心原始碼目錄
可以根據自己的存放位置進行修改。
(5)make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
這就是編譯模組了:首先改變目錄到-C選項指定的位置(即核心原始碼目錄),其中儲存有核心的頂層makefile;
M=選項讓該makefile在構造modules目標之前返回到模組原始碼目錄;然後,modueles目標指向obj-m變數中設定的模組;
在上面的例子中,我們將該變數設定成了hello.o。



按照順序分析以下make的執行步驟:
在模組的原始碼目錄下執行make,此時,巨集“KERNELRELEASE”沒有定義,因此進入else。
由於make 後面沒有目標,所以make會在Makefile中的第一個不是以.開頭的目標作為預設的目標執行。
於是default成為make的目標。
make會執行 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ,假設當前核心版本是2.6.13-study,
所以$(shell uname -r)的結果是 2.6.13-study ,這裡實際執行的是
make -C /lib/modules/2.6.13-study/build M=/home/study/prog/mod/hello/ modules


-C 表示到存放核心的目錄執行其makefile,在執行過程中會定義KERNELRELEASE,
然後M=$(CURDIR)表示返回到當前目錄,再次執行,modules表示編譯成模組的意思。
而此時KERNELRELEASE已定義,則會執行obj-m += hello.o,表示會將hello_world.o目標編譯成.ko模組。
若有多個原始檔,則採用如下方法:
obj-m := hello.o
hello-objs := file1.o file2.o file3.o
關於make modules的更詳細的過程可以在核心原始碼目錄下的scripts/Makefile.modpost檔案的註釋 中找到。


如果把hello模組移動到核心原始碼中。例如放到/usr/src/linux/driver/中, KERNELRELEASE就有定義了。
在/usr/src/linux/Makefile中有KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)。

這時候,hello模組也不再是單獨用make編譯,而是在核心中用make modules進行編譯,此時驅動模組便和核心編譯在一起。

相關推薦

linux裝置驅動makefile入門解析

以下內容僅作參考,能力有限,如有錯誤還請糾正。 對於一個普通的linux裝置驅動模組,以下是一個經典的makefile程式碼,使用下面這個makefile可以 完成大部分驅動的編譯,使用時只需要修改一下要編譯生成的驅動名稱即可。只需修改obj-m的值。 ifneq ($(K

[ARM-LInux開發]linux裝置驅動makefile入門解析

以下內容僅作參考,能力有限,如有錯誤還請糾正。對於一個普通的linux裝置驅動模組,以下是一個經典的makefile程式碼,使用下面這個makefile可以完成大部分驅動的編譯,使用時只需要修改一下要編譯生成的驅動名稱即可。只需修改obj-m的值。ifneq ($(KERN

Linux應用程式訪問字元裝置驅動詳細過程解析

下面先通過一個編寫好的核心驅動模組來體驗以下字元裝置驅動 可以暫時先忽略下面的程式碼實現! memdev.c #include <linux/module.h> #include <linux/fs.h> #include <linux/in

Linux 裝置驅動開發 —— platform裝置驅動應用例項解析

       前面我們已經學習了platform裝置的理論知識Linux 裝置驅動開發 —— platform 裝置驅動 ,下面將通過一個例項來深入我們的學習。 一、platform 驅動的工作過程         platform模型驅動程式設計,需要實現platfor

Linux裝置驅動初探_多原始檔Makefile

首先介紹一下__init這個標誌在驅動原始檔中的作用吧。 核心中帶“__”的函式:核心API函式具有這種名稱的,通常都是一些介面的底層函式,應該謹慎使用。實質上,這裡的雙下劃線就是要告訴程式設計師:謹慎呼叫,否則後果自負。以__init為例,__init表明該函式僅在初

Linux裝置驅動模組自載入示例與原理解析

本文介紹Linux裝置驅動模組在設備註冊時如何實現自動載入和建立裝置節點。 在Linux系統中,基於sysfs檔案系統、裝置驅動模型和udev工具可以實現在裝置模組“冷、熱”載入時自動載入裝置對應的驅動程式,同時可以按需在/dev目錄下建立裝置節點。 本文中我搭建好環

Linux裝置驅動入門及demo事例

 在 Unix like 系統中,正是有了驅動程式才使得使用者可以完全透明的使用計算機系統。裝置驅動隱藏了硬體裝置的具體的細節和功能,對於不同的硬體裝置都提供了一致的介面。比如在 Linux 系統中,為了便於使用者的使用,系統把計算機系統的各種裝置對映成一系列的特殊的裝置檔案

Linux裝置驅動入門----I2C裝置驅動

/* * I2C驅動的一些模板: * (1)、I2C匯流排驅動的的模組載入和解除安裝函式模板 * (2)、I2C匯流排通訊方法 * (3)、I2C裝置驅動模組的載入和解除安裝 * (4)、I2C裝置驅動的檔案操作介面 * (與普通驅動的檔案操作一致,

linux裝置驅動開發學習--記憶體和IO訪問

一 I/O 埠 1. 讀寫位元組埠(8 位寬) unsigned inb(unsigned port); void outb(unsigned char byte, unsigned port); 2. 讀寫字埠(16 位寬) unsigned inw(unsigne

linux裝置驅動模型 - regmap

1. regmap介紹 regmap主要是為了方便操作暫存器而設計的,它將所有模組的暫存器(包括soc上模組的暫存器和外圍裝置的暫存器等) 抽象出來,用一套統一介面來操作暫存器 比如,如果要操作i2c裝置的暫存器,那麼就要呼叫i2c_transfer介面,要操作spi裝置的暫存

linux裝置驅動模型 - device/bus/driver

在linux驅動模型中,為了便於管理各種裝置,我們把不同裝置分別掛在他們對應的總線上,裝置對應的驅動程式也在總線上找,這樣就提出了deivce-bus-driver的模型,硬體上有許多裝置匯流排,那麼我們就在裝置模型上抽象出bus概念,相應的device就代表裝置,driver表示驅動,

linux裝置驅動模型 - sys/kobject

1. sysfs 1.1 sysfs檔案系統註冊 在系統啟動時會註冊sysfs檔案系統 (fs/sysfs/mount.c) int __init sysfs_init(void) { int err; sysfs_root = kernfs_creat

linux裝置驅動模型 - 驅動框架

linux驅動模型框架如圖所示: 1. kernfs 驅動最終是提供給使用者層使用,那麼其中的介面就是通過kernfs檔案系統來註冊,kernfs是一個通用的核心虛擬檔案系統 2. sysfs/kobject sysfs是裝置驅動檔案系統,裝置之間的各種關係會在在/

linux裝置驅動(3)I2C驅動

i2c驅動程式的核心是建立i2c_driver結構體 /* This is the driver that will be inserted */ static struct i2c_driver at24cxx_driver = { .driver = { .name

linux裝置驅動開發》,基於最新的linux 4.0核心-----筆記

第二章 Linux 的核心結構及構建 ---->這一章是自己總結的 1、核心結構(主要是下面這幾個部分) 系統呼叫介面<–>System call interface 程序管理<------>Process manag

linux裝置驅動 按鍵幾種寫法總結

對於基礎按鍵的驅動,有如下幾種寫法: (1)查詢 所謂查詢方法,主要描述應用程式會在while(1)裡面一直read,如果沒有資料會導致阻塞,佔用CPU;這種方法是最差的。   (2)中斷 中斷配合休眠會避免查詢法佔用CPU的缺點。 應用程式和查詢法沒有什麼區別, 但是驅動裡面的read

linux 裝置驅動 nand驅動框架

nand 裝置驅動(一)架構 使用mini2440 - nand 1. nand硬體 1.1 資源 LDATD0~7資料線和地址線是複用的,都是8位 既可以傳輸資料(命令或者資料), 也可以傳送地址訊號 訊號說明: CLE: 命令鎖存, 高表示cmd ALE: 地址鎖存, 高表示地址

linux裝置驅動載入的先後順序

                        &

嵌入式Linux開發——(十七)Linux裝置驅動開發

一、字元裝置驅動程式 1)應用程式、庫、核心、驅動程式的關係 2)Linux驅動程式的分類和開發步驟     ①Linux的外設可分為3類:字元裝置(character device)、塊裝置(block device)、網路介面(network interfa

linux裝置驅動模型之Kobject、kobj_type、kset

一、sysfs檔案系統簡介: 1、sysfs概述 sysfs檔案系統是核心物件(kobject)、屬性(kobj_type)、及它們相互關係的一種表現。 sysfs非常重要的特徵:使用者可以從sysfs中讀出核心資料,也可以將使用者資料寫入核心。 2、核心結構與sysfs對應關係: