编译ARMv7与ARMv5的驱动程序

时间:2017-03-27 19:07:49

标签: linux arm linux-device-driver cross-compiling

我设法为基于ARM的设备编译驱动程序,但是当我尝试加载它时驱动程序崩溃了。 这是cpuinfo的输出:

Processor       : ARMv7 Processor rev 2 (v7l)
BogoMIPS        : 999.42
Features        : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc08
CPU revision    : 2

这是uname -r输出

2.6.37

modinfo driver.ko

filename:       cp210x.ko
description:    Silicon Labs CP210x RS232 serial adaptor driver
license:        GPL
vermagic:       2.6.37 mod_unload ARMv7
vermagic:       2.6.37 mod_unload modversions ARMv5
parm:           debug:Enable verbose debugging messages

您可以添加额外的vermagic(2.6.37 mod_unload ARMv7),以便与目标系统匹配。

因此,如果我理解这是正确的,我已经为ARMv5 cpu编译了这个模块,而目标是v7。这可能是设备驱动程序崩溃的原因吗?

该设备具有此驱动程序,但它嵌入到hw生成器的其他驱动程序包中。这个包还加载了一些我们无法使用的驱动程序。这个驱动程序包没有加载,但我想这表明这个驱动程序应该在这个硬件上运行一些如何。

这是崩溃日志

modprobe cp210x.ko
Unable to handle kernel NULL pointer dereference at virtual address 0000000a
pgd = ca1fc000
[0000000a] *pgd=870dd031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
last sysfs file: /sys/kernel/uevent_seqnum
Modules linked in: dahdi_dummy dahdi cmemk syslink ipt_MASQUERADE nf_nat iptable_filter ip_tables ipt_LOG xt_state nf_conntrack_ftp nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_recent xt_mac xt_limit work_led reset_button ipv6
CPU: 0    Not tainted  (2.6.37 #1)
PC is at sys_init_module+0xfe0/0x1460
LR is at sys_init_module+0xe7c/0x1460
pc : [<c00836e8>]    lr : [<c0083584>]    psr: 20000013
sp : cc5e9ed0  ip : bf3828dc  fp : cc5e8000
r10: bf385ca8  r9 : cf3bcb4e  r8 : 000000c5
r7 : 00000027  r6 : bf382544  r5 : bf38266c  r4 : bf385ca8
r3 : 00000000  r2 : c7c9f000  r1 : 0000000a  r0 : 0000000a
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: 8a1fc019  DAC: 00000015
Process modprobe (pid: 2676, stack limit = 0xcc5e82e8)
Stack: (0xcc5e9ed0 to 0xcc5ea000)
9ec0:                                     bf382544 00000001 000ac048 bf382550
9ee0: 000000c5 cf3bd5a4 cf3b8000 000055f4 cf3bd20c cf3bd128 cf3bc2a0 c7c9f000
9f00: 0000266c 000028dc 00000000 00000000 00000017 00000018 00000010 0000000d
9f20: 00000009 00000000 6e72656b 00006c65 00000000 00000000 00000000 00000000
9f40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9f60: 00000000 00000000 c9a19540 00000000 ca2403c0 00000006 c9a19540 00000000
9f80: ca2403c0 000055f4 00000000 00000006 00000080 c0037c28 cc5e8000 00000000
9fa0: 00000001 c0037a80 000055f4 00000000 000ac998 000055f4 000ac048 000ac978
9fc0: 000055f4 00000000 00000006 00000080 000ac008 000ac028 000ac998 00000001
9fe0: bebaf968 bebaf958 00017764 40214740 60000010 000ac998 c1e38bcc 03de8ad9
[<c00836e8>] (sys_init_module+0xfe0/0x1460) from [<c0037a80>] (ret_fast_syscall+0x0/0x30)
Code: e7923103 e1a03133 e3130001 15963128 (17d33000)
---[ end trace 6e8943127db36208 ]---
Segmentation fault

2 个答案:

答案 0 :(得分:0)

我想改变cp210x.c文件并注释掉有多少使用互斥锁的地方。这是唯一的地方:

static void cp210x_close(struct usb_serial_port *port)
{
        dbg("%s - port %d", __func__, port->number);

        usb_serial_generic_close(port);

        /* mutex_lock(&port->serial->disc_mutex);*/
        if (!port->serial->disconnected)
                cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE);
        /* mutex_unlock(&port->serial->disc_mutex);*/
}

答案 1 :(得分:0)

您是否尝试将为一个内核编译的内核模块加载到另一个内核中? Linux模块(你称之为驱动程序)只应加载到编译它们的内核中。即使具有不同配置或编译器设置的相同版本的内核也可能使模块不兼容。所以玩魔术版是非常危险的。

你的驱动程序崩溃的原因是它试图使用不正确的布局访问内核数据结构,因此它实际上并没有读取它认为应该读取的属性。

将架构从ARMv7更改为ARMv5是一项非常激烈的配置更改,它将彻底改变内核数据结构的内存布局。

与Windows等其他操作系统不同,Linux没有抽象层或固定内存布局,可以将相同的可加载模块加载到不同版本的内核中。