Linux内核---45.关于initcall
来源:互联网 发布:ubuntu配置网络 编辑:程序博客网 时间:2024/05/17 07:47
1. initcall的执行过程
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
在init/main.c中
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
--> do_initcalls
在init/main.c中
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
那么__early_initcall_end又是从哪里来的呢?这个先放一下.
当此处打印出c000e620时,
在System.map中查看-->c000e620 t s3c64xx_init_irq_eint
就是要执行s3c64xx_init_irq_eint这个函数了
2. initcall_start initcall_end等是从哪里来的
在arch/arm/kernel/vmlinux.lds中,有
从上面可以看出在 __early_initcall_end与__initcall_end之间的就是所以的initcall(0-7)
3. 如何将函数放在initcall_start与initcall_end之间的?
以s3c64xx_init_irq_eint为例:
在arch/arm/mach-s3c64xx/irq-eint.c中
宏的定义在include/linux/init.h中
又一个宏:
将arch_initcall(s3c64xx_init_irq_eint);展开后:
static initcall_t __initcall_s3c64xx_init_irq_eint3 __used __attribute__((__section__(".initcall" 3 ".init"))) = s3c64xx_init_irq_eint
就是把s3c64xx_init_irq_eint这个函数放在了.initcall3.init这个section中
注意:这个MODULE宏很奇怪
这里的MODULE都是没有定义的,但是编译出ko来用insmode加载时,MODULE都是定义的
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
在init/main.c中
- static void __init do_basic_setup(void)
- {
- cpuset_init_smp();
- usermodehelper_init();
- init_tmpfs();
- driver_init();
- init_irq_proc();
- do_ctors();
- do_initcalls(); //终于看到主角了
- }
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
--> do_initcalls
在init/main.c中
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
- static void __init do_initcalls(void)
- {
- initcall_t *fn;
- for (fn = __early_initcall_end; fn < __initcall_end; fn++)
- do_one_initcall(*fn);
- }
- int __init_or_module do_one_initcall(initcall_t fn)
- {
- printk(KERN_INFO "fn=%p\n",fn); //自己加的打印
- ret = fn(); //这个fn就是一个函数地址
- }
在System.map中查看-->c000e620 t s3c64xx_init_irq_eint
就是要执行s3c64xx_init_irq_eint这个函数了
2. initcall_start initcall_end等是从哪里来的
在arch/arm/kernel/vmlinux.lds中,有
- 437 __initcall_start = .;
- *(.initcallearly.init)
- __early_initcall_end = .;
- *(.initcall0.init) *(.initcall0s.init)
- *(.initcall1.init) *(.initcall1s.init)
- *(.initcall2.init) *(.initcall2s.init)
- *(.initcall3.init) *(.initcall3s.init)
- *(.initcall4.init) *(.initcall4s.init)
- *(.initcall5.init) *(.initcall5s. init)
- *(.initcallrootfs.init)
- *(.initcall6.init) *(.initcall6s.init)
- *(.initcall7.init) *(.initcall7s.init)
- __initcall_end = .
3. 如何将函数放在initcall_start与initcall_end之间的?
以s3c64xx_init_irq_eint为例:
在arch/arm/mach-s3c64xx/irq-eint.c中
- static int __init s3c64xx_init_irq_eint(void)
- {
- 中间省略
- return 0;
- }
- arch_initcall(s3c64xx_init_irq_eint); //在函数的最后有这么个宏
- #define pure_initcall(fn) __define_initcall("0",fn,0)
- #define core_initcall(fn) __define_initcall("1",fn,1)
- #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
- #define postcore_initcall(fn) __define_initcall("2",fn,2)
- #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
- #define arch_initcall(fn) __define_initcall("3",fn,3)
- #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
- #define subsys_initcall(fn) __define_initcall("4",fn,4)
- #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
- #define fs_initcall(fn) __define_initcall("5",fn,5)
- #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
- #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
- #define device_initcall(fn) __define_initcall("6",fn,6)
- #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
- #define late_initcall(fn) __define_initcall("7",fn,7)
- #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
- #define __initcall(fn) device_initcall(fn)
- #define __define_initcall(level,fn,id) \
- static initcall_t __initcall_##fn##id __used \
- __attribute__((__section__(".initcall" level ".init"))) = fn
static initcall_t __initcall_s3c64xx_init_irq_eint3 __used __attribute__((__section__(".initcall" 3 ".init"))) = s3c64xx_init_irq_eint
就是把s3c64xx_init_irq_eint这个函数放在了.initcall3.init这个section中
注意:这个MODULE宏很奇怪
这里的MODULE都是没有定义的,但是编译出ko来用insmode加载时,MODULE都是定义的
0 0
- Linux内核---45.关于initcall
- Linux内核中的初始化initcall
- 理解内核initcall
- linux kernel initcall函数
- Linux中的initcall
- Linux中的initcall
- linux initcall机制
- linux initcall机制
- linux initcall机制
- linux initcall机制
- Linux内核与驱动开发学习总结:initcall 和contain_of宏(十)
- Linux中的各种initcall总结
- initcall在内核中的调用顺序
- How the Linux Kernel initcall Mechanism Works
- 关于 linux 内核编译
- 关于linux内核学习
- 关于Linux内核学习
- 关于Linux内核学习
- c 语言中宏定义和定义全局变量的区别
- Linux内核---44.关于中断号与中断引脚
- First Bad Version
- java的安装和配置
- Objective-C规范注释心得——同时兼容appledoc(docset、html)与doxygen(html、pdf)的文档生成
- Linux内核---45.关于initcall
- 各种排序算法的场景以及c++实现(插入排序,希尔排序,冒泡排序,快速排序,选择排序,归并排序)
- YUYV码流中提取单帧并转为RGB图片
- echarts3各种配置项
- setbuf()
- POJ1011
- Linux内核---46.关于mem_map
- poj滑雪(记忆化搜索)
- C 语言的程序的编辑,编译和运行