1. 原因
static void rk3288_clk_init(struct device_node *np) {* c; P) @6 z: c6 \* S rk3288_cru_base = of_iomap(np, 0); [...] D; \% {3 }/ f0 Z5 u' P/ t _1 U }6 h0 x& {6 k1 M 2. ioremap() 实验 实验环境:
实验代码: #include <linux/init.h>#include <linux/module.h>; R: R/ d, A+ V! I7 m' N #include <linux/sched.h> #include <asm/io.h>4 y$ h4 L' x+ l: \6 f 4 [ ?5 R* [; o3 z: r* d& m #define USE_IOREMAP0 T% C6 D/ @, p; i$ f2 R6 B #define H3_GPIO_BASE (0x01C20800) ( P. {1 ] S. X% `# Q' } static volatile unsigned long *gpio_regs = NULL;% r9 ?; d; i' s* D3 q- z 9 r- z+ P% J& H' o2 y" c9 O+ G static int __init ioremap_mod_init(void) { 7 U1 m! y/ o* ~- z: X int i = 0;. h& t+ O4 O9 s. t+ O' F printk(KERN_INFO "ioremap_mod init\n"); + R5 D3 W# o% }" s1 a7 i# z #ifdef USE_IOREMAP. Y$ M: h/ z3 V9 j, Y+ ^; ]# V4 | gpio_regs = (volatile unsigned long *)ioremap(H3_GPIO_BASE, 1024);1 P: Y, |! g- O0 ~$ J #else5 u: j9 M4 N9 U% c- l0 Y gpio_regs = (volatile unsigned long *)H3_GPIO_BASE;) b9 Q9 \1 y. q2 I7 v5 U #endif S- N; C& W5 z7 v( K ; x, q( s& _) F. n. E" ?' ~4 C for (i=0; i<3; i++)$ @4 a0 V+ l, `1 S: r" W6 V/ x9 f" e6 @ printk(KERN_INFO "reg[%d] = %lx\n", i, gpio_regs);) ~: j r# B, x8 H- Q return 0; }' x# v' K( r$ }2 y% A; E- r, L: X+ L, _ module_init(ioremap_mod_init); static void __exit ioremap_mod_exit(void) {6 }3 W5 D% u0 S ~7 L4 t6 P5 u! l4 w printk(KERN_INFO "ioremap_mod exit\n "); #ifdef USE_IOREMAP iounmap(gpio_regs); #endif } 2 ^( K1 z8 s% G5 } module_exit(ioremap_mod_exit); MODULE_AUTHOR("es-hacker"); a' i8 W g8 p) c; _ MODULE_LICENSE("GPL v2"); 实验结果: 使用了 ioremap() $ insmod ioremapioremap_mod init reg[0] = 712277222 S8 L @% b, ] reg[1] = 33322177 reg[2] = 773373% w Y6 j3 y u z, v& a8 l4 D 未使用 ioremap(): $ insmod ioremap_mod.ko: C6 A D: g4 n, f, ]8 @4 w9 p5 |4 x! ~/ g7 d3 I Unable to handle kernel paging request at virtual address 01c20800 pgd = c9ece7c04 \. r; | i7 m6 ~/ K [01c20800] *pgd=6ddd7003, *pmd=00000000# @- x/ K( L+ w Internal error: Oops: 206 [#1] SMP ARM0 w/ s& H$ Q$ y CPU: 1 PID: 1253 Comm: insmod Tainted: G O 4.14.111 #116 Hardware name: sun8i task: ef15d140 task.stack: edc500003 H5 e3 ^3 j4 P; `: } PC is at ioremap_mod_init+0x3c/0x1000 [ioremap_mod] LR is at ioremap_mod_init+0x14/0x1000 [ioremap_mod]$ @. ?+ \9 V7 g. Q( {$ Z: I pc : [<bf5d903c>] lr : [<bf5d9014>] psr: 600e0013 sp : edc51df8 ip : 00000007 fp : 118fa95c" g5 x& A2 C, F4 L" J( l r10: 00000001 r9 : ee7056c0 r8 : bf5d6048 r7 : bf5d6000 r6 : 00000000 r5 : bf5d6200 r4 : 00000000 r3 : 01c20800 r2 : 01c20800 r1 : 00000000 r0 : bf5d5048" m: D$ I4 e- d) B% s1 J9 F 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)$ B- W b0 Z( m0 w2 i" k [<bf5d903c>] (ioremap_mod_init [ioremap_mod]) from [<c0201a70>] (do_one_initcall+0x40/0x16c)& t/ `* V( J+ D+ { [<c0201a70>] (do_one_initcall) from [<c02b20c8>] (do_init_module+0x60/0x1f0) [<c02b20c8>] (do_init_module) from [<c02b1214>] (load_module+0x1b48/0x2250) [<c02b1214>] (load_module) from [<c02b1ad8>] (SyS_finit_module+0x8c/0x9c) [<c02b1ad8>] (SyS_finit_module) from [<c0221f80>] (ret_fast_syscall+0x0/0x4c)0 B4 `) @: L$ j8 L% g7 G& k6 F2 g- ~ Code: e5953000 e3050048 e1a01004 e34b0f5d (e7932104) ---[ end trace 928c64a33a054308 ]---4 X; M8 Y+ E$ i6 e" w Segmentation fault 3. ioremap() 的实现内幕 ioremap() 的实现内幕会涉及到比较多的内存管理的知识,这里我们抛开代码细节简单了解一下原理就好。
函数调用流程:
总结一下:
|
微信公众号
手机版