Linux設(shè)備驅(qū)動(dòng)程序移植全過程
介紹
有時(shí)需要升級(jí)到較新版本的 Linux 內(nèi)核,并因此需要移植現(xiàn)有的設(shè)備驅(qū)動(dòng)程序。

移植過程可能需要幾分鐘甚至更長(zhǎng)時(shí)間。這不僅取決于驅(qū)動(dòng)程序的復(fù)雜度,還取決于您要升級(jí)的內(nèi)核版本(API 往往會(huì)發(fā)生變化,而所有問題都源于此),以及代碼實(shí)現(xiàn)的質(zhì)量。有時(shí)重寫比移植更容易,但我們不會(huì)討論這個(gè)問題。
遺憾的是,我無法附上驅(qū)動(dòng)程序的源代碼,但我們會(huì)涵蓋您和我在移植過程中可能遇到的所有問題。下面,我們將看一個(gè)將簡(jiǎn)單驅(qū)動(dòng)程序從內(nèi)核版本 2.6.25 移植到 4.12.5 的示例,該驅(qū)動(dòng)程序位于 drivers/serial/name_uart.c 中。
問題陳述
任務(wù)非常簡(jiǎn)單直接:我們需要將上述驅(qū)動(dòng)程序從內(nèi)核版本 2.6.25 移植到 4.12.5。
執(zhí)行
首先,如果你不熟悉你正在移植的驅(qū)動(dòng)程序,我建議你至少簡(jiǎn)單研究一下。這可以使任務(wù)變得容易得多。之后,你就可以開始移植了。
第一步:
- 我們的驅(qū)動(dòng)程序在 2.6.25 內(nèi)核中有以下路徑:drivers/serial/name_uart.c現(xiàn)在我們需要找到一個(gè)合適的目錄來放置它。
- 在這里我們遇到了第一個(gè)問題:4.12.5 內(nèi)核中沒有 drivers/serial/ 這樣的目錄。
- 解決方案很簡(jiǎn)單:只需將我們的驅(qū)動(dòng)程序放在drivers/tty/serial/name_uart.c中
第二步:
- 之后,為了確保 Linux 可以在構(gòu)建中包含我們的驅(qū)動(dòng)程序,我們需要將它添加到兩個(gè)文件中。
- 第一個(gè)文件是:drivers/tty/serial/Makefile 。
- 在其中添加以下行:
obj-$(CONFIG_SERIAL_NAME) += name_uart.o
- 第二個(gè)文件:drivers/tty/serial/Kconfig
- 我們?cè)诶锩鎸懭胍韵聝?nèi)容:
config SERIAL_NAME tristate "SERIAL_NAME UART driver" help Write description here
第三步:
- 完成前兩步后,我們就可以開始構(gòu)建了。
- 在根目錄下,運(yùn)行 make menuconfig 并將我們的驅(qū)動(dòng)程序包含在構(gòu)建中。
- 運(yùn)行該命令后,會(huì)打開一個(gè)圖形界面,在那里找到我們的驅(qū)動(dòng)程序應(yīng)該沒有問題(您可以按 / 鍵并輸入完整或部分名稱,然后按 Enter 鍵進(jìn)行搜索)。
- 另一種選擇是直接編輯 .config 文件,并將您的驅(qū)動(dòng)程序包含在構(gòu)建中。
- 接下來,您可以嘗試構(gòu)建包含我們驅(qū)動(dòng)程序的內(nèi)核。
第四步:
- 嘗試構(gòu)建內(nèi)核后,我們可能會(huì)遇到一系列錯(cuò)誤,需要解決這些錯(cuò)誤才能成功構(gòu)建內(nèi)核并確保測(cè)試驅(qū)動(dòng)程序的功能。
- 我遇到的錯(cuò)誤是由于與 proc 系統(tǒng)交互的接口過時(shí)以及一個(gè)宏被刪除造成的。
- 例如,在內(nèi)核 2.6.25 中調(diào)用 irequest_irq 函數(shù)可以正常工作,但是
irequest_irq(64 + ISC_DMA, dma_interrupt_handler, IRQF_DISABLED, "DMA", NULL);
在內(nèi)核 4.12.5 中,IRQF_DISABLED 宏已被移除,導(dǎo)致驅(qū)動(dòng)程序無法構(gòu)建。
解決方案是用 0 替換 IRQF_DISABLED。
irequest_irq(64 + ISC_DMA, dma_interrupt_handler, 0, "DMA", NULL);
下一個(gè) bug 是,在內(nèi)核版本 2.6.25 中,與 proc 系統(tǒng)的交互是通過 create_proc_entry 函數(shù)實(shí)現(xiàn)的,而這個(gè)實(shí)現(xiàn)在內(nèi)核版本 4.12.5 中已經(jīng)不存在了。
因此,需要對(duì)該實(shí)現(xiàn)進(jìn)行輕微的重寫,最終版本如下:
/******************************************************************************
* /proc interface
******************************************************************************/
static int xr16_get_status(struct seq_file *m, void *v)
{
struct uart_name_uart *pp;
unsigned long f;
u64 tmp;
int i, xmax = ARRAY_SIZE(pp->in_irq);
seq_printf(m, "UART NAME ports stat:\n");
for (i = 0; i < UART_NAME_MAXPORTS; i++) {
pp = &uart_name_16_ports[i];
if (!pp->used)
continue;
local_irq_save(f);
tmp = ktime_to_us(ktime_sub(ktime_get(), pp->ktm_last));
do_div(tmp, USEC_PER_SEC);
local_irq_restore(f);
}
return 0;
}
static int xr16_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, uart_name_get_status, NULL);
}
static const struct file_operations uart_name_proc_fops = {
.owner = THIS_MODULE,
.open = uart_name_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
}總而言之,驅(qū)動(dòng)程序移植可以按照以下步驟完成:
- 1. 將舊版驅(qū)動(dòng)程序的源代碼復(fù)制到新的 Linux 內(nèi)核;
- 2. 為 Kconfig 和 Makefile 添加描述;
- 3. 使用 busybox 將驅(qū)動(dòng)程序集成到內(nèi)核構(gòu)建中(或直接編輯 .config 文件);
- 4. 修復(fù)所有構(gòu)建錯(cuò)誤,直到內(nèi)核構(gòu)建成功。
總結(jié)
至此,我們介紹了將設(shè)備驅(qū)動(dòng)程序移植到較新 Linux 內(nèi)核的基礎(chǔ)知識(shí),以及您可能遇到的問題。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Ubuntu下使用python3中的venv創(chuàng)建虛擬環(huán)境
這篇文章主要介紹了Ubuntu下使用python3中的venv創(chuàng)建虛擬環(huán)境,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
CentOS7 LNMP+phpmyadmin環(huán)境搭建 第三篇phpmyadmin安裝
這篇文章主要介紹了CentOS7 LNMP+phpmyadmin環(huán)境搭建,第三篇phpmyadmin安裝,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
centos系統(tǒng)為php安裝memcached擴(kuò)展步驟
這篇文章主要介紹了centos系統(tǒng)為php安裝memcached擴(kuò)展的步驟,大家參考使用吧2014-01-01
Ubuntu安裝MySQL5.7并配置數(shù)據(jù)存儲(chǔ)路徑的方法步驟
這篇文章主要介紹了Ubuntu安裝MySQL5.7并配置數(shù)據(jù)存儲(chǔ)路徑的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06

