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

probe 加载过程 和初始化关系相关推荐

  1. JVM之类的加载过程(三):初始化——>Initialization

    本篇主要讲解类的初始化,也就是上图红框的部分. 类的初始化都做了哪些事呢? 一.初始化: 1.初始化阶段就是执行类构造器方法<clinit>() 的过程. 2.此方法不需要定义,是java ...

  2. 框架源码专题:springIOC的加载过程,bean的生命周期,结合spring源码分析

    文章目录 1.BeanFactory和ApplicationContext的区别? 2. IOC与 Bean的加载过程 ①:初始化容器DefaultListableBeanFactory ②:创建读取 ...

  3. 设备树语法,加载过程和与驱动的关系

    文章目录 一.设备树语法 1.1 简介 1.2 基本数据格式 1.3 一个例子 1.3.1 根节点 2.3.2 CPU 1.3.3 节点名称 1.3.4 设备 1.3.5 status 1.3.6 编 ...

  4. 类的加载过程详解:加载、验证、准备、解析、初始化

    想要弄明白的知识点: 类加载的过程,加载.验证.准备.解析.初始化.每个部分详细描述. 加载阶段读入.class文件,class文件时二进制吗,为什么需要使用二进制的方式? 验证过程是防止什么问题?验 ...

  5. Trembling ! Java类的加载过程详解(加载验证准备解析初始化使用卸载)

    [1]类的生命周期 一个类从加载进内存到卸载出内存为止,一共经历7个阶段: 加载->验证->准备->解析->初始化->使用->卸载 其中,类加载包括5个阶段: 加载 ...

  6. 模块加载过程代码分析1

    一.概述 模块是作为ELF对象文件存放在文件系统中的,并通过执行insmod程序链接到内核中.对于每个模块,系统都要分配一个包含以下数据结构的内存区. 一个module对象,表示模块名的一个以null ...

  7. 面试官:讲讲Spring框架Bean的加载过程

    spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...

  8. Spring component-scan类扫描加载过程

    2019独角兽企业重金招聘Python工程师标准>>> https://github.com/javahongxi 有朋友最近问到了spring加载类的过程,尤其是基于annotat ...

  9. 从JVM看类的加载过程与对象实例化过程

    一. 类的加载过程 1. 类的加载过程大致是个什么过程? 我们编写产生.java文件,这些.java文件经过Java编译器编译成拓展名为.class的文件,.class文件中保存着Java代码经转换后 ...

最新文章

  1. R数据可视化 火山图
  2. codevs——1576 最长严格上升子序列(序列DP)
  3. spring cloud微服务分布式云架构-Gateway入门
  4. SSM始用 @Autowired(required = false)的一个坑
  5. Building COM Objects in C#
  6. 解决Red hat 5.4的中文问题
  7. 修改oracle归档目录和大小
  8. java linux root权限管理_新的 Linux sudo 漏洞使本地用户获得 root 权限
  9. c语言十六进制转换加H,c语言十六进制和十进制间的转换.docx
  10. 计算机网络阅读报告,计算机网络实验二报告
  11. named 委派与转发
  12. Django Form 详解
  13. 怎么将kux格式视频转换成MP4格式
  14. Java文件操作——简单文件搜索
  15. 能上QQ不能上网的解决方法
  16. 【lphtw】第三弹笔记ex24-ex35
  17. 从动态性、并发性、独立性和异步性上比较进程和程序。
  18. CC1310 WOR如何设置几秒钟醒一次
  19. java微信小程序调用支付接口
  20. Windows Server 2008使用无线网卡上网

热门文章

  1. 软件生命周期模型—W模型
  2. 关于sklearn库的安装
  3. Django之jango框架 及 APP
  4. 【GT-Android开发之音量调节】
  5. Flask-WTF 示例
  6. 一文让你马上了解机器学习在马蜂窝酒店聚合中的应用初探
  7. java web自学视频网盘_WEB学习路线2020完整版(附视频教程+网盘下载地址)
  8. 编写Java程序实现阶乘和递归
  9. Java根据word模板生成word文档并转成PDF文件
  10. 怎么判断噎到没噎到_宝宝噎着好了怎么判断