1. 原因
static void rk3288_clk_init(struct device_node *np) { rk3288_cru_base = of_iomap(np, 0); [...] } 2. ioremap() 实验 实验环境:
实验代码: #include <linux/init.h>#include <linux/module.h> #include <linux/sched.h>. n. @* M1 E' w$ T4 l$ F0 ^- R c4 @ #include <asm/io.h> #define USE_IOREMAP% T: e( M$ y+ h P3 Y) E/ P 7 m. ]) c* a1 w7 A #define H3_GPIO_BASE (0x01C20800) static volatile unsigned long *gpio_regs = NULL; static int __init ioremap_mod_init(void) {! q1 U' t u) s) B int i = 0; printk(KERN_INFO "ioremap_mod init\n");) J3 G6 `! j- p X 1 ]. f" \0 t8 M- U) O8 N #ifdef USE_IOREMAP gpio_regs = (volatile unsigned long *)ioremap(H3_GPIO_BASE, 1024);! E% B2 X9 M9 q; ]5 q8 M #else gpio_regs = (volatile unsigned long *)H3_GPIO_BASE;4 p5 N5 V" `$ x( j2 W7 T2 s9 }& N( e #endif for (i=0; i<3; i++)7 H, L r/ v- {5 O7 N% t+ x printk(KERN_INFO "reg[%d] = %lx\n", i, gpio_regs);8 X7 s/ ]7 z( X3 m" f, P return 0; }, y/ n" `, D4 E! D/ p0 t4 l module_init(ioremap_mod_init);( ?7 p# O( }- J3 f3 @; m2 l ( ^9 K% ~5 a7 `2 p [ static void __exit ioremap_mod_exit(void) {' ~# l, q, `8 p6 t4 W' ]9 Z printk(KERN_INFO "ioremap_mod exit\n ");: X( n( r. [: f" _# G( M 0 p3 c) O. {, k! D #ifdef USE_IOREMAP iounmap(gpio_regs); #endif }" e) B; p. K. A4 q$ y; h module_exit(ioremap_mod_exit); MODULE_AUTHOR("es-hacker");/ q+ q3 Q9 D. M: n% L0 q MODULE_LICENSE("GPL v2"); 实验结果: 使用了 ioremap() $ insmod ioremap* \* G2 J. w9 k* Rioremap_mod init: _6 P1 n1 T- z3 U7 b reg[0] = 712277223 z, n2 O4 t* W% U reg[1] = 333221770 x7 g! v: `; Y& [- B reg[2] = 7733739 q9 M5 j$ b5 [, h6 G 未使用 ioremap(): $ insmod ioremap_mod.ko4 o. V5 h8 l9 V# J' l J' d/ M" n Unable to handle kernel paging request at virtual address 01c20800 pgd = c9ece7c0 [01c20800] *pgd=6ddd7003, *pmd=00000000 Internal error: Oops: 206 [#1] SMP ARM+ f" C" ^, w' m( M CPU: 1 PID: 1253 Comm: insmod Tainted: G O 4.14.111 #116 Hardware name: sun8i3 O& ]; p; N) D" ]' F+ @ task: ef15d140 task.stack: edc500006 k. Z$ e0 ^7 P) ^0 L, H8 g PC is at ioremap_mod_init+0x3c/0x1000 [ioremap_mod]1 J& L5 m. _% |' O* b. x" X LR is at ioremap_mod_init+0x14/0x1000 [ioremap_mod]4 s, o# E5 ?( H- z* R% q pc : [<bf5d903c>] lr : [<bf5d9014>] psr: 600e0013 sp : edc51df8 ip : 00000007 fp : 118fa95c r10: 00000001 r9 : ee7056c0 r8 : bf5d6048 r7 : bf5d6000 r6 : 00000000 r5 : bf5d6200 r4 : 00000000 r3 : 01c20800 r2 : 01c20800 r1 : 00000000 r0 : bf5d5048* J+ ?" I/ O) R/ G2 H; h Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 30c5387d Table: 49ece7c0 DAC: b106c794 Process insmod (pid: 1253, stack limit = 0xedc50210) " A* a8 @4 v4 q6 }1 I+ ~1 t [<bf5d903c>] (ioremap_mod_init [ioremap_mod]) from [<c0201a70>] (do_one_initcall+0x40/0x16c)9 g6 v- F5 `* Y4 Q( D2 O: X [<c0201a70>] (do_one_initcall) from [<c02b20c8>] (do_init_module+0x60/0x1f0)2 }; A/ @" e0 A8 q [<c02b20c8>] (do_init_module) from [<c02b1214>] (load_module+0x1b48/0x2250)0 Q+ }3 X7 _8 _8 Z5 ] [<c02b1214>] (load_module) from [<c02b1ad8>] (SyS_finit_module+0x8c/0x9c)7 d0 k; h. a) B: o5 J. W [<c02b1ad8>] (SyS_finit_module) from [<c0221f80>] (ret_fast_syscall+0x0/0x4c), q5 \7 m, D$ v+ L5 y+ m" c Code: e5953000 e3050048 e1a01004 e34b0f5d (e7932104) ' h1 T, u2 X- E& @0 @ E ---[ end trace 928c64a33a054308 ]---" N+ Z) H# A5 y E9 f5 d Segmentation fault 3. ioremap() 的实现内幕 ioremap() 的实现内幕会涉及到比较多的内存管理的知识,这里我们抛开代码细节简单了解一下原理就好。
函数调用流程:
总结一下:
|
微信公众号
手机版