当前位置: 首页 > article >正文

别光看init.rc了!/system、/vendor、/odm下那些*.rc文件,Android 11是怎么决定谁先谁后的?

Android 11启动脚本加载机制深度解析从/system到/odm的优先级博弈在Android系统启动过程中init进程扮演着至关重要的角色。作为Linux内核启动后的第一个用户空间进程它负责初始化系统环境、挂载文件系统、启动关键守护进程等一系列基础工作。而这一切行为的剧本就写在各种.rc配置文件中。随着Android系统架构的演进特别是从Android 8.0引入Treble项目以来系统模块化程度不断提高.rc文件也从传统的单一init.rc发展为分散在/system、/vendor、/odm等多个目录下的模块化配置集合。本文将深入剖析Android 11中这些分散的.rc文件加载顺序背后的设计哲学与实现细节。1. Android启动脚本的模块化演进Android系统的模块化设计并非一蹴而就。在早期版本中系统启动配置高度集中几乎所有启动逻辑都被写在单个init.rc文件中。这种设计虽然简单直接但随着Android生态的扩张其局限性日益明显耦合度过高芯片厂商、设备制造商和系统开发者都需要修改同一份配置文件维护困难任何一方的修改都可能影响其他模块的正常工作升级障碍系统框架和硬件驱动无法独立更新为解决这些问题Google在Android 8.0中引入了Treble项目核心思想就是通过接口标准化实现框架与驱动的解耦。这一架构变革直接影响了init系统的设计# 传统Android启动脚本布局 /init.rc /init.{hardware}.rc # Android 8.0的模块化布局 /system/etc/init/ # 核心系统服务 /vendor/etc/init/ # SoC厂商定制 /odm/etc/init/ # 设备制造商定制这种模块化布局带来了几个显著优势职责分离各层级开发者只需关注自己负责的模块并行开发不同团队可以独立开发和测试自己的启动脚本安全隔离系统核心部分与硬件定制部分相互隔离2. 多目录.rc文件的加载顺序规则在Android 11中init进程通过LoadBootScripts()函数加载所有.rc文件。这个函数的执行逻辑决定了不同目录下脚本的加载顺序进而影响系统服务的启动序列。让我们深入分析这一过程的关键细节。2.1 基础加载流程LoadBootScripts()的加载顺序遵循严格的层级规则主init.rc文件首先加载/system/etc/init/hw/init.rc这是系统最基础的启动配置系统核心脚本按字母顺序加载/system/etc/init/目录下的所有.rc文件厂商定制脚本按字母顺序加载/vendor/etc/init/目录下的文件设备专属脚本最后按字母顺序加载/odm/etc/init/目录下的文件这一顺序体现了Android系统的分层设计理念越基础的组件越先加载越具体的定制越后加载。这种金字塔式的加载顺序确保了高层模块可以覆盖或扩展底层模块的行为。2.2 字母顺序规则的实现细节在每个目录内部.rc文件的加载顺序由文件名决定具体规则如下纯字母比较完全按照文件名ASCII码值排序例如a.rc会先于b.rc加载数字优先数字开头的文件排在字母开头的文件之前如10mount.rc先于netd.rc大小写敏感大写字母排在小写字母之前Z.rc先于a.rc这种设计允许开发者通过精心命名来控制脚本的执行顺序。例如对于有依赖关系的服务00-setup.rc # 基础环境配置 10-network.rc # 网络相关服务 20-storage.rc # 存储服务依赖网络提示虽然字母顺序提供了基本的控制手段但过度依赖文件名来控制顺序会导致代码难以维护。最佳实践是使用init语言的import和trigger机制来显式声明依赖关系。2.3 import语句的作用域与限制在.rc文件中import语句用于引入其他配置文件其行为有几点需要注意非递归加载import目录时不会递归处理子目录相对路径基于当前文件所在目录解析作用域隔离import的文件中的定义不会影响父文件的作用域一个典型的import使用示例# 在/system/etc/init/netd.rc中 import /vendor/etc/init/netd-vendor.rc # 加载厂商定制配置import的执行时机是在解析包含它的.rc文件时立即处理这意味着import的文件会在父文件继续解析前被完整加载。3. 启动脚本冲突解决策略在多模块协作的场景下不同目录中的.rc文件可能定义相同的服务或动作这就产生了冲突的可能性。Android系统通过以下几种机制来解决或规避冲突3.1 服务定义的覆盖规则当不同.rc文件中定义了同名服务时遵循后加载者有效的原则定义位置能否被覆盖覆盖者/system/etc/init/是vendor或odm/vendor/etc/init/是odm/odm/etc/init/否-这种覆盖是完整的即后加载的服务定义会完全替代先前的定义而不是合并。3.2 动作(action)的合并策略与服务不同同名action不会相互覆盖而是会合并它们的命令序列。合并后的执行顺序遵循以下规则同一文件中的action按出现顺序执行不同文件中的action按文件加载顺序执行相同trigger所有匹配的action都会被执行这种设计使得不同模块可以为同一系统事件(如boot-completed)添加自己的初始化逻辑。3.3 常见冲突场景与解决方案在实际开发中经常会遇到以下几类冲突案例1服务属性冲突# /vendor/etc/init/my_daemon.rc service my_daemon /vendor/bin/my_daemon class core user system # /odm/etc/init/my_daemon.rc service my_daemon /odm/bin/my_daemon class late_start user odm这种情况下最终生效的是odm版本的服务定义包括其可执行路径和所有属性。案例2动作命令顺序敏感# /system/etc/init/init.rc on boot setprop sys.example.prop 1 # /vendor/etc/init/vendor.rc on boot setprop sys.example.prop 2两个action都会执行但执行顺序取决于文件加载顺序。要确保特定值最终生效可以使用on property:sys.example.prop* if ${sys.example.prop} 1 setprop sys.example.prop 2 fi4. 实战优化启动顺序的最佳实践理解了.rc文件的加载机制后我们可以据此优化系统启动流程。以下是针对不同角色的实践建议。4.1 对于系统开发者合理划分启动阶段使用明确的trigger区分不同初始化阶段on early-init # 最早阶段仅基本文件系统可用 on init # 设备节点创建完成 on late-init # 大多数服务已启动模块化组织脚本按功能而非按加载顺序组织文件/system/etc/init/ ├── graphics.rc ├── network.rc └── storage.rc提供清晰的接口通过属性变化通知其他模块on property:vendor.display.ready1 start surfaceflinger4.2 对于芯片厂商最小化修改原则只覆盖必须定制的部分善用import机制复用系统定义而非完全重写import /system/etc/init/netd.rc service netd /vendor/bin/netd # 仅覆盖可执行路径命名空间隔离使用vendor前缀避免冲突setprop vendor.mtk.special.feature 14.3 对于设备制造商延迟初始化策略将非关键初始化放到后期on property:sys.boot_completed1 start my_custom_service硬件特定配置使用硬件抽象层(HAL)而非直接修改.rc调试工具集成添加调试服务但默认禁用service debug_daemon /odm/bin/debug_daemon disabled oneshot5. 调试技巧与问题排查当启动顺序出现问题时以下工具和技巧可以帮助快速定位5.1 日志分析工具# 查看init进程详细日志 adb logcat -s init # 过滤特定服务的启动信息 adb logcat | grep -E init:.*service_name5.2 属性调试法通过检查启动过程中的属性变化来追踪初始化进度# 监控属性变化 adb shell watch -n 0.5 getprop # 手动触发特定阶段 adb shell setprop ctl.start boot-completed5.3 启动时间分析使用系统内置的工具测量各阶段耗时adb shell bootchart adb shell dumpsys boot_progress5.4 常见问题症状与对策症状可能原因解决方案服务反复重启依赖未就绪添加适当的property trigger启动顺序不稳定文件名排序不可靠改用显式trigger控制部分配置未生效被后续文件覆盖检查加载顺序和覆盖规则在解决一个实际的启动顺序问题时我曾遇到vendor定义的网络服务在odm中需要额外配置的情况。通过分析发现由于odm文件加载最晚直接覆盖了vendor的定义导致部分配置丢失。最终的解决方案是在odm文件中使用import引入vendor配置然后仅修改必要的参数而非完全重写服务定义。

相关文章:

别光看init.rc了!/system、/vendor、/odm下那些*.rc文件,Android 11是怎么决定谁先谁后的?

Android 11启动脚本加载机制深度解析:从/system到/odm的优先级博弈 在Android系统启动过程中,init进程扮演着至关重要的角色。作为Linux内核启动后的第一个用户空间进程,它负责初始化系统环境、挂载文件系统、启动关键守护进程等一系列基础工…...

StructBERT零样本分类-中文-base知识注入:融合领域词典提升专业文本分类精度

StructBERT零样本分类-中文-base知识注入:融合领域词典提升专业文本分类精度 1. 模型介绍与核心优势 StructBERT零样本分类是阿里达摩院专门为中文场景开发的文本分类模型,基于强大的StructBERT预训练架构构建。这个模型最大的特点就是"零样本&qu…...

Qwen3-32B-Chat镜像快速上手:RTX4090D优化版,开箱即用无需复杂配置

Qwen3-32B-Chat镜像快速上手:RTX4090D优化版,开箱即用无需复杂配置 1. 镜像概述与核心优势 Qwen3-32B-Chat是阿里云推出的高性能大语言模型私有部署解决方案,专为RTX 4090D显卡优化。相比通用部署方案,这个镜像有三大突出优势&a…...

NVIDIA Jetson AGX Orin上OpenPCDet环境搭建避坑指南:从CUDA配置到PointRCNN运行

NVIDIA Jetson AGX Orin上OpenPCDet环境搭建全流程实战:从CUDA配置到PointRCNN部署 在边缘计算设备上部署3D目标检测模型正成为自动驾驶和机器人导航领域的关键需求。NVIDIA Jetson AGX Orin凭借其强大的AI算力和能效比,成为这类场景的理想选择。本文将带…...

从零到一:用P、V原语解决经典并发问题(附实战代码解析)

1. 为什么我们需要P、V原语? 想象一下周末去网红餐厅吃饭的场景。当服务员告诉你"现在没有空位,请取号等待"时,你手中的号码牌其实就是一种信号量——它既记录了排队人数(同步),也确保了叫号时不…...

告别“恼~”时刻:手把手教你为Qt Kit补全缺失的MSVC编译器

1. 问题现象:当Qt Creator找不到MSVC编译器时 刚安装完Qt Creator,兴冲冲地准备新建项目,却在构建套件(Kit)配置里死活找不到MSVC编译器选项。这个场景我太熟悉了——去年帮团队搭建Qt开发环境时,十个同事里…...

Ostrakon-VL-8B效果集锦:从快餐到宴席,多场景识别实录

Ostrakon-VL-8B效果集锦:从快餐到宴席,多场景识别实录 最近在折腾一些视觉相关的项目,正好深度体验了一下Ostrakon-VL-8B这个模型。说实话,一开始没抱太大期望,毕竟现在各种视觉语言模型层出不穷,但用下来…...

手把手教你调TSL1401线性CCD的曝光时间,让STM32智能小车循迹更稳

STM32智能小车CCD循迹曝光时间优化实战指南 从理论到实践:曝光时间对CCD循迹的影响机制 调试过TSL1401线性CCD的开发者都深有体会——曝光时间这个看似简单的参数,实际影响着整个循迹系统的稳定性。当小车在赛道上出现"蛇形走位"或突然丢线时&…...

Phi-3-mini-4k-instruct-gguf生产环境部署:supervisor服务管理与稳定性优化

Phi-3-mini-4k-instruct-gguf生产环境部署:supervisor服务管理与稳定性优化 1. 项目背景与模型介绍 Phi-3-mini-4k-instruct-gguf是微软推出的轻量级文本生成模型,属于Phi-3系列中的高效版本。这个GGUF格式的模型特别适合生产环境部署,主要…...

保姆级教程:用Python+Requests搞定携程汽车票数据爬取(附完整代码与常见报错解决)

Python爬虫实战:高效获取汽车票数据的完整解决方案 最近在帮朋友处理一个需求时,遇到了一个典型的爬虫场景:需要批量查询多个城市之间的汽车票班次信息。这个任务看似简单,但实际操作中会遇到各种技术挑战,特别是对于刚…...

微信小程序点餐系统核心交互与状态管理实战

1. 微信小程序点餐系统的核心交互设计 点餐系统作为餐饮行业数字化转型的重要入口,其交互体验直接影响用户下单转化率。在实际开发中,我发现很多新手开发者容易陷入"功能堆砌"的误区,而忽视了真正的用户体验优化。下面分享几个经过…...

GitHub YOLOv5 实战入门:从零部署到首次推理运行

1. 从零开始:YOLOv5环境搭建与源码获取 第一次接触YOLOv5可能会觉得有点懵,但别担心,跟着我的步骤来,保证你能顺利跑通第一个目标检测demo。我去年第一次部署YOLOv5时也踩了不少坑,现在把这些经验都总结给你。 YOLOv5是…...

AI人工智能和数字孪生赋能智慧城市生命线数字化监测平台设计方案 :五层分层解耦的数字孪生架构、深度融合BIM与GIS技术

本方案构建AI与数字孪生驱动的城市生命线监测平台,融合物联网、5G、BIM/GIS及智能算法,实现供水、燃气等基础设施的实时感知、风险预警与应急联动,形成“感知-分析-决策”闭环,全面提升城市安全韧性与治理效能。 标准体系&#xf…...

中科蓝讯AB536x/530x串口引脚映射实战:手把手教你配置PA6/PA7做UART1通信

中科蓝讯AB536x/530x串口引脚映射实战:从寄存器解析到PA6/PA7配置全流程 最近在调试中科蓝讯AB536x系列芯片时,发现其UART引脚复用功能比想象中更灵活——同一组物理引脚通过寄存器配置可切换多种通信角色。这种设计虽然提升了硬件布局的灵活性&#xff…...

从源码层面理解Cookie:一次Chromium编译实战,揭秘浏览器会话保持的底层逻辑

从源码层面理解Cookie:一次Chromium编译实战,揭秘浏览器会话保持的底层逻辑 在数字世界的每一次跳转背后,都有一串看不见的"记忆碎片"在默默工作——这就是Cookie。对于普通用户而言,它可能只是登录状态的保持者&#x…...

拯救者笔记本电池健康完整策略:LenovoLegionToolkit充电控制实战方案

拯救者笔记本电池健康完整策略:LenovoLegionToolkit充电控制实战方案 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit …...

别再折腾了!VS2019配置Eigen库最稳的一步到位指南(附常见报错解决方案)

VS2019与Eigen库深度整合:从配置陷阱到高效开发实战 引言:为什么你的Eigen配置总是出问题? 在C数值计算领域,Eigen库以其卓越的性能和优雅的API设计赢得了广大开发者的青睐。然而,许多开发者在Visual Studio 2019环境中…...

【51单片机实战】智能倒车雷达系统:从超声波测距到分级报警的完整实现

1. 项目背景与核心功能 倒车雷达是汽车电子中非常实用的安全装置,对于电子工程专业的学生来说,用51单片机实现一个简易版的倒车防撞系统是个不错的练手项目。这个系统主要利用超声波测距原理,通过LED灯和蜂鸣器实现分级报警,还能保…...

逆向解析q某音乐API:从sign生成到vKey获取的完整链路剖析

1. 初探q音乐API的加密机制 第一次接触q音乐API时,我发现获取歌曲资源链接需要两个关键参数:vKey和sign。这就像去银行取钱需要密码和身份证一样,缺一不可。但问题是,这两个参数都不是直接暴露在前端代码里的,而是经过…...

别再为小目标检测发愁了!手把手教你给YOLOv8模型加个P2层(附完整代码和调参技巧)

别再为小目标检测发愁了!手把手教你给YOLOv8模型加个P2层(附完整代码和调参技巧) 在工业质检、遥感影像分析等场景中,小目标检测一直是计算机视觉领域的痛点。当目标像素不足3232时,传统检测模型的召回率往往断崖式下跌…...

Halcon实战:用intensity算子5分钟搞定图像区域灰度分析(含Mean和Deviation详解)

Halcon实战:5分钟掌握图像区域灰度分析的核心技巧 在工业质检和缺陷检测领域,快速准确地评估图像区域的灰度特性是每个工程师的必备技能。Halcon作为机器视觉领域的标杆工具,其intensity算子能以惊人的效率完成这项任务——但很多初学者往往止…...

SDC时钟约束实战:从基础定义到高级时序控制

1. SDC时钟约束基础入门 刚接触数字芯片设计时,我最头疼的就是时序收敛问题。明明RTL仿真都通过了,综合后却总是出现时序违例。后来才发现,SDC时钟约束才是真正的幕后黑手。它就像交通信号灯,告诉EDA工具各个时钟信号应该如何协调…...

[FPGA] 高速数据转换系统实战:DDS驱动并行ADC/DAC的时钟、接口与信号链设计

1. 高速数据转换系统概述 在数字信号处理领域,FPGADDSADC/DAC的组合堪称"黄金搭档"。这个组合能做什么?简单来说,就是让数字世界和模拟世界自由对话。想象一下,你正在设计一套无线通信系统,需要产生精确的射…...

树莓派4B无头模式极简指南:5分钟搞定SSH+WiFi预配置(含国内源加速)

树莓派4B无头模式极简配置:SSHWiFi预配置与国内源加速实战 1. 无头模式的核心价值与准备工作 无头模式(Headless Mode)彻底解放了树莓派对显示器和外设的依赖,让这块信用卡大小的计算机真正成为物联网项目的隐形引擎。想象一下&am…...

终极画中画体验:如何用Chrome扩展实现高效多任务视频观看

终极画中画体验:如何用Chrome扩展实现高效多任务视频观看 【免费下载链接】picture-in-picture-chrome-extension 项目地址: https://gitcode.com/gh_mirrors/pi/picture-in-picture-chrome-extension 你是否曾想过一边观看在线课程一边记笔记?或…...

Qwen3-VL-8B Web系统定制化改造:修改chat.html主题色/Logo/欢迎语教程

Qwen3-VL-8B Web系统定制化改造:修改chat.html主题色/Logo/欢迎语教程 1. 项目概述与定制需求 Qwen3-VL-8B AI聊天系统是一个功能完整的Web应用,包含前端界面、代理服务器和推理后端。虽然系统开箱即用,但很多用户希望根据自己的品牌风格进…...

从理论到仿真:用ADS复现Doherty功放的高效奥秘

1. Doherty功放为何能成为5G时代的效率担当? 第一次接触Doherty功放时,我和大多数射频工程师一样充满疑惑:为什么这个诞生于1936年的老技术,反而在5G时代大放异彩?直到我用ADS软件完整复现了它的工作过程,才…...

Navicat高级选项怎么配置同步前执行预处理脚本_定制化规则

Navicat同步前SQL脚本需在「Advanced Options...」中配置,勾选Enable advanced options后才可编辑;脚本于同步执行前运行一次,环境为目标库连接,不支持变量、存储过程及DELIMITER,须匹配目标库版本语法。同步前执行 SQ…...

GBase 8a数据库双活容灾方案之GVR工具核心功能介绍

南大通用(gbase database)可视化集群双活同步工具软件(GBase Visio Rsynctool),是GBASE南大通用自主研发的、专门适用于GBase 8a MPP Cluster的集群间同步工具。通过 GVR,可以灵活高效的实现集群间的数据同步&#xff…...

【AI Agent 从入门到精通】第七章:AI Agent 记忆系统:从短期到长期记忆的设计与实现

📌 前置说明:本系列共 8 章,建议按顺序阅读。 📖 系列导航: 第一章:AI Agent 是什么?一文讲清楚核心概念与架构 第二章:AI Agent 的技术原理:LLM + 规划 + 记忆 + 工具 第三章:主流 AI Agent 框架对比:LangChain、AutoGPT、AutoGen、LlamaIndex 第四章:动手实现你…...