注册 | 登录

Unable to handle kernel paging request at virtual address 的解决办法

warmshepherd 分享于



推荐:Unable to handle kernel paging request at virtual address

kernel里调试时写alc5642时机器会时而重启,终于抓到了log,如下: Unable to handle kernel paging request at virtual address xxxx 网上一搜,如下: Restarti


root@WK:mknod -m 600 /dev/dram_driver c 221 1
in dram_open!
Unable to handle kernel paging request at virtual address c4881fff
pgd = c3e2c000
[c4881fff] *pgd=23c18011, *pte=300010a3, *ppte=30001552
Internal error: Oops: 803 [#1] PREEMPT
Modules linked in: dram_driver [last unloaded: dram_driver]
CPU: 0    Tainted: G        W  ( #9)
PC is at dram_open+0x68/0x84 [dram_driver]
LR is at 0x0
pc : [<bf0000dc>]    lr : [<00000000>]    psr: 60000013
sp : c3e43e20  ip : 00000000  fp : c3e43e2c
r10: c3a98800  r9 : c3e42000  r8 : c3e92280
r7 : 00000000  r6 : c3a74e40  r5 : c3e90d80  r4 : 00000001
r3 : 00002000  r2 : 00000000  r1 : ffffffe0  r0 : c4881fff
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: 23e2c000  DAC: 00000015
Process dram_test (pid: 914, stack limit = 0xc3e42268)
Stack: (0xc3e43e20 to 0xc3e44000)
3e20: c3e43e5c c3e43e30 c0089f9c bf000084 c3e43e6c 00000001 c3e43e5c 00000000
3e40: c3e92280 c3a74e40 c0089dc0 c3d2e980 c3e43e84 c3e43e60 c0084d00 c0089dd0
3e60: c3e92280 c3e43ed8 ffffff9c 00000001 c3dd9000 00000000 c3e43ea4 c3e43e88
3e80: c0084e48 c0084b7c 00000000 c3e43ed8 ffffff9c 00000000 c3e43f64 c3e43ea8
3ea0: c0092850 c0084e20 00000001 c3e43eb8 c002829c c0052698 400d5000 c039bea0
3ec0: becdce9c 00000000 00000004 00000017 00000000 ffffffff c3d2e980 c3a98800

3f60: c0084a68 c0092500 00000000 00000000 00000000 00000000 00000000 000083bc
3f80: 00000005 c0021ca8 c3e43fa4 c3e43f98 c0084b30 c0084a20 00000000 c3e43fa8
3fa0: c0021b00 c0084b1c 00000000 00000000 0000870c 00000000 becdce9c 00000000
3fc0: 00000000 00000000 000083bc 00000005 00000000 00000000 40024000 becdcd44
3fe0: 00000000 becdcd28 000084b0 400d5b0c 60000010 0000870c 00000000 00000000
[<bf000074>] (dram_open+0x0/0x84 [dram_driver]) from [<c0089f9c>] (chrdev_open+0
[<c0089dc0>] (chrdev_open+0x0/0x200) from [<c0084d00>] (__dentry_open+0x194/0x2a
 r8:c3d2e980 r7:c0089dc0 r6:c3a74e40 r5:c3e92280 r4:00000000
[<c0084b6c>] (__dentry_open+0x0/0x2a4) from [<c0084e48>] (nameidata_to_filp+0x38
[<c0084e10>] (nameidata_to_filp+0x0/0x50) from [<c0092850>] (do_filp_open+0x360/
[<c00924f0>] (do_filp_open+0x0/0x768) from [<c0084a68>] (do_sys_open+0x58/0xe8)
[<c0084a10>] (do_sys_open+0x0/0xe8) from [<c0084b30>] (sys_open+0x24/0x28)
 r8:c0021ca8 r7:00000005 r6:000083bc r5:00000000 r4:00000000
[<c0084b0c>] (sys_open+0x0/0x28) from [<c0021b00>] (ret_fast_syscall+0x0/0x2c)
Code: e1a03803 e1a03823 e3a02000 e3530a02 (e0c020b1)
---[ end trace 815ab7660b1b7e73 ]---
Segmentation fault

推荐:Unable to handle kernel paging request at virtual address f600030a

  今天在移植linux操作系统时,将编译好的的linux内核下载到开发板上莫名其妙的提示(我的开发板是cs8900a的驱动): Copy linux kernel from 0x00240000 to 0x300

初步分析可能是我在内核中操作双口RAM时没有正确读写!Segmentation fault错误一般是由于内存操作越限造成的,修改过后果然解决了此问题。



Oops Messages

Oops 消息

    Most bugs show themselves in NULL pointer dereferences or by the use of other incorrect pointer values. The usual outcome of such bugs is an oops message.


    Almost any address used by the processor is a virtual address and is mapped to physical addresses through a complex structure of page tables (the exceptions are physical addresses used with the memory management subsystem itself). When an invalid pointer is dereferenced, the paging mechanism fails to map the pointer to a physical address, and the processor signals a page fault to the operating system. If the address is not valid, the kernel is not able to "page in" the missing address; it (usually) generates an oops if this happens while the processor is in supervisor mode.


     An oops displays the processor status at the time of the fault, including the contents of the CPU registers and other seemingly incomprehensible information. The message is generated by printk statements in the fault handler (arch/*/kernel/traps.c) and is dispatched as described earlier in Section 4.2.1).


     Let's look at one such message. Here's what results from dereferencing a NULL pointer on a PC running Version 2.6 of the kernel. The most relevant information here is the instruction pointer (EIP), the address of the faulty instruction.


Unable to handle kernel NULL pointer dereference at virtual address 00000000 printing eip: d083a064 Oops: 0002 [#1] SMP CPU: 0 EIP: 0060:[] Not tainted EFLAGS: 00010246 (2.6.6) EIP is at faulty_write+0x4/0x10 [faulty] eax: 00000000 ebx: 00000000 ecx: 00000000 edx: 00000000 esi: cf8b2460 edi: cf8b2480 ebp: 00000005 esp: c31c5f74 ds: 007b es: 007b ss: 0068 Process bash (pid: 2086, threadinfo=c31c4000 task=cfa0a6c0) Stack: c0150558 cf8b2460 080e9408 00000005 cf8b2480 00000000 cf8b2460 cf8b2460 fffffff7 080e9408 c31c4000 c0150682 cf8b2460 080e9408 00000005 cf8b2480 00000000 00000001 00000005 c0103f8f 00000001 080e9408 00000005 00000005 Call Trace: [] vfs_write+0xb8/0x130 [] sys_write+0x42/0x70 [] syscall_call+0x7/0xb Code: 89 15 00 00 00 00 c3 90 8d 74 26 00 83 ec 0c b8 00 a6 83 d0

     This message was generated by writing to a device owned by the faulty module, a module built deliberately to demonstrate failures. The implementation of the write method of faulty.c is trivial:


ssize_t faulty_write (struct file *filp, const char _ _user *buf, size_t count, loff_t *pos)


     /* make a simple fault by dereferencing a NULL pointer */

     *(int *)0 = 0;

     return 0;


     As you can see, what we do here is dereference a NULL pointer. Since 0 is never a valid pointer value, a fault occurs, which the kernel turns into the oops message shown earlier. The calling process is then killed.


The faulty module has a different fault condition in its read implementation: faulty


ssize_t faulty_read(struct file *filp, char _ _user *buf, size_t count, loff_t *pos)


     int ret;

     char stack_buf[4];

     /* Let's try a buffer overflow */

     memset(stack_buf, 0xff, 20);

     if (count > 4)

         count = 4;

     /* copy 4 bytes to the user */

     ret = copy_to_user(buf, stack_buf, count);

     if (!ret)

         return count;

     return ret;


     This method copies a string into a local variable; unfortunately, the string is longer than the destination array. The resulting buffer overflow causes an oops when the function returns. Since the return instruction brings the instruction pointer to nowhere land, this kind of fault is much harder to trace, and you can get something such as the following:


EIP: 0010:[<00000000>] Unable to handle kernel paging request at virtual address ffffffff printing eip: ffffffff Oops: 0000 [#5] SMP CPU: 0 EIP: 0060:[] Not tainted EFLAGS: 00010296 (2.6.6) EIP is at 0xffffffff eax: 0000000c ebx: ffffffff ecx: 00000000 edx: bfffda7c esi: cf434f00 edi: ffffffff ebp: 00002000 esp: c27fff78 ds: 007b es: 007b ss: 0068 Process head (pid: 2331, threadinfo=c27fe000 task=c3226150) Stack: ffffffff bfffda70 00002000 cf434f20 00000001 00000286 cf434f00 fffffff7 bfffda70 c27fe000 c0150612 cf434f00 bfffda70 00002000 cf434f20 00000000 00000003 00002000 c0103f8f 00000003 bfffda70 00002000 00002000 bfffda70 Call Trace: [] sys_read+0x42/0x70 [] syscall_call+0x7/0xb Code: Bad EIP value.

     In this case, we see only part of the call stack (vfs_read and faulty_read are missing), and the kernel complains about a "bad EIP value." That complaint, and the offending address (ffffffff) listed at the beginning are both hints that the kernel stack has been corrupted.


     In general, when you are confronted with an oops, the first thing to do is to look at the location where the problem happened, which is usually listed separately from the call stack. In the first oops shown above, the relevant line is:


EIP is at faulty_write+0x4/0x10 [faulty]

     Here we see that we were in the function faulty_write , which is located in the faulty module (which is listed in square brackets). The hex numbers indicate that the instruction pointer was 4 bytes into the function, which appears to be 10 (hex) bytes long. Often that is enough to figure out what the problem is.


      If you need more information, the call stack shows you how you got to where things fell apart. The stack itself is printed in hex form; with a bit of work, you can often determine the values of local variables and function parameters from the stack listing. Experienced kernel developers can benefit from a certain amount of pattern recognition here; for example, if we look at the stack listing from the faulty_read oops:


Stack: ffffffff bfffda70 00002000 cf434f20 00000001 00000286 cf434f00 fffffff7 bfffda70 c27fe000 c0150612 cf434f00 bfffda70 00002000 cf434f20 00000000 00000003 00002000 c0103f8f 00000003 bfffda70 00002000 00002000 bfffda70

    The ffffffff at the top of the stack is part of our string that broke things. On the x86 architecture, by default, the user-space stack starts just below 0xc0000000; thus, the recurring value 0xbfffda70 is probably a user-space stack address; it is, in fact, the address of the buffer passed to the read system call, replicated each time it is passed down the kernel call chain. On the x86 (again, by default), kernel space starts at 0xc0000000, so values above that are almost certainly kernel-space addresses, and so on.


    Finally, when looking at oops listings, always be on the lookout for the "slab poisoning" values discussed at the beginning of this chapter. Thus, for example, if you get a kernel oops where the offending address is 0xa5a5a5a5, you are almost certainly forgetting to initialize dynamic memory somewhere.

    最后要注意的一点是,当你查看oops信息时,始终要留意本章开始时讨论的“slab poisoning”的值。因此,如果一条内核oops中出现了讨厌的地址值0xa5a5a5a5,那么你肯定是在什么地方忘记初始化动态分配的内存了。

    Please note that you see a symbolic call stack (as shown above) only if your kernel is built with the CONFIG_KALLSYMS option turned on. Otherwise, you see a bare, hexadecimal listing, which is far less useful until you have decoded it in other ways.


推荐:Unable to handle kernel paging request at virtual address错误的解决

今天写了一个触摸屏的驱动程序,在卸载模块时出现oops,主要信息如下  Unable to handle kernel paging request at virtual address cc33cc33 …… pc is at kfre

 今天想正式开始编写各底层硬件的驱动程序,首先是双口RAM的,结果吓一一大跳,居然出现如下这么多的问题,这就是传说中的oops消息: root@WK:mknod -m 600 /dev/dram_driver c 221 1 root@WK:.








您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱