17人参与 • 2025-10-18 • Linux
有时需要升级到较新版本的 linux 内核,并因此需要移植现有的设备驱动程序。

移植过程可能需要几分钟甚至更长时间。这不仅取决于驱动程序的复杂度,还取决于您要升级的内核版本(api 往往会发生变化,而所有问题都源于此),以及代码实现的质量。有时重写比移植更容易,但我们不会讨论这个问题。
遗憾的是,我无法附上驱动程序的源代码,但我们会涵盖您和我在移植过程中可能遇到的所有问题。下面,我们将看一个将简单驱动程序从内核版本 2.6.25 移植到 4.12.5 的示例,该驱动程序位于 drivers/serial/name_uart.c 中。
任务非常简单直接:我们需要将上述驱动程序从内核版本 2.6.25 移植到 4.12.5。
首先,如果你不熟悉你正在移植的驱动程序,我建议你至少简单研究一下。这可以使任务变得容易得多。之后,你就可以开始移植了。
第一步:
第二步:
obj-$(config_serial_name) += name_uart.o
config serial_name tristate "serial_name uart driver" help write description here
第三步:
第四步:
irequest_irq(64 + isc_dma, dma_interrupt_handler, irqf_disabled, "dma", null);
在内核 4.12.5 中,irqf_disabled 宏已被移除,导致驱动程序无法构建。
解决方案是用 0 替换 irqf_disabled。
irequest_irq(64 + isc_dma, dma_interrupt_handler, 0, "dma", null);
下一个 bug 是,在内核版本 2.6.25 中,与 proc 系统的交互是通过 create_proc_entry 函数实现的,而这个实现在内核版本 4.12.5 中已经不存在了。
因此,需要对该实现进行轻微的重写,最终版本如下:
/******************************************************************************
* /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,
}总而言之,驱动程序移植可以按照以下步骤完成:
至此,我们介绍了将设备驱动程序移植到较新 linux 内核的基础知识,以及您可能遇到的问题。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论