
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> #include <asm/io.h> #define USE_IOREMAP #define H3_GPIO_BASE (0x01C20800) static volatile unsigned long *gpio_regs = NULL; static int __init ioremap_mod_init(void) { int i = 0; printk(KERN_INFO "ioremap_mod init\n"); #ifdef USE_IOREMAP gpio_regs = (volatile unsigned long *)ioremap(H3_GPIO_BASE, 1024); #else gpio_regs = (volatile unsigned long *)H3_GPIO_BASE; #endif for (i=0; i<3; i++) printk(KERN_INFO "reg[%d] = %lx\n", i, gpio_regs); return 0; } module_init(ioremap_mod_init); static void __exit ioremap_mod_exit(void) { printk(KERN_INFO "ioremap_mod exit\n "); #ifdef USE_IOREMAP iounmap(gpio_regs); #endif } module_exit(ioremap_mod_exit); MODULE_AUTHOR("es-hacker"); MODULE_LICENSE("GPL v2"); 实验结果: 使用了 ioremap() $ insmod ioremapioremap_mod init reg[0] = 71227722 reg[1] = 33322177 reg[2] = 773373 未使用 ioremap(): $ insmod ioremap_mod.koUnable to handle kernel paging request at virtual address 01c20800 pgd = c9ece7c0 [01c20800] *pgd=6ddd7003, *pmd=00000000 Internal error: Oops: 206 [#1] SMP ARM CPU: 1 PID: 1253 Comm: insmod Tainted: G O 4.14.111 #116 Hardware name: sun8i task: ef15d140 task.stack: edc50000 PC is at ioremap_mod_init+0x3c/0x1000 [ioremap_mod] LR is at ioremap_mod_init+0x14/0x1000 [ioremap_mod] 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 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) [<bf5d903c>] (ioremap_mod_init [ioremap_mod]) from [<c0201a70>] (do_one_initcall+0x40/0x16c) [<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) Code: e5953000 e3050048 e1a01004 e34b0f5d (e7932104) ---[ end trace 928c64a33a054308 ]--- Segmentation fault 3. ioremap() 的实现内幕 ioremap() 的实现内幕会涉及到比较多的内存管理的知识,这里我们抛开代码细节简单了解一下原理就好。
函数调用流程: ![]() 总结一下:
|