Hej
我正在使用yocto和meta-atmel为Atmel的SAMA5D3x平台生成自己的嵌入式Linux。这包括一个自编写的内核模块。这是一个非常简单的字符设备(chrdev),它可以切换引脚来打开/关闭LED。
当我将其构建到内核4.1时,它工作正常。但是当迁移到内核4.4时,它会在写入函数中因“页面域错误”而崩溃。
直到崩溃的代码如下所示:
//! reads the commands from the i/o
static ssize_t dev_write(struct file *filp, const char *buff, size_t len, loff_t *off)
{
char * szDevice;
int deviceLen;
char * szPara;
int paraLen;
char * szValue;
int valueLen;
size_t remBytes;
char * szErrorStr;
int devIndex, paraIndx;
TBoardLed_State state;
char tb[len+1];
memcpy(tb, buff, len);
tb[len] = 0;
printk(KERN_INFO "%s: dev_write: %s (%i)\n", dSEK4Dev_indi, tb, (int) len);
错误打印是:
[ 107.140000] Unhandled fault: page domain fault (0x01b) at 0x00101090
[ 107.140000] pgd = d41a4000
[ 107.140000] [00101090] *pgd=346e1831, *pte=3f5ba34f, *ppte=3f5ba83f
[ 107.140000] Internal error: : 1b [#1] ARM
[ 107.140000] Modules linked in: sek4matrixled(O) sek4comconfig(O) sek4boardled(O)
[ 107.140000] CPU: 0 PID: 428 Comm: sh Tainted: G O 4.4.19-linux4sam_5.4 #1
[ 107.140000] Hardware name: Atmel SAMA5
[ 107.140000] task: d45a0040 ti: d45b4000 task.ti: d45b4000
[ 107.140000] PC is at memcpy+0x7c/0x330
[ 107.140000] LR is at dev_write+0x2c/0x25c [sek4boardled]
[ 107.140000] pc : [<c020effc>] lr : [<bf0002f8>] psr: 00020013
sp : d45b5e74 ip : 0000000c fp : d45b5efc
[ 107.140000] r10: 00000000 r9 : d45b4000 r8 : c000f564
[ 107.140000] r7 : d45b5f88 r6 : 00101090 r5 : 00000015 r4 : d45b5ea8
[ 107.140000] r3 : 00000018 r2 : fffffff5 r1 : 00101090 r0 : d45b5ea8
[ 107.140000] Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
[ 107.140000] Control: 10c53c7d Table: 341a4059 DAC: 00000051
[ 107.140000] Process sh (pid: 428, stack limit = 0xd45b4208)
[ 107.140000] Stack: (0xd45b5e74 to 0xd45b6000)
[ 107.140000] 5e60: 00000015 00101090 d45b5f88
[ 107.140000] 5e80: c000f564 d45b5ea8 d45b5ea8 bf0002f8 00000000 00000000 d45b4000 00000068
[ 107.140000] 5ea0: d45b5ed8 befff3f0 befff3f0 c0219c8c d46e07fc d45b5fb0 d45a0040 d4650540
[ 107.140000] 5ec0: 00000817 0010209c d4650574 00000055 00000800 c001674c 00000006 d457e1c0
[ 107.140000] 5ee0: bf0002cc 00101090 d45b5f88 c000f564 d45b4000 00000000 00000000 c00a2ae8
[ 107.140000] 5f00: b6f627cc 00006950 00007958 c000928c 00001000 00000000 00000000 00000000
[ 107.140000] 5f20: 57dabaed 258d097f 57dabaed 258d097f 57dabaed 258d097f 000005e5 00000000
[ 107.140000] 5f40: befff3f0 b6f62d58 b6f62d58 d457e1c0 00000015 00101090 d45b5f88 c000f564
[ 107.140000] 5f60: d45b4000 c00a32b0 00000000 0fa00000 d457e1c0 d457e1c0 00101090 00000015
[ 107.140000] 5f80: c000f564 c00a3ac8 00000000 00000000 b6fd16d0 00000015 00101090 b6f62d58
[ 107.140000] 5fa0: 00000004 c000f3a0 00000015 00101090 00000001 00101090 00000015 00000000
[ 107.140000] 5fc0: 00000015 00101090 b6f62d58 00000004 00000015 000ed124 00000001 00000000
[ 107.140000] 5fe0: 00000000 befff954 b6e8fe6c b6ee8f80 60020010 00000001 00000000 00000000
[ 107.140000] [<c020effc>] (memcpy) from [<bf0002f8>] (dev_write+0x2c/0x25c [sek4boardled])
[ 107.140000] [<bf0002f8>] (dev_write [sek4boardled]) from [<c00a2ae8>] (__vfs_write+0x1c/0xd8)
[ 107.140000] [<c00a2ae8>] (__vfs_write) from [<c00a32b0>] (vfs_write+0x90/0x16c)
[ 107.140000] [<c00a32b0>] (vfs_write) from [<c00a3ac8>] (SyS_write+0x44/0x9c)
[ 107.140000] [<c00a3ac8>] (SyS_write) from [<c000f3a0>] (ret_fast_syscall+0x0/0x3c)
[ 107.140000] Code: ea000011 e320f000 e4913004 e4914004 (e4915004)
[ 107.140000] ---[ end trace 2c62698a45a8d21d ]---
对我而言,我的模块不允许从用户空间读取数据。但我不知道如何克服这个错误。
有什么想法吗?
答案 0 :(得分:1)
正如Tsyvarev所提到的,输入缓冲区需要通过copy_from_user从用户空间复制到内核空间。在memcpy被copy_from_user替换后,模块可以正常工作。
答案 1 :(得分:1)
启用CONFIG_CPU_SW_DOMAIN_PAN
时发生页面域错误。 CONFIG_CPU_SW_DOMAIN_PAN
不允许副本从内核空间直接写入用户空间。
解决方案::要么删除此驱动程序,要么修改您的代码。