probe 加载过程 和初始化关系

1、probe 是进程里面跑的吗?

2、probe 可以睡眠吗?睡眠后怎么被再次唤醒并继续执行?

3、probe 调度和执行顺序

4、probe 没跑完 系统怎处理

 

 

probe 是驱动用的探测函数,明白一点 探测的目的。驱动的加载是需要条件的,问了保证系统的精简 ,probe作为一个判断条件,通过检查对应设备是否存在当前硬件系统中,通常是如果存在 就允许加载驱动,当然也有例外,就是有些模块存在但是探测不到,所以会在让probe函数 探测成功。

   我们来看下 通常一个driver驱动会通过subsys_initcall 或者module_init 方式加载。

我们来看下这两个函数的关系。

 

#define module_init(x)    __initcall(x);

 

#define __initcall(fn) device_initcall(fn)

 

#define pure_initcall(fn)        __define_initcall(fn, 0)

#define core_initcall(fn)        __define_initcall(fn, 1)
#define core_initcall_sync(fn)        __define_initcall(fn, 1s)
#define postcore_initcall(fn)        __define_initcall(fn, 2)
#define postcore_initcall_sync(fn)    __define_initcall(fn, 2s)
#define arch_initcall(fn)        __define_initcall(fn, 3)
#define arch_initcall_sync(fn)        __define_initcall(fn, 3s)
#define subsys_initcall(fn)        __define_initcall(fn, 4)
#define subsys_initcall_sync(fn)    __define_initcall(fn, 4s)
#define fs_initcall(fn)            __define_initcall(fn, 5)
#define fs_initcall_sync(fn)        __define_initcall(fn, 5s)
#define rootfs_initcall(fn)        __define_initcall(fn, rootfs)
#define device_initcall(fn)        __define_initcall(fn, 6)
#define device_initcall_sync(fn)    __define_initcall(fn, 6s)
#define late_initcall(fn)        __define_initcall(fn, 7)
#define late_initcall_sync(fn)        __define_initcall(fn, 7s)

 

#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)

 

#define ___define_initcall(fn, id, __sec)            \
    __ADDRESSABLE(fn)                    \
    asm(".section    \"" #__sec ".init\", \"a\"    \n"    \     //.section  ".initcall6.init","a" 
    "__initcall_" #fn #id ":            \n"    \                        // __initcall_ "函数"  "6" :
        ".long    " #fn " - .            \n"    \                           //.long  "函数" -.
        ".previous                    \n");                                //.previous 

 

#define INIT_CALLS_LEVEL(level)                                         \
                __initcall##level##_start = .;                          \
                KEEP(*(.initcall##level##.init))                        \     //.initcall6.init
                KEEP(*(.initcall##level##s.init))                       \

#define INIT_CALLS                                                      \
                __initcall_start = .;                                   \
                KEEP(*(.initcallearly.init))                            \
                INIT_CALLS_LEVEL(0)                                     \
                INIT_CALLS_LEVEL(1)                                     \
                INIT_CALLS_LEVEL(2)                                     \
                INIT_CALLS_LEVEL(3)                                     \
                INIT_CALLS_LEVEL(4)                                     \
                INIT_CALLS_LEVEL(5)                                     \
                INIT_CALLS_LEVEL(rootfs)                                \
                INIT_CALLS_LEVEL(6)                                     \
                INIT_CALLS_LEVEL(7)                                     \
                __initcall_end = .;

 

 

 

我们来看下整个如下这log 

[    0.000000] <0>-(0)[0:swapper]Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] <0>-(0)[0:swapper]Linux version 4.19.127 (nobody@android-build) (Android (6443078 based on r383902) clang version 11.0.1 (https://android.googlesource.com/toolchain/llvm-project b397f81060ce6d701042b782172ed13bee898b79), LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)) #2 SMP PREEMPT Wed Apr 7 09:27:22 CST 2021
[    0.000000] <0>-(0)[0:swapper]Machine model: xxxx
[    0.000000] <0>-(0)[0:swapper]OF: reserved mem: initialized node reserve-memory-sspm_share, compatible id mediatek,reserve-memory-sspm_share
[    0.000000] <0>-(0)[0:swapper]Reserved memory: created CMA memory pool at 0x000000012f000000, size 256 MiB
[    0.000000] <0>-(0)[0:swapper]OF: reserved mem: initialized node ssmr-reserved-cma_memory, compatible id shared-dma-pool
[    0.000000] <0>-(0)[0:swapper]Reserved memory: created DMA memory pool at 0x00000000be000000, size 3 MiB
[    0.000000] <0>-(0)[0:swapper]OF: reserved mem: initialized node wifi-reserve-memory, compatible id shared-dma-pool
[    0.000000] <0>-(0)[0:swapper]ion_reserve_memory_to_camera: name:ion-carveout-heap,base:cfffb000,size:0x5000
[    0.000000] <0>-(0)[0:swapper]OF: reserved mem: initialized node ion-carveout-heap, compatible id mediatek,ion-carveout-heap
[    0.000000] <0>-(0)[0:swapper][memblock]mediatek,minirdump: 0x47d70000 - 0x47d80000 (0x10000)
[    0.000000] <0>-(0)[0:swapper]OF: reserved mem: initialized node mblock-11-minirdump, compatible id mediatek,minirdump
[    0.000000] <0>-(0)[0:swapper]cma: Reserved 16 MiB at 0x00000000ff000000
[    0.000000] <0>-(0)[0:swapper]psci: probing for conduit method from DT.
[    0.000000] <0>-(0)[0:swapper]psci: PSCIv1.0 detected in firmware.
[    0.000000] <0>-(0)[0:swapper]psci: Using standard PSCI v0.2 function IDs
[    0.000000] <0>-(0)[0:swapper]psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] <0>-(0)[0:swapper]psci: SMC Calling Convention v1.0
[    0.000000] <0>-(0)[0:swapper]percpu: Embedded 24 pages/cpu s58776 r8192 d31336 u98304
[    0.000000] <0>-(0)[0:swapper]Detected VIPT I-cache on CPU0

 

 

[   15.766233] <7>.(7)[1:init]init 25: [15720][0]starting service 'vendor.audio-hal'...
[   15.771998] <3>.(3)[1:init]init 25: [15720][0]starting service 'bluetooth-1-0'...
[   15.778482] <1>.(1)[1:init]init 25: [15720][0]starting service 'vendor.cas-hal-1-2'...
[   15.784456] <1>.(1)[1:init]init 25: [15720][0]starting service 'vendor.drm-clearkey-hal-1-3'...
[   15.790797] <2>.(2)[1:init]init 25: [15720][0]starting service 'vendor.drm-widevine-hal-1-3'...
[   15.796519] <2>.(2)[331:init]init 22: [15765][0]ReapLogC PropSet [init.svc_debug_pid.hidl_memory]=[477]15734 

 

进程0和进程1    0:swapper和  1:init    
所有进程的祖先叫做进程0,idle进程或者swapper进程,它是在Linux的初始化阶段从无到有的创建的内核进程(该进程描述符使用的是静态分配的数据结构,其他进程都是动态分配的)。
进程0调用start_kernel()函数初始化内核需要的所有数据结构,激活中断,创建一个进程1 的内核进程(init进程),进程0和进程1 共享每进程的所有内核数据结构。
多处理器中,每个CPU都有自己的进程0。
进程0创建的内核进程执行init()函数初始化内核。然后调用execve()系统调用装入可执行程序init.至此,init为一个普通的进程,且拥有每进程内核数据结构。在系统关闭之前,init一直存在,它创建和监控在操作系统外层的执行的所有进程的活动。

这样*进程调度算法*总能成功的选择要执行的进程。总是至少有一个进程。即swapper进程。PID等于0。只有当没有其他进程处于TASK_RUNNING状态下,调度程序才选择进程0。

我们总结下和probe相关的问题的信息。

前期 swapper 作为系统初始化的 进程载体, 运行会probe 函数,  自然可以创建线程 , 不过一般probe可能比较晚一点,前面先把平台环境配置,后面再探测一些设备,这个时候即使创建也基本不影响swapper 的工作了。 probe 也是系统定义顺序分类执行的,对于同一级别的probe  ,我猜想估计要看 编译器 排的init字段的顺序了。

我们做个实验 再swapper 睡眠几秒   看下是不是  系统再一直等待了。

 

[    2.330419] <3>.(3)[1:swapper/0]usb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
[    2.344275] <5>-(5)[0:swapper/5]Perf order domain is not ready!
[    2.361239] <3>-(3)[1:swapper/0]Perf order domain is not ready!
[    2.378208] <1>-(1)[0:swapper/1]Perf order domain is not ready!
[    2.395181] <7>-(7)[0:swapper/7]Perf order domain is not ready!

[    3.023018] <5>-(5)[0:swapper/5]Perf order domain is not ready!
[    3.039985] <3>-(3)[1:swapper/0]Perf order domain is not ready!
[    3.056954] <1>-(1)[0:swapper/1]Perf order domain is not ready!
[    3.073925] <7>-(7)[0:swapper/7]Perf order domain is not ready!
[    3.090894] <5>-(5)[0:swapper/5]Perf order domain is not ready!

[    4.346573] <1>-(1)[0:swapper/1]Perf order domain is not ready!
[    4.363544] <7>-(7)[0:swapper/7]Perf order domain is not ready!
[    4.380512] <5>-(5)[0:swapper/5]Perf order domain is not ready!
[    4.391988] <3>.(3)[1:swapper/0]usb_probe mac=0xffffff800baf0000, phy=0xffffff800bb10000, irq=243

 

我因我这是多核cpu 出现 swapper其他核心的 打印 但是  再swapper/0   上是再等待,不过至少说明了 ,在前期没有其他任务的时候系统,cpu0 的确 再空跑灯定时器唤醒。

大部分格式都是  kworker /u2:0 或者  kworker /0:0H, 查看资料得知:

内核中有很多kworker,有绑定cpu的和不绑定cpu的,它支持cpu的hotplug时work的迁移。

u:是unbound的缩写,代表没有绑定特定的CPU,kworker /u2:0中的 2 是 work_pool 的ID

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值